diff --git a/doc/timer-design.odg b/doc/timer-design.odg new file mode 100644 index 0000000..0b475cf Binary files /dev/null and b/doc/timer-design.odg differ diff --git a/hypervisor/Makefile b/hypervisor/Makefile index 1519bd0..a323122 100644 --- a/hypervisor/Makefile +++ b/hypervisor/Makefile @@ -3,7 +3,7 @@ ASFLAGS = --32 -march=i486 -mtune=i486 CFLAGS = -m32 -I../include -COBJS = start.o font.o mouse.o int.o keyboard.o memtest.o mm.o fifo8.o serial.o console.o mmu.o libmmu.o +COBJS = start.o font.o mouse.o int.o keyboard.o memtest.o mm.o fifo8.o serial.o console.o mmu.o libmmu.o timer.o SOBJS = int_entry.o libmemtest.o diff --git a/hypervisor/int_entry.s b/hypervisor/int_entry.s index d1b71df..54d6658 100644 --- a/hypervisor/int_entry.s +++ b/hypervisor/int_entry.s @@ -1,10 +1,11 @@ .text .code32 +.global inthandler20 .global inthandler21 +.global inthandler24 .global inthandler27 .global inthandler2c -.global inthandler24 inthandler24: @@ -23,6 +24,23 @@ inthandler24: pop %es iretl +#for timer +inthandler20: + push %es + push %ds + pushal + movl %esp,%eax + pushl %eax + mov %ss,%ax + mov %ax,%ds + mov %ax,%es + call _inthandler20 + popl %eax + popal + pop %ds + pop %es + iretl + #for keyboard inthandler21: push %es diff --git a/hypervisor/start.c b/hypervisor/start.c index 01885fe..c58e8ed 100644 --- a/hypervisor/start.c +++ b/hypervisor/start.c @@ -16,8 +16,8 @@ extern char mcursor[256]; struct wjn { - int t; - int w; + int t; + int w; }; struct fifo key_fifo; @@ -61,37 +61,40 @@ static void set_gatedesc(struct GATE_DESCRIPTOR *gd, int offset, int selector, i static void init_gdtidt(void) { - struct SEGMENT_DESCRIPTOR *gdt = - (struct SEGMENT_DESCRIPTOR *)(ADR_GDT - (SYSSEG << 4)); - struct GATE_DESCRIPTOR *idt = - (struct GATE_DESCRIPTOR *)(ADR_IDT - (SYSSEG << 4)); - //struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT; - int i; - /* GDT<82>Ì<8f><89><8a>ú<89>» */ - for (i = 0; i <= LIMIT_GDT / 8; i++) { - set_segmdesc(gdt + i, 0, 0, 0); - } + struct SEGMENT_DESCRIPTOR *gdt = + (struct SEGMENT_DESCRIPTOR *)(ADR_GDT - (SYSSEG << 4)); + struct GATE_DESCRIPTOR *idt = + (struct GATE_DESCRIPTOR *)(ADR_IDT - (SYSSEG << 4)); + //struct GATE_DESCRIPTOR *idt = (struct GATE_DESCRIPTOR *) ADR_IDT; + int i; + /* GDT<82>Ì<8f><89><8a>ú<89>» */ + for (i = 0; i <= LIMIT_GDT / 8; i++) { + set_segmdesc(gdt + i, 0, 0, 0); + } #if 0 - set_segmdesc(gdt + 2, 0xffffffff, 0x00010000, AR_CODE32_ER); - set_segmdesc(gdt + 3, LIMIT_BOTPAK, ADR_BOTPAK, AR_DATA32_RW); - load_gdtr(LIMIT_GDT, ADR_GDT); + set_segmdesc(gdt + 2, 0xffffffff, 0x00010000, AR_CODE32_ER); + set_segmdesc(gdt + 3, LIMIT_BOTPAK, ADR_BOTPAK, AR_DATA32_RW); + load_gdtr(LIMIT_GDT, ADR_GDT); #endif - /* IDT<82>Ì<8f><89><8a>ú<89>» */ - for (i = 0; i <= LIMIT_IDT / 8; i++) { - set_gatedesc(idt + i, 0xfff, 0, 0); - } - load_idtr(LIMIT_IDT, ADR_IDT); + /* IDT<82>Ì<8f><89><8a>ú<89>» */ + for (i = 0; i <= LIMIT_IDT / 8; i++) { + set_gatedesc(idt + i, 0xfff, 0, 0); + } + load_idtr(LIMIT_IDT, ADR_IDT); + + set_gatedesc(idt + 0x20, (int)inthandler20, 2 * 8, AR_INTGATE32); - set_gatedesc(idt + 0x24, (int)inthandler24, 2 * 8, AR_INTGATE32); + set_gatedesc(idt + 0x21, (int)inthandler21, 2 * 8, AR_INTGATE32); + + set_gatedesc(idt + 0x24, (int)inthandler24, 2 * 8, AR_INTGATE32); - set_gatedesc(idt + 0x21, (int)inthandler21, 2 * 8, AR_INTGATE32); #if 1 - /* IDT<82>Ì<90>Ý<92>è */ - set_gatedesc(idt + 0x27, (int)inthandler27, 2 * 8, AR_INTGATE32); + /* IDT<82>Ì<90>Ý<92>è */ + set_gatedesc(idt + 0x27, (int)inthandler27, 2 * 8, AR_INTGATE32); #endif - set_gatedesc(idt + 0x2c, (int)inthandler2c, 2 * 8, AR_INTGATE32); - return; + set_gatedesc(idt + 0x2c, (int)inthandler2c, 2 * 8, AR_INTGATE32); + return; } static void drawing_desktop() @@ -109,7 +112,7 @@ static void drawing_desktop() 0x00, 0x18, 0x18, 0x18, 0x18, 0x24, 0x24, 0x24, 0x24, 0x7e, 0x42, 0x42, 0x42, 0xe7, 0x00, 0x00 }; - /*init mouse global data*/ + /*init mouse global data*/ mouse_status.mx = (xsize - 16) / 2; mouse_status.my = (ysize - 28 - 16) / 2; init_mouse_cursor8(mcursor, COL8_008484); @@ -147,31 +150,31 @@ static void drawing_desktop() void drawing_mem_map() { - unsigned char *vram = VRAM_ADDR; - unsigned short xsize, ysize; - xsize = 320; - ysize = 200; - char buf[50]; - //print memory map - struct MEMMAP *memmap = (struct MEMMAP *)(MEM_MAP_ADDR); - int pos = 20; - for (; memmap->type != 0;) { - sprintf(buf, "base:%X", memmap->base); - putfont8_string(vram, xsize, 8, pos, COL8_FFFFFF, font.Bitmap, - buf); - sprintf(buf, "len:%X", memmap->length); - putfont8_string(vram, xsize, 150, pos, COL8_FFFFFF, font.Bitmap, - buf); - if (memmap->type == 1) { - sprintf(buf, "%s", "free"); - } else { - sprintf(buf, "%s", "reserve"); - } - putfont8_string(vram, xsize, 270, pos, COL8_FFFFFF, font.Bitmap, - buf); - memmap++; - pos = pos + 16; - } + unsigned char *vram = VRAM_ADDR; + unsigned short xsize, ysize; + xsize = 320; + ysize = 200; + char buf[50]; + //print memory map + struct MEMMAP *memmap = (struct MEMMAP *)(MEM_MAP_ADDR); + int pos = 20; + for (; memmap->type != 0;) { + sprintf(buf, "base:%X", memmap->base); + putfont8_string(vram, xsize, 8, pos, COL8_FFFFFF, font.Bitmap, + buf); + sprintf(buf, "len:%X", memmap->length); + putfont8_string(vram, xsize, 150, pos, COL8_FFFFFF, font.Bitmap, + buf); + if (memmap->type == 1) { + sprintf(buf, "%s", "free"); + } else { + sprintf(buf, "%s", "reserve"); + } + putfont8_string(vram, xsize, 270, pos, COL8_FFFFFF, font.Bitmap, + buf); + memmap++; + pos = pos + 16; + } } static void wait_KBC_sendready(void) @@ -193,18 +196,18 @@ static void init_keyboard(void) static void enable_mouse(void) { /* 激活鼠标 */ -// unsigned char status; -// wait_KBC_sendready(); -// io_out8(PORT_KEYCMD, 0x20); -// wait_KBC_sendready(); -// status = ((char)io_in8(PORT_KEYDAT)|0x2); -// status &= 0xDF; -// wait_KBC_sendready(); -// io_out8(PORT_KEYCMD, 0x60); -// wait_KBC_sendready(); -// io_out8(PORT_KEYDAT, status); -// -// + // unsigned char status; + // wait_KBC_sendready(); + // io_out8(PORT_KEYCMD, 0x20); + // wait_KBC_sendready(); + // status = ((char)io_in8(PORT_KEYDAT)|0x2); + // status &= 0xDF; + // wait_KBC_sendready(); + // io_out8(PORT_KEYCMD, 0x60); + // wait_KBC_sendready(); + // io_out8(PORT_KEYDAT, status); + // + // wait_KBC_sendready(); io_out8(PORT_KEYCMD, KEYCMD_SENDTO_MOUSE); wait_KBC_sendready(); @@ -214,84 +217,85 @@ static void enable_mouse(void) static void set_palette(int start, int end, unsigned char *rgb) { - int i, eflags; - io_out8(0x03c8, start); - for (i = start; i <= end; i++) { - io_out8(0x03c9, rgb[0] / 4); - io_out8(0x03c9, rgb[1] / 4); - io_out8(0x03c9, rgb[2] / 4); - rgb += 3; - } - return; + int i, eflags; + io_out8(0x03c8, start); + for (i = start; i <= end; i++) { + io_out8(0x03c9, rgb[0] / 4); + io_out8(0x03c9, rgb[1] / 4); + io_out8(0x03c9, rgb[2] / 4); + rgb += 3; + } + return; } static void init_palette(void) { - static unsigned char table_rgb[16 * 3] = { - 0x00, 0x00, 0x00, /* 0: */ - 0xff, 0x00, 0x00, /* 1: */ - 0x00, 0xff, 0x00, /* 2: */ - 0xff, 0xff, 0x00, /* 3: */ - 0x00, 0x00, 0xff, /* 4: */ - 0xff, 0x00, 0xff, /* 5: */ - 0x00, 0xff, 0xff, /* 6: */ - 0xff, 0xff, 0xff, /* 7: */ - 0xc6, 0xc6, 0xc6, /* 8: */ - 0x84, 0x00, 0x00, /* 9: */ - 0x00, 0x84, 0x00, /* 10: */ - 0x84, 0x84, 0x00, /* 11: */ - 0x00, 0x00, 0x84, /* 12: */ - 0x84, 0x00, 0x84, /* 13: */ - 0x00, 0x84, 0x84, /* 14: */ - 0x84, 0x84, 0x84 /* 15: */ - }; - set_palette(0, 15, table_rgb); - return; - - /* static char <96>$<97>ß<82>Í<81>A<83>f<81>[<83>^<82>É<82>µ<82>©<8e>g<82>¦<82>È<82>¢<82>¯<82>ÇDB<96>$<97>ß<91><8a><93><96> */ + static unsigned char table_rgb[16 * 3] = { + 0x00, 0x00, 0x00, /* 0: */ + 0xff, 0x00, 0x00, /* 1: */ + 0x00, 0xff, 0x00, /* 2: */ + 0xff, 0xff, 0x00, /* 3: */ + 0x00, 0x00, 0xff, /* 4: */ + 0xff, 0x00, 0xff, /* 5: */ + 0x00, 0xff, 0xff, /* 6: */ + 0xff, 0xff, 0xff, /* 7: */ + 0xc6, 0xc6, 0xc6, /* 8: */ + 0x84, 0x00, 0x00, /* 9: */ + 0x00, 0x84, 0x00, /* 10: */ + 0x84, 0x84, 0x00, /* 11: */ + 0x00, 0x00, 0x84, /* 12: */ + 0x84, 0x00, 0x84, /* 13: */ + 0x00, 0x84, 0x84, /* 14: */ + 0x84, 0x84, 0x84 /* 15: */ + }; + set_palette(0, 15, table_rgb); + return; + + /* static char <96>$<97>ß<82>Í<81>A<83>f<81>[<83>^<82>É<82>µ<82>©<8e>g<82>¦<82>È<82>¢<82>¯<82>ÇDB<96>$<97>ß<91><8a><93><96> */ } + static void init_pic(void) { io_out8(PIC1_OCW1, 0xFF); io_out8(PIC0_OCW1, 0xFF); - io_out8(PIC0_COMMAND, 0x11); - io_out8(PIC1_COMMAND, 0x11); + io_out8(PIC0_COMMAND, 0x11); + io_out8(PIC1_COMMAND, 0x11); - io_out8(PIC1_DATA, 0x28); - io_out8(PIC0_DATA, 0x20); + io_out8(PIC1_DATA, 0x28); + io_out8(PIC0_DATA, 0x20); - io_out8(PIC0_DATA, 1 << 2); - io_out8(PIC1_DATA, 2); + io_out8(PIC0_DATA, 1 << 2); + io_out8(PIC1_DATA, 2); - io_out8(PIC0_DATA, 0x01); /*8086 mode for both */ - io_out8(PIC1_DATA, 0x01); + io_out8(PIC0_DATA, 0x01); /*8086 mode for both */ + io_out8(PIC1_DATA, 0x01); - io_out8(PIC0_DATA, 0xfb); - io_out8(PIC1_DATA, 0xff); + io_out8(PIC0_DATA, 0xfb); + io_out8(PIC1_DATA, 0xff); - return; + return; } static void serial_handler(unsigned char data) { - serial_console(); + serial_console(); } #define PORT_KEYDAT 0x0060 static void keyboard_handler(unsigned char data) { - unsigned char *vram = VRAM_ADDR; - unsigned short xsize, ysize; - unsigned char out_buffer[3]; - unsigned char t; - xsize = 320; - ysize = 200; - if (data >= 0x81 || data == -1) - return; - out_buffer[0] = scancode[data]; - if (out_buffer[0] == 0) { + unsigned char *vram = VRAM_ADDR; + unsigned short xsize, ysize; + unsigned char out_buffer[3]; + unsigned char t; + xsize = 320; + ysize = 200; + if (data >= 0x81 || data == -1) + return; + out_buffer[0] = scancode[data]; + if (out_buffer[0] == 0) { t=(data & 0xf0)>>4; if (t >= 0xa && t <= 0xf) { out_buffer[0] = 'A' + t - 10; @@ -323,16 +327,16 @@ static void keyboard_handler(unsigned char data) boxfill8(vram, xsize, COL8_FFFFFF, xsize - 3, ysize - 24, xsize - 3, ysize - 3); putfont8_string(vram,xsize, 283, 180, COL8_00FF00,font.Bitmap , out_buffer); - return; - } - out_buffer[1] = 0; + return; + } + out_buffer[1] = 0; putfont8_string(vram,xsize, 0, 0, COL8_FFFFFF,font.Bitmap , out_buffer); - if (data == 0x30 || data == 0xB0) { - putfont8_string(vram, xsize, 8, 100, COL8_FFFFFF, font.Bitmap, - (unsigned char *)"May the source be with you!"); - } + if (data == 0x30 || data == 0xB0) { + putfont8_string(vram, xsize, 8, 100, COL8_FFFFFF, font.Bitmap, + (unsigned char *)"May the source be with you!"); + } } static void mouse_handler(unsigned char data) @@ -362,7 +366,7 @@ static void mouse_handler(unsigned char data) mouse_status.btn = mouse_status.buf[0] & 0x07; mouse_status.x = mouse_status.buf[1]; mouse_status.y = mouse_status.buf[2]; - + if ((mouse_status.buf[0] & 0x10) != 0) { mouse_status.x |= 0xffffff00; } @@ -371,7 +375,6 @@ static void mouse_handler(unsigned char data) } mouse_status.y = -mouse_status.y; boxfill8(VRAM_ADDR, xsize, COL8_008484, mouse_status.mx, mouse_status.my, mouse_status.mx + 15, mouse_status.my + 15); - //mouse_status.mx += mouse_status.x; mouse_status.mx += mouse_status.x; mouse_status.my += mouse_status.y; if (mouse_status.mx < 0) { @@ -404,12 +407,13 @@ void kernelstart(char *arg) init_gdtidt(); init_pic(); + init_pit(); fifo_init(&key_fifo, 32, keybuffer); fifo_init(&mouse_fifo, 128, mousebuffer); fifo_init(&serial_fifo, 32, serialbuffer); io_sti(); - io_out8(PIC0_DATA, 0xe9); /* PIC0<82>Æ<83>L<81>[<83>{<81>[<83>h<82>ð<8b><96><89>Â(11101001) */ + io_out8(PIC0_DATA, 0xe8); /* PIC0<82>Æ<83>L<81>[<83>{<81>[<83>h<82>ð<8b><96><89>Â(11101001) */ io_out8(PIC1_DATA, 0xef); /* <83>}<83>E<83>X<82>ð<8b><96><89>Â(11101111) */ init_keyboard(); @@ -439,7 +443,7 @@ void kernelstart(char *arg) mouse_handler(data); } else if (fifo_status(&serial_fifo) > 0) { io_sti(); - serial_handler(0); + serial_handler(0); } } } @@ -527,20 +531,20 @@ void boxfill8(unsigned char *vram, int xsize, unsigned char c, int x0, int y0, i void _inthandler21(int *esp) { - unsigned char data; - io_out8(PIC0_COMMAND, PIC_EOI); - data = io_in8(PORT_KEYDAT); - fifo_put(&key_fifo, data); - return; + unsigned char data; + io_out8(PIC0_COMMAND, PIC_EOI); + data = io_in8(PORT_KEYDAT); + fifo_put(&key_fifo, data); + return; } void _inthandler24(int *esp) { - unsigned char data; - io_out8(PIC0_COMMAND, 0x20); - data = read_serial(); - fifo_put(&serial_fifo, data); - return; + unsigned char data; + io_out8(PIC0_COMMAND, 0x20); + data = read_serial(); + fifo_put(&serial_fifo, data); + return; } @@ -556,6 +560,6 @@ void _inthandler2c(int *esp) void _inthandler27(int *esp) { - io_out8(PIC0_COMMAND, 0x67); /* IRQ-07<8e>ó<95>t<8a>®<97>¹<82>ðPIC<82>É<92>Ê<92>m(7-1<8e>Q<8f>Æ) */ - return; + io_out8(PIC0_COMMAND, 0x67); /* IRQ-07<8e>ó<95>t<8a>®<97>¹<82>ðPIC<82>É<92>Ê<92>m(7-1<8e>Q<8f>Æ) */ + return; } diff --git a/hypervisor/timer.c b/hypervisor/timer.c new file mode 100644 index 0000000..eb6d94e --- /dev/null +++ b/hypervisor/timer.c @@ -0,0 +1,92 @@ +#include "common.h" +#include "timer.h" +#include "serial.h" + +timer_zone timers; + + +void init_pit(void) +{ + /* + * https://wiki.osdev.org/Programmable_Interval_Timer + */ + + int i; + timer *t; + /* bit - 7 + * + * 0 0 = Channel 0 + * + * 1 1 = Access mode: lobyte/hibyte + * + * 0 1 0 = Mode 2 (rate generator) + * + * 0 BCD/Binary mode: 0 = 16-bit binary, 1 = four-digit BCD + * + * bit - 0 + */ + io_out8(PIT_CMD, 0x34); + /* + * Write two times, data port is 8bits. + * so we have to write two times. This value helps PIT to generate + * a frequency. + */ + io_out8(PIT_CH0, 0x9c); + io_out8(PIT_CH0, 0x2e); + + + /* timer_zone datastructure init */ + timers.count = 0; + for (i=0;itimeout = -1; + t->next = 0; + + /* set current timer to new timer*/ + timers.current = t; + timers.next = -1; + + return; +} +void timer_free(timer *t) +{ + t->flags = UNUSE; /* set to unused*/ + return; +} + + +timer* timer_alloc(void) +{ + int i; + for (i = 0; i < MAX_TIMER; i++) { + if (timers.pool[i].flags == UNUSE) { + timers.pool[i].flags = USED; + return &timers.pool[i]; + } + } + return 0; /* no free */ +} + +void _inthandler20(int *esp) +{ + timer *t; + io_out8(PIC0_COMMAND, PIC_EOI); + timers.count++; + if (timers.next > timers.count) { + return; + } + + /*time is up, pick the current timer*/ + t = timers.current; + while (t->timeout >= timers.count) { + t->flags = USED; + write_string_serial("."); + t = t->next; + } + timers.current = t; + timers.next = t->timeout; + return; +} diff --git a/include/common.h b/include/common.h index b9906c2..aad118d 100644 --- a/include/common.h +++ b/include/common.h @@ -84,6 +84,11 @@ void load_idtr(int limit, int addr); #define PIC1_DATA (PIC1+1) #define PIC_EOI 0x20 /* End-of-interrupt command code */ +/* PIT chip I/O port*/ +#define PIT_CH0 0x40 +#define PIT_CMD 0x43 + + /*GDT / IDT data*/ #define ADR_IDT 0x0026f800 @@ -99,10 +104,11 @@ void load_idtr(int limit, int addr); /*Serial PORT*/ #define PORT 0x3F8 +extern void inthandler20(void); extern void inthandler21(void); +extern void inthandler24(void); extern void inthandler27(void); extern void inthandler2c(void); -extern void inthandler24(void); struct mouse_info { char phase; diff --git a/include/serial.h b/include/serial.h index 316b0cf..41c50ca 100644 --- a/include/serial.h +++ b/include/serial.h @@ -1,6 +1,5 @@ #ifndef _SERIAL_H #define _SERIAL_H -#include "common.h" int serial_received(); char read_serial(); diff --git a/include/timer.h b/include/timer.h new file mode 100644 index 0000000..71c6cbd --- /dev/null +++ b/include/timer.h @@ -0,0 +1,23 @@ +#ifndef _TIMER_H +#define _TIMER_H +#include "common.h" + +#define MAX_TIMER 128 + +#define UNUSE 0 +#define USED 1 + +typedef struct timer{ + struct timer *next; + unsigned int timeout, flags; + int data; +}timer; + +typedef struct timer_zone{ + unsigned int count, next; /*next means timeout*/ + timer *current; + timer pool[MAX_TIMER]; +}timer_zone; +void init_pit(void); +timer* timer_alloc(void); +#endif