large refactor of ioe

This commit is contained in:
Yanyan Jiang 2018-03-25 16:56:23 +08:00
parent 21ce8d8014
commit 1722e218ef
8 changed files with 201 additions and 189 deletions

10
am/am.h
View File

@ -30,10 +30,10 @@ enum {
_EVENT_SYSCALL, _EVENT_SYSCALL,
}; };
#define _PROT_NONE 1 #define _PROT_NONE 1 // no access
#define _PROT_READ 2 #define _PROT_READ 2 // can read
#define _PROT_WRITE 4 #define _PROT_WRITE 4 // can write
#define _PROT_EXEC 8 #define _PROT_EXEC 8 // can execute
// A memory area of [@start, @end) // A memory area of [@start, @end)
typedef struct _Area { typedef struct _Area {
@ -91,7 +91,7 @@ void _prot_switch(_Protect *p);
void _map(_Protect *p, void *va, void *pa); void _map(_Protect *p, void *va, void *pa);
void _protect(_Protect *p, void *va, int len, int prot); void _protect(_Protect *p, void *va, int len, int prot);
_RegSet *_umake(_Protect *p, _Area ustack, _Area kstack, _RegSet *_umake(_Protect *p, _Area ustack, _Area kstack,
void *entry, void *args); void (*entry)(void *), void *args);
// ================= Multi-Processor Extension (MPE) ================= // ================= Multi-Processor Extension (MPE) =================

View File

@ -3,6 +3,9 @@
#include <stdint.h> #include <stdint.h>
// =========================== AM Devices ============================
// ((_Device *)dev)->id
#define _DEV_PERFCNT 0x0000ac01 #define _DEV_PERFCNT 0x0000ac01
#define _DEV_INPUT 0x0000ac02 #define _DEV_INPUT 0x0000ac02
#define _DEV_TIMER 0x0000ac03 #define _DEV_TIMER 0x0000ac03
@ -11,74 +14,74 @@
#define _DEV_ATA0 0x00000dd0 #define _DEV_ATA0 0x00000dd0
#define _DEV_ATA1 0x00000dd1 #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 // ----------- _DEV_TIMER: AM Real Time Clock (0000ac03) -------------
#define _KEYS(_) \ #define _DEVREG_TIMER_UPTIME 1
_(ESCAPE) \ typedef struct {
_(F1) _(F2) _(F3) _(F4) _(F5) _(F6) _(F7) _(F8) _(F9) _(F10) _(F11) _(F12) \ uint32_t hi; // high 32bit of uptime (ms)
_(GRAVE) _(1) _(2) _(3) _(4) _(5) _(6) _(7) _(8) _(9) _(0) \ uint32_t lo; // low 32bit of uptime (ms)
_(MINUS) _(EQUALS) _(BACKSPACE) \ } _UptimeReg;
_(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)
};
// Timer (0000ac03) #define _DEVREG_TIMER_DATE 2
typedef struct {
int year, month, day; // date
int hour, minute, second; // time
} _RTCReg;
typedef struct _TimerUptime { // ----------- _DEV_VIDEO: AM Video Controller (0000ac04) ------------
uint32_t hi, lo; #define _DEVREG_VIDEO_INFO 1
} _Dev_Timer_Uptime; typedef struct {
#define _DEV_TIMER_REG_UPTIME 1 int32_t width, height; // screen size
typedef struct _TimerRTC { } _VideoInfoReg;
int year, month, day, hour, minute, second;
} _Dev_Timer_RTC;
#define _DEV_TIMER_REG_DATE 2
// 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 { // -------- _DEV_PCICONF: PCI Configuration Space (00000080) ---------
int32_t width, height; #define _DEVREG_PCICONF(bus, slot, func, offset) \
} _Dev_Video_Info; ((uint32_t)( 1) << 31) | ((uint32_t)( bus) << 16) | \
#define _DEV_VIDEO_REG_INFO 1 ((uint32_t)(slot) << 11) | ((uint32_t)(func) << 8) | (offset)
typedef struct _Video_FBCtl {
int x, y, w, h, sync;
uint32_t *pixels;
} _Dev_Video_FBCtl;
#define _DEV_VIDEO_REG_FBCTL 2
// PCI Configuration (00000080) // ------ _DEV_ATAx: ATA Disk Controller (00000dd0 -- 00000dd1) ------
#define _DEVREG_ATA_DATA 0
static inline uint32_t #define _DEVREG_ATA_FEATURE 1
_DEV_PCICONF_REG(uint8_t bus, uint8_t slot, uint8_t func, uint8_t offset) { #define _DEVREG_ATA_NSECT 2
return ((uint32_t)1 << 31) #define _DEVREG_ATA_SECT 3
| ((uint32_t)bus << 16) #define _DEVREG_ATA_CYLOW 4
| ((uint32_t)slot << 11) #define _DEVREG_ATA_CYHIGH 5
| ((uint32_t)func << 8) #define _DEVREG_ATA_DRIVE 6
| offset; #define _DEVREG_ATA_STATUS 7
}
// 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
#endif #endif

View File

@ -223,7 +223,7 @@ _RegSet *_make(_Area stack, void *entry, void *arg) {
regs->cs = KSEL(SEG_KCODE); regs->cs = KSEL(SEG_KCODE);
regs->ds = regs->es = regs->ss = KSEL(SEG_KDATA); regs->ds = regs->es = regs->ss = KSEL(SEG_KDATA);
regs->eip = (uint32_t)entry; regs->eip = (uint32_t)entry;
regs->eflags = FL_IF; regs->eflags = 0;
regs->esp0 -= 4; regs->esp0 -= 4;
*((void**)(regs->esp0)) = arg; // argument *((void**)(regs->esp0)) = arg; // argument
regs->esp0 -= 4; regs->esp0 -= 4;

View File

@ -0,0 +1,101 @@
#include <am.h>
#include <amdev.h>
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;
}

View File

@ -14,64 +14,9 @@ static inline uint64_t rdtsc() {
extern "C" { extern "C" {
struct VBEInfo { extern void vga_init();
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));
static inline uint32_t pixel(uint8_t r, uint8_t g, uint8_t b) { static _RTCReg boot_date;
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<VBEInfo*>(0x00004000);
W = info->width;
H = info->height;
fb = reinterpret_cast<FBPixel*>(info->framebuffer);
}
static _Dev_Timer_RTC boot_date;
static int read_rtc(int reg) { static int read_rtc(int reg) {
outb(0x70, reg); outb(0x70, reg);
int ret = inb(0x71); int ret = inb(0x71);
@ -107,7 +52,7 @@ static uint32_t estimate_freq() {
return freq; return freq;
} }
static void get_date(_Dev_Timer_RTC *rtc) { static void get_date(_RTCReg *rtc) {
int tmp; int tmp;
do { do {
rtc->second = read_rtc(0); rtc->second = read_rtc(0);
@ -116,7 +61,7 @@ static void get_date(_Dev_Timer_RTC *rtc) {
rtc->day = read_rtc(7); rtc->day = read_rtc(7);
rtc->month = read_rtc(8); rtc->month = read_rtc(8);
rtc->year = read_rtc(9) + 2000; rtc->year = read_rtc(9) + 2000;
tmp = read_rtc(0); tmp = read_rtc(0);
} while (tmp != rtc->second); } while (tmp != rtc->second);
} }
@ -190,7 +135,7 @@ static size_t input_read(uintptr_t reg, void *buf, size_t size) {
ret = _KEY_NONE; ret = _KEY_NONE;
} else { } else {
if (status & 0x20) { // mouse if (status & 0x20) { // mouse
ret = upevent(_KEY_NONE); ret = _KEY_NONE;
} else { } else {
int code = inb(0x60) & 0xff; 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) { static size_t timer_read(uintptr_t reg, void *buf, size_t size) {
switch (reg) { switch (reg) {
case _DEV_TIMER_REG_UPTIME: { case _DEVREG_TIMER_UPTIME: {
uint64_t tsc = rdtsc() - uptsc; uint64_t tsc = rdtsc() - uptsc;
uint32_t mticks = (tsc >> 20); uint32_t mticks = (tsc >> 20);
uint32_t ms = mticks * 1000 / freq_mhz; uint32_t ms = mticks * 1000 / freq_mhz;
_Dev_Timer_Uptime *uptime = (_Dev_Timer_Uptime *)buf; _UptimeReg *uptime = (_UptimeReg *)buf;
uptime->hi = 0; uptime->hi = 0;
uptime->lo = ms; uptime->lo = ms;
return sizeof(_Dev_Timer_Uptime); return sizeof(_UptimeReg);
} }
case _DEV_TIMER_REG_DATE: { case _DEVREG_TIMER_DATE: {
get_date((_Dev_Timer_RTC *)buf); get_date((_RTCReg *)buf);
return sizeof(_Dev_Timer_RTC); return sizeof(_RTCReg);
}
}
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);
} }
} }
return 0; return 0;
@ -279,6 +185,9 @@ static size_t hd_write(uintptr_t reg, void *buf, size_t size) {
return 0; 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[] = { static _Device x86_dev[] = {
{_DEV_INPUT, "8279 Keyboard Controller", input_read, nullptr}, {_DEV_INPUT, "8279 Keyboard Controller", input_read, nullptr},
{_DEV_TIMER, "Dummy Timer", timer_read, nullptr}, {_DEV_TIMER, "Dummy Timer", timer_read, nullptr},

View File

@ -102,7 +102,7 @@ void *_query(_Protect *p, void *va, int *prot) {
void _unmap(_Protect *p, void *va) { 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; _RegSet *regs = (_RegSet*)kstack.start;
regs->cs = USEL(SEG_UCODE); regs->cs = USEL(SEG_UCODE);
regs->ds = regs->es = regs->ss = USEL(SEG_UDATA); regs->ds = regs->es = regs->ss = USEL(SEG_UDATA);

View File

@ -6,7 +6,6 @@
#define __KLIB_H__ #define __KLIB_H__
#include <am.h> #include <am.h>
#include <amdev.h>
#include <stdarg.h> #include <stdarg.h>
#ifdef __cplusplus #ifdef __cplusplus
@ -16,7 +15,7 @@ extern "C" {
// am devices // am devices
uint32_t uptime(); uint32_t uptime();
void gettimeofday(_Dev_Timer_RTC *rtc); void gettimeofday(void *rtc);
int read_key(); int read_key();
void draw_rect(uint32_t *pixels, int x, int y, int w, int h); void draw_rect(uint32_t *pixels, int x, int y, int w, int h);
void draw_sync(); void draw_sync();

View File

@ -20,56 +20,56 @@ static _Device *video_dev;
static _Device *timer_dev; static _Device *timer_dev;
uint32_t uptime() { uint32_t uptime() {
_Dev_Timer_Uptime uptime; _UptimeReg uptime;
_Device *dev = getdev(&timer_dev, _DEV_TIMER); _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; return uptime.lo;
} }
void gettimeofday(_Dev_Timer_RTC *rtc) { void gettimeofday(void *rtc) {
_Device *dev = getdev(&timer_dev, _DEV_TIMER); _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() { int read_key() {
_Device *dev = getdev(&input_dev, _DEV_INPUT); _Device *dev = getdev(&input_dev, _DEV_INPUT);
int32_t key; int32_t key;
dev->read(_DEV_INPUT_REG_KBD, &key, sizeof(int32_t)); dev->read(_DEVREG_INPUT_KBD, &key, sizeof(int32_t));
return key; return key;
} }
void draw_rect(uint32_t *pixels, int x, int y, int w, int h) { void draw_rect(uint32_t *pixels, int x, int y, int w, int h) {
_Device *dev = getdev(&video_dev, _DEV_VIDEO); _Device *dev = getdev(&video_dev, _DEV_VIDEO);
_Dev_Video_FBCtl ctl; _FBCtlReg ctl;
ctl.pixels = pixels; ctl.pixels = pixels;
ctl.x = x; ctl.x = x;
ctl.y = y; ctl.y = y;
ctl.w = w; ctl.w = w;
ctl.h = h; ctl.h = h;
ctl.sync = 0; ctl.sync = 0;
dev->write(_DEV_VIDEO_REG_FBCTL, &ctl, sizeof(ctl)); dev->write(_DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl));
} }
void draw_sync() { void draw_sync() {
_Device *dev = getdev(&video_dev, _DEV_VIDEO); _Device *dev = getdev(&video_dev, _DEV_VIDEO);
_Dev_Video_FBCtl ctl; _FBCtlReg ctl;
ctl.pixels = NULL; ctl.pixels = NULL;
ctl.x = ctl.y = ctl.w = ctl.h = 0; ctl.x = ctl.y = ctl.w = ctl.h = 0;
ctl.sync = 1; ctl.sync = 1;
dev->write(_DEV_VIDEO_REG_FBCTL, &ctl, sizeof(ctl)); dev->write(_DEVREG_VIDEO_FBCTL, &ctl, sizeof(ctl));
} }
int screen_width() { int screen_width() {
_Device *dev = getdev(&video_dev, _DEV_VIDEO); _Device *dev = getdev(&video_dev, _DEV_VIDEO);
_Dev_Video_Info info; _VideoInfoReg info;
dev->read(_DEV_VIDEO_REG_INFO, &info, sizeof(info)); dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info));
return info.width; return info.width;
} }
int screen_height() { int screen_height() {
_Device *dev = getdev(&video_dev, _DEV_VIDEO); _Device *dev = getdev(&video_dev, _DEV_VIDEO);
_Dev_Video_Info info; _VideoInfoReg info;
dev->read(_DEV_VIDEO_REG_INFO, &info, sizeof(info)); dev->read(_DEVREG_VIDEO_INFO, &info, sizeof(info));
return info.height; return info.height;
} }