1/* $NetBSD: genfb_machdep.c,v 1.11 2013/07/25 15:09:27 macallan Exp $ */
2
3/*-
4 * Copyright (c) 2009 Jared D. McNeill <jmcneill@invisible.ca>
5 * All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
17 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
18 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
19 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
20 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
21 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
22 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
23 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
24 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
25 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
26 * POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/*
30 * Early attach support for raster consoles
31 */
32
33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: genfb_machdep.c,v 1.11 2013/07/25 15:09:27 macallan Exp $");
35
36#include "opt_mtrr.h"
37
38#include <sys/param.h>
39#include <sys/conf.h>
40#include <sys/device.h>
41#include <sys/ioctl.h>
42#include <sys/kernel.h>
43#include <sys/lwp.h>
44
45#include <sys/bus.h>
46#include <machine/bootinfo.h>
47#include <machine/mtrr.h>
48
49#include <dev/wscons/wsconsio.h>
50#include <dev/wscons/wsdisplayvar.h>
51#include <dev/rasops/rasops.h>
52#include <dev/wsfont/wsfont.h>
53#include <dev/wscons/wsdisplay_vconsvar.h>
54
55#include <dev/wsfb/genfbvar.h>
56#include <arch/x86/include/genfb_machdep.h>
57
58#include "wsdisplay.h"
59#include "genfb.h"
60#include "acpica.h"
61
62#if NWSDISPLAY > 0 && NGENFB > 0
63struct vcons_screen x86_genfb_console_screen;
64
65#if NACPICA > 0
66extern int acpi_md_vesa_modenum;
67#endif
68
69static device_t x86_genfb_console_dev = NULL;
70
71static struct wsscreen_descr x86_genfb_stdscreen = {
72 "std",
73 0, 0,
74 0,
75 0, 0,
76 0,
77 NULL
78};
79
80void
81x86_genfb_set_console_dev(device_t dev)
82{
83 KASSERT(x86_genfb_console_dev == NULL);
84 x86_genfb_console_dev = dev;
85}
86
87void
88x86_genfb_ddb_trap_callback(int where)
89{
90 if (x86_genfb_console_dev == NULL)
91 return;
92
93 if (where) {
94 genfb_enable_polling(x86_genfb_console_dev);
95 } else {
96 genfb_disable_polling(x86_genfb_console_dev);
97 }
98}
99
100void
101x86_genfb_mtrr_init(uint64_t physaddr, uint32_t size)
102{
103#if notyet
104#ifdef MTRR
105 struct mtrr mtrr;
106 int error, n;
107
108 if (mtrr_funcs == NULL) {
109 aprint_debug("%s: no mtrr funcs\n", __func__);
110 return;
111 }
112
113 mtrr.base = physaddr;
114 mtrr.len = size;
115 mtrr.type = MTRR_TYPE_WC;
116 mtrr.flags = MTRR_VALID;
117 mtrr.owner = 0;
118
119 aprint_debug("%s: 0x%" PRIx64 "-0x%" PRIx64 "\n", __func__,
120 mtrr.base, mtrr.base + mtrr.len - 1);
121
122 n = 1;
123 KERNEL_LOCK(1, NULL);
124 error = mtrr_set(&mtrr, &n, curlwp->l_proc, MTRR_GETSET_KERNEL);
125 if (n != 0)
126 mtrr_commit();
127 KERNEL_UNLOCK_ONE(NULL);
128
129 aprint_debug("%s: mtrr_set returned %d\n", __func__, error);
130#else
131 aprint_debug("%s: kernel lacks MTRR option\n", __func__);
132#endif
133#endif
134}
135
136int
137x86_genfb_cnattach(void)
138{
139 static int ncalls = 0;
140 struct rasops_info *ri = &x86_genfb_console_screen.scr_ri;
141 const struct btinfo_framebuffer *fbinfo;
142 bus_space_tag_t t = x86_bus_space_mem;
143 bus_space_handle_t h;
144 void *bits;
145 long defattr;
146 int err;
147
148 /* XXX jmcneill
149 * Defer console initialization until UVM is initialized
150 */
151 ++ncalls;
152 if (ncalls < 3)
153 return -1;
154
155 memset(&x86_genfb_console_screen, 0, sizeof(x86_genfb_console_screen));
156
157 fbinfo = lookup_bootinfo(BTINFO_FRAMEBUFFER);
158 if (fbinfo == NULL || fbinfo->physaddr == 0)
159 return 0;
160
161 err = _x86_memio_map(t, (bus_addr_t)fbinfo->physaddr,
162 fbinfo->height * fbinfo->stride,
163 BUS_SPACE_MAP_LINEAR | BUS_SPACE_MAP_PREFETCHABLE, &h);
164 if (err) {
165 aprint_error("x86_genfb_cnattach: couldn't map framebuffer\n");
166 return 0;
167 }
168
169 bits = bus_space_vaddr(t, h);
170 if (bits == NULL) {
171 aprint_error("x86_genfb_cnattach: couldn't get fb vaddr\n");
172 return 0;
173 }
174
175#if NACPICA > 0
176 acpi_md_vesa_modenum = fbinfo->vbemode;
177#endif
178
179 wsfont_init();
180
181 ri->ri_width = fbinfo->width;
182 ri->ri_height = fbinfo->height;
183 ri->ri_depth = fbinfo->depth;
184 ri->ri_stride = fbinfo->stride;
185 ri->ri_bits = bits;
186 ri->ri_flg = RI_CENTER | RI_FULLCLEAR | RI_CLEAR;
187 rasops_init(ri, ri->ri_width / 8, ri->ri_height / 8);
188 ri->ri_caps = WSSCREEN_WSCOLORS;
189 rasops_reconfig(ri, ri->ri_height / ri->ri_font->fontheight,
190 ri->ri_width / ri->ri_font->fontwidth);
191
192 x86_genfb_stdscreen.nrows = ri->ri_rows;
193 x86_genfb_stdscreen.ncols = ri->ri_cols;
194 x86_genfb_stdscreen.textops = &ri->ri_ops;
195 x86_genfb_stdscreen.capabilities = ri->ri_caps;
196
197 ri->ri_ops.allocattr(ri, 0, 0, 0, &defattr);
198 wsdisplay_preattach(&x86_genfb_stdscreen, ri, 0, 0, defattr);
199
200 return 1;
201}
202#else /* NWSDISPLAY > 0 && NGENFB > 0 */
203int
204x86_genfb_cnattach(void)
205{
206 return 0;
207}
208#endif
209