ioe,x86-qemu: better register decls

This commit is contained in:
Yanyan Jiang 2019-01-30 12:47:30 +00:00
parent fc23eb92b2
commit 99a3253487
7 changed files with 55 additions and 94 deletions

View File

@ -71,6 +71,8 @@ void _halt(int code) __attribute__((__noreturn__));
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);
// ====================== Context Extension (CTE) ====================

View File

@ -16,88 +16,48 @@ extern "C" {
#define _DEV_VIDEO 0x0000ac04 // AM Virtual Video Controller
#define _DEV_SERIAL 0x0000ac05 // AM Virtual Serial
#define _DEV_PCICONF 0x00000080 // PCI Configuration Space
#define _DEV_ATA0 0x00000dd0 // Primary ATA
#define _DEV_ATA1 0x00000dd1 // Secondary ATA
#define _AM_DEVREG(dev, reg, id, ...) \
enum { _DEVREG_##dev##_##reg = id }; \
typedef struct { __VA_ARGS__; } __attribute__((packed)) \
_DEV_##dev##_##reg##_t;
// ================= Device Register Specifications ==================
// --------- _DEV_PERFCNT AM Performance Counter (0000ac01) ----------
// ------------- _DEV_INPUT: AM Input Devices (0000ac02) -------------
#define _DEVREG_INPUT_KBD 1
#define _KEYS(_) \
_(ESCAPE) \
_(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) _(F8) _(F9) _(F10) _(F11) _(F12) \
_(GRAVE) _(1) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(0) \
_(MINUS) _(EQUALS) _(BACKSPACE) \
_(TAB) _(Q) _(W) _(E) _(R) _(T) _(Y) _(U) _(I) _(O) _(P) \
_(LEFTBRACKET) _(RIGHTBRACKET) _(BACKSLASH) \
_(CAPSLOCK) _(A) _(S) _(D) _(F) _(G) _(H) _(J) _(K) _(L) \
_(SEMICOLON) _(APOSTROPHE) _(RETURN) \
_(LSHIFT) _(Z) _(X) _(C) _(V) _(B) _(N) _(M) \
_(COMMA) _(PERIOD) _(SLASH) _(RSHIFT) \
_(LCTRL) _(APPLICATION) _(LALT) _(SPACE) _(RALT) _(RCTRL) \
_(UP) _(DOWN) _(LEFT) _(RIGHT) _(INSERT) _(DELETE) \
_(HOME) _(END) _(PAGEUP) _(PAGEDOWN)
#define _KEY_NAME(k) _KEY_##k,
enum {
_KEY_NONE = 0,
_KEYS(_KEY_NAME)
};
typedef struct {
int keydown; // is keydown ? 1 : 0
int keycode; // key code _KEY_XXX
} _KbdReg;
// ----------- _DEV_TIMER: AM Real Time Clock (0000ac03) -------------
#define _DEVREG_TIMER_UPTIME 1
typedef struct {
uint32_t hi; // high 32bit of uptime (ms)
uint32_t lo; // low 32bit of uptime (ms)
} _UptimeReg;
#define _DEVREG_TIMER_DATE 2
typedef struct {
int year, month, day; // date
int hour, minute, second; // time
} _RTCReg;
// ----------- _DEV_VIDEO: AM Video Controller (0000ac04) ------------
#define _DEVREG_VIDEO_INFO 1
typedef struct {
int32_t width, height; // screen size: @width * @height
} _VideoInfoReg;
#define _DEVREG_VIDEO_FBCTL 2
typedef struct {
int x, y; // draw to (@x, @y)
uint32_t *pixels; // @pixels: @w*@h pixels to draw
int w, h; // @pixels[i * w + j] is 00RRGGBB
int sync; // @sync ? sync screen : do nothing
} _FBCtlReg;
// ---------- _DEV_SERIAL: AM Serial Controller (0000ac05) -----------
#define _DEVREG_SERIAL_RECV 0
#define _DEVREG_SERIAL_SEND 1
#define _DEVREG_SERIAL_STAT 2
#define _DEVREG_SERIAL_CTRL 3
// -------- _DEV_PCICONF: PCI Configuration Space (00000080) ---------
_AM_DEVREG(INPUT, KBD, 1, int keydown, keycode);
_AM_DEVREG(TIMER, UPTIME, 1, uint32_t hi, lo);
_AM_DEVREG(TIMER, DATE, 2, int year, month, day, hour, minute, second);
_AM_DEVREG(VIDEO, INFO, 1, int width, height);
_AM_DEVREG(VIDEO, FBCTL, 2, int x, y; uint32_t *pixels; int w, h, sync);
_AM_DEVREG(SERIAL, RECV, 1, uint8_t data);
_AM_DEVREG(SERIAL, SEND, 2, uint8_t data);
_AM_DEVREG(SERIAL, STAT, 3, uint8_t data);
_AM_DEVREG(SERIAL, CTRL, 4, uint8_t data);
#define _DEVREG_PCICONF(bus, slot, func, offset) \
((uint32_t)( 1) << 31) | ((uint32_t)( bus) << 16) | \
((uint32_t)(slot) << 11) | ((uint32_t)(func) << 8) | (offset)
// ------ _DEV_ATAx: ATA Disk Controller (00000dd0 -- 00000dd1) ------
#define _DEVREG_ATA_DATA 0
#define _DEVREG_ATA_FEATURE 1
#define _DEVREG_ATA_NSECT 2
#define _DEVREG_ATA_SECT 3
#define _DEVREG_ATA_CYLOW 4
#define _DEVREG_ATA_CYHIGH 5
#define _DEVREG_ATA_DRIVE 6
#define _DEVREG_ATA_STATUS 7
// ============================ Key Codes ============================
#define _KEYS(_) \
_(ESCAPE) \
_(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) _(F8) _(F9) _(F10) _(F11) _(F12) \
_(GRAVE) _(1) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(0) \
_(MINUS) _(EQUALS) _(BACKSPACE) \
_(TAB) _(Q) _(W) _(E) _(R) _(T) _(Y) _(U) _(I) _(O) _(P) \
_(LEFTBRACKET) _(RIGHTBRACKET) _(BACKSLASH) \
_(CAPSLOCK) _(A) _(S) _(D) _(F) _(G) _(H) _(J) _(K) _(L) \
_(SEMICOLON) _(APOSTROPHE) _(RETURN) \
_(LSHIFT) _(Z) _(X) _(C) _(V) _(B) _(N) _(M) \
_(COMMA) _(PERIOD) _(SLASH) _(RSHIFT) \
_(LCTRL) _(APPLICATION) _(LALT) _(SPACE) _(RALT) _(RCTRL) \
_(UP) _(DOWN) _(LEFT) _(RIGHT) _(INSERT) _(DELETE) \
_(HOME) _(END) _(PAGEUP) _(PAGEDOWN)
#define _KEY_NAME(k) _KEY_##k,
enum {
_KEY_NONE = 0,
_KEYS(_KEY_NAME)
};
#ifdef __cplusplus
}

View File

@ -11,7 +11,7 @@ static int scan_code[] = {
};
size_t input_read(uintptr_t reg, void *buf, size_t size) {
_KbdReg *kbd = (_KbdReg *)buf;
_DEV_INPUT_KBD_t *kbd = (_DEV_INPUT_KBD_t *)buf;
int status = inb(0x64);
kbd->keydown = 0;

View File

@ -1,6 +1,6 @@
#include <am-x86.h>
static _RTCReg boot_date;
static _DEV_TIMER_DATE_t boot_date;
static uint32_t freq_mhz = 2000;
uint64_t uptsc;
@ -45,7 +45,7 @@ static uint32_t estimate_freq() {
return freq;
}
static void get_date(_RTCReg *rtc) {
static void get_date(_DEV_TIMER_DATE_t *rtc) {
int tmp;
do {
rtc->second = read_rtc(0);
@ -70,14 +70,14 @@ size_t timer_read(uintptr_t reg, void *buf, size_t size) {
uint64_t tsc = rdtsc() - uptsc;
uint32_t mticks = (tsc >> 20);
uint32_t ms = mticks * 1000 / freq_mhz;
_UptimeReg *uptime = (_UptimeReg *)buf;
_DEV_TIMER_UPTIME_t *uptime = (_DEV_TIMER_UPTIME_t *)buf;
uptime->hi = 0;
uptime->lo = ms;
return sizeof(_UptimeReg);
return sizeof(_DEV_TIMER_UPTIME_t);
}
case _DEVREG_TIMER_DATE: {
get_date((_RTCReg *)buf);
return sizeof(_RTCReg);
get_date((_DEV_TIMER_DATE_t *)buf);
return sizeof(_DEV_TIMER_DATE_t);
}
}
return 0;

View File

@ -62,10 +62,10 @@ void vga_init() {
size_t video_read(uintptr_t reg, void *buf, size_t size) {
switch(reg) {
case _DEVREG_VIDEO_INFO: {
_VideoInfoReg *info = (_VideoInfoReg *)buf;
_DEV_VIDEO_INFO_t *info = (_DEV_VIDEO_INFO_t *)buf;
info->width = W;
info->height = H;
return sizeof(_VideoInfoReg);
return sizeof(_DEV_VIDEO_INFO_t);
}
}
return 0;
@ -74,7 +74,7 @@ size_t video_read(uintptr_t reg, void *buf, size_t size) {
size_t video_write(uintptr_t reg, void *buf, size_t size) {
switch(reg) {
case _DEVREG_VIDEO_FBCTL: {
_FBCtlReg *ctl = (_FBCtlReg *)buf;
_DEV_VIDEO_FBCTL_t *ctl = (_DEV_VIDEO_FBCTL_t *)buf;
int x = ctl->x, y = ctl->y, w = ctl->w, h = ctl->h;
uint32_t *pixels = ctl->pixels;
int len = (x + w >= W) ? W - x : w;

View File

@ -20,7 +20,6 @@ static _Device x86_dev[] = {
{_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},
{_DEV_ATA0, "ATA Disk Controller 0", hd_read, hd_write},
};
int _ioe_init() {

View File

@ -20,7 +20,7 @@ static _Device *video_dev;
static _Device *timer_dev;
uint32_t uptime() {
_UptimeReg uptime;
_DEV_TIMER_UPTIME_t uptime;
_Device *dev = getdev(&timer_dev, _DEV_TIMER);
dev->read(_DEVREG_TIMER_UPTIME, &uptime, sizeof(uptime));
return uptime.lo;
@ -28,13 +28,13 @@ uint32_t uptime() {
void get_timeofday(void *rtc) {
_Device *dev = getdev(&timer_dev, _DEV_TIMER);
dev->read(_DEVREG_TIMER_DATE, rtc, sizeof(_RTCReg));
dev->read(_DEVREG_TIMER_DATE, rtc, sizeof(_DEV_TIMER_DATE_t));
}
int read_key() {
_Device *dev = getdev(&input_dev, _DEV_INPUT);
_KbdReg key;
dev->read(_DEVREG_INPUT_KBD, &key, sizeof(_KbdReg));
_DEV_INPUT_KBD_t key;
dev->read(_DEVREG_INPUT_KBD, &key, sizeof(_DEV_INPUT_KBD_t));
int ret = key.keycode;
if (key.keydown) ret |= 0x8000;
return ret;
@ -42,7 +42,7 @@ int read_key() {
void draw_rect(uint32_t *pixels, int x, int y, int w, int h) {
_Device *dev = getdev(&video_dev, _DEV_VIDEO);
_FBCtlReg ctl;
_DEV_VIDEO_FBCTL_t ctl;
ctl.pixels = pixels;
ctl.x = x;
ctl.y = y;
@ -54,7 +54,7 @@ void draw_rect(uint32_t *pixels, int x, int y, int w, int h) {
void draw_sync() {
_Device *dev = getdev(&video_dev, _DEV_VIDEO);
_FBCtlReg ctl;
_DEV_VIDEO_FBCTL_t ctl;
ctl.pixels = NULL;
ctl.x = ctl.y = ctl.w = ctl.h = 0;
ctl.sync = 1;
@ -63,14 +63,14 @@ void draw_sync() {
int screen_width() {
_Device *dev = getdev(&video_dev, _DEV_VIDEO);
_VideoInfoReg info;
_DEV_VIDEO_INFO_t info;
dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info));
return info.width;
}
int screen_height() {
_Device *dev = getdev(&video_dev, _DEV_VIDEO);
_VideoInfoReg info;
_DEV_VIDEO_INFO_t info;
dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info));
return info.height;
}