]> CyberLeo.Net >> Repos - FreeBSD/stable/9.git/blob - sys/dev/vt/hw/xboxfb/xboxfb.c
MFC 219886, 226100, 226111, 226341, 242529, 259015, 259016, 259019, 259049,
[FreeBSD/stable/9.git] / sys / dev / vt / hw / xboxfb / xboxfb.c
1 /*-
2  * Copyright (c) 2013 The FreeBSD Foundation
3  * All rights reserved.
4  *
5  * This software was developed by Aleksandr Rybalko under sponsorship from the
6  * FreeBSD Foundation.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  *    notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in the
15  *    documentation and/or other materials provided with the distribution.
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
18  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27  * SUCH DAMAGE.
28  *
29  * $FreeBSD$
30  */
31
32 #include <sys/cdefs.h>
33 __FBSDID("$FreeBSD$");
34
35 #include <sys/param.h>
36 #include <sys/systm.h>
37 #include <sys/kernel.h>
38 #include <sys/fbio.h>
39
40 #include "opt_platform.h"
41
42 #include <dev/vt/vt.h>
43 #include <dev/vt/hw/fb/vt_fb.h>
44 #include <dev/vt/colors/vt_termcolors.h>
45
46 #include <vm/vm.h>
47 #include <vm/pmap.h>
48
49 #include <machine/bus.h>
50 #include <machine/pmap.h>
51 #include <machine/vmparam.h>
52 #include <machine/xbox.h>
53
54 #define VT_XBOX_WIDTH   640
55 #define VT_XBOX_HEIGHT  480
56
57 static vd_init_t xboxfb_init;
58
59 static struct vt_driver xboxfb_driver = {
60         .vd_init = xboxfb_init,
61         .vd_blank = vt_fb_blank,
62         .vd_bitbltchr = vt_fb_bitbltchr,
63         .vd_priority = VD_PRIORITY_GENERIC,
64 };
65
66 static struct fb_info xboxfb_info;
67 VT_CONSDEV_DECLARE(xboxfb_driver, PIXEL_WIDTH(VT_XBOX_WIDTH),
68     PIXEL_HEIGHT(VT_XBOX_HEIGHT), &xboxfb_info);
69
70 static int
71 xboxfb_init(struct vt_device *vd)
72 {
73         struct fb_info *info;
74         int i;
75
76         if (!arch_i386_is_xbox)
77                 return (CN_DEAD);
78
79         info = &xboxfb_info;
80         /*
81          * We must make a mapping from video framebuffer memory
82          * to real. This is very crude:  we map the entire
83          * videomemory to PAGE_SIZE! Since our kernel lives at
84          * it's relocated address range (0xc0xxxxxx), it won't
85          * care.
86          *
87          * We use address PAGE_SIZE and up so we can still trap
88          * NULL pointers.  Once the real init is called, the
89          * mapping will be done via the OS and stored in a more
90          * sensible location ... but since we're not fully
91          * initialized, this is our only way to go :-(
92          */
93         for (i = 0; i < (XBOX_FB_SIZE / PAGE_SIZE); i++) {
94                 pmap_kenter(((i + 1) * PAGE_SIZE),
95                     XBOX_FB_START + (i * PAGE_SIZE));
96         }
97         pmap_kenter((i + 1) * PAGE_SIZE,
98             XBOX_FB_START_PTR - XBOX_FB_START_PTR % PAGE_SIZE);
99
100         /* Ensure the framebuffer is where we want it to be. */
101         *(uint32_t *)((i + 1) * PAGE_SIZE + XBOX_FB_START_PTR % PAGE_SIZE) =
102             XBOX_FB_START;
103
104         /* Initialize fb_info. */
105         info = vd->vd_softc;
106
107         info->fb_width = VT_XBOX_WIDTH;
108         info->fb_height = VT_XBOX_HEIGHT;
109
110         info->fb_size = XBOX_FB_SIZE;
111         info->fb_stride = VT_XBOX_WIDTH * 4; /* 32bits per pixel. */
112
113         info->fb_vbase = PAGE_SIZE;
114         info->fb_pbase = XBOX_FB_START_PTR;
115
116         /* Get pixel storage size. */
117         info->fb_bpp = 32;
118         /* Get color depth. */
119         info->fb_depth = 24;
120
121         vt_generate_vga_palette(info->fb_cmap, COLOR_FORMAT_RGB, 255, 0, 255,
122             8, 255, 16);
123         fb_probe(info);
124         vt_fb_init(vd);
125
126         return (CN_INTERNAL);
127 }
128
129 static void
130 xbox_remap(void *unused)
131 {
132         struct fb_info *info;
133
134         if (!arch_i386_is_xbox)
135                 return;
136
137         info = &xboxfb_info;
138         info->fb_vbase = (intptr_t)pmap_mapdev(info->fb_pbase, info->fb_size);
139 }
140
141 SYSINIT(xboxfb, SI_SUB_DRIVERS, SI_ORDER_ANY, xbox_remap, NULL);