Working PS/2 keyboard driver
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m19s
All checks were successful
Build documentation / build-and-deploy (push) Successful in 2m19s
This commit is contained in:
1
Makefile
1
Makefile
@@ -8,3 +8,4 @@ include make/liballoc.mk
|
|||||||
include make/libterminal.mk
|
include make/libterminal.mk
|
||||||
include make/libprocess.mk
|
include make/libprocess.mk
|
||||||
include make/libstring.mk
|
include make/libstring.mk
|
||||||
|
include make/libkb.mk
|
||||||
|
|||||||
@@ -8,3 +8,4 @@ make -B all_compiledb_libmsl
|
|||||||
make -B all_compiledb_libprocess
|
make -B all_compiledb_libprocess
|
||||||
make -B all_compiledb_libterminal
|
make -B all_compiledb_libterminal
|
||||||
make -B all_compiledb_libstring
|
make -B all_compiledb_libstring
|
||||||
|
make -B all_compiledb_libkb
|
||||||
|
|||||||
@@ -13,6 +13,7 @@ make -B all_liballoc
|
|||||||
make -B all_libprocess
|
make -B all_libprocess
|
||||||
make -B all_libterminal
|
make -B all_libterminal
|
||||||
make -B all_libstring
|
make -B all_libstring
|
||||||
|
make -B all_libkb
|
||||||
make -B all_apps
|
make -B all_apps
|
||||||
make -B all_dist
|
make -B all_dist
|
||||||
./aux/limine_iso_amd64.sh
|
./aux/limine_iso_amd64.sh
|
||||||
|
|||||||
@@ -9,5 +9,6 @@ make -B docs_libmsl
|
|||||||
make -B docs_libprocess
|
make -B docs_libprocess
|
||||||
make -B docs_libstring
|
make -B docs_libstring
|
||||||
make -B docs_libterminal
|
make -B docs_libterminal
|
||||||
|
make -B docs_libkb
|
||||||
|
|
||||||
mkdocs build
|
mkdocs build
|
||||||
|
|||||||
2
ce/ce.c
2
ce/ce.c
@@ -2,6 +2,6 @@
|
|||||||
|
|
||||||
void app_main (void) {
|
void app_main (void) {
|
||||||
for (;;) {
|
for (;;) {
|
||||||
test ('x');
|
/* test ('x'); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
8
include/m/kb_device.h
Normal file
8
include/m/kb_device.h
Normal file
@@ -0,0 +1,8 @@
|
|||||||
|
#ifndef _M_KB_DEVICE_H
|
||||||
|
#define _M_KB_DEVICE_H
|
||||||
|
|
||||||
|
#define KB_DEVICE 1
|
||||||
|
|
||||||
|
#define KB_READ_KEY 0
|
||||||
|
|
||||||
|
#endif // _M_KB_DEVICE_H
|
||||||
@@ -14,5 +14,6 @@
|
|||||||
#define ST_OOB_ERROR 10
|
#define ST_OOB_ERROR 10
|
||||||
#define ST_BAD_PATH 11
|
#define ST_BAD_PATH 11
|
||||||
#define ST_EXEC_ERROR 12
|
#define ST_EXEC_ERROR 12
|
||||||
|
#define ST_TRY_AGAIN 13
|
||||||
|
|
||||||
#endif // _M_STATUS_H
|
#endif // _M_STATUS_H
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
#ifndef _M_TERMINAL_DEVICE_H
|
#ifndef _M_TERMINAL_DEVICE_H
|
||||||
#define _M_TERMINAL_DEVICE_H
|
#define _M_TERMINAL_DEVICE_H
|
||||||
|
|
||||||
|
#define TERMINAL_DEVICE 0
|
||||||
|
|
||||||
#define TERMINAL_PUTSTR 0
|
#define TERMINAL_PUTSTR 0
|
||||||
|
|
||||||
#endif // _M_TERMINAL_DEVICE_H
|
#endif // _M_TERMINAL_DEVICE_H
|
||||||
|
|||||||
@@ -4,5 +4,6 @@ $(eval $(call add_lib,libterminal))
|
|||||||
$(eval $(call add_lib,liballoc))
|
$(eval $(call add_lib,liballoc))
|
||||||
$(eval $(call add_lib,libprocess))
|
$(eval $(call add_lib,libprocess))
|
||||||
$(eval $(call add_lib,libstring))
|
$(eval $(call add_lib,libstring))
|
||||||
|
$(eval $(call add_lib,libkb))
|
||||||
|
|
||||||
include ../make/user.mk
|
include ../make/user.mk
|
||||||
|
|||||||
28
init/init.c
28
init/init.c
@@ -1,3 +1,4 @@
|
|||||||
|
#include <kb.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
#include <process.h>
|
#include <process.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
@@ -34,21 +35,28 @@ void app_main (void) {
|
|||||||
|
|
||||||
letter = 'a';
|
letter = 'a';
|
||||||
|
|
||||||
process_exec ("ramdisk:/ce");
|
/* process_exec ("ramdisk:/ce"); */
|
||||||
|
|
||||||
process_spawn (&app_proc, (void*)'b');
|
/* process_spawn (&app_proc, (void*)'b'); */
|
||||||
process_spawn (&app_proc, (void*)'c');
|
/* process_spawn (&app_proc, (void*)'c'); */
|
||||||
process_spawn (&app_proc, (void*)'d');
|
/* process_spawn (&app_proc, (void*)'d'); */
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
mutex_lock (MUTEX);
|
int ch = kb_read_key ();
|
||||||
|
|
||||||
for (int i = 0; i < 3; i++)
|
if (ch < 0)
|
||||||
terminal_print (&letter, 1);
|
continue;
|
||||||
|
|
||||||
for (volatile int i = 0; i < 1000 * 1000; i++)
|
terminal_print ((char*)&ch, 1);
|
||||||
;
|
|
||||||
|
|
||||||
mutex_unlock (MUTEX);
|
/* mutex_lock (MUTEX); */
|
||||||
|
|
||||||
|
/* for (int i = 0; i < 3; i++) */
|
||||||
|
/* terminal_print (&letter, 1); */
|
||||||
|
|
||||||
|
/* for (volatile int i = 0; i < 1000 * 1000; i++) */
|
||||||
|
/* ; */
|
||||||
|
|
||||||
|
/* mutex_unlock (MUTEX); */
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -122,6 +122,7 @@ void amd64_ioapic_route_irq (uint32_t vec, uint32_t irq, uint64_t flags, uint64_
|
|||||||
uint32_t gsi = found_override ? override->gsi : irq;
|
uint32_t gsi = found_override ? override->gsi : irq;
|
||||||
|
|
||||||
ioapic = amd64_ioapic_find (gsi);
|
ioapic = amd64_ioapic_find (gsi);
|
||||||
|
DEBUG ("%p\n", ioapic);
|
||||||
|
|
||||||
if (ioapic == NULL)
|
if (ioapic == NULL)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
#ifndef _KERNEL_AMD64_INTR_DEFS_H
|
#ifndef _KERNEL_AMD64_INTR_DEFS_H
|
||||||
#define _KERNEL_AMD64_INTR_DEFS_H
|
#define _KERNEL_AMD64_INTR_DEFS_H
|
||||||
|
|
||||||
/* Definitions for custom, nonstandard IDT entries. They have to be remapped by amd64_resolve_irq
|
#define PS2KB 32
|
||||||
* into legacy IRQs. */
|
|
||||||
|
|
||||||
#define SCHED_PREEMPT_TIMER 80
|
#define SCHED_PREEMPT_TIMER 80
|
||||||
#define TLB_SHOOTDOWN 81
|
#define TLB_SHOOTDOWN 81
|
||||||
|
|||||||
@@ -4,9 +4,15 @@
|
|||||||
#include <libk/rbtree.h>
|
#include <libk/rbtree.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <libk/string.h>
|
#include <libk/string.h>
|
||||||
|
#include <m/kb_device.h>
|
||||||
#include <m/terminal_device.h>
|
#include <m/terminal_device.h>
|
||||||
#include <mm/liballoc.h>
|
#include <mm/liballoc.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
|
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
#include <device/ps2_kb.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
static struct rb_node_link* device_tree = NULL;
|
static struct rb_node_link* device_tree = NULL;
|
||||||
static spin_lock_t device_tree_lock;
|
static spin_lock_t device_tree_lock;
|
||||||
@@ -26,6 +32,8 @@ struct device* device_create (int id, device_op_func_t* ops, size_t ops_len,
|
|||||||
device->id = id;
|
device->id = id;
|
||||||
device->init = init;
|
device->init = init;
|
||||||
device->fini = fini;
|
device->fini = fini;
|
||||||
|
|
||||||
|
if (ops != NULL)
|
||||||
memcpy (device->ops, ops, ops_len * sizeof (device_op_func_t));
|
memcpy (device->ops, ops, ops_len * sizeof (device_op_func_t));
|
||||||
|
|
||||||
if (!device->init (arg)) {
|
if (!device->init (arg)) {
|
||||||
@@ -67,6 +75,14 @@ void devices_init (void) {
|
|||||||
device_op_func_t ops[] = {
|
device_op_func_t ops[] = {
|
||||||
[TERMINAL_PUTSTR] = &terminal_putstr,
|
[TERMINAL_PUTSTR] = &terminal_putstr,
|
||||||
};
|
};
|
||||||
device_create (1, ops, lengthof (ops), &terminal_init, &terminal_fini, NULL);
|
device_create (TERMINAL_DEVICE, ops, lengthof (ops), &terminal_init, &terminal_fini, NULL);
|
||||||
}
|
}
|
||||||
|
#if defined(__x86_64__)
|
||||||
|
{
|
||||||
|
device_op_func_t ops[] = {
|
||||||
|
[KB_READ_KEY] = &ps2kb_read_key,
|
||||||
|
};
|
||||||
|
device_create (KB_DEVICE, ops, lengthof (ops), &ps2kb_init, &ps2kb_fini, NULL);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|||||||
219
kernel/device/ps2_kb.c
Normal file
219
kernel/device/ps2_kb.c
Normal file
@@ -0,0 +1,219 @@
|
|||||||
|
#include <amd64/apic.h>
|
||||||
|
#include <amd64/intr_defs.h>
|
||||||
|
#include <amd64/io.h>
|
||||||
|
#include <irq/irq.h>
|
||||||
|
#include <libk/ringbuffer.h>
|
||||||
|
#include <libk/std.h>
|
||||||
|
#include <m/status.h>
|
||||||
|
#include <proc/capability.h>
|
||||||
|
#include <proc/proc.h>
|
||||||
|
#include <sync/spin_lock.h>
|
||||||
|
#include <sys/debug.h>
|
||||||
|
#include <sys/smp.h>
|
||||||
|
|
||||||
|
#define KB_CTL_STATUS 0x64
|
||||||
|
#define KB_DATA_IN_BUF 0x01
|
||||||
|
#define KB_DATA 0x60
|
||||||
|
|
||||||
|
#define KB_SHIFT (1 << 0)
|
||||||
|
#define KB_CTL (1 << 1)
|
||||||
|
#define KB_ALT (1 << 2)
|
||||||
|
|
||||||
|
#define KB_CAPSLOCK (1 << 3)
|
||||||
|
#define KB_NUMLOCK (1 << 4)
|
||||||
|
#define KB_SCRLLOCK (1 << 5)
|
||||||
|
#define KB_E0ESC (1 << 6)
|
||||||
|
|
||||||
|
#define KB_HOME 0xe0
|
||||||
|
#define KB_END 0xe1
|
||||||
|
#define KB_UP 0xe2
|
||||||
|
#define KB_DOWN 0xe3
|
||||||
|
#define KB_LEFT 0xe4
|
||||||
|
#define KB_RIGHT 0xe5
|
||||||
|
#define KB_PAGEUP 0xe6
|
||||||
|
#define KB_PAGEDN 0xe7
|
||||||
|
#define KB_INSERT 0xe8
|
||||||
|
#define KB_DELETE 0xe9
|
||||||
|
|
||||||
|
#define C(x) ((x) - '@')
|
||||||
|
|
||||||
|
#define PS2KB_RINGBUFFER_MAX 2048
|
||||||
|
|
||||||
|
static struct ringbuffer ps2kb_ringbuffer;
|
||||||
|
static spin_lock_t ps2kb_ringbuffer_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
|
static uint8_t shiftcode[0x100] = {
|
||||||
|
[0x1d] = KB_CTL, [0x2a] = KB_SHIFT, [0x36] = KB_SHIFT,
|
||||||
|
[0x38] = KB_ALT, [0x9d] = KB_CTL, [0xb8] = KB_ALT,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t togglecode[0x100] = {
|
||||||
|
[0x3a] = KB_CAPSLOCK,
|
||||||
|
[0x45] = KB_NUMLOCK,
|
||||||
|
[0x46] = KB_SCRLLOCK,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t normalmap[0x100] = {
|
||||||
|
/* clang-format off */
|
||||||
|
0x0, 0x1b, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=', '\b', '\t',
|
||||||
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', '\n', 0x0, 'a', 's',
|
||||||
|
'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', '\'', '`', 0x0, '\\', 'z', 'x', 'c', 'v',
|
||||||
|
'b', 'n', 'm', ',', '.', '/', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0x0, 0x0, 0x0, 0x0,
|
||||||
|
[0x9c] = '\n',
|
||||||
|
[0xb5] = '/',
|
||||||
|
[0xc8] = KB_UP,
|
||||||
|
[0xd0] = KB_DOWN,
|
||||||
|
[0xc9] = KB_PAGEUP,
|
||||||
|
[0xd1] = KB_PAGEDN,
|
||||||
|
[0xcb] = KB_LEFT,
|
||||||
|
[0xcd] = KB_RIGHT,
|
||||||
|
[0x97] = KB_HOME,
|
||||||
|
[0xcf] = KB_END,
|
||||||
|
[0xd2] = KB_INSERT,
|
||||||
|
[0xd3] = KB_DELETE,
|
||||||
|
[0xc7] = KB_HOME,
|
||||||
|
/* clang-format on */
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t shiftmap[256] = {
|
||||||
|
/* clang-format off */
|
||||||
|
0x0, 033, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+', '\b', '\t',
|
||||||
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', '\n', 0x0, 'A', 'S',
|
||||||
|
'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~', 0x0, '|', 'Z', 'X', 'C', 'V',
|
||||||
|
'B', 'N', 'M', '<', '>', '?', 0x0, '*', 0x0, ' ', 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, '7', '8', '9', '-', '4', '5', '6', '+', '1',
|
||||||
|
'2', '3', '0', '.', 0x0, 0x0, 0x0, 0x0,
|
||||||
|
[0x9C] = '\n',
|
||||||
|
[0xB5] = '/',
|
||||||
|
[0xc8] = KB_UP,
|
||||||
|
[0xd0] = KB_DOWN,
|
||||||
|
[0xc9] = KB_PAGEUP,
|
||||||
|
[0xd1] = KB_PAGEDN,
|
||||||
|
[0xcb] = KB_LEFT,
|
||||||
|
[0xcd] = KB_RIGHT,
|
||||||
|
[0x97] = KB_HOME,
|
||||||
|
[0xcf] = KB_END,
|
||||||
|
[0xd2] = KB_INSERT,
|
||||||
|
[0xd3] = KB_DELETE,
|
||||||
|
[0xc7] = KB_HOME,
|
||||||
|
/* clang-format on */
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint8_t ctlmap[256] = {
|
||||||
|
/* clang-format off */
|
||||||
|
0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
|
||||||
|
C ('Q'), C ('W'), C ('E'), C ('R'), C ('T'), C ('Y'), C ('U'), C ('I'), C ('O'),
|
||||||
|
C ('P'), 0x0, 0x0, '\r', 0x0, C ('A'), C ('S'), C ('D'), C ('F'), C ('G'), C ('H'),
|
||||||
|
C ('J'), C ('K'), C ('L'), 0x0, 0x0, 0x0, 0x0, C ('\\'), C ('Z'), C ('X'), C ('C'),
|
||||||
|
C ('V'), C ('B'), C ('N'), C ('M'), 0x0, 0x0, C ('/'), 0x0, 0x0,
|
||||||
|
[0x9C] = '\r',
|
||||||
|
[0xB5] = C ('/'),
|
||||||
|
[0xc8] = KB_UP,
|
||||||
|
[0xd0] = KB_DOWN,
|
||||||
|
[0xc9] = KB_PAGEUP,
|
||||||
|
[0xd1] = KB_PAGEDN,
|
||||||
|
[0xcb] = KB_LEFT,
|
||||||
|
[0xcd] = KB_RIGHT,
|
||||||
|
[0x97] = KB_HOME,
|
||||||
|
[0xcf] = KB_END,
|
||||||
|
[0xd2] = KB_INSERT,
|
||||||
|
[0xd3] = KB_DELETE,
|
||||||
|
[0xc7] = KB_HOME,
|
||||||
|
/* clang-format on */
|
||||||
|
};
|
||||||
|
|
||||||
|
int32_t ps2kb_keycode (void) {
|
||||||
|
static uint8_t shift;
|
||||||
|
static uint8_t* charcode[4] = {normalmap, shiftmap, ctlmap, ctlmap};
|
||||||
|
uint32_t st, data, c;
|
||||||
|
|
||||||
|
st = amd64_io_inb (KB_CTL_STATUS);
|
||||||
|
if (!(st & KB_DATA_IN_BUF)) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
data = amd64_io_inb (KB_DATA);
|
||||||
|
|
||||||
|
if (data == 0xe0) {
|
||||||
|
shift |= KB_E0ESC;
|
||||||
|
return 0;
|
||||||
|
} else if (data & 0x80) {
|
||||||
|
data = (shift & KB_E0ESC ? data : data & 0x7F);
|
||||||
|
shift &= ~(shiftcode[data] | KB_E0ESC);
|
||||||
|
return 0;
|
||||||
|
} else if (shift & KB_E0ESC) {
|
||||||
|
data |= 0x80;
|
||||||
|
shift &= ~KB_E0ESC;
|
||||||
|
}
|
||||||
|
|
||||||
|
shift |= shiftcode[data];
|
||||||
|
shift ^= togglecode[data];
|
||||||
|
c = charcode[shift & (KB_CTL | KB_SHIFT)][data];
|
||||||
|
if (shift & KB_CAPSLOCK) {
|
||||||
|
if ('a' <= c && c <= 'z') {
|
||||||
|
c += 'A' - 'a';
|
||||||
|
} else if ('A' <= c && c <= 'Z') {
|
||||||
|
c += 'a' - 'A';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return c;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ps2kb_irq (void* arg, void* regs) {
|
||||||
|
int32_t keycode = ps2kb_keycode ();
|
||||||
|
|
||||||
|
if (keycode >= 0) {
|
||||||
|
spin_lock (&ps2kb_ringbuffer_lock);
|
||||||
|
ringbuffer_push (uint8_t, &ps2kb_ringbuffer, (uint8_t)keycode);
|
||||||
|
spin_unlock (&ps2kb_ringbuffer_lock);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ps2kb_read_key (struct proc* proc, void* a1, void* a2, void* a3, void* a4) {
|
||||||
|
if (!(proc->procgroup->capabilities & PROC_CAP_KB))
|
||||||
|
return -ST_PERMISSION_ERROR;
|
||||||
|
|
||||||
|
uint8_t* chbuf = (uint8_t*)a1;
|
||||||
|
|
||||||
|
spin_lock (&ps2kb_ringbuffer_lock);
|
||||||
|
|
||||||
|
size_t prev_count = ps2kb_ringbuffer.count;
|
||||||
|
ringbuffer_pop (uint8_t, &ps2kb_ringbuffer, chbuf);
|
||||||
|
size_t new_count = ps2kb_ringbuffer.count;
|
||||||
|
|
||||||
|
spin_unlock (&ps2kb_ringbuffer_lock);
|
||||||
|
|
||||||
|
/* didn't pop anything */
|
||||||
|
if (prev_count == new_count)
|
||||||
|
return -ST_TRY_AGAIN;
|
||||||
|
|
||||||
|
return ST_OK;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ps2kb_init (void* arg) {
|
||||||
|
amd64_ioapic_route_irq (PS2KB, 1, 0, thiscpu->lapic_id);
|
||||||
|
irq_attach (&ps2kb_irq, NULL, PS2KB);
|
||||||
|
|
||||||
|
ringbuffer_init (&ps2kb_ringbuffer, PS2KB_RINGBUFFER_MAX, sizeof (uint8_t));
|
||||||
|
|
||||||
|
while (amd64_io_inb (KB_CTL_STATUS) & KB_DATA_IN_BUF)
|
||||||
|
amd64_io_inb (KB_DATA);
|
||||||
|
|
||||||
|
amd64_io_outb (KB_CTL_STATUS, 0x20);
|
||||||
|
|
||||||
|
uint8_t cb = amd64_io_inb (KB_DATA);
|
||||||
|
cb |= 0x01;
|
||||||
|
cb |= 0x40;
|
||||||
|
|
||||||
|
amd64_io_outb (KB_CTL_STATUS, 0x60);
|
||||||
|
amd64_io_outb (KB_DATA, cb);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ps2kb_fini (void) {
|
||||||
|
irq_detach (PS2KB);
|
||||||
|
ringbuffer_fini (&ps2kb_ringbuffer);
|
||||||
|
}
|
||||||
10
kernel/device/ps2_kb.h
Normal file
10
kernel/device/ps2_kb.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
#ifndef _KERNEL_DEVICE_PS2_KB_H
|
||||||
|
#define _KERNEL_DEVICE_PS2_KB_H
|
||||||
|
|
||||||
|
#include <proc/proc.h>
|
||||||
|
|
||||||
|
int ps2kb_read_key (struct proc* proc, void* a1, void* a2, void* a3, void* a4);
|
||||||
|
bool ps2kb_init (void* arg);
|
||||||
|
void ps2kb_fini (void);
|
||||||
|
|
||||||
|
#endif // _KERNEL_DEVICE_PS2_KB_H
|
||||||
@@ -3,3 +3,8 @@ c += device/device.c \
|
|||||||
|
|
||||||
o += device/device.o \
|
o += device/device.o \
|
||||||
device/terminal.o
|
device/terminal.o
|
||||||
|
|
||||||
|
ifeq ($(platform),amd64)
|
||||||
|
c += device/ps2_kb.c
|
||||||
|
o += device/ps2_kb.o
|
||||||
|
endif
|
||||||
|
|||||||
@@ -43,6 +43,9 @@ int terminal_putstr (struct proc* proc, void* a1, void* a2, void* a3, void* a4)
|
|||||||
char* string = (char*)a1;
|
char* string = (char*)a1;
|
||||||
size_t* len = (size_t*)a2;
|
size_t* len = (size_t*)a2;
|
||||||
|
|
||||||
|
if (string == NULL || len == NULL)
|
||||||
|
return -ST_BAD_ADDRESS_SPACE;
|
||||||
|
|
||||||
flanterm_write (ft_ctx, string, *len);
|
flanterm_write (ft_ctx, string, *len);
|
||||||
|
|
||||||
return ST_OK;
|
return ST_OK;
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
#include <irq/irq.h>
|
#include <irq/irq.h>
|
||||||
#include <libk/list.h>
|
#include <libk/rbtree.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
#include <mm/liballoc.h>
|
#include <mm/liballoc.h>
|
||||||
#include <sync/spin_lock.h>
|
#include <sync/spin_lock.h>
|
||||||
@@ -10,8 +10,7 @@
|
|||||||
#include <amd64/intr.h>
|
#include <amd64/intr.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
struct irq* irq_table[0x100];
|
static struct rb_node_link* irq_tree = NULL;
|
||||||
|
|
||||||
static spin_lock_t irqs_lock = SPIN_LOCK_INIT;
|
static spin_lock_t irqs_lock = SPIN_LOCK_INIT;
|
||||||
|
|
||||||
bool irq_attach (void (*func) (void*, void*), void* arg, uint32_t irq_num) {
|
bool irq_attach (void (*func) (void*, void*), void* arg, uint32_t irq_num) {
|
||||||
@@ -25,17 +24,27 @@ bool irq_attach (void (*func) (void*, void*), void* arg, uint32_t irq_num) {
|
|||||||
irq->irq_num = irq_num;
|
irq->irq_num = irq_num;
|
||||||
|
|
||||||
spin_lock (&irqs_lock);
|
spin_lock (&irqs_lock);
|
||||||
irq_table[irq_num] = irq;
|
rbtree_insert (struct irq, &irq_tree, &irq->irq_tree_link, irq_tree_link, irq_num);
|
||||||
spin_unlock (&irqs_lock);
|
spin_unlock (&irqs_lock);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct irq* irq_find (uint32_t irq_num) {
|
void irq_detach (uint32_t irq_num) {
|
||||||
|
struct irq* irq = irq_find (irq_num);
|
||||||
|
|
||||||
spin_lock (&irqs_lock);
|
spin_lock (&irqs_lock);
|
||||||
|
rbtree_delete (&irq_tree, &irq->irq_tree_link);
|
||||||
|
spin_unlock (&irqs_lock);
|
||||||
|
|
||||||
struct irq* irq = irq_table[irq_num];
|
free (irq);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct irq* irq_find (uint32_t irq_num) {
|
||||||
|
struct irq* irq = NULL;
|
||||||
|
|
||||||
|
spin_lock (&irqs_lock);
|
||||||
|
rbtree_find (struct irq, &irq_tree, irq_num, irq, irq_tree_link, irq_num);
|
||||||
spin_unlock (&irqs_lock);
|
spin_unlock (&irqs_lock);
|
||||||
|
|
||||||
return irq;
|
return irq;
|
||||||
|
|||||||
@@ -1,20 +1,21 @@
|
|||||||
#ifndef _KERNEL_IRQ_IRQ_H
|
#ifndef _KERNEL_IRQ_IRQ_H
|
||||||
#define _KERNEL_IRQ_IRQ_H
|
#define _KERNEL_IRQ_IRQ_H
|
||||||
|
|
||||||
#include <libk/list.h>
|
#include <libk/rbtree.h>
|
||||||
#include <libk/std.h>
|
#include <libk/std.h>
|
||||||
|
|
||||||
typedef void (*irq_func_t) (void* arg, void* regs);
|
typedef void (*irq_func_t) (void* arg, void* regs);
|
||||||
|
|
||||||
struct irq {
|
struct irq {
|
||||||
struct list_node_link irqs_link;
|
uint32_t irq_num;
|
||||||
|
struct rb_node_link irq_tree_link;
|
||||||
|
|
||||||
irq_func_t func;
|
irq_func_t func;
|
||||||
void* arg;
|
void* arg;
|
||||||
uint32_t irq_num;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
bool irq_attach (irq_func_t, void* arg, uint32_t irq_num);
|
bool irq_attach (irq_func_t, void* arg, uint32_t irq_num);
|
||||||
|
void irq_detach (uint32_t irq_num);
|
||||||
struct irq* irq_find (uint32_t irq_num);
|
struct irq* irq_find (uint32_t irq_num);
|
||||||
|
|
||||||
#endif // _KERNEL_IRQ_IRQ_H
|
#endif // _KERNEL_IRQ_IRQ_H
|
||||||
|
|||||||
@@ -3,10 +3,13 @@ include libk/src.mk
|
|||||||
include sync/src.mk
|
include sync/src.mk
|
||||||
include mm/src.mk
|
include mm/src.mk
|
||||||
include limine/src.mk
|
include limine/src.mk
|
||||||
include uACPI/src.mk
|
|
||||||
include irq/src.mk
|
include irq/src.mk
|
||||||
include proc/src.mk
|
include proc/src.mk
|
||||||
include syscall/src.mk
|
include syscall/src.mk
|
||||||
include fs/src.mk
|
include fs/src.mk
|
||||||
include device/src.mk
|
include device/src.mk
|
||||||
include Flanterm/src.mk
|
include Flanterm/src.mk
|
||||||
|
|
||||||
|
ifeq ($(PLATFORM_ACPI),1)
|
||||||
|
include uACPI/src.mk
|
||||||
|
endif
|
||||||
|
|||||||
@@ -2,5 +2,6 @@
|
|||||||
#define _KERNEL_PROC_CAPABILITY_H
|
#define _KERNEL_PROC_CAPABILITY_H
|
||||||
|
|
||||||
#define PROC_CAP_TERMINAL (1 << 0)
|
#define PROC_CAP_TERMINAL (1 << 0)
|
||||||
|
#define PROC_CAP_KB (1 << 1)
|
||||||
|
|
||||||
#endif // _KERNEL_PROC_CAPABILITY_H
|
#endif // _KERNEL_PROC_CAPABILITY_H
|
||||||
|
|||||||
@@ -304,7 +304,7 @@ void proc_init (void) {
|
|||||||
proc_register (spin_proc, &spin_cpu);
|
proc_register (spin_proc, &spin_cpu);
|
||||||
|
|
||||||
struct proc* init = proc_from_file ("ramdisk", "/init");
|
struct proc* init = proc_from_file ("ramdisk", "/init");
|
||||||
init->procgroup->capabilities |= PROC_CAP_TERMINAL;
|
init->procgroup->capabilities |= (PROC_CAP_TERMINAL | PROC_CAP_KB);
|
||||||
struct cpu* init_cpu = thiscpu;
|
struct cpu* init_cpu = thiscpu;
|
||||||
proc_register (init, &init_cpu);
|
proc_register (init, &init_cpu);
|
||||||
|
|
||||||
|
|||||||
4
libkb/.gitignore
vendored
Normal file
4
libkb/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
*.o
|
||||||
|
*.json
|
||||||
|
docs/
|
||||||
|
.cache/
|
||||||
7
libkb/Makefile
Normal file
7
libkb/Makefile
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
include ../make/ufuncs.mk
|
||||||
|
|
||||||
|
$(eval $(call add_include,libmsl))
|
||||||
|
|
||||||
|
libname := libkb
|
||||||
|
|
||||||
|
include ../make/lib.mk
|
||||||
15
libkb/kb.c
Normal file
15
libkb/kb.c
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
#include <stdint.h>
|
||||||
|
#include <kb.h>
|
||||||
|
#include <m/system.h>
|
||||||
|
#include <m/kb_device.h>
|
||||||
|
#include <m/status.h>
|
||||||
|
|
||||||
|
int kb_read_key (void) {
|
||||||
|
char ch = 0;
|
||||||
|
int r = device_do (KB_DEVICE, KB_READ_KEY, &ch, NULL, NULL, NULL);
|
||||||
|
|
||||||
|
if (r == ST_OK)
|
||||||
|
return (int)ch;
|
||||||
|
else
|
||||||
|
return r;
|
||||||
|
}
|
||||||
12
libkb/kb.h
Normal file
12
libkb/kb.h
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
#ifndef _LIBKB_KB_H
|
||||||
|
#define _LIBKB_KB_H
|
||||||
|
|
||||||
|
#include <m/kb_device.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/* \brief Read key from keyboard
|
||||||
|
* \return < 0 status on failure; ascii key on success
|
||||||
|
*/
|
||||||
|
int kb_read_key (void);
|
||||||
|
|
||||||
|
#endif // _LIBKB_KB_H
|
||||||
3
libkb/src.mk
Normal file
3
libkb/src.mk
Normal file
@@ -0,0 +1,3 @@
|
|||||||
|
c += kb.c
|
||||||
|
|
||||||
|
o += kb.o
|
||||||
@@ -4,9 +4,6 @@
|
|||||||
#include <m/terminal_device.h>
|
#include <m/terminal_device.h>
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
|
|
||||||
/* ID of kernel terminal device */
|
|
||||||
#define TERMINAL_DEVICE 1
|
|
||||||
|
|
||||||
/* Print a string onto a graphical terminal. Prints len chars */
|
/* Print a string onto a graphical terminal. Prints len chars */
|
||||||
void terminal_print (const char* string, size_t len);
|
void terminal_print (const char* string, size_t len);
|
||||||
|
|
||||||
|
|||||||
16
make/libkb.mk
Normal file
16
make/libkb.mk
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
all_libkb:
|
||||||
|
make -C libkb platform=$(platform) all
|
||||||
|
|
||||||
|
all_compiledb_libkb:
|
||||||
|
bear --output libkb/compile_commands.json -- make -C libkb platform=$(platform) all
|
||||||
|
|
||||||
|
clean_libkb:
|
||||||
|
make -C libkb platform=$(platform) clean
|
||||||
|
|
||||||
|
format_libkb:
|
||||||
|
make -C libkb platform=$(platform) format
|
||||||
|
|
||||||
|
docs_libkb:
|
||||||
|
make -C libkb platform=$(platform) docs
|
||||||
|
|
||||||
|
.PHONY: all_libkb clean_libkb format_libkb docs_libkb
|
||||||
Reference in New Issue
Block a user