#include #include #include #include "fpu.h" #include "gdt.h" #include "gfx.h" #include "gfx_font.h" #include "idt.h" #include "isr.h" #include "irq.h" #include "log.h" #include "multiboot.h" #include "panic.h" #include "pcspkr.h" #include "ps2.h" #include "fpu.h" #include "timer.h" #include "tty.h" void gpf(struct regs_t regs) { gfx_reset(); printf("General protection fault!\n"); printf("EIP before fault: 0x%x\n", regs.eip); printf("Error code: 0x%x\n", regs.err_code); panic("GPF!"); } void main(struct multiboot_info_t *hdr, uint32_t magic) { fpu_enable(); asm("movq %xmm0, %xmm0"); /* this should go to port e9, which is the Bochs debug port */ printf("Testing early I/O\n"); printf("GFX init\n"); bool gfx_status = gfx_init((struct vbe_info_t*)hdr->vbe_mode_info); /* if graphical initialization fails, fall back to text mode */ if(!gfx_status) { tty_init(); printf("Graphics init failed, fell back to text mode.\n"); } if(magic != 0x2BADB002) { panic("Multiboot magic invalid"); } /* then the descriptor tables so we can do more useful stuff */ gdt_init(); idt_init(); /* install all the interrupt stubs */ isr_init(); irq_init(); /* initialize other drivers */ timer_init(HZ); ps2_init(); set_interrupt_handler(0xd, gpf); asm("sti"); printf("Boot finished.\n"); printf("Running graphics benchmark...\n"); srand(42); if(gfx_status) { const int width = *gfx_width; const int height = *gfx_height; gfx_clear(); int startpix = *current_tick; for(int i=0;i<1000000;++i) { int rx = rand() % width; int ry = rand() % height; gfx_set_foreground(rand() % 0x1000000); gfx_drawpixel(rx, ry); } int endpix = *current_tick; gfx_clear(); int startfill = *current_tick; for(int i=0;i<1000;++i) { gfx_set_background(rand() % 0x1000000); gfx_clear(); } int endfill = *current_tick; gfx_clear(); int starttext = *current_tick; for(int i=0;i<1000000;++i) { int rx = rand() % width; int ry = rand() % height; gfx_set_foreground(rand() % 0x1000000); gfx_drawchar(rx, ry, rand()%127+1); } int endtext = *current_tick; gfx_clear(); int starthline = *current_tick; for(int i=0;i<1000000;++i) { gfx_set_foreground(rand() % 0x1000000); gfx_hline(rand() % width, rand() % width, rand() % height); } int endhline = *current_tick; gfx_clear(); int startvline = *current_tick; for(int i=0;i<1000000;++i) { gfx_set_foreground(rand() % 0x1000000); gfx_vline(rand() % height, rand() % height, rand() % width); } int endvline = *current_tick; gfx_clear(); int startrect = *current_tick; for(int i=0;i<10000;++i) { int x = rand() % width; int y = rand() % height; int w = rand() % (width - x); int h = rand() % (height - y); gfx_set_foreground(rand() % 0x1000000); gfx_fillrect(x, y, w, h); } int endrect = *current_tick; gfx_clear(); int startline = *current_tick; for(int i=0;i<1000000;++i) { int x1= rand() % width; int x2= rand() % width; int y1= rand() % height; int y2= rand() % height; gfx_set_foreground(rand() % 0x1000000); gfx_drawline(x1, y1, x2, y2); } int endline = *current_tick; gfx_reset(); printf("--- Graphics benchmark results ---\n"); printf("Ticks for 1,000,000 random pixels: %d\n", endpix-startpix); printf("Ticks for 1,000 random fills: %d\n", endfill-startfill); printf("Ticks for 1,000,000 random chars: %d\n", endtext-starttext); printf("Ticks for 1,000,000 random hlines: %d\n", endhline-starthline); printf("Ticks for 1,000,000 random vlines: %d\n", endvline-startvline); printf("Ticks for 10,000 random rects: %d\n", endrect-startrect); printf("Ticks for 1,000,000 random lines: %d\n", endline-startline); printf("Ticks per second: %d\n", HZ); printf("Resolution: %dx%dx%d\n", *gfx_width, *gfx_height, *gfx_bpp * 8); } printf("Testing keyboard LED's...\n"); while(1) { ps2_set_leds(PS2_NUM_LOCK); timer_delay(HZ/4); ps2_set_leds(PS2_CAPS_LOCK); timer_delay(HZ/4); ps2_set_leds(PS2_SCROLL_LOCK); timer_delay(HZ/4); ps2_set_leds(PS2_CAPS_LOCK); timer_delay(HZ/4); } }