Files
Deshab-OS/CODE/DKM/ps2kbd/ps2kbd.c
T

140 lines
4.2 KiB
C
Raw Normal View History

/* DKM PS/2 Keyboard Driver — IRQ1 scan code → ASCII
* Stage 3, optional, depends on "irq", provides "keyboard".
* Registers IRQ1 handler, translates scan codes via lookup table.
*/
#include <stdint.h>
/* DKM ABI types */
#define DKM_DRIVER_MAGIC 0x444B4D31u
#define DKM_ABI_VERSION 1u
typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;
typedef unsigned long long u64;
typedef long long i64;
#define NULL ((void *)0)
struct dkm_log_api {
void (*info)(const char *msg);
void (*warn)(const char *msg);
void (*error)(const char *msg);
void (*panic)(const char *msg);
};
struct dkm_kernel_api {
u32 version; u32 size; u64 feature_bits;
const struct dkm_log_api *log;
const void *mem,*utsm,*irq_api,*pci_api,*dma,*vfs_api,*net,*timer,*drr;
const void *rsdp_address,*fb_address;
u64 fb_width,fb_height,fb_pitch; u16 fb_bpp;
const void *boot_modules_response;
int (*irq_register)(u8 irq, void *handler);
};
struct dkm_driver_handle;
struct dkm_driver_desc {
u32 magic; u16 abi_version; u16 desc_size;
const char *name,*version,*vendor;
u32 driver_class,stage,flags,priority;
const char *const *depends; u32 depends_count;
const char *const *provides; u32 provides_count;
u64 min_kernel_abi,feature_bits,reserved0,reserved1;
};
/* Driver descriptor */
static const char *const g_depends[] = {"irq"};
static const char *const g_provides[] = {"keyboard"};
__attribute__((visibility("default"), used))
const struct dkm_driver_desc driver_desc = {
.magic=DKM_DRIVER_MAGIC, .abi_version=DKM_ABI_VERSION,
.desc_size=sizeof(struct dkm_driver_desc),
.name="ps2kbd", .version="0.1.0", .vendor="Deshab",
.driver_class=10, .stage=3, .flags=0, .priority=0,
.depends=g_depends, .depends_count=1,
.provides=g_provides, .provides_count=1,
.min_kernel_abi=1,
};
/* Scan code set 1 → ASCII (lowercase) */
static const char sc_ascii[] = {
0,0,'1','2','3','4','5','6','7','8','9','0','-','=',0,
0,'q','w','e','r','t','y','u','i','o','p','[',']',0,
0,'a','s','d','f','g','h','j','k','l',';','\'','`',0,
'\\','z','x','c','v','b','n','m',',','.','/',0,
'*',0,' ',0
};
static const struct dkm_log_api *g_log;
static volatile int g_has_key;
static volatile u8 g_last_sc;
/* inline I/O */
static u8 inb(u16 p) { u8 v; __asm__("inb %1,%0":"=a"(v):"Nd"(p)); return v; }
static void outb(u16 p, u8 v) { __asm__("outb %0,%1"::"a"(v),"Nd"(p)); }
static void log_hex(const char *prefix, u64 v) {
static const char h[]="0123456789abcdef";
char b[19]; u32 i=0; b[i++]='0'; b[i++]='x';
for (int j=15;j>=0;j--) b[i++]=h[(v>>(j*4))&0xf];
b[i]=0; g_log->info(prefix); g_log->info(b);
}
static int kbd_handler(u8 irq) {
(void)irq;
g_last_sc = inb(0x60);
g_has_key = 1;
return 0; /* let kernel send EOI */
}
__attribute__((visibility("default")))
int driver_init(const struct dkm_kernel_api *api,
struct dkm_driver_handle *handle) {
(void)handle;
if (!api||!api->log) return -1;
g_log=api->log;
if (!api->irq_register) {
g_log->warn("[kbd] irq_register not available");
return 0;
}
if (api->irq_register(1, (void*)(uintptr_t)kbd_handler) != 0) {
g_log->error("[kbd] failed to register IRQ1");
return -1;
}
g_log->info("[kbd] IRQ1 registered, waiting for keypress");
g_log->info("[kbd] (boot will continue, key echo in ISR)");
/* spin briefly to show a key echo demo */
int ticks = 0;
while (ticks < 200000) {
if (g_has_key) {
u8 sc = g_last_sc;
g_has_key = 0;
if (sc < 0x80) {
/* make code */
log_hex("[kbd] sc=", sc);
if (sc < sizeof(sc_ascii) && sc_ascii[sc]) {
char buf[2] = {sc_ascii[sc], 0};
g_log->info("[kbd] key");
g_log->info(buf);
}
}
}
for (volatile int z=0;z<100;z++) {}
ticks++;
}
g_log->info("[kbd] driver ready");
return 0;
}
__attribute__((visibility("default")))
int driver_exit(struct dkm_driver_handle *handle) {
(void)handle; return 0;
}