1*20e2cd35SImre Vadász /*-
2*20e2cd35SImre Vadász * Copyright (c) 1999 Kazutaka YOKOTA <yokota@zodiac.mech.utsunomiya-u.ac.jp>
3*20e2cd35SImre Vadász * All rights reserved.
4*20e2cd35SImre Vadász *
5*20e2cd35SImre Vadász * Redistribution and use in source and binary forms, with or without
6*20e2cd35SImre Vadász * modification, are permitted provided that the following conditions
7*20e2cd35SImre Vadász * are met:
8*20e2cd35SImre Vadász * 1. Redistributions of source code must retain the above copyright
9*20e2cd35SImre Vadász * notice, this list of conditions and the following disclaimer as
10*20e2cd35SImre Vadász * the first lines of this file unmodified.
11*20e2cd35SImre Vadász * 2. Redistributions in binary form must reproduce the above copyright
12*20e2cd35SImre Vadász * notice, this list of conditions and the following disclaimer in the
13*20e2cd35SImre Vadász * documentation and/or other materials provided with the distribution.
14*20e2cd35SImre Vadász *
15*20e2cd35SImre Vadász * THIS SOFTWARE IS PROVIDED BY THE AUTHORS ``AS IS'' AND ANY EXPRESS OR
16*20e2cd35SImre Vadász * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17*20e2cd35SImre Vadász * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18*20e2cd35SImre Vadász * IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY DIRECT, INDIRECT,
19*20e2cd35SImre Vadász * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20*20e2cd35SImre Vadász * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21*20e2cd35SImre Vadász * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22*20e2cd35SImre Vadász * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23*20e2cd35SImre Vadász * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24*20e2cd35SImre Vadász * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25*20e2cd35SImre Vadász *
26*20e2cd35SImre Vadász * $FreeBSD: src/sys/isa/syscons_isa.c,v 1.11.2.2 2001/08/01 10:42:28 yokota Exp $
27*20e2cd35SImre Vadász */
28*20e2cd35SImre Vadász
29*20e2cd35SImre Vadász #include "opt_syscons.h"
30*20e2cd35SImre Vadász
31*20e2cd35SImre Vadász #include <sys/param.h>
32*20e2cd35SImre Vadász #include <sys/systm.h>
33*20e2cd35SImre Vadász #include <sys/kernel.h>
34*20e2cd35SImre Vadász #include <sys/module.h>
35*20e2cd35SImre Vadász #include <sys/systimer.h>
36*20e2cd35SImre Vadász #include <sys/bus.h>
37*20e2cd35SImre Vadász #include <sys/cons.h>
38*20e2cd35SImre Vadász
39*20e2cd35SImre Vadász #include <machine/console.h>
40*20e2cd35SImre Vadász #include <machine/framebuffer.h>
41*20e2cd35SImre Vadász
42*20e2cd35SImre Vadász #include <dev/misc/syscons/syscons.h>
43*20e2cd35SImre Vadász
44*20e2cd35SImre Vadász static devclass_t sc_devclass;
45*20e2cd35SImre Vadász
46*20e2cd35SImre Vadász static void scidentify(driver_t *driver, device_t parent);
47*20e2cd35SImre Vadász static int scprobe(device_t dev);
48*20e2cd35SImre Vadász static int scattach(device_t dev);
49*20e2cd35SImre Vadász
50*20e2cd35SImre Vadász static device_method_t sc_methods[] = {
51*20e2cd35SImre Vadász DEVMETHOD(device_identify, scidentify),
52*20e2cd35SImre Vadász DEVMETHOD(device_probe, scprobe),
53*20e2cd35SImre Vadász DEVMETHOD(device_attach, scattach),
54*20e2cd35SImre Vadász DEVMETHOD_END
55*20e2cd35SImre Vadász };
56*20e2cd35SImre Vadász
57*20e2cd35SImre Vadász static driver_t sc_driver = {
58*20e2cd35SImre Vadász SC_DRIVER_NAME,
59*20e2cd35SImre Vadász sc_methods,
60*20e2cd35SImre Vadász sizeof(sc_softc_t),
61*20e2cd35SImre Vadász };
62*20e2cd35SImre Vadász
63*20e2cd35SImre Vadász static sc_softc_t main_softc;
64*20e2cd35SImre Vadász
65*20e2cd35SImre Vadász static void
scidentify(driver_t * driver,device_t parent)66*20e2cd35SImre Vadász scidentify(driver_t *driver, device_t parent)
67*20e2cd35SImre Vadász {
68*20e2cd35SImre Vadász device_t child;
69*20e2cd35SImre Vadász int i, u;
70*20e2cd35SImre Vadász int f;
71*20e2cd35SImre Vadász
72*20e2cd35SImre Vadász for (i = -1; (i = resource_locate(i, SC_DRIVER_NAME)) >= 0;) {
73*20e2cd35SImre Vadász u = resource_query_unit(i);
74*20e2cd35SImre Vadász if (u < 0)
75*20e2cd35SImre Vadász continue;
76*20e2cd35SImre Vadász if (resource_disabled(SC_DRIVER_NAME, u))
77*20e2cd35SImre Vadász continue;
78*20e2cd35SImre Vadász if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
79*20e2cd35SImre Vadász f = 0;
80*20e2cd35SImre Vadász child = BUS_ADD_CHILD(parent, parent, 0, "sc", u);
81*20e2cd35SImre Vadász if (child == NULL)
82*20e2cd35SImre Vadász panic("%s", __func__);
83*20e2cd35SImre Vadász device_set_flags(child, f);
84*20e2cd35SImre Vadász }
85*20e2cd35SImre Vadász }
86*20e2cd35SImre Vadász
87*20e2cd35SImre Vadász static int
scprobe(device_t dev)88*20e2cd35SImre Vadász scprobe(device_t dev)
89*20e2cd35SImre Vadász {
90*20e2cd35SImre Vadász device_set_desc(dev, "System console");
91*20e2cd35SImre Vadász return sc_probe_unit(device_get_unit(dev), device_get_flags(dev));
92*20e2cd35SImre Vadász }
93*20e2cd35SImre Vadász
94*20e2cd35SImre Vadász static int
scattach(device_t dev)95*20e2cd35SImre Vadász scattach(device_t dev)
96*20e2cd35SImre Vadász {
97*20e2cd35SImre Vadász return sc_attach_unit(device_get_unit(dev), device_get_flags(dev));
98*20e2cd35SImre Vadász }
99*20e2cd35SImre Vadász
100*20e2cd35SImre Vadász int
sc_max_unit(void)101*20e2cd35SImre Vadász sc_max_unit(void)
102*20e2cd35SImre Vadász {
103*20e2cd35SImre Vadász return devclass_get_maxunit(sc_devclass);
104*20e2cd35SImre Vadász }
105*20e2cd35SImre Vadász
106*20e2cd35SImre Vadász sc_softc_t *
sc_get_softc(int unit,int flags)107*20e2cd35SImre Vadász sc_get_softc(int unit, int flags)
108*20e2cd35SImre Vadász {
109*20e2cd35SImre Vadász sc_softc_t *sc;
110*20e2cd35SImre Vadász
111*20e2cd35SImre Vadász if (unit < 0)
112*20e2cd35SImre Vadász return NULL;
113*20e2cd35SImre Vadász if (flags & SC_KERNEL_CONSOLE) {
114*20e2cd35SImre Vadász /* FIXME: clear if it is wired to another unit! */
115*20e2cd35SImre Vadász sc = &main_softc;
116*20e2cd35SImre Vadász } else {
117*20e2cd35SImre Vadász sc = (sc_softc_t *)device_get_softc(devclass_get_device(sc_devclass, unit));
118*20e2cd35SImre Vadász if (sc == NULL)
119*20e2cd35SImre Vadász return NULL;
120*20e2cd35SImre Vadász }
121*20e2cd35SImre Vadász sc->unit = unit;
122*20e2cd35SImre Vadász if (!(sc->flags & SC_INIT_DONE)) {
123*20e2cd35SImre Vadász sc->keyboard = -1;
124*20e2cd35SImre Vadász sc->adapter = -1;
125*20e2cd35SImre Vadász sc->cursor_char = SC_CURSOR_CHAR;
126*20e2cd35SImre Vadász sc->mouse_char = SC_MOUSE_CHAR;
127*20e2cd35SImre Vadász }
128*20e2cd35SImre Vadász return sc;
129*20e2cd35SImre Vadász }
130*20e2cd35SImre Vadász
131*20e2cd35SImre Vadász sc_softc_t *
sc_find_softc(struct video_adapter * adp,struct keyboard * kbd)132*20e2cd35SImre Vadász sc_find_softc(struct video_adapter *adp, struct keyboard *kbd)
133*20e2cd35SImre Vadász {
134*20e2cd35SImre Vadász sc_softc_t *sc;
135*20e2cd35SImre Vadász int units;
136*20e2cd35SImre Vadász int i;
137*20e2cd35SImre Vadász
138*20e2cd35SImre Vadász sc = &main_softc;
139*20e2cd35SImre Vadász if (((adp == NULL) || (adp == sc->adp))
140*20e2cd35SImre Vadász && ((kbd == NULL) || (kbd == sc->kbd)))
141*20e2cd35SImre Vadász return sc;
142*20e2cd35SImre Vadász units = devclass_get_maxunit(sc_devclass);
143*20e2cd35SImre Vadász for (i = 0; i < units; ++i) {
144*20e2cd35SImre Vadász sc = (sc_softc_t *)device_get_softc(devclass_get_device(sc_devclass, i));
145*20e2cd35SImre Vadász if (sc == NULL)
146*20e2cd35SImre Vadász continue;
147*20e2cd35SImre Vadász if (((adp == NULL) || (adp == sc->adp))
148*20e2cd35SImre Vadász && ((kbd == NULL) || (kbd == sc->kbd)))
149*20e2cd35SImre Vadász return sc;
150*20e2cd35SImre Vadász }
151*20e2cd35SImre Vadász return NULL;
152*20e2cd35SImre Vadász }
153*20e2cd35SImre Vadász
154*20e2cd35SImre Vadász int
sc_get_cons_priority(int * unit,int * flags)155*20e2cd35SImre Vadász sc_get_cons_priority(int *unit, int *flags)
156*20e2cd35SImre Vadász {
157*20e2cd35SImre Vadász int u, f;
158*20e2cd35SImre Vadász int i;
159*20e2cd35SImre Vadász int have_efi_fb = (probe_efi_fb(1) == 0);
160*20e2cd35SImre Vadász
161*20e2cd35SImre Vadász *unit = -1;
162*20e2cd35SImre Vadász for (i = -1; (i = resource_locate(i, SC_DRIVER_NAME)) >= 0;) {
163*20e2cd35SImre Vadász u = resource_query_unit(i);
164*20e2cd35SImre Vadász if (resource_disabled(SC_DRIVER_NAME, u))
165*20e2cd35SImre Vadász continue;
166*20e2cd35SImre Vadász if (resource_int_value(SC_DRIVER_NAME, u, "flags", &f) != 0)
167*20e2cd35SImre Vadász f = 0;
168*20e2cd35SImre Vadász /* We prefer the EFI Framebuffer over other video devices */
169*20e2cd35SImre Vadász if (have_efi_fb && !(f & SC_EFI_FB))
170*20e2cd35SImre Vadász continue;
171*20e2cd35SImre Vadász if (f & SC_KERNEL_CONSOLE) {
172*20e2cd35SImre Vadász /* the user designates this unit to be the console */
173*20e2cd35SImre Vadász *unit = u;
174*20e2cd35SImre Vadász *flags = f;
175*20e2cd35SImre Vadász break;
176*20e2cd35SImre Vadász }
177*20e2cd35SImre Vadász if (*unit < 0) {
178*20e2cd35SImre Vadász /* ...otherwise remember the first found unit */
179*20e2cd35SImre Vadász *unit = u;
180*20e2cd35SImre Vadász *flags = f;
181*20e2cd35SImre Vadász }
182*20e2cd35SImre Vadász }
183*20e2cd35SImre Vadász if ((i < 0) && (*unit < 0))
184*20e2cd35SImre Vadász return CN_DEAD;
185*20e2cd35SImre Vadász if (!have_efi_fb)
186*20e2cd35SImre Vadász *flags &= ~SC_EFI_FB;
187*20e2cd35SImre Vadász #if 0
188*20e2cd35SImre Vadász return ((*flags & SC_KERNEL_CONSOLE) ? CN_INTERNAL : CN_NORMAL);
189*20e2cd35SImre Vadász #endif
190*20e2cd35SImre Vadász return CN_INTERNAL;
191*20e2cd35SImre Vadász }
192*20e2cd35SImre Vadász
193*20e2cd35SImre Vadász void
sc_get_bios_values(bios_values_t * values)194*20e2cd35SImre Vadász sc_get_bios_values(bios_values_t *values)
195*20e2cd35SImre Vadász {
196*20e2cd35SImre Vadász values->cursor_start = 0;
197*20e2cd35SImre Vadász values->cursor_end = 32;
198*20e2cd35SImre Vadász values->shift_state = 0;
199*20e2cd35SImre Vadász values->bell_pitch = BELL_PITCH;
200*20e2cd35SImre Vadász }
201*20e2cd35SImre Vadász
202*20e2cd35SImre Vadász int
sc_tone(int hertz)203*20e2cd35SImre Vadász sc_tone(int hertz)
204*20e2cd35SImre Vadász {
205*20e2cd35SImre Vadász return EBUSY;
206*20e2cd35SImre Vadász #if 0
207*20e2cd35SImre Vadász /* XXX use sound device if available */
208*20e2cd35SImre Vadász return 0;
209*20e2cd35SImre Vadász #endif
210*20e2cd35SImre Vadász }
211*20e2cd35SImre Vadász
212*20e2cd35SImre Vadász DRIVER_MODULE(sc, nexus, sc_driver, sc_devclass, NULL, NULL);
213