large refactor of ioe
This commit is contained in:
parent
21ce8d8014
commit
1722e218ef
10
am/am.h
10
am/am.h
|
@ -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) =================
|
||||||
|
|
||||||
|
|
127
am/amdev.h
127
am/amdev.h
|
@ -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
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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;
|
||||||
|
}
|
||||||
|
|
|
@ -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;
|
static _RTCReg boot_date;
|
||||||
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) {
|
|
||||||
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},
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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();
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue