diff --git a/am/am.h b/am/am.h index e6b43951..3e2ce844 100644 --- a/am/am.h +++ b/am/am.h @@ -36,15 +36,6 @@ typedef struct _Area { void *start, *end; } _Area; -// A device (@id, @name) with @read/@write support -// See for device descriptions -typedef struct _Device { - uint32_t id; - const char *name; - size_t (*read) (uintptr_t reg, void *buf, size_t size); - size_t (*write)(uintptr_t reg, void *buf, size_t size); -} _Device; - // An event of type @event, caused by @cause of pointer @ref typedef struct _Event { int event; @@ -70,7 +61,6 @@ void _halt(int code) __attribute__((__noreturn__)); // ======================= I/O Extension (IOE) ======================= int _ioe_init(); -_Device *_device(int n); size_t _io_read(uint32_t dev, uintptr_t reg, void *buf, size_t size); size_t _io_write(uint32_t dev, uintptr_t reg, void *buf, size_t size); diff --git a/am/arch/x86-qemu/src/ioe.c b/am/arch/x86-qemu/src/ioe.c index d9e03386..2c93de56 100644 --- a/am/arch/x86-qemu/src/ioe.c +++ b/am/arch/x86-qemu/src/ioe.c @@ -3,36 +3,37 @@ void vga_init(); void timer_init(); -#define DEVOP_DEF(dev, op) \ - size_t dev##_##op(uintptr_t reg, void *buf, size_t size); +#define DEF_DEVOP(fn) \ + size_t fn(uintptr_t reg, void *buf, size_t size); -#define DEVOPS(_) \ - _(input, read) \ - _(timer, read) \ - _(video, read) _(video, write) \ - _(pciconf, read) _(pciconf, write) \ - _(hd, read) _(hd, write) +DEF_DEVOP(input_read); +DEF_DEVOP(timer_read); +DEF_DEVOP(video_read); +DEF_DEVOP(video_write); +DEF_DEVOP(pciconf_read); +DEF_DEVOP(pciconf_write); -DEVOPS(DEVOP_DEF) +size_t _io_read(uint32_t dev, uintptr_t reg, void *buf, size_t size) { + switch (dev) { + case _DEV_INPUT: return input_read(reg, buf, size); + case _DEV_TIMER: return timer_read(reg, buf, size); + case _DEV_VIDEO: return video_read(reg, buf, size); + case _DEV_PCICONF: return pciconf_read(reg, buf, size); + } + return 0; +} -static _Device x86_dev[] = { - {_DEV_INPUT, "8279 Keyboard Controller", input_read, NULL}, - {_DEV_TIMER, "RDTSC Timer / CMOS RTC", timer_read, NULL}, - {_DEV_VIDEO, "Standard VGA Controller", video_read, video_write}, - {_DEV_PCICONF, "PCI Configuration", pciconf_read, pciconf_write}, -}; +size_t _io_write(uint32_t dev, uintptr_t reg, void *buf, size_t size) { + switch (dev) { + case _DEV_VIDEO: return video_write(reg, buf, size); + case _DEV_PCICONF: return pciconf_write(reg, buf, size); + } + return 0; +} int _ioe_init() { if (_cpu() != 0) panic("init IOE in non-bootstrap CPU"); timer_init(); vga_init(); return 0; -} - -_Device *_device(int n) { - if (n >= 1 && n <= sizeof(x86_dev) / sizeof(x86_dev[0])) { - return &x86_dev[n - 1]; - } else { - return NULL; - } -} +} \ No newline at end of file diff --git a/libs/klib/src/io.c b/libs/klib/src/io.c index 20553a23..29bae729 100644 --- a/libs/klib/src/io.c +++ b/libs/klib/src/io.c @@ -1,77 +1,49 @@ #include #include -static _Device *getdev(_Device **ptr, uint32_t id) { - if (*ptr) return *ptr; - for (int n = 1; ; n ++) { - _Device *cur = _device(n); - if (cur->id == id) { - *ptr = cur; - return cur; - } - if (!cur) break; - } - assert(0); - return NULL; -} - -static _Device *input_dev; -static _Device *video_dev; -static _Device *timer_dev; - uint32_t uptime() { _DEV_TIMER_UPTIME_t uptime; - _Device *dev = getdev(&timer_dev, _DEV_TIMER); - dev->read(_DEVREG_TIMER_UPTIME, &uptime, sizeof(uptime)); + _io_read(_DEV_TIMER, _DEVREG_TIMER_UPTIME, &uptime, sizeof(uptime)); return uptime.lo; } void get_timeofday(void *rtc) { - _Device *dev = getdev(&timer_dev, _DEV_TIMER); - dev->read(_DEVREG_TIMER_DATE, rtc, sizeof(_DEV_TIMER_DATE_t)); + _io_read(_DEV_TIMER, _DEVREG_TIMER_DATE, rtc, sizeof(_DEV_TIMER_DATE_t)); } int read_key() { - _Device *dev = getdev(&input_dev, _DEV_INPUT); _DEV_INPUT_KBD_t key; - dev->read(_DEVREG_INPUT_KBD, &key, sizeof(_DEV_INPUT_KBD_t)); + _io_read(_DEV_INPUT, _DEVREG_INPUT_KBD, &key, sizeof(_DEV_INPUT_KBD_t)); int ret = key.keycode; if (key.keydown) ret |= 0x8000; return ret; } void draw_rect(uint32_t *pixels, int x, int y, int w, int h) { - _Device *dev = getdev(&video_dev, _DEV_VIDEO); - _DEV_VIDEO_FBCTL_t ctl; - ctl.pixels = pixels; - ctl.x = x; - ctl.y = y; - ctl.w = w; - ctl.h = h; - ctl.sync = 0; - dev->write(_DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl)); + _DEV_VIDEO_FBCTL_t ctl = (_DEV_VIDEO_FBCTL_t) { + .pixels = pixels, + .x = x, .y = y, .w = w, .h = h, + .sync = 0, + }; + _io_write(_DEV_VIDEO, _DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl)); } void draw_sync() { - _Device *dev = getdev(&video_dev, _DEV_VIDEO); _DEV_VIDEO_FBCTL_t ctl; ctl.pixels = NULL; ctl.x = ctl.y = ctl.w = ctl.h = 0; ctl.sync = 1; - dev->write(_DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl)); + _io_write(_DEV_VIDEO, _DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl)); } int screen_width() { - _Device *dev = getdev(&video_dev, _DEV_VIDEO); _DEV_VIDEO_INFO_t info; - dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info)); + _io_read(_DEV_VIDEO, _DEVREG_VIDEO_INFO, &info, sizeof(info)); return info.width; } int screen_height() { - _Device *dev = getdev(&video_dev, _DEV_VIDEO); _DEV_VIDEO_INFO_t info; - dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info)); + _io_read(_DEV_VIDEO, _DEVREG_VIDEO_INFO, &info, sizeof(info)); return info.height; } -