ioe: refactor IO apis
This commit is contained in:
parent
99a3253487
commit
506b845f51
10
am/am.h
10
am/am.h
|
@ -36,15 +36,6 @@ typedef struct _Area {
|
|||
void *start, *end;
|
||||
} _Area;
|
||||
|
||||
// A device (@id, @name) with @read/@write support
|
||||
// See <amdev.h> 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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -1,77 +1,49 @@
|
|||
#include <klib.h>
|
||||
#include <amdev.h>
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue