ioe: refactor IO apis

This commit is contained in:
Yanyan Jiang 2019-01-31 05:32:57 +00:00
parent 99a3253487
commit 506b845f51
3 changed files with 37 additions and 74 deletions

10
am/am.h
View File

@ -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);

View File

@ -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;
}
}
}

View File

@ -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;
}