diff --git a/am/am.h b/am/am.h index 69669754..c8ae3736 100755 --- a/am/am.h +++ b/am/am.h @@ -30,10 +30,10 @@ enum { _EVENT_SYSCALL, }; -#define _PROT_NONE 1 -#define _PROT_READ 2 -#define _PROT_WRITE 4 -#define _PROT_EXEC 8 +#define _PROT_NONE 1 // no access +#define _PROT_READ 2 // can read +#define _PROT_WRITE 4 // can write +#define _PROT_EXEC 8 // can execute // A memory area of [@start, @end) typedef struct _Area { @@ -91,7 +91,7 @@ void _prot_switch(_Protect *p); void _map(_Protect *p, void *va, void *pa); void _protect(_Protect *p, void *va, int len, int prot); _RegSet *_umake(_Protect *p, _Area ustack, _Area kstack, - void *entry, void *args); + void (*entry)(void *), void *args); // ================= Multi-Processor Extension (MPE) ================= diff --git a/am/amdev.h b/am/amdev.h index 3eb8b64c..eee1d144 100644 --- a/am/amdev.h +++ b/am/amdev.h @@ -3,6 +3,9 @@ #include +// =========================== AM Devices ============================ +// ((_Device *)dev)->id + #define _DEV_PERFCNT 0x0000ac01 #define _DEV_INPUT 0x0000ac02 #define _DEV_TIMER 0x0000ac03 @@ -11,74 +14,74 @@ #define _DEV_ATA0 0x00000dd0 #define _DEV_ATA1 0x00000dd1 -// Performance Counter (0000ac01) +// ================= Device Register Specifications ================== -// Input (0000ac02) +// ------------- _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; -#define _DEV_INPUT_REG_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) -}; +// ----------- _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; -// Timer (0000ac03) +#define _DEVREG_TIMER_DATE 2 + typedef struct { + int year, month, day; // date + int hour, minute, second; // time + } _RTCReg; -typedef struct _TimerUptime { - uint32_t hi, lo; -} _Dev_Timer_Uptime; -#define _DEV_TIMER_REG_UPTIME 1 -typedef struct _TimerRTC { - int year, month, day, hour, minute, second; -} _Dev_Timer_RTC; -#define _DEV_TIMER_REG_DATE 2 +// ----------- _DEV_VIDEO: AM Video Controller (0000ac04) ------------ +#define _DEVREG_VIDEO_INFO 1 + typedef struct { + int32_t width, height; // screen size + } _VideoInfoReg; -// Video (0000ac04) +#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; -typedef struct _VideoInfo { - int32_t width, height; -} _Dev_Video_Info; -#define _DEV_VIDEO_REG_INFO 1 -typedef struct _Video_FBCtl { - int x, y, w, h, sync; - uint32_t *pixels; -} _Dev_Video_FBCtl; -#define _DEV_VIDEO_REG_FBCTL 2 +// -------- _DEV_PCICONF: PCI Configuration Space (00000080) --------- +#define _DEVREG_PCICONF(bus, slot, func, offset) \ + ((uint32_t)( 1) << 31) | ((uint32_t)( bus) << 16) | \ + ((uint32_t)(slot) << 11) | ((uint32_t)(func) << 8) | (offset) -// PCI Configuration (00000080) - -static inline uint32_t -_DEV_PCICONF_REG(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { - return ((uint32_t)1 << 31) - | ((uint32_t)bus << 16) - | ((uint32_t)slot << 11) - | ((uint32_t)func << 8) - | offset; -} - -// ATA (00000dd0 -- 00000dd1) - -#define _DEV_ATA_REG_DATA 0 -#define _DEV_ATA_REG_FEATURE 1 -#define _DEV_ATA_REG_NSECT 2 -#define _DEV_ATA_REG_SECT 3 -#define _DEV_ATA_REG_CYLOW 4 -#define _DEV_ATA_REG_CYHIGH 5 -#define _DEV_ATA_REG_DRIVE 6 -#define _DEV_ATA_REG_STATUS 7 +// ------ _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 #endif diff --git a/am/arch/x86-qemu/src/asye.cpp b/am/arch/x86-qemu/src/asye.cpp index 40dbf044..53dc8a7a 100644 --- a/am/arch/x86-qemu/src/asye.cpp +++ b/am/arch/x86-qemu/src/asye.cpp @@ -223,7 +223,7 @@ _RegSet *_make(_Area stack, void *entry, void *arg) { regs->cs = KSEL(SEG_KCODE); regs->ds = regs->es = regs->ss = KSEL(SEG_KDATA); regs->eip = (uint32_t)entry; - regs->eflags = FL_IF; + regs->eflags = 0; regs->esp0 -= 4; *((void**)(regs->esp0)) = arg; // argument regs->esp0 -= 4; diff --git a/am/arch/x86-qemu/src/devices/video.c b/am/arch/x86-qemu/src/devices/video.c new file mode 100644 index 00000000..816a40f2 --- /dev/null +++ b/am/arch/x86-qemu/src/devices/video.c @@ -0,0 +1,101 @@ +#include +#include + +struct VBEInfo { + uint16_t attributes; + uint8_t window_a; + uint8_t window_b; + uint16_t granularity; + uint16_t window_size; + uint16_t segment_a; + uint16_t segment_b; + uint32_t win_func_ptr; + uint16_t pitch; + uint16_t width; + uint16_t height; + uint8_t w_char; + uint8_t y_char; + uint8_t planes; + uint8_t bpp; + uint8_t banks; + uint8_t memory_model; + uint8_t bank_size; + uint8_t image_pages; + uint8_t reserved0; + + uint8_t red_mask; + uint8_t red_position; + uint8_t green_mask; + uint8_t green_position; + uint8_t blue_mask; + uint8_t blue_position; + uint8_t reserved_mask; + uint8_t reserved_position; + uint8_t direct_color_attributes; + + uint32_t framebuffer; + uint32_t off_screen_mem_off; + uint16_t off_screen_mem_size; + uint8_t reserved1[206]; +} __attribute__ ((packed)); +typedef struct VBEInfo VBEInfo; + +static inline uint32_t pixel(uint8_t r, uint8_t g, uint8_t b) { + return (r << 16) | (g << 8) | b; +} +static uint8_t R(uint32_t p) { return p >> 16; } +static uint8_t G(uint32_t p) { return p >> 8; } +static uint8_t B(uint32_t p) { return p; } + +static struct FBPixel { + uint8_t b, g, r; +} __attribute__ ((packed)) *fb; +typedef struct FBPixel FBPixel; +static int W, H; + +void vga_init() { + VBEInfo *info = (VBEInfo *)0x00004000; + W = info->width; + H = info->height; + fb = (FBPixel*)(info->framebuffer); +} + +size_t video_read(uintptr_t reg, void *buf, size_t size) { + switch(reg) { + case _DEVREG_VIDEO_INFO: { + _VideoInfoReg *info = (_VideoInfoReg *)buf; + info->width = W; + info->height = H; + return sizeof(_VideoInfoReg); + } + } + return 0; +} + +size_t video_write(uintptr_t reg, void *buf, size_t size) { + switch(reg) { + case _DEVREG_VIDEO_FBCTL: { + _FBCtlReg *ctl = (_FBCtlReg *)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; + FBPixel *v; + for (int j = 0; j < h; j ++) { + if (y + j < H) { + v = &fb[x + (j + y) * W]; + for (int i = 0; i < len; i ++, v ++) { + uint32_t p = pixels[i]; + v->r = R(p); v->g = G(p); v->b = B(p); + } + } + pixels += w; + } + if (ctl->sync) { + // do nothing, hardware syncs. + } + return sizeof(size); + } + } + return 0; +} + diff --git a/am/arch/x86-qemu/src/ioe.cpp b/am/arch/x86-qemu/src/ioe.cpp index d7c525f6..8d072fea 100644 --- a/am/arch/x86-qemu/src/ioe.cpp +++ b/am/arch/x86-qemu/src/ioe.cpp @@ -14,64 +14,9 @@ static inline uint64_t rdtsc() { extern "C" { -struct VBEInfo { - uint16_t attributes; - uint8_t window_a; - uint8_t window_b; - uint16_t granularity; - uint16_t window_size; - uint16_t segment_a; - uint16_t segment_b; - uint32_t win_func_ptr; - uint16_t pitch; - uint16_t width; - uint16_t height; - uint8_t w_char; - uint8_t y_char; - uint8_t planes; - uint8_t bpp; - uint8_t banks; - uint8_t memory_model; - uint8_t bank_size; - uint8_t image_pages; - uint8_t reserved0; - - uint8_t red_mask; - uint8_t red_position; - uint8_t green_mask; - uint8_t green_position; - uint8_t blue_mask; - uint8_t blue_position; - uint8_t reserved_mask; - uint8_t reserved_position; - uint8_t direct_color_attributes; - - uint32_t framebuffer; - uint32_t off_screen_mem_off; - uint16_t off_screen_mem_size; - uint8_t reserved1[206]; -} __attribute__ ((packed)); +extern void vga_init(); -static inline uint32_t pixel(uint8_t r, uint8_t g, uint8_t b) { - return (r << 16) | (g << 8) | b; -} -static uint8_t R(uint32_t p) { return p >> 16; } -static uint8_t G(uint32_t p) { return p >> 8; } -static uint8_t B(uint32_t p) { return p; } - -static struct FBPixel { - uint8_t b, g, r; -} __attribute__ ((packed)) *fb; -static int W, H; - -static void vga_init() { - VBEInfo *info = reinterpret_cast(0x00004000); - W = info->width; - H = info->height; - fb = reinterpret_cast(info->framebuffer); -} - -static _Dev_Timer_RTC boot_date; +static _RTCReg boot_date; static int read_rtc(int reg) { outb(0x70, reg); int ret = inb(0x71); @@ -107,7 +52,7 @@ static uint32_t estimate_freq() { return freq; } -static void get_date(_Dev_Timer_RTC *rtc) { +static void get_date(_RTCReg *rtc) { int tmp; do { rtc->second = read_rtc(0); @@ -116,7 +61,7 @@ static void get_date(_Dev_Timer_RTC *rtc) { rtc->day = read_rtc(7); rtc->month = read_rtc(8); rtc->year = read_rtc(9) + 2000; - tmp = read_rtc(0); + tmp = read_rtc(0); } while (tmp != rtc->second); } @@ -190,7 +135,7 @@ static size_t input_read(uintptr_t reg, void *buf, size_t size) { ret = _KEY_NONE; } else { if (status & 0x20) { // mouse - ret = upevent(_KEY_NONE); + ret = _KEY_NONE; } else { int code = inb(0x60) & 0xff; @@ -212,57 +157,18 @@ static size_t input_read(uintptr_t reg, void *buf, size_t size) { static size_t timer_read(uintptr_t reg, void *buf, size_t size) { switch (reg) { - case _DEV_TIMER_REG_UPTIME: { + case _DEVREG_TIMER_UPTIME: { uint64_t tsc = rdtsc() - uptsc; uint32_t mticks = (tsc >> 20); uint32_t ms = mticks * 1000 / freq_mhz; - _Dev_Timer_Uptime *uptime = (_Dev_Timer_Uptime *)buf; + _UptimeReg *uptime = (_UptimeReg *)buf; uptime->hi = 0; uptime->lo = ms; - return sizeof(_Dev_Timer_Uptime); + return sizeof(_UptimeReg); } - case _DEV_TIMER_REG_DATE: { - get_date((_Dev_Timer_RTC *)buf); - return sizeof(_Dev_Timer_RTC); - } - } - return 0; -} - -static size_t video_read(uintptr_t reg, void *buf, size_t size) { - switch(reg) { - case _DEV_VIDEO_REG_INFO: { - _Dev_Video_Info *info = (_Dev_Video_Info *)buf; - info->width = W; - info->height = H; - return sizeof(_Dev_Video_Info); - } - } - return 0; -} - -static size_t video_write(uintptr_t reg, void *buf, size_t size) { - switch(reg) { - case _DEV_VIDEO_REG_FBCTL: { - _Dev_Video_FBCtl *ctl = (_Dev_Video_FBCtl *)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; - FBPixel *v; - for (int j = 0; j < h; j ++) { - if (y + j < H) { - v = &fb[x + (j + y) * W]; - for (int i = 0; i < len; i ++, v ++) { - uint32_t p = pixels[i]; - v->r = R(p); v->g = G(p); v->b = B(p); - } - } - pixels += w; - } - if (ctl->sync) { - // do nothing, hardware syncs. - } - return sizeof(size); + case _DEVREG_TIMER_DATE: { + get_date((_RTCReg *)buf); + return sizeof(_RTCReg); } } return 0; @@ -279,6 +185,9 @@ static size_t hd_write(uintptr_t reg, void *buf, size_t size) { return 0; } +size_t video_read(uintptr_t reg, void *buf, size_t size); +size_t video_write(uintptr_t reg, void *buf, size_t size); + static _Device x86_dev[] = { {_DEV_INPUT, "8279 Keyboard Controller", input_read, nullptr}, {_DEV_TIMER, "Dummy Timer", timer_read, nullptr}, diff --git a/am/arch/x86-qemu/src/pte.cpp b/am/arch/x86-qemu/src/pte.cpp index d63a28be..71c9c373 100644 --- a/am/arch/x86-qemu/src/pte.cpp +++ b/am/arch/x86-qemu/src/pte.cpp @@ -102,7 +102,7 @@ void *_query(_Protect *p, void *va, int *prot) { void _unmap(_Protect *p, void *va) { } -_RegSet *_umake(_Protect *p, _Area ustack, _Area kstack, void *entry, void *args) { +_RegSet *_umake(_Protect *p, _Area ustack, _Area kstack, void (*entry)(void *), void *args) { _RegSet *regs = (_RegSet*)kstack.start; regs->cs = USEL(SEG_UCODE); regs->ds = regs->es = regs->ss = USEL(SEG_UDATA); diff --git a/libs/klib/include/klib.h b/libs/klib/include/klib.h index 46e33029..132f6d5f 100644 --- a/libs/klib/include/klib.h +++ b/libs/klib/include/klib.h @@ -6,7 +6,6 @@ #define __KLIB_H__ #include -#include #include #ifdef __cplusplus @@ -16,7 +15,7 @@ extern "C" { // am devices uint32_t uptime(); -void gettimeofday(_Dev_Timer_RTC *rtc); +void gettimeofday(void *rtc); int read_key(); void draw_rect(uint32_t *pixels, int x, int y, int w, int h); void draw_sync(); diff --git a/libs/klib/src/io.c b/libs/klib/src/io.c index 4ab55f57..25654b31 100644 --- a/libs/klib/src/io.c +++ b/libs/klib/src/io.c @@ -20,56 +20,56 @@ static _Device *video_dev; static _Device *timer_dev; uint32_t uptime() { - _Dev_Timer_Uptime uptime; + _UptimeReg uptime; _Device *dev = getdev(&timer_dev, _DEV_TIMER); - dev->read(_DEV_TIMER_REG_UPTIME, &uptime, sizeof(uptime)); + dev->read(_DEVREG_TIMER_UPTIME, &uptime, sizeof(uptime)); return uptime.lo; } -void gettimeofday(_Dev_Timer_RTC *rtc) { +void gettimeofday(void *rtc) { _Device *dev = getdev(&timer_dev, _DEV_TIMER); - dev->read(_DEV_TIMER_REG_DATE, rtc, sizeof(_DEV_TIMER_REG_DATE)); + dev->read(_DEVREG_TIMER_DATE, rtc, sizeof(_RTCReg)); } int read_key() { _Device *dev = getdev(&input_dev, _DEV_INPUT); int32_t key; - dev->read(_DEV_INPUT_REG_KBD, &key, sizeof(int32_t)); + dev->read(_DEVREG_INPUT_KBD, &key, sizeof(int32_t)); return key; } void draw_rect(uint32_t *pixels, int x, int y, int w, int h) { _Device *dev = getdev(&video_dev, _DEV_VIDEO); - _Dev_Video_FBCtl ctl; + _FBCtlReg ctl; ctl.pixels = pixels; ctl.x = x; ctl.y = y; ctl.w = w; ctl.h = h; ctl.sync = 0; - dev->write(_DEV_VIDEO_REG_FBCTL, &ctl, sizeof(ctl)); + dev->write(_DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl)); } void draw_sync() { _Device *dev = getdev(&video_dev, _DEV_VIDEO); - _Dev_Video_FBCtl ctl; + _FBCtlReg ctl; ctl.pixels = NULL; ctl.x = ctl.y = ctl.w = ctl.h = 0; ctl.sync = 1; - dev->write(_DEV_VIDEO_REG_FBCTL, &ctl, sizeof(ctl)); + dev->write(_DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl)); } int screen_width() { _Device *dev = getdev(&video_dev, _DEV_VIDEO); - _Dev_Video_Info info; - dev->read(_DEV_VIDEO_REG_INFO, &info, sizeof(info)); + _VideoInfoReg info; + dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info)); return info.width; } int screen_height() { _Device *dev = getdev(&video_dev, _DEV_VIDEO); - _Dev_Video_Info info; - dev->read(_DEV_VIDEO_REG_INFO, &info, sizeof(info)); + _VideoInfoReg info; + dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info)); return info.height; }