1*5c4a5fe1SAndy Fiddaman /*-
2*5c4a5fe1SAndy Fiddaman * SPDX-License-Identifier: BSD-2-Clause
3*5c4a5fe1SAndy Fiddaman *
4*5c4a5fe1SAndy Fiddaman * Copyright (c) 2014 Tycho Nightingale <tycho.nightingale@pluribusnetworks.com>
5*5c4a5fe1SAndy Fiddaman * Copyright (c) 2015 Nahanni Systems Inc.
6*5c4a5fe1SAndy Fiddaman * All rights reserved.
7*5c4a5fe1SAndy Fiddaman *
8*5c4a5fe1SAndy Fiddaman * Redistribution and use in source and binary forms, with or without
9*5c4a5fe1SAndy Fiddaman * modification, are permitted provided that the following conditions
10*5c4a5fe1SAndy Fiddaman * are met:
11*5c4a5fe1SAndy Fiddaman * 1. Redistributions of source code must retain the above copyright
12*5c4a5fe1SAndy Fiddaman * notice, this list of conditions and the following disclaimer.
13*5c4a5fe1SAndy Fiddaman * 2. Redistributions in binary form must reproduce the above copyright
14*5c4a5fe1SAndy Fiddaman * notice, this list of conditions and the following disclaimer in the
15*5c4a5fe1SAndy Fiddaman * documentation and/or other materials provided with the distribution.
16*5c4a5fe1SAndy Fiddaman *
17*5c4a5fe1SAndy Fiddaman * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND
18*5c4a5fe1SAndy Fiddaman * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19*5c4a5fe1SAndy Fiddaman * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20*5c4a5fe1SAndy Fiddaman * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
21*5c4a5fe1SAndy Fiddaman * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22*5c4a5fe1SAndy Fiddaman * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23*5c4a5fe1SAndy Fiddaman * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24*5c4a5fe1SAndy Fiddaman * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25*5c4a5fe1SAndy Fiddaman * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26*5c4a5fe1SAndy Fiddaman * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27*5c4a5fe1SAndy Fiddaman * SUCH DAMAGE.
28*5c4a5fe1SAndy Fiddaman */
29*5c4a5fe1SAndy Fiddaman
30*5c4a5fe1SAndy Fiddaman
31*5c4a5fe1SAndy Fiddaman #include <sys/types.h>
32*5c4a5fe1SAndy Fiddaman
33*5c4a5fe1SAndy Fiddaman #include <machine/vmm.h>
34*5c4a5fe1SAndy Fiddaman
35*5c4a5fe1SAndy Fiddaman #include <vmmapi.h>
36*5c4a5fe1SAndy Fiddaman
37*5c4a5fe1SAndy Fiddaman #include <assert.h>
38*5c4a5fe1SAndy Fiddaman #include <errno.h>
39*5c4a5fe1SAndy Fiddaman #include <stdbool.h>
40*5c4a5fe1SAndy Fiddaman #include <stdlib.h>
41*5c4a5fe1SAndy Fiddaman #include <stdio.h>
42*5c4a5fe1SAndy Fiddaman #include <string.h>
43*5c4a5fe1SAndy Fiddaman #include <unistd.h>
44*5c4a5fe1SAndy Fiddaman #include <pthread.h>
45*5c4a5fe1SAndy Fiddaman #include <pthread_np.h>
46*5c4a5fe1SAndy Fiddaman
47*5c4a5fe1SAndy Fiddaman #include "acpi.h"
48*5c4a5fe1SAndy Fiddaman #include "atkbdc.h"
49*5c4a5fe1SAndy Fiddaman #include "inout.h"
50*5c4a5fe1SAndy Fiddaman #include "pci_emul.h"
51*5c4a5fe1SAndy Fiddaman #include "pci_irq.h"
52*5c4a5fe1SAndy Fiddaman #include "pci_lpc.h"
53*5c4a5fe1SAndy Fiddaman #include "ps2kbd.h"
54*5c4a5fe1SAndy Fiddaman #include "ps2mouse.h"
55*5c4a5fe1SAndy Fiddaman
56*5c4a5fe1SAndy Fiddaman #define KBD_DATA_PORT 0x60
57*5c4a5fe1SAndy Fiddaman
58*5c4a5fe1SAndy Fiddaman #define KBD_STS_CTL_PORT 0x64
59*5c4a5fe1SAndy Fiddaman
60*5c4a5fe1SAndy Fiddaman #define KBDC_RESET 0xfe
61*5c4a5fe1SAndy Fiddaman
62*5c4a5fe1SAndy Fiddaman #define KBD_DEV_IRQ 1
63*5c4a5fe1SAndy Fiddaman #define AUX_DEV_IRQ 12
64*5c4a5fe1SAndy Fiddaman
65*5c4a5fe1SAndy Fiddaman /* controller commands */
66*5c4a5fe1SAndy Fiddaman #define KBDC_SET_COMMAND_BYTE 0x60
67*5c4a5fe1SAndy Fiddaman #define KBDC_GET_COMMAND_BYTE 0x20
68*5c4a5fe1SAndy Fiddaman #define KBDC_DISABLE_AUX_PORT 0xa7
69*5c4a5fe1SAndy Fiddaman #define KBDC_ENABLE_AUX_PORT 0xa8
70*5c4a5fe1SAndy Fiddaman #define KBDC_TEST_AUX_PORT 0xa9
71*5c4a5fe1SAndy Fiddaman #define KBDC_TEST_CTRL 0xaa
72*5c4a5fe1SAndy Fiddaman #define KBDC_TEST_KBD_PORT 0xab
73*5c4a5fe1SAndy Fiddaman #define KBDC_DISABLE_KBD_PORT 0xad
74*5c4a5fe1SAndy Fiddaman #define KBDC_ENABLE_KBD_PORT 0xae
75*5c4a5fe1SAndy Fiddaman #define KBDC_READ_INPORT 0xc0
76*5c4a5fe1SAndy Fiddaman #define KBDC_READ_OUTPORT 0xd0
77*5c4a5fe1SAndy Fiddaman #define KBDC_WRITE_OUTPORT 0xd1
78*5c4a5fe1SAndy Fiddaman #define KBDC_WRITE_KBD_OUTBUF 0xd2
79*5c4a5fe1SAndy Fiddaman #define KBDC_WRITE_AUX_OUTBUF 0xd3
80*5c4a5fe1SAndy Fiddaman #define KBDC_WRITE_TO_AUX 0xd4
81*5c4a5fe1SAndy Fiddaman
82*5c4a5fe1SAndy Fiddaman /* controller command byte (set by KBDC_SET_COMMAND_BYTE) */
83*5c4a5fe1SAndy Fiddaman #define KBD_TRANSLATION 0x40
84*5c4a5fe1SAndy Fiddaman #define KBD_SYS_FLAG_BIT 0x04
85*5c4a5fe1SAndy Fiddaman #define KBD_DISABLE_KBD_PORT 0x10
86*5c4a5fe1SAndy Fiddaman #define KBD_DISABLE_AUX_PORT 0x20
87*5c4a5fe1SAndy Fiddaman #define KBD_ENABLE_AUX_INT 0x02
88*5c4a5fe1SAndy Fiddaman #define KBD_ENABLE_KBD_INT 0x01
89*5c4a5fe1SAndy Fiddaman #define KBD_KBD_CONTROL_BITS (KBD_DISABLE_KBD_PORT | KBD_ENABLE_KBD_INT)
90*5c4a5fe1SAndy Fiddaman #define KBD_AUX_CONTROL_BITS (KBD_DISABLE_AUX_PORT | KBD_ENABLE_AUX_INT)
91*5c4a5fe1SAndy Fiddaman
92*5c4a5fe1SAndy Fiddaman /* controller status bits */
93*5c4a5fe1SAndy Fiddaman #define KBDS_KBD_BUFFER_FULL 0x01
94*5c4a5fe1SAndy Fiddaman #define KBDS_SYS_FLAG 0x04
95*5c4a5fe1SAndy Fiddaman #define KBDS_CTRL_FLAG 0x08
96*5c4a5fe1SAndy Fiddaman #define KBDS_AUX_BUFFER_FULL 0x20
97*5c4a5fe1SAndy Fiddaman
98*5c4a5fe1SAndy Fiddaman /* controller output port */
99*5c4a5fe1SAndy Fiddaman #define KBDO_KBD_OUTFULL 0x10
100*5c4a5fe1SAndy Fiddaman #define KBDO_AUX_OUTFULL 0x20
101*5c4a5fe1SAndy Fiddaman
102*5c4a5fe1SAndy Fiddaman #define RAMSZ 32
103*5c4a5fe1SAndy Fiddaman #define FIFOSZ 15
104*5c4a5fe1SAndy Fiddaman #define CTRL_CMD_FLAG 0x8000
105*5c4a5fe1SAndy Fiddaman
106*5c4a5fe1SAndy Fiddaman struct kbd_dev {
107*5c4a5fe1SAndy Fiddaman bool irq_active;
108*5c4a5fe1SAndy Fiddaman int irq;
109*5c4a5fe1SAndy Fiddaman
110*5c4a5fe1SAndy Fiddaman uint8_t buffer[FIFOSZ];
111*5c4a5fe1SAndy Fiddaman int brd, bwr;
112*5c4a5fe1SAndy Fiddaman int bcnt;
113*5c4a5fe1SAndy Fiddaman };
114*5c4a5fe1SAndy Fiddaman
115*5c4a5fe1SAndy Fiddaman struct aux_dev {
116*5c4a5fe1SAndy Fiddaman bool irq_active;
117*5c4a5fe1SAndy Fiddaman int irq;
118*5c4a5fe1SAndy Fiddaman };
119*5c4a5fe1SAndy Fiddaman
120*5c4a5fe1SAndy Fiddaman struct atkbdc_softc {
121*5c4a5fe1SAndy Fiddaman struct vmctx *ctx;
122*5c4a5fe1SAndy Fiddaman pthread_mutex_t mtx;
123*5c4a5fe1SAndy Fiddaman
124*5c4a5fe1SAndy Fiddaman struct ps2kbd_softc *ps2kbd_sc;
125*5c4a5fe1SAndy Fiddaman struct ps2mouse_softc *ps2mouse_sc;
126*5c4a5fe1SAndy Fiddaman
127*5c4a5fe1SAndy Fiddaman uint8_t status; /* status register */
128*5c4a5fe1SAndy Fiddaman uint8_t outport; /* controller output port */
129*5c4a5fe1SAndy Fiddaman uint8_t ram[RAMSZ]; /* byte0 = controller config */
130*5c4a5fe1SAndy Fiddaman
131*5c4a5fe1SAndy Fiddaman uint32_t curcmd; /* current command for next byte */
132*5c4a5fe1SAndy Fiddaman uint32_t ctrlbyte;
133*5c4a5fe1SAndy Fiddaman
134*5c4a5fe1SAndy Fiddaman struct kbd_dev kbd;
135*5c4a5fe1SAndy Fiddaman struct aux_dev aux;
136*5c4a5fe1SAndy Fiddaman };
137*5c4a5fe1SAndy Fiddaman
138*5c4a5fe1SAndy Fiddaman static void
atkbdc_assert_kbd_intr(struct atkbdc_softc * sc)139*5c4a5fe1SAndy Fiddaman atkbdc_assert_kbd_intr(struct atkbdc_softc *sc)
140*5c4a5fe1SAndy Fiddaman {
141*5c4a5fe1SAndy Fiddaman if ((sc->ram[0] & KBD_ENABLE_KBD_INT) != 0) {
142*5c4a5fe1SAndy Fiddaman sc->kbd.irq_active = true;
143*5c4a5fe1SAndy Fiddaman vm_isa_pulse_irq(sc->ctx, sc->kbd.irq, sc->kbd.irq);
144*5c4a5fe1SAndy Fiddaman }
145*5c4a5fe1SAndy Fiddaman }
146*5c4a5fe1SAndy Fiddaman
147*5c4a5fe1SAndy Fiddaman static void
atkbdc_assert_aux_intr(struct atkbdc_softc * sc)148*5c4a5fe1SAndy Fiddaman atkbdc_assert_aux_intr(struct atkbdc_softc *sc)
149*5c4a5fe1SAndy Fiddaman {
150*5c4a5fe1SAndy Fiddaman if ((sc->ram[0] & KBD_ENABLE_AUX_INT) != 0) {
151*5c4a5fe1SAndy Fiddaman sc->aux.irq_active = true;
152*5c4a5fe1SAndy Fiddaman vm_isa_pulse_irq(sc->ctx, sc->aux.irq, sc->aux.irq);
153*5c4a5fe1SAndy Fiddaman }
154*5c4a5fe1SAndy Fiddaman }
155*5c4a5fe1SAndy Fiddaman
156*5c4a5fe1SAndy Fiddaman static int
atkbdc_kbd_queue_data(struct atkbdc_softc * sc,uint8_t val)157*5c4a5fe1SAndy Fiddaman atkbdc_kbd_queue_data(struct atkbdc_softc *sc, uint8_t val)
158*5c4a5fe1SAndy Fiddaman {
159*5c4a5fe1SAndy Fiddaman assert(pthread_mutex_isowned_np(&sc->mtx));
160*5c4a5fe1SAndy Fiddaman
161*5c4a5fe1SAndy Fiddaman if (sc->kbd.bcnt < FIFOSZ) {
162*5c4a5fe1SAndy Fiddaman sc->kbd.buffer[sc->kbd.bwr] = val;
163*5c4a5fe1SAndy Fiddaman sc->kbd.bwr = (sc->kbd.bwr + 1) % FIFOSZ;
164*5c4a5fe1SAndy Fiddaman sc->kbd.bcnt++;
165*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_KBD_BUFFER_FULL;
166*5c4a5fe1SAndy Fiddaman sc->outport |= KBDO_KBD_OUTFULL;
167*5c4a5fe1SAndy Fiddaman } else {
168*5c4a5fe1SAndy Fiddaman printf("atkbd data buffer full\n");
169*5c4a5fe1SAndy Fiddaman }
170*5c4a5fe1SAndy Fiddaman
171*5c4a5fe1SAndy Fiddaman return (sc->kbd.bcnt < FIFOSZ);
172*5c4a5fe1SAndy Fiddaman }
173*5c4a5fe1SAndy Fiddaman
174*5c4a5fe1SAndy Fiddaman static void
atkbdc_kbd_read(struct atkbdc_softc * sc)175*5c4a5fe1SAndy Fiddaman atkbdc_kbd_read(struct atkbdc_softc *sc)
176*5c4a5fe1SAndy Fiddaman {
177*5c4a5fe1SAndy Fiddaman const uint8_t translation[256] = {
178*5c4a5fe1SAndy Fiddaman 0xff, 0x43, 0x41, 0x3f, 0x3d, 0x3b, 0x3c, 0x58,
179*5c4a5fe1SAndy Fiddaman 0x64, 0x44, 0x42, 0x40, 0x3e, 0x0f, 0x29, 0x59,
180*5c4a5fe1SAndy Fiddaman 0x65, 0x38, 0x2a, 0x70, 0x1d, 0x10, 0x02, 0x5a,
181*5c4a5fe1SAndy Fiddaman 0x66, 0x71, 0x2c, 0x1f, 0x1e, 0x11, 0x03, 0x5b,
182*5c4a5fe1SAndy Fiddaman 0x67, 0x2e, 0x2d, 0x20, 0x12, 0x05, 0x04, 0x5c,
183*5c4a5fe1SAndy Fiddaman 0x68, 0x39, 0x2f, 0x21, 0x14, 0x13, 0x06, 0x5d,
184*5c4a5fe1SAndy Fiddaman 0x69, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, 0x5e,
185*5c4a5fe1SAndy Fiddaman 0x6a, 0x72, 0x32, 0x24, 0x16, 0x08, 0x09, 0x5f,
186*5c4a5fe1SAndy Fiddaman 0x6b, 0x33, 0x25, 0x17, 0x18, 0x0b, 0x0a, 0x60,
187*5c4a5fe1SAndy Fiddaman 0x6c, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0c, 0x61,
188*5c4a5fe1SAndy Fiddaman 0x6d, 0x73, 0x28, 0x74, 0x1a, 0x0d, 0x62, 0x6e,
189*5c4a5fe1SAndy Fiddaman 0x3a, 0x36, 0x1c, 0x1b, 0x75, 0x2b, 0x63, 0x76,
190*5c4a5fe1SAndy Fiddaman 0x55, 0x56, 0x77, 0x78, 0x79, 0x7a, 0x0e, 0x7b,
191*5c4a5fe1SAndy Fiddaman 0x7c, 0x4f, 0x7d, 0x4b, 0x47, 0x7e, 0x7f, 0x6f,
192*5c4a5fe1SAndy Fiddaman 0x52, 0x53, 0x50, 0x4c, 0x4d, 0x48, 0x01, 0x45,
193*5c4a5fe1SAndy Fiddaman 0x57, 0x4e, 0x51, 0x4a, 0x37, 0x49, 0x46, 0x54,
194*5c4a5fe1SAndy Fiddaman 0x80, 0x81, 0x82, 0x41, 0x54, 0x85, 0x86, 0x87,
195*5c4a5fe1SAndy Fiddaman 0x88, 0x89, 0x8a, 0x8b, 0x8c, 0x8d, 0x8e, 0x8f,
196*5c4a5fe1SAndy Fiddaman 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97,
197*5c4a5fe1SAndy Fiddaman 0x98, 0x99, 0x9a, 0x9b, 0x9c, 0x9d, 0x9e, 0x9f,
198*5c4a5fe1SAndy Fiddaman 0xa0, 0xa1, 0xa2, 0xa3, 0xa4, 0xa5, 0xa6, 0xa7,
199*5c4a5fe1SAndy Fiddaman 0xa8, 0xa9, 0xaa, 0xab, 0xac, 0xad, 0xae, 0xaf,
200*5c4a5fe1SAndy Fiddaman 0xb0, 0xb1, 0xb2, 0xb3, 0xb4, 0xb5, 0xb6, 0xb7,
201*5c4a5fe1SAndy Fiddaman 0xb8, 0xb9, 0xba, 0xbb, 0xbc, 0xbd, 0xbe, 0xbf,
202*5c4a5fe1SAndy Fiddaman 0xc0, 0xc1, 0xc2, 0xc3, 0xc4, 0xc5, 0xc6, 0xc7,
203*5c4a5fe1SAndy Fiddaman 0xc8, 0xc9, 0xca, 0xcb, 0xcc, 0xcd, 0xce, 0xcf,
204*5c4a5fe1SAndy Fiddaman 0xd0, 0xd1, 0xd2, 0xd3, 0xd4, 0xd5, 0xd6, 0xd7,
205*5c4a5fe1SAndy Fiddaman 0xd8, 0xd9, 0xda, 0xdb, 0xdc, 0xdd, 0xde, 0xdf,
206*5c4a5fe1SAndy Fiddaman 0xe0, 0xe1, 0xe2, 0xe3, 0xe4, 0xe5, 0xe6, 0xe7,
207*5c4a5fe1SAndy Fiddaman 0xe8, 0xe9, 0xea, 0xeb, 0xec, 0xed, 0xee, 0xef,
208*5c4a5fe1SAndy Fiddaman 0xf0, 0xf1, 0xf2, 0xf3, 0xf4, 0xf5, 0xf6, 0xf7,
209*5c4a5fe1SAndy Fiddaman 0xf8, 0xf9, 0xfa, 0xfb, 0xfc, 0xfd, 0xfe, 0xff
210*5c4a5fe1SAndy Fiddaman };
211*5c4a5fe1SAndy Fiddaman uint8_t val;
212*5c4a5fe1SAndy Fiddaman uint8_t release = 0;
213*5c4a5fe1SAndy Fiddaman
214*5c4a5fe1SAndy Fiddaman assert(pthread_mutex_isowned_np(&sc->mtx));
215*5c4a5fe1SAndy Fiddaman
216*5c4a5fe1SAndy Fiddaman if (sc->ram[0] & KBD_TRANSLATION) {
217*5c4a5fe1SAndy Fiddaman while (ps2kbd_read(sc->ps2kbd_sc, &val) != -1) {
218*5c4a5fe1SAndy Fiddaman if (val == 0xf0) {
219*5c4a5fe1SAndy Fiddaman release = 0x80;
220*5c4a5fe1SAndy Fiddaman continue;
221*5c4a5fe1SAndy Fiddaman } else {
222*5c4a5fe1SAndy Fiddaman val = translation[val] | release;
223*5c4a5fe1SAndy Fiddaman }
224*5c4a5fe1SAndy Fiddaman atkbdc_kbd_queue_data(sc, val);
225*5c4a5fe1SAndy Fiddaman break;
226*5c4a5fe1SAndy Fiddaman }
227*5c4a5fe1SAndy Fiddaman } else {
228*5c4a5fe1SAndy Fiddaman while (sc->kbd.bcnt < FIFOSZ) {
229*5c4a5fe1SAndy Fiddaman if (ps2kbd_read(sc->ps2kbd_sc, &val) != -1)
230*5c4a5fe1SAndy Fiddaman atkbdc_kbd_queue_data(sc, val);
231*5c4a5fe1SAndy Fiddaman else
232*5c4a5fe1SAndy Fiddaman break;
233*5c4a5fe1SAndy Fiddaman }
234*5c4a5fe1SAndy Fiddaman }
235*5c4a5fe1SAndy Fiddaman
236*5c4a5fe1SAndy Fiddaman if (((sc->ram[0] & KBD_DISABLE_AUX_PORT) ||
237*5c4a5fe1SAndy Fiddaman ps2mouse_fifocnt(sc->ps2mouse_sc) == 0) && sc->kbd.bcnt > 0)
238*5c4a5fe1SAndy Fiddaman atkbdc_assert_kbd_intr(sc);
239*5c4a5fe1SAndy Fiddaman }
240*5c4a5fe1SAndy Fiddaman
241*5c4a5fe1SAndy Fiddaman static void
atkbdc_aux_poll(struct atkbdc_softc * sc)242*5c4a5fe1SAndy Fiddaman atkbdc_aux_poll(struct atkbdc_softc *sc)
243*5c4a5fe1SAndy Fiddaman {
244*5c4a5fe1SAndy Fiddaman if (ps2mouse_fifocnt(sc->ps2mouse_sc) > 0) {
245*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL;
246*5c4a5fe1SAndy Fiddaman sc->outport |= KBDO_AUX_OUTFULL;
247*5c4a5fe1SAndy Fiddaman atkbdc_assert_aux_intr(sc);
248*5c4a5fe1SAndy Fiddaman }
249*5c4a5fe1SAndy Fiddaman }
250*5c4a5fe1SAndy Fiddaman
251*5c4a5fe1SAndy Fiddaman static void
atkbdc_kbd_poll(struct atkbdc_softc * sc)252*5c4a5fe1SAndy Fiddaman atkbdc_kbd_poll(struct atkbdc_softc *sc)
253*5c4a5fe1SAndy Fiddaman {
254*5c4a5fe1SAndy Fiddaman assert(pthread_mutex_isowned_np(&sc->mtx));
255*5c4a5fe1SAndy Fiddaman
256*5c4a5fe1SAndy Fiddaman atkbdc_kbd_read(sc);
257*5c4a5fe1SAndy Fiddaman }
258*5c4a5fe1SAndy Fiddaman
259*5c4a5fe1SAndy Fiddaman static void
atkbdc_poll(struct atkbdc_softc * sc)260*5c4a5fe1SAndy Fiddaman atkbdc_poll(struct atkbdc_softc *sc)
261*5c4a5fe1SAndy Fiddaman {
262*5c4a5fe1SAndy Fiddaman atkbdc_aux_poll(sc);
263*5c4a5fe1SAndy Fiddaman atkbdc_kbd_poll(sc);
264*5c4a5fe1SAndy Fiddaman }
265*5c4a5fe1SAndy Fiddaman
266*5c4a5fe1SAndy Fiddaman static void
atkbdc_dequeue_data(struct atkbdc_softc * sc,uint8_t * buf)267*5c4a5fe1SAndy Fiddaman atkbdc_dequeue_data(struct atkbdc_softc *sc, uint8_t *buf)
268*5c4a5fe1SAndy Fiddaman {
269*5c4a5fe1SAndy Fiddaman assert(pthread_mutex_isowned_np(&sc->mtx));
270*5c4a5fe1SAndy Fiddaman
271*5c4a5fe1SAndy Fiddaman if (ps2mouse_read(sc->ps2mouse_sc, buf) == 0) {
272*5c4a5fe1SAndy Fiddaman if (ps2mouse_fifocnt(sc->ps2mouse_sc) == 0) {
273*5c4a5fe1SAndy Fiddaman if (sc->kbd.bcnt == 0)
274*5c4a5fe1SAndy Fiddaman sc->status &= ~(KBDS_AUX_BUFFER_FULL |
275*5c4a5fe1SAndy Fiddaman KBDS_KBD_BUFFER_FULL);
276*5c4a5fe1SAndy Fiddaman else
277*5c4a5fe1SAndy Fiddaman sc->status &= ~(KBDS_AUX_BUFFER_FULL);
278*5c4a5fe1SAndy Fiddaman sc->outport &= ~KBDO_AUX_OUTFULL;
279*5c4a5fe1SAndy Fiddaman }
280*5c4a5fe1SAndy Fiddaman
281*5c4a5fe1SAndy Fiddaman atkbdc_poll(sc);
282*5c4a5fe1SAndy Fiddaman return;
283*5c4a5fe1SAndy Fiddaman }
284*5c4a5fe1SAndy Fiddaman
285*5c4a5fe1SAndy Fiddaman if (sc->kbd.bcnt > 0) {
286*5c4a5fe1SAndy Fiddaman *buf = sc->kbd.buffer[sc->kbd.brd];
287*5c4a5fe1SAndy Fiddaman sc->kbd.brd = (sc->kbd.brd + 1) % FIFOSZ;
288*5c4a5fe1SAndy Fiddaman sc->kbd.bcnt--;
289*5c4a5fe1SAndy Fiddaman if (sc->kbd.bcnt == 0) {
290*5c4a5fe1SAndy Fiddaman sc->status &= ~KBDS_KBD_BUFFER_FULL;
291*5c4a5fe1SAndy Fiddaman sc->outport &= ~KBDO_KBD_OUTFULL;
292*5c4a5fe1SAndy Fiddaman }
293*5c4a5fe1SAndy Fiddaman
294*5c4a5fe1SAndy Fiddaman atkbdc_poll(sc);
295*5c4a5fe1SAndy Fiddaman }
296*5c4a5fe1SAndy Fiddaman
297*5c4a5fe1SAndy Fiddaman if (ps2mouse_fifocnt(sc->ps2mouse_sc) == 0 && sc->kbd.bcnt == 0) {
298*5c4a5fe1SAndy Fiddaman sc->status &= ~(KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL);
299*5c4a5fe1SAndy Fiddaman }
300*5c4a5fe1SAndy Fiddaman }
301*5c4a5fe1SAndy Fiddaman
302*5c4a5fe1SAndy Fiddaman static int
atkbdc_data_handler(struct vmctx * ctx __unused,int in,int port __unused,int bytes,uint32_t * eax,void * arg)303*5c4a5fe1SAndy Fiddaman atkbdc_data_handler(struct vmctx *ctx __unused, int in,
304*5c4a5fe1SAndy Fiddaman int port __unused, int bytes, uint32_t *eax, void *arg)
305*5c4a5fe1SAndy Fiddaman {
306*5c4a5fe1SAndy Fiddaman struct atkbdc_softc *sc;
307*5c4a5fe1SAndy Fiddaman uint8_t buf;
308*5c4a5fe1SAndy Fiddaman int retval;
309*5c4a5fe1SAndy Fiddaman
310*5c4a5fe1SAndy Fiddaman if (bytes != 1)
311*5c4a5fe1SAndy Fiddaman return (-1);
312*5c4a5fe1SAndy Fiddaman sc = arg;
313*5c4a5fe1SAndy Fiddaman retval = 0;
314*5c4a5fe1SAndy Fiddaman
315*5c4a5fe1SAndy Fiddaman pthread_mutex_lock(&sc->mtx);
316*5c4a5fe1SAndy Fiddaman if (in) {
317*5c4a5fe1SAndy Fiddaman sc->curcmd = 0;
318*5c4a5fe1SAndy Fiddaman if (sc->ctrlbyte != 0) {
319*5c4a5fe1SAndy Fiddaman *eax = sc->ctrlbyte & 0xff;
320*5c4a5fe1SAndy Fiddaman sc->ctrlbyte = 0;
321*5c4a5fe1SAndy Fiddaman } else {
322*5c4a5fe1SAndy Fiddaman /* read device buffer; includes kbd cmd responses */
323*5c4a5fe1SAndy Fiddaman atkbdc_dequeue_data(sc, &buf);
324*5c4a5fe1SAndy Fiddaman *eax = buf;
325*5c4a5fe1SAndy Fiddaman }
326*5c4a5fe1SAndy Fiddaman
327*5c4a5fe1SAndy Fiddaman sc->status &= ~KBDS_CTRL_FLAG;
328*5c4a5fe1SAndy Fiddaman pthread_mutex_unlock(&sc->mtx);
329*5c4a5fe1SAndy Fiddaman return (retval);
330*5c4a5fe1SAndy Fiddaman }
331*5c4a5fe1SAndy Fiddaman
332*5c4a5fe1SAndy Fiddaman if (sc->status & KBDS_CTRL_FLAG) {
333*5c4a5fe1SAndy Fiddaman /*
334*5c4a5fe1SAndy Fiddaman * Command byte for the controller.
335*5c4a5fe1SAndy Fiddaman */
336*5c4a5fe1SAndy Fiddaman switch (sc->curcmd) {
337*5c4a5fe1SAndy Fiddaman case KBDC_SET_COMMAND_BYTE:
338*5c4a5fe1SAndy Fiddaman sc->ram[0] = *eax;
339*5c4a5fe1SAndy Fiddaman if (sc->ram[0] & KBD_SYS_FLAG_BIT)
340*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_SYS_FLAG;
341*5c4a5fe1SAndy Fiddaman else
342*5c4a5fe1SAndy Fiddaman sc->status &= ~KBDS_SYS_FLAG;
343*5c4a5fe1SAndy Fiddaman break;
344*5c4a5fe1SAndy Fiddaman case KBDC_WRITE_OUTPORT:
345*5c4a5fe1SAndy Fiddaman sc->outport = *eax;
346*5c4a5fe1SAndy Fiddaman break;
347*5c4a5fe1SAndy Fiddaman case KBDC_WRITE_TO_AUX:
348*5c4a5fe1SAndy Fiddaman ps2mouse_write(sc->ps2mouse_sc, *eax, 0);
349*5c4a5fe1SAndy Fiddaman atkbdc_poll(sc);
350*5c4a5fe1SAndy Fiddaman break;
351*5c4a5fe1SAndy Fiddaman case KBDC_WRITE_KBD_OUTBUF:
352*5c4a5fe1SAndy Fiddaman atkbdc_kbd_queue_data(sc, *eax);
353*5c4a5fe1SAndy Fiddaman break;
354*5c4a5fe1SAndy Fiddaman case KBDC_WRITE_AUX_OUTBUF:
355*5c4a5fe1SAndy Fiddaman ps2mouse_write(sc->ps2mouse_sc, *eax, 1);
356*5c4a5fe1SAndy Fiddaman sc->status |= (KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL);
357*5c4a5fe1SAndy Fiddaman atkbdc_aux_poll(sc);
358*5c4a5fe1SAndy Fiddaman break;
359*5c4a5fe1SAndy Fiddaman default:
360*5c4a5fe1SAndy Fiddaman /* write to particular RAM byte */
361*5c4a5fe1SAndy Fiddaman if (sc->curcmd >= 0x61 && sc->curcmd <= 0x7f) {
362*5c4a5fe1SAndy Fiddaman int byten;
363*5c4a5fe1SAndy Fiddaman
364*5c4a5fe1SAndy Fiddaman byten = (sc->curcmd - 0x60) & 0x1f;
365*5c4a5fe1SAndy Fiddaman sc->ram[byten] = *eax & 0xff;
366*5c4a5fe1SAndy Fiddaman }
367*5c4a5fe1SAndy Fiddaman break;
368*5c4a5fe1SAndy Fiddaman }
369*5c4a5fe1SAndy Fiddaman
370*5c4a5fe1SAndy Fiddaman sc->curcmd = 0;
371*5c4a5fe1SAndy Fiddaman sc->status &= ~KBDS_CTRL_FLAG;
372*5c4a5fe1SAndy Fiddaman
373*5c4a5fe1SAndy Fiddaman pthread_mutex_unlock(&sc->mtx);
374*5c4a5fe1SAndy Fiddaman return (retval);
375*5c4a5fe1SAndy Fiddaman }
376*5c4a5fe1SAndy Fiddaman
377*5c4a5fe1SAndy Fiddaman /*
378*5c4a5fe1SAndy Fiddaman * Data byte for the device.
379*5c4a5fe1SAndy Fiddaman */
380*5c4a5fe1SAndy Fiddaman ps2kbd_write(sc->ps2kbd_sc, *eax);
381*5c4a5fe1SAndy Fiddaman atkbdc_poll(sc);
382*5c4a5fe1SAndy Fiddaman
383*5c4a5fe1SAndy Fiddaman pthread_mutex_unlock(&sc->mtx);
384*5c4a5fe1SAndy Fiddaman
385*5c4a5fe1SAndy Fiddaman return (retval);
386*5c4a5fe1SAndy Fiddaman }
387*5c4a5fe1SAndy Fiddaman
388*5c4a5fe1SAndy Fiddaman static int
atkbdc_sts_ctl_handler(struct vmctx * ctx,int in,int port __unused,int bytes,uint32_t * eax,void * arg)389*5c4a5fe1SAndy Fiddaman atkbdc_sts_ctl_handler(struct vmctx *ctx, int in,
390*5c4a5fe1SAndy Fiddaman int port __unused, int bytes, uint32_t *eax, void *arg)
391*5c4a5fe1SAndy Fiddaman {
392*5c4a5fe1SAndy Fiddaman struct atkbdc_softc *sc;
393*5c4a5fe1SAndy Fiddaman int error, retval;
394*5c4a5fe1SAndy Fiddaman
395*5c4a5fe1SAndy Fiddaman if (bytes != 1)
396*5c4a5fe1SAndy Fiddaman return (-1);
397*5c4a5fe1SAndy Fiddaman
398*5c4a5fe1SAndy Fiddaman sc = arg;
399*5c4a5fe1SAndy Fiddaman retval = 0;
400*5c4a5fe1SAndy Fiddaman
401*5c4a5fe1SAndy Fiddaman pthread_mutex_lock(&sc->mtx);
402*5c4a5fe1SAndy Fiddaman
403*5c4a5fe1SAndy Fiddaman if (in) {
404*5c4a5fe1SAndy Fiddaman /* read status register */
405*5c4a5fe1SAndy Fiddaman *eax = sc->status;
406*5c4a5fe1SAndy Fiddaman pthread_mutex_unlock(&sc->mtx);
407*5c4a5fe1SAndy Fiddaman return (retval);
408*5c4a5fe1SAndy Fiddaman }
409*5c4a5fe1SAndy Fiddaman
410*5c4a5fe1SAndy Fiddaman
411*5c4a5fe1SAndy Fiddaman sc->curcmd = 0;
412*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_CTRL_FLAG;
413*5c4a5fe1SAndy Fiddaman sc->ctrlbyte = 0;
414*5c4a5fe1SAndy Fiddaman
415*5c4a5fe1SAndy Fiddaman switch (*eax) {
416*5c4a5fe1SAndy Fiddaman case KBDC_GET_COMMAND_BYTE:
417*5c4a5fe1SAndy Fiddaman sc->ctrlbyte = CTRL_CMD_FLAG | sc->ram[0];
418*5c4a5fe1SAndy Fiddaman break;
419*5c4a5fe1SAndy Fiddaman case KBDC_TEST_CTRL:
420*5c4a5fe1SAndy Fiddaman sc->ctrlbyte = CTRL_CMD_FLAG | 0x55;
421*5c4a5fe1SAndy Fiddaman break;
422*5c4a5fe1SAndy Fiddaman case KBDC_TEST_AUX_PORT:
423*5c4a5fe1SAndy Fiddaman case KBDC_TEST_KBD_PORT:
424*5c4a5fe1SAndy Fiddaman sc->ctrlbyte = CTRL_CMD_FLAG | 0;
425*5c4a5fe1SAndy Fiddaman break;
426*5c4a5fe1SAndy Fiddaman case KBDC_READ_INPORT:
427*5c4a5fe1SAndy Fiddaman sc->ctrlbyte = CTRL_CMD_FLAG | 0;
428*5c4a5fe1SAndy Fiddaman break;
429*5c4a5fe1SAndy Fiddaman case KBDC_READ_OUTPORT:
430*5c4a5fe1SAndy Fiddaman sc->ctrlbyte = CTRL_CMD_FLAG | sc->outport;
431*5c4a5fe1SAndy Fiddaman break;
432*5c4a5fe1SAndy Fiddaman case KBDC_SET_COMMAND_BYTE:
433*5c4a5fe1SAndy Fiddaman case KBDC_WRITE_OUTPORT:
434*5c4a5fe1SAndy Fiddaman case KBDC_WRITE_KBD_OUTBUF:
435*5c4a5fe1SAndy Fiddaman case KBDC_WRITE_AUX_OUTBUF:
436*5c4a5fe1SAndy Fiddaman sc->curcmd = *eax;
437*5c4a5fe1SAndy Fiddaman break;
438*5c4a5fe1SAndy Fiddaman case KBDC_DISABLE_KBD_PORT:
439*5c4a5fe1SAndy Fiddaman sc->ram[0] |= KBD_DISABLE_KBD_PORT;
440*5c4a5fe1SAndy Fiddaman break;
441*5c4a5fe1SAndy Fiddaman case KBDC_ENABLE_KBD_PORT:
442*5c4a5fe1SAndy Fiddaman sc->ram[0] &= ~KBD_DISABLE_KBD_PORT;
443*5c4a5fe1SAndy Fiddaman if (sc->kbd.bcnt > 0)
444*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_KBD_BUFFER_FULL;
445*5c4a5fe1SAndy Fiddaman atkbdc_poll(sc);
446*5c4a5fe1SAndy Fiddaman break;
447*5c4a5fe1SAndy Fiddaman case KBDC_WRITE_TO_AUX:
448*5c4a5fe1SAndy Fiddaman sc->curcmd = *eax;
449*5c4a5fe1SAndy Fiddaman break;
450*5c4a5fe1SAndy Fiddaman case KBDC_DISABLE_AUX_PORT:
451*5c4a5fe1SAndy Fiddaman sc->ram[0] |= KBD_DISABLE_AUX_PORT;
452*5c4a5fe1SAndy Fiddaman ps2mouse_toggle(sc->ps2mouse_sc, 0);
453*5c4a5fe1SAndy Fiddaman sc->status &= ~(KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL);
454*5c4a5fe1SAndy Fiddaman sc->outport &= ~KBDS_AUX_BUFFER_FULL;
455*5c4a5fe1SAndy Fiddaman break;
456*5c4a5fe1SAndy Fiddaman case KBDC_ENABLE_AUX_PORT:
457*5c4a5fe1SAndy Fiddaman sc->ram[0] &= ~KBD_DISABLE_AUX_PORT;
458*5c4a5fe1SAndy Fiddaman ps2mouse_toggle(sc->ps2mouse_sc, 1);
459*5c4a5fe1SAndy Fiddaman if (ps2mouse_fifocnt(sc->ps2mouse_sc) > 0)
460*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL;
461*5c4a5fe1SAndy Fiddaman break;
462*5c4a5fe1SAndy Fiddaman case KBDC_RESET: /* Pulse "reset" line */
463*5c4a5fe1SAndy Fiddaman error = vm_suspend(ctx, VM_SUSPEND_RESET);
464*5c4a5fe1SAndy Fiddaman assert(error == 0 || errno == EALREADY);
465*5c4a5fe1SAndy Fiddaman break;
466*5c4a5fe1SAndy Fiddaman default:
467*5c4a5fe1SAndy Fiddaman if (*eax >= 0x21 && *eax <= 0x3f) {
468*5c4a5fe1SAndy Fiddaman /* read "byte N" from RAM */
469*5c4a5fe1SAndy Fiddaman int byten;
470*5c4a5fe1SAndy Fiddaman
471*5c4a5fe1SAndy Fiddaman byten = (*eax - 0x20) & 0x1f;
472*5c4a5fe1SAndy Fiddaman sc->ctrlbyte = CTRL_CMD_FLAG | sc->ram[byten];
473*5c4a5fe1SAndy Fiddaman }
474*5c4a5fe1SAndy Fiddaman break;
475*5c4a5fe1SAndy Fiddaman }
476*5c4a5fe1SAndy Fiddaman
477*5c4a5fe1SAndy Fiddaman pthread_mutex_unlock(&sc->mtx);
478*5c4a5fe1SAndy Fiddaman
479*5c4a5fe1SAndy Fiddaman if (sc->ctrlbyte != 0) {
480*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_KBD_BUFFER_FULL;
481*5c4a5fe1SAndy Fiddaman sc->status &= ~KBDS_AUX_BUFFER_FULL;
482*5c4a5fe1SAndy Fiddaman atkbdc_assert_kbd_intr(sc);
483*5c4a5fe1SAndy Fiddaman } else if (ps2mouse_fifocnt(sc->ps2mouse_sc) > 0 &&
484*5c4a5fe1SAndy Fiddaman (sc->ram[0] & KBD_DISABLE_AUX_PORT) == 0) {
485*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_AUX_BUFFER_FULL | KBDS_KBD_BUFFER_FULL;
486*5c4a5fe1SAndy Fiddaman atkbdc_assert_aux_intr(sc);
487*5c4a5fe1SAndy Fiddaman } else if (sc->kbd.bcnt > 0 && (sc->ram[0] & KBD_DISABLE_KBD_PORT) == 0) {
488*5c4a5fe1SAndy Fiddaman sc->status |= KBDS_KBD_BUFFER_FULL;
489*5c4a5fe1SAndy Fiddaman atkbdc_assert_kbd_intr(sc);
490*5c4a5fe1SAndy Fiddaman }
491*5c4a5fe1SAndy Fiddaman
492*5c4a5fe1SAndy Fiddaman return (retval);
493*5c4a5fe1SAndy Fiddaman }
494*5c4a5fe1SAndy Fiddaman
495*5c4a5fe1SAndy Fiddaman void
atkbdc_event(struct atkbdc_softc * sc,int iskbd)496*5c4a5fe1SAndy Fiddaman atkbdc_event(struct atkbdc_softc *sc, int iskbd)
497*5c4a5fe1SAndy Fiddaman {
498*5c4a5fe1SAndy Fiddaman pthread_mutex_lock(&sc->mtx);
499*5c4a5fe1SAndy Fiddaman
500*5c4a5fe1SAndy Fiddaman if (iskbd)
501*5c4a5fe1SAndy Fiddaman atkbdc_kbd_poll(sc);
502*5c4a5fe1SAndy Fiddaman else
503*5c4a5fe1SAndy Fiddaman atkbdc_aux_poll(sc);
504*5c4a5fe1SAndy Fiddaman pthread_mutex_unlock(&sc->mtx);
505*5c4a5fe1SAndy Fiddaman }
506*5c4a5fe1SAndy Fiddaman
507*5c4a5fe1SAndy Fiddaman void
atkbdc_init(struct vmctx * ctx)508*5c4a5fe1SAndy Fiddaman atkbdc_init(struct vmctx *ctx)
509*5c4a5fe1SAndy Fiddaman {
510*5c4a5fe1SAndy Fiddaman struct inout_port iop;
511*5c4a5fe1SAndy Fiddaman struct atkbdc_softc *sc;
512*5c4a5fe1SAndy Fiddaman int error;
513*5c4a5fe1SAndy Fiddaman
514*5c4a5fe1SAndy Fiddaman sc = calloc(1, sizeof(struct atkbdc_softc));
515*5c4a5fe1SAndy Fiddaman sc->ctx = ctx;
516*5c4a5fe1SAndy Fiddaman
517*5c4a5fe1SAndy Fiddaman pthread_mutex_init(&sc->mtx, NULL);
518*5c4a5fe1SAndy Fiddaman
519*5c4a5fe1SAndy Fiddaman bzero(&iop, sizeof(struct inout_port));
520*5c4a5fe1SAndy Fiddaman iop.name = "atkdbc";
521*5c4a5fe1SAndy Fiddaman iop.port = KBD_STS_CTL_PORT;
522*5c4a5fe1SAndy Fiddaman iop.size = 1;
523*5c4a5fe1SAndy Fiddaman iop.flags = IOPORT_F_INOUT;
524*5c4a5fe1SAndy Fiddaman iop.handler = atkbdc_sts_ctl_handler;
525*5c4a5fe1SAndy Fiddaman iop.arg = sc;
526*5c4a5fe1SAndy Fiddaman
527*5c4a5fe1SAndy Fiddaman error = register_inout(&iop);
528*5c4a5fe1SAndy Fiddaman assert(error == 0);
529*5c4a5fe1SAndy Fiddaman
530*5c4a5fe1SAndy Fiddaman bzero(&iop, sizeof(struct inout_port));
531*5c4a5fe1SAndy Fiddaman iop.name = "atkdbc";
532*5c4a5fe1SAndy Fiddaman iop.port = KBD_DATA_PORT;
533*5c4a5fe1SAndy Fiddaman iop.size = 1;
534*5c4a5fe1SAndy Fiddaman iop.flags = IOPORT_F_INOUT;
535*5c4a5fe1SAndy Fiddaman iop.handler = atkbdc_data_handler;
536*5c4a5fe1SAndy Fiddaman iop.arg = sc;
537*5c4a5fe1SAndy Fiddaman
538*5c4a5fe1SAndy Fiddaman error = register_inout(&iop);
539*5c4a5fe1SAndy Fiddaman assert(error == 0);
540*5c4a5fe1SAndy Fiddaman
541*5c4a5fe1SAndy Fiddaman pci_irq_reserve(KBD_DEV_IRQ);
542*5c4a5fe1SAndy Fiddaman sc->kbd.irq = KBD_DEV_IRQ;
543*5c4a5fe1SAndy Fiddaman
544*5c4a5fe1SAndy Fiddaman pci_irq_reserve(AUX_DEV_IRQ);
545*5c4a5fe1SAndy Fiddaman sc->aux.irq = AUX_DEV_IRQ;
546*5c4a5fe1SAndy Fiddaman
547*5c4a5fe1SAndy Fiddaman sc->ps2kbd_sc = ps2kbd_init(sc);
548*5c4a5fe1SAndy Fiddaman sc->ps2mouse_sc = ps2mouse_init(sc);
549*5c4a5fe1SAndy Fiddaman }
550*5c4a5fe1SAndy Fiddaman
551*5c4a5fe1SAndy Fiddaman static void
atkbdc_dsdt(void)552*5c4a5fe1SAndy Fiddaman atkbdc_dsdt(void)
553*5c4a5fe1SAndy Fiddaman {
554*5c4a5fe1SAndy Fiddaman
555*5c4a5fe1SAndy Fiddaman dsdt_line("");
556*5c4a5fe1SAndy Fiddaman dsdt_line("Device (KBD)");
557*5c4a5fe1SAndy Fiddaman dsdt_line("{");
558*5c4a5fe1SAndy Fiddaman dsdt_line(" Name (_HID, EisaId (\"PNP0303\"))");
559*5c4a5fe1SAndy Fiddaman dsdt_line(" Name (_CRS, ResourceTemplate ()");
560*5c4a5fe1SAndy Fiddaman dsdt_line(" {");
561*5c4a5fe1SAndy Fiddaman dsdt_indent(2);
562*5c4a5fe1SAndy Fiddaman dsdt_fixed_ioport(KBD_DATA_PORT, 1);
563*5c4a5fe1SAndy Fiddaman dsdt_fixed_ioport(KBD_STS_CTL_PORT, 1);
564*5c4a5fe1SAndy Fiddaman dsdt_fixed_irq(1);
565*5c4a5fe1SAndy Fiddaman dsdt_unindent(2);
566*5c4a5fe1SAndy Fiddaman dsdt_line(" })");
567*5c4a5fe1SAndy Fiddaman dsdt_line("}");
568*5c4a5fe1SAndy Fiddaman
569*5c4a5fe1SAndy Fiddaman dsdt_line("");
570*5c4a5fe1SAndy Fiddaman dsdt_line("Device (MOU)");
571*5c4a5fe1SAndy Fiddaman dsdt_line("{");
572*5c4a5fe1SAndy Fiddaman dsdt_line(" Name (_HID, EisaId (\"PNP0F13\"))");
573*5c4a5fe1SAndy Fiddaman dsdt_line(" Name (_CRS, ResourceTemplate ()");
574*5c4a5fe1SAndy Fiddaman dsdt_line(" {");
575*5c4a5fe1SAndy Fiddaman dsdt_indent(2);
576*5c4a5fe1SAndy Fiddaman dsdt_fixed_ioport(KBD_DATA_PORT, 1);
577*5c4a5fe1SAndy Fiddaman dsdt_fixed_ioport(KBD_STS_CTL_PORT, 1);
578*5c4a5fe1SAndy Fiddaman dsdt_fixed_irq(12);
579*5c4a5fe1SAndy Fiddaman dsdt_unindent(2);
580*5c4a5fe1SAndy Fiddaman dsdt_line(" })");
581*5c4a5fe1SAndy Fiddaman dsdt_line("}");
582*5c4a5fe1SAndy Fiddaman }
583*5c4a5fe1SAndy Fiddaman LPC_DSDT(atkbdc_dsdt);
584*5c4a5fe1SAndy Fiddaman
585