AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
i8042.c
Go to the documentation of this file.
1
12
13#include <core/system.h>
14#include <core/string.h>
15#include <core/kargs.h>
16#include <core/module.h>
17#include <cpu/io.h>
18#include <dev/irq.h>
19#include <dev/platform.h>
20#include <dev/i8042.h>
21#include <aquila/errno.h>
22
23static struct ioaddr i8042_ioaddr;
24static int i8042_found;
25
26/* the handler of each port's bytes */
27static void (*port_handler[2])(int);
28
29#define DATA_PORT 0x00
30#define STATUS_PORT 0x04
31#define COMMAND_PORT 0x04
32
33#define STATUS_OBUF_FULL 0x01
34#define STATUS_IBUF_FULL 0x02
35#define STATUS_SYSTEM 0x04
36#define STATUS_COMMAND 0x08
37#define STATUS_TOUT 0x40
38#define STATUS_PARITY 0x80
39
41static uint8_t read_status(void)
42{
44}
45
49static int has_byte(void)
50{
52}
53
56static void i8042_irq(void *arg)
57{
58 void (**handler)(int) = arg;
59
60 if (!has_byte())
61 return;
62
63 int byte = io_in8(&i8042_ioaddr, DATA_PORT);
64
65 if (*handler)
66 (*handler)(byte);
67}
68
75void i8042_handler_register(int port, void (*fun)(int))
76{
77 if (port == 1 || port == 2)
78 port_handler[port - 1] = fun;
79}
80
83static int write_wait(void)
84{
85 for (int i = 0; i < 100000; ++i)
87 return 0;
88
89 return -ETIMEDOUT;
90}
91
101{
102 if (!i8042_found)
103 return -ENODEV;
104
105 int err = write_wait();
106
107 if (err)
108 return err;
109
111
112 if ((err = write_wait()))
113 return err;
114
116 return 0;
117}
118
123void i8042_reboot(void)
124{
125 if (i8042_found)
127}
128
131static int read_wait(void)
132{
133 for (int i = 0; i < 100000; ++i)
134 if (has_byte())
135 return io_in8(&i8042_ioaddr, DATA_PORT);
136
137 return -ETIMEDOUT;
138}
139
140#define CMD_READ_CONFIG 0x20
141#define CMD_WRITE_CONFIG 0x60
142#define CMD_AUX_ENABLE 0xA8
143#define CONFIG_AUX_IRQ 0x02
144
148static int aux_enable(void)
149{
150 int err, config;
151
152 if ((err = write_wait()))
153 return err;
154
156
157 if ((err = write_wait()))
158 return err;
159
161
162 if ((config = read_wait()) < 0)
163 return config;
164
165 if ((err = write_wait()))
166 return err;
167
169
170 if ((err = write_wait()))
171 return err;
172
174 return 0;
175}
176
179static int i8042_init(void)
180{
181 const struct platform_device *pd = platform_device_get("i8042", 0);
182
183 if (!pd)
184 return -ENODEV;
185
186 int err = platform_device_io(pd, &i8042_ioaddr);
187
188 if (err)
189 return err;
190
191 /* the controller should say it passed its self-test; with the
192 * i8042.nocheck argument, that isn't checked */
193 if (kargs_get("i8042.nocheck", NULL)) {
194 if (!(read_status() & STATUS_SYSTEM)) {
195 printk("i8042: controller not found\n");
196 return -ENODEV;
197 }
198 } else {
199 printk("i8042: skipping check\n");
200 }
201
202 i8042_found = 1;
203 printk("i8042: controller at %p (%s)\n", (void *) pd->io.addr, ioaddr_type_str(&i8042_ioaddr));
204
205 /* the mouse's port, if the platform gives it an interrupt */
206 if (pd->nirq > 1 && aux_enable())
207 printk("i8042: the second port didn't come on\n");
208
209 /* drop any bytes waiting from before */
210 for (int i = 0; i < 10; ++i)
212
213 for (int i = 0; i < pd->nirq && i < 2; ++i)
215
216 return 0;
217}
218
int irq_install(unsigned irq, irq_handler_t fn, void *arg)
Installs a handler for an IRQ.
Definition irq.c:32
static uint8_t io_in8(struct ioaddr *io, uintptr_t off)
Reads an 8-, 16- or 32-bit register.
Definition io.h:28
static void io_out8(struct ioaddr *io, uintptr_t off, uint8_t val)
Writes an 8-, 16- or 32-bit register.
Definition io.h:44
static char * ioaddr_type_str(struct ioaddr *io)
Definition io.h:101
static int aux_enable(void)
Turns the second port on, and its interrupt (a bit of the controller's configuration byte).
Definition i8042.c:148
static uint8_t read_status(void)
Returns the controller's status register.
Definition i8042.c:41
#define STATUS_OBUF_FULL
Definition i8042.c:33
#define COMMAND_PORT
Definition i8042.c:31
void i8042_handler_register(int port, void(*fun)(int))
Registers the function that gets each byte a port receives.
Definition i8042.c:75
static void(* port_handler[2])(int)
Definition i8042.c:27
#define CMD_AUX_ENABLE
Definition i8042.c:142
#define CMD_WRITE_CONFIG
Definition i8042.c:141
static int i8042_found
Definition i8042.c:24
int i8042_aux_write(uint8_t byte)
Sends a byte to the device on the second port (the mouse).
Definition i8042.c:100
static int read_wait(void)
Waits for the controller's reply to a command.
Definition i8042.c:131
#define STATUS_SYSTEM
Definition i8042.c:35
#define STATUS_PORT
Definition i8042.c:30
static int has_byte(void)
Returns whether the controller has a byte for us (its output buffer is full).
Definition i8042.c:49
#define CMD_READ_CONFIG
Definition i8042.c:140
#define DATA_PORT
Definition i8042.c:29
#define STATUS_IBUF_FULL
Definition i8042.c:34
void i8042_reboot(void)
Resets the CPU, through the controller's output line: this reboots the PC.
Definition i8042.c:123
#define CONFIG_AUX_IRQ
Definition i8042.c:143
static void i8042_irq(void *arg)
Handles a port's interrupt: its byte goes to the port's handler.
Definition i8042.c:56
static int write_wait(void)
Waits until the controller can take a byte.
Definition i8042.c:83
static int i8042_init(void)
Finds the platform's i8042, turns the mouse's port on, and installs the ports' interrupt handlers.
Definition i8042.c:179
static struct ioaddr i8042_ioaddr
Definition i8042.c:23
int kargs_get(const char *key, const char **value)
Looks up an argument of the kernel's command line.
Definition kargs.c:73
#define MODULE_INIT(name, i, f)
Definition module.h:10
int platform_device_io(const struct platform_device *pd, struct ioaddr *io)
Gets a device's registers, ready for io_in8() and the others.
Definition platform.c:38
const struct platform_device * platform_device_get(const char *name, int index)
Finds one of the platform's devices by its driver's name.
Definition platform.c:21
int printk(const char *fmt,...)
Writes a kernel message, to the message buffer and the consoles.
Definition printk.c:249
#define NULL
Definition stddef.h:27
unsigned char uint8_t
Definition stddef.h:20
An installed handler, on its interrupt's list.
Definition irq.c:19
Where a device's registers are.
Definition io.h:95
uintptr_t addr
Definition io.h:97
A device of the platform's table.
Definition platform.h:20
unsigned irq[PLATFORM_IRQS]
Definition platform.h:25
struct ioaddr io
Definition platform.h:22