From c7252588ebb95f97631e9470778c69afa00c35b5 Mon Sep 17 00:00:00 2001 From: Franklin Wei Date: Sun, 1 Mar 2015 14:20:47 -0500 Subject: Huge restructure --- Makefile | 6 +- OBJ | 34 +- arch/i686/boot/head.S | 41 +++ arch/i686/drivers/gfx-as.S | 101 ++++++ arch/i686/drivers/gfx.c | 540 ++++++++++++++++++++++++++++++++ arch/i686/drivers/pcspkr.c | 19 ++ arch/i686/drivers/ps2kbd.c | 212 +++++++++++++ arch/i686/drivers/vgatext.c | 124 ++++++++ arch/i686/fpu.c | 25 ++ arch/i686/gdt-as.S | 14 + arch/i686/gdt.c | 34 ++ arch/i686/idt-as.S | 6 + arch/i686/idt.c | 24 ++ arch/i686/irq-as.S | 146 +++++++++ arch/i686/irq.c | 73 +++++ arch/i686/isr-as.S | 214 +++++++++++++ arch/i686/isr.c | 60 ++++ arch/i686/linker.ld | 45 +++ arch/i686/paging-as.S | 9 + arch/i686/paging.c | 64 ++++ boot/head.S | 41 --- drivers/gfx-as.S | 101 ------ drivers/gfx.c | 540 -------------------------------- drivers/include/gfx.h | 105 ------- drivers/include/gfx_font.h | 4 - drivers/include/pcspkr.h | 3 - drivers/include/ps2_keymaps.h | 39 --- drivers/include/ps2kbd.h | 66 ---- drivers/include/vgatext.h | 9 - drivers/pcspkr.c | 19 -- drivers/ps2kbd.c | 212 ------------- drivers/vgatext.c | 124 -------- include/arch/i686/drivers/gfx.h | 105 +++++++ include/arch/i686/drivers/gfx_font.h | 4 + include/arch/i686/drivers/pcspkr.h | 3 + include/arch/i686/drivers/ps2_keymaps.h | 39 +++ include/arch/i686/drivers/ps2kbd.h | 66 ++++ include/arch/i686/drivers/vgatext.h | 9 + include/arch/i686/fpu.h | 2 + include/arch/i686/gdt.h | 23 ++ include/arch/i686/idt.h | 23 ++ include/arch/i686/irq.h | 19 ++ include/arch/i686/isr.h | 51 +++ include/arch/i686/paging.h | 8 + include/arch/i686/timer.h | 13 + include/kernel/heap.h | 5 + include/kernel/io.h | 5 + include/kernel/log.h | 3 + include/kernel/multiboot.h | 90 ++++++ include/kernel/panic.h | 1 + include/kernel/task.c | 16 + include/kernel/task.h | 10 + include/kernel/version.h | 2 + include/stdio.h | 7 + include/stdlib.h | 30 ++ include/string.h | 4 + kernel/fpu.c | 25 -- kernel/gdt-as.S | 14 - kernel/gdt.c | 34 -- kernel/idt-as.S | 6 - kernel/idt.c | 24 -- kernel/include/fpu.h | 2 - kernel/include/gdt.h | 23 -- kernel/include/heap.h | 5 - kernel/include/idt.h | 23 -- kernel/include/io.h | 5 - kernel/include/irq.h | 19 -- kernel/include/isr.h | 51 --- kernel/include/log.h | 3 - kernel/include/multiboot.h | 90 ------ kernel/include/paging.h | 8 - kernel/include/panic.h | 1 - kernel/include/timer.h | 13 - kernel/include/version.h | 2 - kernel/irq-as.S | 146 --------- kernel/irq.c | 73 ----- kernel/isr-as.S | 214 ------------- kernel/isr.c | 60 ---- kernel/linker.ld | 45 --- kernel/main.c | 2 + kernel/paging-as.S | 9 - kernel/paging.c | 64 ---- kernel/ssp.c | 19 -- libc/include/stdio.h | 7 - libc/include/stdlib.h | 30 -- libc/include/string.h | 4 - 86 files changed, 2311 insertions(+), 2302 deletions(-) create mode 100644 arch/i686/boot/head.S create mode 100644 arch/i686/drivers/gfx-as.S create mode 100644 arch/i686/drivers/gfx.c create mode 100644 arch/i686/drivers/pcspkr.c create mode 100644 arch/i686/drivers/ps2kbd.c create mode 100644 arch/i686/drivers/vgatext.c create mode 100644 arch/i686/fpu.c create mode 100644 arch/i686/gdt-as.S create mode 100644 arch/i686/gdt.c create mode 100644 arch/i686/idt-as.S create mode 100644 arch/i686/idt.c create mode 100644 arch/i686/irq-as.S create mode 100644 arch/i686/irq.c create mode 100644 arch/i686/isr-as.S create mode 100644 arch/i686/isr.c create mode 100644 arch/i686/linker.ld create mode 100644 arch/i686/paging-as.S create mode 100644 arch/i686/paging.c delete mode 100644 boot/head.S delete mode 100644 drivers/gfx-as.S delete mode 100644 drivers/gfx.c delete mode 100644 drivers/include/gfx.h delete mode 100644 drivers/include/gfx_font.h delete mode 100644 drivers/include/pcspkr.h delete mode 100644 drivers/include/ps2_keymaps.h delete mode 100644 drivers/include/ps2kbd.h delete mode 100644 drivers/include/vgatext.h delete mode 100644 drivers/pcspkr.c delete mode 100644 drivers/ps2kbd.c delete mode 100644 drivers/vgatext.c create mode 100644 include/arch/i686/drivers/gfx.h create mode 100644 include/arch/i686/drivers/gfx_font.h create mode 100644 include/arch/i686/drivers/pcspkr.h create mode 100644 include/arch/i686/drivers/ps2_keymaps.h create mode 100644 include/arch/i686/drivers/ps2kbd.h create mode 100644 include/arch/i686/drivers/vgatext.h create mode 100644 include/arch/i686/fpu.h create mode 100644 include/arch/i686/gdt.h create mode 100644 include/arch/i686/idt.h create mode 100644 include/arch/i686/irq.h create mode 100644 include/arch/i686/isr.h create mode 100644 include/arch/i686/paging.h create mode 100644 include/arch/i686/timer.h create mode 100644 include/kernel/heap.h create mode 100644 include/kernel/io.h create mode 100644 include/kernel/log.h create mode 100644 include/kernel/multiboot.h create mode 100644 include/kernel/panic.h create mode 100644 include/kernel/task.c create mode 100644 include/kernel/task.h create mode 100644 include/kernel/version.h create mode 100644 include/stdio.h create mode 100644 include/stdlib.h create mode 100644 include/string.h delete mode 100644 kernel/fpu.c delete mode 100644 kernel/gdt-as.S delete mode 100644 kernel/gdt.c delete mode 100644 kernel/idt-as.S delete mode 100644 kernel/idt.c delete mode 100644 kernel/include/fpu.h delete mode 100644 kernel/include/gdt.h delete mode 100644 kernel/include/heap.h delete mode 100644 kernel/include/idt.h delete mode 100644 kernel/include/io.h delete mode 100644 kernel/include/irq.h delete mode 100644 kernel/include/isr.h delete mode 100644 kernel/include/log.h delete mode 100644 kernel/include/multiboot.h delete mode 100644 kernel/include/paging.h delete mode 100644 kernel/include/panic.h delete mode 100644 kernel/include/timer.h delete mode 100644 kernel/include/version.h delete mode 100644 kernel/irq-as.S delete mode 100644 kernel/irq.c delete mode 100644 kernel/isr-as.S delete mode 100644 kernel/isr.c delete mode 100644 kernel/linker.ld delete mode 100644 kernel/paging-as.S delete mode 100644 kernel/paging.c delete mode 100644 kernel/ssp.c delete mode 100644 libc/include/stdio.h delete mode 100644 libc/include/stdlib.h delete mode 100644 libc/include/string.h diff --git a/Makefile b/Makefile index cfa96c0..f2a11a7 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ OBJ := $(shell cat OBJ) CC = gcc LD = ld -INCLUDES = -Idrivers/include -Ikernel/include -Ilibc/include -Iapps/ +INCLUDES = -Iinclude -Iapps -Iinclude/arch/i686 -Iinclude/arch/i686/drivers -Iinclude/kernel CFLAGS = -std=gnu99 -ffreestanding -fno-stack-protector -nostdlib -Wall -Wextra -m32 $(INCLUDES) -g OPTFLAGS = -fexpensive-optimizations -ftree-loop-vectorize -finline-functions -fomit-frame-pointer -ftree-vectorize -O1 -mtune=generic @@ -35,10 +35,10 @@ kappa.iso: kappa.bin @grub-mkrescue -o kappa.iso $(ISODIR) 2> /dev/null kappa.bin: $(OBJ) $(SOURCES) Makefile - @$(LD) -T kernel/linker.ld -o kappa.bin -melf_i386 $(OBJ) -L /usr/lib32 -lgcc_s -static @echo "LD $@" + @$(LD) -T arch/i686/linker.ld -o kappa.bin -melf_i386 $(OBJ) -L /usr/lib32 -lgcc_s -static -drivers/gfx.o: drivers/gfx.c Makefile +arch/i686/drivers/gfx.o: arch/i686/drivers/gfx.c Makefile @echo "CC $<" @$(CC) $(CFLAGS) -O3 -msse -c $< -o $@ diff --git a/OBJ b/OBJ index f8b9faa..ce6fff4 100644 --- a/OBJ +++ b/OBJ @@ -7,29 +7,29 @@ apps/xracer/map.o apps/xracer/maps.o apps/xracer/sprite.o apps/xracer/util.o -boot/head.o -drivers/gfx-as.o -drivers/gfx.o +arch/i686/boot/head.o +arch/i686/drivers/gfx-as.o +arch/i686/drivers/gfx.o +arch/i686/drivers/pcspkr.o +arch/i686/drivers/ps2kbd.o +arch/i686/drivers/vgatext.o +arch/i686/fpu.o +arch/i686/gdt-as.o +arch/i686/gdt.o +arch/i686/idt-as.o +arch/i686/idt.o +arch/i686/irq-as.o +arch/i686/irq.o +arch/i686/isr-as.o +arch/i686/isr.o +arch/i686/paging-as.o +arch/i686/paging.o drivers/gfx_font.o -drivers/pcspkr.o drivers/ps2_keymaps.o -drivers/ps2kbd.o -drivers/vgatext.o -kernel/fpu.o -kernel/gdt-as.o -kernel/gdt.o kernel/heap.o -kernel/idt-as.o -kernel/idt.o kernel/io.o -kernel/irq-as.o -kernel/irq.o -kernel/isr-as.o -kernel/isr.o kernel/log.o kernel/main.o -kernel/paging.o -kernel/paging-as.o kernel/panic.o kernel/timer.o libc/stdio.o diff --git a/arch/i686/boot/head.S b/arch/i686/boot/head.S new file mode 100644 index 0000000..9118c20 --- /dev/null +++ b/arch/i686/boot/head.S @@ -0,0 +1,41 @@ + .set ALIGN, 1<<0 + .set MEMINFO, 1<<1 + .set GFXMODE, 1<<2 # this flag enables the graphics fields + .set FLAGS, ALIGN | MEMINFO | GFXMODE + .set MAGIC, 0x1BADB002 # multiboot magic + .set CHECKSUM, -(MAGIC + FLAGS) + +.section .multiboot + .align 4 +multiboot_header: + .long MAGIC + .long FLAGS + .long CHECKSUM + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 + .long 0 # 1=text mode, 0=graphics mode + .long 0 # screen width (don't care) + .long 0 # screen height (don't care) + .long 32 # screen BPP: MUST be 32 + +.section .stack +stack_bottom: # Stack grows up in addresses, so bottom is + # lower in memory than the top + .skip 32768 # 32KB stack +stack_top: + +.section .text + .global _start +_start: + cli + movl $stack_top, %esp + push %eax # multiboot magic + push %ebx # multiboot header + call main +.Lhang: # Idle + cli + hlt + jmp .Lhang diff --git a/arch/i686/drivers/gfx-as.S b/arch/i686/drivers/gfx-as.S new file mode 100644 index 0000000..a58fa12 --- /dev/null +++ b/arch/i686/drivers/gfx-as.S @@ -0,0 +1,101 @@ + .extern fb_width + .extern fb_height + .extern fb_stride + .extern fb_bpp + .extern _gfx_fgcol + .extern _gfx_bgcol + .extern framebuffer + + .global gfx_clear_packed +gfx_clear_packed: + movl framebuffer, %eax + movzwl fb_stride, %ecx + movzwl fb_height, %edx + imull %ecx, %edx + addl %eax, %edx + pushl %ebx + movzwl fb_bpp, %ebx + movl _gfx_bgcol, %ecx +.L1: + movl %ecx, (%eax) + addl %ebx, %eax + cmpl %eax, %edx + ja .L1 +.L2: + popl %ebx + ret + + .global gfx_hline_fast + +gfx_hline_fast: + int $0x80 + pushl %ebx + movl 8(%esp), %eax + movl 12(%esp), %ecx + cmpl %eax, %ecx + jge .L3 + xchgl %eax, %ecx +.L3: + movzwl fb_stride, %edx + movzbl fb_bpp, %ebx + imull 16(%esp), %edx + addl framebuffer, %edx + imull %ebx, %ecx + imull %ebx, %eax + addl %edx, %eax + addl %ecx, %edx + movl _gfx_fgcol, %ecx + cmpl %edx, %eax + jnb .L5 +.L4: + movl %ecx, (%eax) + addl %ebx, %eax + cmpl %eax, %edx + ja .L4 +.L5: + popl %ebx + ret + + .global gfx_vline_fast + +gfx_vline_fast: + pushl %esi + pushl %ebx + movl 12(%esp), %eax + movl 16(%esp), %edx + cmpl %eax, %edx + jge .L6 + xchgl %eax, %edx +.L6: + movzwl fb_stride, %ebx + movzbl fb_bpp, %ecx + imull 20(%esp), %ecx + movl framebuffer, %esi + imull %ebx, %edx + imull %ebx, %eax + addl %ecx, %eax + addl %edx, %ecx + leal (%esi,%ecx), %edx + addl %esi, %eax + movl _gfx_fgcol, %ecx + cmpl %edx, %eax + jnb .L8 +.L7: + movl %ecx, (%eax) + addl %ebx, %eax + cmpl %eax, %edx + ja .L7 +.L8: + popl %ebx + popl %esi + ret + + .global gfx_drawpixel_32bpp +gfx_drawpixel_32bpp: + movzwl fb_stride32, %eax + movl framebuffer, %edx + imull 8(%esp), %eax + movl _gfx_fgcol, %ecx + addl 4(%esp), %eax + movl %ecx, (%edx,%eax,4) + ret diff --git a/arch/i686/drivers/gfx.c b/arch/i686/drivers/gfx.c new file mode 100644 index 0000000..2f4864b --- /dev/null +++ b/arch/i686/drivers/gfx.c @@ -0,0 +1,540 @@ +#include +#include +#include +#include +#include +#include "gfx_font.h" +#include "log.h" +#include "multiboot.h" +#include "paging.h" +#include "panic.h" +#include "gfx.h" + +uint8_t *real_framebuffer = NULL; +uint8_t *temp_framebuffer = NULL; +uint8_t *framebuffer = NULL; +bool double_buffer = false; +uint16_t fb_width; +uint16_t fb_height; + +/* this is BYTES per pixel */ +uint8_t fb_bpp; +uint16_t fb_stride; +/* fb_stride / 4 */ +uint16_t fb_stride32; +const uint8_t *gfx_bpp = &fb_bpp; + +const uint16_t *gfx_width = &fb_width; +const uint16_t *gfx_height = &fb_height; + +static int cursor_x, cursor_y; +uint32_t _gfx_fgcol, _gfx_bgcol; + +void (*gfx_clear)(void); +void (*gfx_drawpixel)(int x, int y); +void (*gfx_hline)(int x1, int x2, int y); +void (*gfx_vline)(int y1, int y2, int x); + +void gfx_set_background(uint32_t col) +{ + _gfx_bgcol = col; +} + +uint32_t gfx_get_background(void) +{ + return _gfx_bgcol; +} + +void gfx_set_foreground(uint32_t col) +{ + _gfx_fgcol = col; +} + +uint32_t gfx_get_foreground(void) +{ + return _gfx_fgcol; +} + +/* assembly */ +void gfx_drawpixel_32bpp_checked(int x, int y) +{ + if(0 <= x && x < fb_width && + 0 <= y && y < fb_height) + ((uint32_t*)framebuffer)[y * fb_stride32 + x] = _gfx_fgcol; + else + panic("pixel OOB!\n"); +} + +/* implemented in assembly now */ +/* +void gfx_clear(uint32_t col) +{ + uint8_t *p = framebuffer; + uint8_t *stop = framebuffer + fb_width * fb_height * fb_bpp; + while(p < stop) + { + *(uint32_t*)p = col; + p += fb_bpp; + } +} +*/ + +void gfx_clear_unpacked(void) +{ + uint8_t *fb = framebuffer; + const uint32_t bg = _gfx_bgcol; + + const uint16_t padding = fb_stride - (fb_bpp * fb_width); + + for(int y = 0; y < fb_height; ++y) + { + for(int x = 0; x < fb_width; ++x) + { + *(uint32_t*)fb++ = bg; + } + fb += padding; + } +} + +void gfx_reset(void) +{ + _gfx_fgcol = VGA_RGBPACK(0xff, 0xff, 0xff); + _gfx_bgcol = VGA_RGBPACK(0, 0, 0); + gfx_clear(); + cursor_y = 0; + cursor_x = 0; +} + +void gfx_drawchar(int x, int y, int c) +{ + uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride); + const uint32_t fg = _gfx_fgcol; + const uint16_t stride = fb_stride; + const uint8_t stop_y = MIN(FONT_HEIGHT, fb_height - y); + const uint8_t stop_x = MIN(FONT_WIDTH, fb_width - x); + if(c < 0 || c > 132) + return; + for(int i = 0; i < stop_y; ++i) + { + uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1}; + for(int j = 0; j < stop_x; ++j) + { + if(gfx_font[c][i] & mask_table[j]) + ((uint32_t*)line_addr)[j] = fg; + } + line_addr += stride; + } +} + +void gfx_drawchar_bg(int x, int y, int c) +{ + uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride); + const uint32_t fg = _gfx_fgcol; + const uint16_t stride = fb_stride; + const uint8_t stop_y = MIN(FONT_HEIGHT, fb_height - y); + const uint8_t stop_x = MIN(FONT_WIDTH, fb_width - x); + if(c < 0 || c > 132) + return; + for(int i = 0; i < stop_y; ++i) + { + uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1}; + for(int j = 0; j < stop_x; ++j) + { + if(gfx_font[c][i] & mask_table[j]) + ((uint32_t*)line_addr)[j] = fg; + else + ((uint32_t*)line_addr)[j] = _gfx_bgcol; + } + line_addr += stride; + } +} + +void gfx_putchar(int ch) +{ + if(ch != '\n' && ch != '\b') + { + gfx_drawchar(cursor_x, cursor_y, ch); + cursor_x += FONT_WIDTH; + if(cursor_x >= fb_width) + { + cursor_x = 0; + cursor_y += FONT_HEIGHT; + if(cursor_y >= fb_height) + { + gfx_clear(); + cursor_y = 0; + } + } + } + else if(ch == '\n') + { + cursor_x = 0; + cursor_y += FONT_HEIGHT; + if(cursor_y >= fb_height) + { + gfx_clear(); + cursor_y = 0; + } + } + else if(ch == '\b') + { + int temp_x = cursor_x - FONT_WIDTH; + if(temp_x >= 0) + cursor_x = temp_x; + gfx_drawchar_bg(cursor_x, cursor_y, ' '); + } +} + +void gfx_puts(const char* str) +{ + while(*str) + { + gfx_putchar(*str++); + } +} + +/* implemented in assembly now */ +void gfx_hline_checked(int x1, int x2, int y) +{ + /* make sure x1 is to the left of x2 */ + if(x2 < x1) + { + int temp = x1; + x1 = x2; + x2 = temp; + } + + x1 = MAX(0, x1); + x2 = MIN(x2, fb_width); + + if(0 <= y && y < fb_height) + { + + uint8_t *base = framebuffer + y * fb_stride; + + uint8_t *dest = base + x1 * fb_bpp; + uint8_t *stop = base + x2 * fb_bpp; + const uint32_t col = _gfx_fgcol; + while(dest < stop) + { + *(uint32_t*)dest = col; + dest += fb_bpp; + } + } +} + +void gfx_vline_checked(int y1, int y2, int x) +{ + /* make sure y1 is above y2 */ + if(y2 < y1) + { + int temp = y1; + y1 = y2; + y2 = temp; + } + + y1 = MAX(0, y1); + y2 = MIN(y2, fb_height); + + if(0 <= x && x < fb_width) + { + uint8_t *dest = framebuffer + y1 * fb_stride + x * fb_bpp; + uint8_t *stop = framebuffer + y2 * fb_stride + x * fb_bpp; + const uint32_t col = _gfx_fgcol; + const uint16_t stride = fb_stride; + while(dest < stop) + { + *(uint32_t*)dest = col; + dest += stride; + } + } +} + +void gfx_fillrect(int x, int y, int w, int h) +{ + for(int i = 0; i < h; ++i) + { + gfx_hline(x, x + w, y + i); + } +} + +void gfx_drawline(int x1, int y1, int x2, int y2) +{ + int dx = abs(x2 - x1); + int sx = x1 < x2 ? 1 : -1; + int dy = -abs(y2 - y1); + int sy = y1 < y2 ? 1 : -1; + int err = dx + dy; + int e2; /* error value e_xy */ + + while(1) + { + gfx_drawpixel(x1, y1); + if (x1 == x2 && y1 == y2) + break; + e2 = err << 1; + if (e2 >= dy) + { + err += dy; + x1 += sx; + } + if (e2 <= dx) + { + err += dx; + y1 += sy; + } + } +} + +void gfx_drawcircle(int cx, int cy, int r) +{ + int d = 3 - (r * 2); + int x = 0; + int y = r; + while(x <= y) + { + gfx_drawpixel(cx + x, cy + y); + gfx_drawpixel(cx - x, cy + y); + gfx_drawpixel(cx + x, cy - y); + gfx_drawpixel(cx - x, cy - y); + gfx_drawpixel(cx + y, cy + x); + gfx_drawpixel(cx - y, cy + x); + gfx_drawpixel(cx + y, cy - x); + gfx_drawpixel(cx - y, cy - x); + if(d < 0) + { + d += (x * 4) + 6; + } + else + { + d += ((x - y) * 4) + 10; + --y; + } + ++x; + } +} + +void gfx_fillcircle(int cx, int cy, int r) +{ + int d = 3 - (r * 2); + int x = 0; + int y = r; + while(x <= y) + { + gfx_hline(cx - x, cx + x, cy + y); + gfx_hline(cx - x, cx + x, cy - y); + gfx_hline(cx - y, cx + y, cy + x); + gfx_hline(cx - y, cx + y, cy - x); + if(d < 0) + { + d += (x * 4) + 6; + } + else + { + d += ((x - y) * 4) + 10; + --y; + } + ++x; + } +} + +/* these next two functions were taken directly from the Rockbox project's XLCD + * library. + * Copyright (C) 2005 Jens Arnold */ + +/* sort the given coordinates by increasing x value */ +static void sort_points_by_increasing_y(int* y1, int* x1, + int* y2, int* x2, + int* y3, int* x3) +{ + int x, y; + if (*x1 > *x3) + { + if (*x2 < *x3) /* x2 < x3 < x1 */ + { + x = *x1; *x1 = *x2; *x2 = *x3; *x3 = x; + y = *y1; *y1 = *y2; *y2 = *y3; *y3 = y; + } + else if (*x2 > *x1) /* x3 < x1 < x2 */ + { + x = *x1; *x1 = *x3; *x3 = *x2; *x2 = x; + y = *y1; *y1 = *y3; *y3 = *y2; *y2 = y; + } + else /* x3 <= x2 <= x1 */ + { + x = *x1; *x1 = *x3; *x3 = x; + y = *y1; *y1 = *y3; *y3 = y; + } + } + else + { + if (*x2 < *x1) /* x2 < x1 <= x3 */ + { + x = *x1; *x1 = *x2; *x2 = x; + y = *y1; *y1 = *y2; *y2 = y; + } + else if (*x2 > *x3) /* x1 <= x3 < x2 */ + { + x = *x2; *x2 = *x3; *x3 = x; + y = *y2; *y2 = *y3; *y3 = y; + } + /* else already sorted */ + } +} + +/* draw a filled triangle, using horizontal lines for speed */ +void gfx_filltriangle(int x1, int y1, + int x2, int y2, + int x3, int y3) +{ + long fp_x1, fp_x2, fp_dx1, fp_dx2; + int y; + sort_points_by_increasing_y(&x1, &y1, &x2, &y2, &x3, &y3); + + if (y1 < y3) /* draw */ + { + fp_dx1 = ((x3 - x1) << 16) / (y3 - y1); + fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1); + + if (y1 < y2) /* first part */ + { + fp_dx2 = ((x2 - x1) << 16) / (y2 - y1); + fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1); + for (y = y1; y < y2; y++) + { + gfx_hline(fp_x1 >> 16, fp_x2 >> 16, y); + fp_x1 += fp_dx1; + fp_x2 += fp_dx2; + } + } + if (y2 < y3) /* second part */ + { + fp_dx2 = ((x3 - x2) << 16) / (y3 - y2); + fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1); + for (y = y2; y < y3; y++) + { + gfx_hline(fp_x1 >> 16, fp_x2 >> 16, y); + fp_x1 += fp_dx1; + fp_x2 += fp_dx2; + } + } + } +} + +static void gfx_bitmap32(int x, int y, const struct bitmap_t *bmp) +{ + /* SLOOW */ + uint8_t *data = bmp->data; + for(unsigned int i = y; i < y + bmp->h && i < fb_height; ++i) + { + for(unsigned int j = x; j < x + bmp->w && j < fb_width; ++j) + { + uint8_t r = *data++; + uint8_t g = *data++; + uint8_t b = *data++; + gfx_set_foreground(VGA_RGBPACK(r, g, b)); + gfx_drawpixel(j, i); + } + } +} + +void gfx_bitmap(int x, int y, const struct bitmap_t *bmp) +{ + gfx_bitmap32(x, y, bmp); +} + +void gfx_drawrect(int x, int y, int w, int h) +{ + gfx_hline(MAX(0, x), MIN(x + w, fb_width), MAX(0, y)); + gfx_hline(MAX(0, x), MIN(x + w, fb_width), MIN(y + h, fb_height)); + gfx_vline(MAX(0, y), MIN(y + h, fb_height),MAX(0, x)); + gfx_vline(MAX(0, y), MIN(y + h, fb_height),MIN(x + w, fb_width)); +} + +void gfx_update(void) +{ + memcpy(real_framebuffer, framebuffer, fb_height * fb_stride); +} + +void gfx_set_doublebuffer(bool yesno) +{ + if(yesno) + framebuffer = temp_framebuffer; + else + framebuffer = real_framebuffer; +} + +bool gfx_get_doublebuffer(void) +{ + if(framebuffer == temp_framebuffer) + return true; + else + return false; +} + +void gfx_putsxy(int x, int y, const char* str) +{ + while(*str) + { + gfx_drawchar(x, y, *str); + x += FONT_WIDTH; + str++; + } +} + +void gfx_putsxy_bg(int x, int y, const char* str) +{ + while(*str) + { + gfx_drawchar_bg(x, y, *str); + x += FONT_WIDTH; + str++; + } +} + +bool gfx_init(struct vbe_info_t *vbe_mode_info) +{ + real_framebuffer = (uint8_t*)vbe_mode_info->physbase; + gfx_set_doublebuffer(false); + fb_width = vbe_mode_info->Xres; + fb_height = vbe_mode_info->Yres; + fb_bpp = vbe_mode_info->bpp / 8; + fb_stride = vbe_mode_info->pitch; + fb_stride32 = fb_stride / sizeof(uint32_t); + gfx_hline = gfx_hline_checked; + gfx_vline = gfx_vline_checked; + temp_framebuffer = malloc(fb_height * fb_stride); + if(fb_bpp != 4) + { + printf("WARNING: BPP != 32, falling back to text mode...\n"); + return false; + } + else + { + extern void gfx_drawpixel_32bpp(int, int); + gfx_drawpixel = &gfx_drawpixel_32bpp; + } + + set_putchar(gfx_putchar); + set_puts(gfx_puts); + + /* A bit of fragile code here... don't call gfx_reset() before setting gfx_clear! */ + + if(fb_stride != fb_bpp * fb_width) + { + gfx_clear = &gfx_clear_unpacked; + gfx_reset(); + printf("WARNING: Internal framebuffer padding detected, support is experimental.\n"); + } + else + { + /* assembly */ + extern void gfx_clear_packed(void); + gfx_clear = &gfx_clear_packed; + gfx_reset(); + } + + printf("Real FB addr: 0x%x\n", (uint32_t)real_framebuffer); + + return true; +} diff --git a/arch/i686/drivers/pcspkr.c b/arch/i686/drivers/pcspkr.c new file mode 100644 index 0000000..33c0540 --- /dev/null +++ b/arch/i686/drivers/pcspkr.c @@ -0,0 +1,19 @@ +#include +#include "io.h" +#include "pcspkr.h" + +void pcspkr_play(uint32_t freq) +{ + uint32_t div; + uint8_t tmp; + + div = 1193180 / freq; + outb(0x43, 0xb6); + outb(0x42, (uint8_t)(div)); + outb(0x42, (uint8_t)(div >> 8)); + + tmp = inb(0x61); + if (tmp != (tmp | 3)) { + outb(0x61, tmp | 3); + } +} diff --git a/arch/i686/drivers/ps2kbd.c b/arch/i686/drivers/ps2kbd.c new file mode 100644 index 0000000..29d02dc --- /dev/null +++ b/arch/i686/drivers/ps2kbd.c @@ -0,0 +1,212 @@ +/* this is a PS/2 keyboard driver */ +#include +#include +#include +#include "io.h" +#include "isr.h" +#include "ps2kbd.h" +#include "ps2_keymaps.h" + +static void ps2_wait(void) +{ + /* wait for the keyboard */ + while(1) + if ((inb(0x64) & 2) == 0) break; +} + +void ps2kbd_set_leds(uint8_t status) +{ + ps2_wait(); + outb(0x60, 0xED); + outb(0x60, status); +} + +#define IDX_UP 0 +#define IDX_LEFT 1 +#define IDX_DOWN 2 +#define IDX_RIGHT 3 + +static uint8_t ps2_arrowkeys[4]; + +uint8_t ps2kbd_button_get(void) +{ + uint8_t ret = 0; + if(ps2_arrowkeys[IDX_UP]) + ret |= BUTTON_UP; + if(ps2_arrowkeys[IDX_LEFT]) + ret |= BUTTON_LEFT; + if(ps2_arrowkeys[IDX_DOWN]) + ret |= BUTTON_DOWN; + if(ps2_arrowkeys[IDX_RIGHT]) + ret |= BUTTON_RIGHT; + return ret; +} + +static uint8_t ps2_ctrl; +static uint8_t ps2_shift; +static uint8_t ps2_alt; + +uint8_t ps2kbd_modifier_get(void) +{ + uint8_t ret = 0; + if(ps2_ctrl) + ret |= MODIFIER_CTRL; + if(ps2_shift) + ret |= MODIFIER_SHIFT; + if(ps2_alt) + ret |= MODIFIER_ALT; + return ret; +} + +static struct ps2_specialkeys_t special_keys; + +static void handle_special_key(uint8_t scancode, int release) +{ + int press = ~release; + switch(ps2_set1_special[scancode]) + { + case SPECIAL_SHIFT: + special_keys.shift = press; + break; + case SPECIAL_CTRL: + special_keys.ctrl = press; + break; + case SPECIAL_BKSP: + special_keys.bksp = press; + break; + case SPECIAL_ALT: + special_keys.alt = press; + break; + case SPECIAL_NUMLOCK: + special_keys.numlock = ~special_keys.numlock; + ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); + break; + case SPECIAL_CAPLOCK: + special_keys.capslock = ~special_keys.capslock; + ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); + break; + case SPECIAL_SCRLLOCK: + special_keys.scrllock = ~special_keys.scrllock; + ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); + break; + case SPECIAL_ESC: + special_keys.esc = press; + break; + case SPECIAL_F1: + special_keys.f1 = press; + break; + case SPECIAL_F2: + special_keys.f2 = press; + break; + case SPECIAL_F3: + special_keys.f3 = press; + break; + case SPECIAL_F4: + special_keys.f4 = press; + break; + case SPECIAL_F5: + special_keys.f5 = press; + break; + case SPECIAL_F6: + special_keys.f6 = press; + break; + case SPECIAL_F7: + special_keys.f7 = press; + break; + case SPECIAL_F8: + special_keys.f8 = press; + break; + case SPECIAL_F9: + special_keys.f9 = press; + break; + case SPECIAL_F10: + special_keys.f10 = press; + break; + case SPECIAL_F11: + special_keys.f11 = press; + break; + case SPECIAL_F12: + special_keys.f12 = press; + break; + } +} + +static void handle_extended_scancode(void) +{ + uint8_t temp = inb(0x60); + (void) temp; + //printf("Extended scancode: 0x%x\n", temp); +} + +void (*keyevent_handler)(const struct ps2_keyevent*); + +static void key_handler(struct regs_t *regs) +{ + (void) regs; + uint8_t scancode = inb(0x60); + //printf("INTR SCAN: 0x%x\n", scancode); + if(scancode == EXTENDED_SCANCODE) + { + handle_extended_scancode(); + return; + } + + /* AND by 0x7F to get in the range of [0,128) */ + + int type = ps2_set1_scancodes[scancode & 0x7F]; + int release = (scancode & (1<<7)) >> 7; + char ascii = '\0'; + switch(type) + { + case PRINTING_KEY: + { + if(!release) + { + int capitals = special_keys.capslock; + if(special_keys.shift) + capitals = ~capitals; + if(capitals) + ascii = ps2_set1_shift[scancode]; + else + ascii = ps2_set1_ascii[scancode]; + } + break; + } + case SPECIAL_KEY: + handle_special_key(scancode & 0x7F, release); + break; + } + if(special_keys.bksp) + ascii = '\b'; + if(keyevent_handler) + { + struct ps2_keyevent ev; + ev.special_keys = &special_keys; + ev.ascii = ascii; + keyevent_handler(&ev); + } +} + +static void ps2_set_scancode_set(uint8_t set) +{ + ps2_wait(); + outb(0x60, 0xF0); + outb(0x60, set); +} + +static void keyboard_init(void) +{ + set_interrupt_handler(IRQ(1), key_handler); + ps2_set_scancode_set(1); + memset(&special_keys, 0, sizeof(special_keys)); +} + +void ps2kbd_set_handler(void (*handler)(const struct ps2_keyevent*)) +{ + keyevent_handler = handler; +} + +void ps2kbd_init(void) +{ + keyboard_init(); +} diff --git a/arch/i686/drivers/vgatext.c b/arch/i686/drivers/vgatext.c new file mode 100644 index 0000000..d0633af --- /dev/null +++ b/arch/i686/drivers/vgatext.c @@ -0,0 +1,124 @@ +#include +#include +#include "gfx.h" +#include "io.h" +#include "panic.h" +#include "vgatext.h" + +static int term_x, term_y; +static uint8_t term_col; +/* VGA buffer starts at 0xB8000 on color or 0xB0000 on monochrome */ +static uint16_t *term_buf; + +static uint16_t video_detect_hardware(void) +{ + const uint16_t *ptr = (const uint16_t*)0x410; + return *ptr; +} + +void vgatext_init(void) +{ + uint16_t vid_type = video_detect_hardware() & 0x30; + if(vid_type == 0x20) + { + /* color */ + term_buf = (uint16_t*)0xB8000; + } + else if(vid_type == 0x30) + { + term_buf = (uint16_t*)0xB0000; + } + else + { + /* none */ + panic("VGATEXT init failed!"); + } + vgatext_set_color(VGA_MAKE_COLOR(VGA_LIGHT_GRAY, VGA_BLACK)); + vgatext_clear(); + set_putchar(vgatext_putchar); + set_puts(vgatext_puts); +} + +static void move_cursor(uint16_t cursor_idx) +{ + outb(0x3D4, 14); + outb(0x3D5, cursor_idx >> 8); // high byte + outb(0x3D4, 15); + outb(0x3D5, cursor_idx); // low byte +} + +static void update_cursor(void) +{ + move_cursor(term_y * VGA_WIDTH + term_x); +} + +void vgatext_clear(void) +{ + term_x = 0; + term_y = 0; + for(int y = 0; y < VGA_HEIGHT; ++y) + { + for(int x = 0; x < VGA_WIDTH; ++x) + { + term_buf[y * VGA_WIDTH + x] = VGA_MAKE_ENTRY(' ', term_col); + } + } +} + +void vgatext_set_color(uint8_t color) +{ + term_col = color; +} + +uint8_t vgatext_get_color(void) +{ + return term_col; +} + +void vgatext_putchar_at(int ch, uint8_t col, int x, int y) +{ + term_buf[y * VGA_WIDTH + x] = VGA_MAKE_ENTRY((char)ch, col); +} + +void vgatext_putchar(int ch) +{ + if(ch != '\n' && ch != '\b') + { + vgatext_putchar_at(ch, term_col, term_x, term_y); + if(++term_x == VGA_WIDTH) + { + term_x = 0; + if(++term_y == VGA_HEIGHT) + { + vgatext_clear(); + term_y = 0; + } + } + } + else if(ch == '\n') + { + term_x = 0; + if(++term_y == VGA_HEIGHT) + { + vgatext_clear(); + term_y = 0; + } + } + else if(ch == '\b') + { + int temp_x = term_x - 1; + if(temp_x >= 0) + term_x = temp_x; + vgatext_putchar_at(' ', term_col, term_x, term_y); + } + + update_cursor(); +} + +void vgatext_puts(const char *str) +{ + while(*str) + { + vgatext_putchar(*str++); + } +} diff --git a/arch/i686/fpu.c b/arch/i686/fpu.c new file mode 100644 index 0000000..f5512d6 --- /dev/null +++ b/arch/i686/fpu.c @@ -0,0 +1,25 @@ +/* Copyright (C) 2011-2013 Kevin Lange */ +/* this code from toaruos */ +#include +#include "fpu.h" + +/** + * Enable the FPU and SSE + */ +void fpu_enable(void) { + asm volatile ("clts"); + size_t t; + asm volatile ("mov %%cr4, %0" : "=r"(t)); + t |= 3 << 9; + asm volatile ("mov %0, %%cr4" :: "r"(t)); +} + +/** + * Disable FPU and SSE so it traps to the kernel + */ +void fpu_disable(void) { + size_t t; + asm volatile ("mov %%cr0, %0" : "=r"(t)); + t |= 1 << 3; + asm volatile ("mov %0, %%cr0" :: "r"(t)); +} diff --git a/arch/i686/gdt-as.S b/arch/i686/gdt-as.S new file mode 100644 index 0000000..5a481e3 --- /dev/null +++ b/arch/i686/gdt-as.S @@ -0,0 +1,14 @@ + .global gdt_flush +gdt_flush: # prototype: void gdt_flush(uint32) + movl 4(%esp), %eax + lgdt (%eax) + # 0x8 is the code segment selector + jmp $0x8, $.flush +.flush: + mov $0x10, %ax # 0x10 is the data segment selector + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %ax, %ss + ret diff --git a/arch/i686/gdt.c b/arch/i686/gdt.c new file mode 100644 index 0000000..36a0cda --- /dev/null +++ b/arch/i686/gdt.c @@ -0,0 +1,34 @@ +#include "gdt.h" + +static void gdt_set_gate(int idx, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) +{ + /* Setup the descriptor base address */ + gdt[idx].base_low = (base & 0xFFFF); + gdt[idx].base_middle = (base >> 16) & 0xFF; + gdt[idx].base_high = (base >> 24) & 0xFF; + + /* Setup the descriptor limits */ + gdt[idx].limit_low = (limit & 0xFFFF); + gdt[idx].granularity = ((limit >> 16) & 0x0F); + + /* Finally, set up the granularity and access flags */ + gdt[idx].granularity |= (gran & 0xF0); + gdt[idx].access = access; +} + +void gdt_init(void) +{ + gp.limit = sizeof(gdt) - 1; + gp.base = (uint32_t)&gdt; + + /* null segment */ + gdt_set_gate(0, 0, 0, 0, 0); + + /* code segment */ + gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); + + /* data segment */ + gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); + + gdt_flush((uint32_t)&gp); +} diff --git a/arch/i686/idt-as.S b/arch/i686/idt-as.S new file mode 100644 index 0000000..d1ab7e2 --- /dev/null +++ b/arch/i686/idt-as.S @@ -0,0 +1,6 @@ + .global idt_flush + .type idt_flush, @function +idt_flush: # prototype: void idt_flush(uint32) + movl 4(%esp), %eax + lidt (%eax) + ret diff --git a/arch/i686/idt.c b/arch/i686/idt.c new file mode 100644 index 0000000..0108991 --- /dev/null +++ b/arch/i686/idt.c @@ -0,0 +1,24 @@ +#include +#include +#include "idt.h" +#include "isr.h" +#include "irq.h" + +void idt_set_gate(uint8_t idx, uint32_t base, uint16_t sel, uint8_t flags) +{ + idt[idx].base_lo = base & 0xFFFF; + idt[idx].base_hi = base >> 16; + idt[idx].sel = sel; + idt[idx].zero = 0; + idt[idx].flags = flags; +} + +void idt_init(void) +{ + idt_pt.limit = sizeof(idt) - 1; + idt_pt.base = (uint32_t)&idt; + + memset(&idt, 0, sizeof(idt)); + + idt_flush((uint32_t)&idt_pt); +} diff --git a/arch/i686/irq-as.S b/arch/i686/irq-as.S new file mode 100644 index 0000000..1d16392 --- /dev/null +++ b/arch/i686/irq-as.S @@ -0,0 +1,146 @@ + .extern irq_handler + +irq_stub: + + pusha + push %ds + push %es + push %fs + push %gs + mov $0x10, %ax + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %esp, %eax # push the stack + push %eax + mov $irq_handler, %eax + call *%eax + pop %eax + pop %gs + pop %fs + pop %es + pop %ds + popa + addl $8, %esp + iret + + .global _irq0 + .global _irq1 + .global _irq2 + .global _irq3 + .global _irq4 + .global _irq5 + .global _irq6 + .global _irq7 + .global _irq8 + .global _irq9 + .global _irq10 + .global _irq11 + .global _irq12 + .global _irq13 + .global _irq14 + .global _irq15 + .global _int0x80 + +_irq0: + cli + pushl $0 + pushl $32 + jmp irq_stub + +_irq1: + cli + pushl $0 + pushl $33 + jmp irq_stub + +_irq2: + cli + pushl $0 + pushl $34 + jmp irq_stub + +_irq3: + cli + pushl $0 + pushl $35 + jmp irq_stub + +_irq4: + cli + pushl $0 + pushl $36 + jmp irq_stub + +_irq5: + cli + pushl $0 + pushl $37 + jmp irq_stub + +_irq6: + cli + pushl $0 + pushl $38 + jmp irq_stub + +_irq7: + cli + pushl $0 + pushl $39 + jmp irq_stub + +_irq8: + cli + pushl $0 + pushl $40 + jmp irq_stub + +_irq9: + cli + pushl $0 + pushl $41 + jmp irq_stub + +_irq10: + cli + pushl $0 + pushl $42 + jmp irq_stub + +_irq11: + cli + pushl $0 + pushl $43 + jmp irq_stub + +_irq12: + cli + pushl $0 + pushl $44 + jmp irq_stub + +_irq13: + cli + pushl $0 + pushl $45 + jmp irq_stub + +_irq14: + cli + pushl $0 + pushl $46 + jmp irq_stub + +_irq15: + cli + pushl $0 + pushl $47 + jmp irq_stub + +_int0x80: + cli + pushl $0 + pushl $0x80 + jmp irq_stub diff --git a/arch/i686/irq.c b/arch/i686/irq.c new file mode 100644 index 0000000..c6dbf4c --- /dev/null +++ b/arch/i686/irq.c @@ -0,0 +1,73 @@ +#include +#include +#include +#include "idt.h" +#include "io.h" +#include "irq.h" +#include "isr.h" +#include "panic.h" + +/* in isr.c */ +extern void *int_callbacks[256]; + +void irq_remap(void) +{ + outb(0x20, 0x11); + outb(0xA0, 0x11); + outb(0x21, 0x20); + outb(0xA1, 0x28); + outb(0x21, 0x04); + outb(0xA1, 0x02); + outb(0x21, 0x01); + outb(0xA1, 0x01); + outb(0x21, 0x0); + outb(0xA1, 0x0); +} + +void irq_init(void) +{ + irq_remap(); + idt_set_gate(32, (uint32_t)_irq0, 0x08, 0x8E); + idt_set_gate(33, (uint32_t)_irq1, 0x08, 0x8E); + idt_set_gate(34, (uint32_t)_irq2, 0x08, 0x8E); + idt_set_gate(35, (uint32_t)_irq3, 0x08, 0x8E); + idt_set_gate(36, (uint32_t)_irq4, 0x08, 0x8E); + idt_set_gate(37, (uint32_t)_irq5, 0x08, 0x8E); + idt_set_gate(38, (uint32_t)_irq6, 0x08, 0x8E); + idt_set_gate(39, (uint32_t)_irq7, 0x08, 0x8E); + idt_set_gate(40, (uint32_t)_irq8, 0x08, 0x8E); + idt_set_gate(41, (uint32_t)_irq9, 0x08, 0x8E); + idt_set_gate(42, (uint32_t)_irq10, 0x08, 0x8E); + idt_set_gate(43, (uint32_t)_irq11, 0x08, 0x8E); + idt_set_gate(44, (uint32_t)_irq12, 0x08, 0x8E); + idt_set_gate(45, (uint32_t)_irq13, 0x08, 0x8E); + idt_set_gate(46, (uint32_t)_irq14, 0x08, 0x8E); + idt_set_gate(47, (uint32_t)_irq15, 0x08, 0x8E); + idt_set_gate(128,(uint32_t)_int0x80, 0x08, 0x8E); +} + +void irq_handler(struct regs_t *regs) +{ + void (*handler)(struct regs_t *r); + + handler = int_callbacks[regs->int_no]; + + if(handler) + { + handler(regs); + } + else + { + } + + /* If the IDT entry that was invoked was greater than 40 + * (meaning IRQ8 - 15), then we need to send an EOI to + * the slave controller */ + if (regs->int_no >= 40) + { + outb(0xA0, 0x20); + } + + /* send an EOI to the master controller */ + outb(0x20, 0x20); +} diff --git a/arch/i686/isr-as.S b/arch/i686/isr-as.S new file mode 100644 index 0000000..858ce47 --- /dev/null +++ b/arch/i686/isr-as.S @@ -0,0 +1,214 @@ + .extern isr_handler +isr_stub: + pusha + push %ds + push %es + push %fs + push %gs + mov $0x10, %ax # Load the Kernel Data Segment descriptor! + mov %ax, %ds + mov %ax, %es + mov %ax, %fs + mov %ax, %gs + mov %esp, %eax # Push us the stack + push %eax + call isr_handler + pop %eax + pop %gs + pop %fs + pop %es + pop %ds + popa + add $8, %esp + iret + + # stub ISR's: + .global _isr0 + .global _isr1 + .global _isr2 + .global _isr3 + .global _isr4 + .global _isr5 + .global _isr6 + .global _isr7 + .global _isr8 + .global _isr9 + .global _isr10 + .global _isr11 + .global _isr12 + .global _isr13 + .global _isr14 + .global _isr15 + .global _isr16 + .global _isr17 + .global _isr18 + .global _isr19 + .global _isr20 + .global _isr21 + .global _isr22 + .global _isr23 + .global _isr24 + .global _isr25 + .global _isr26 + .global _isr27 + .global _isr28 + .global _isr29 + .global _isr30 + .global _isr31 + + # Interrupts 8, 10, 11, 12, 13, and 14 push error codes onto the stack + +_isr0: + cli + pushl $0 + pushl $0 + jmp isr_stub +_isr1: + cli + pushl $0 + pushl $1 + jmp isr_stub +_isr2: + cli + pushl $0 + pushl $2 + jmp isr_stub +_isr3: + cli + pushl $0 + pushl $3 + jmp isr_stub +_isr4: + cli + pushl $0 + pushl $4 + jmp isr_stub +_isr5: + cli + pushl $0 + pushl $5 + jmp isr_stub +_isr6: + cli + pushl $0 + pushl $6 + jmp isr_stub +_isr7: + cli + pushl $0 + pushl $7 + jmp isr_stub +_isr8: + cli + pushl $8 + jmp isr_stub +_isr9: + cli + pushl $0 + pushl $9 + jmp isr_stub +_isr10: + cli + pushl $10 + jmp isr_stub +_isr11: + cli + pushl $11 + jmp isr_stub +_isr12: + cli + pushl $12 + jmp isr_stub +_isr13: + cli + pushl $13 + jmp isr_stub +_isr14: + cli + pushl $14 + jmp isr_stub +_isr15: + cli + pushl $0 + pushl $15 + jmp isr_stub +_isr16: + cli + pushl $0 + pushl $16 + jmp isr_stub +_isr17: + cli + pushl $0 + pushl $17 + jmp isr_stub +_isr18: + cli + pushl $0 + pushl $18 + jmp isr_stub +_isr19: + cli + pushl $0 + pushl $19 + jmp isr_stub +_isr20: + cli + pushl $0 + pushl $20 + jmp isr_stub +_isr21: + cli + pushl $0 + pushl $21 + jmp isr_stub +_isr22: + cli + pushl $0 + pushl $22 + jmp isr_stub +_isr23: + cli + pushl $0 + pushl $23 + jmp isr_stub +_isr24: + cli + pushl $0 + pushl $24 + jmp isr_stub +_isr25: + cli + pushl $0 + pushl $25 + jmp isr_stub +_isr26: + cli + pushl $0 + pushl $26 + jmp isr_stub +_isr27: + cli + pushl $0 + pushl $27 + jmp isr_stub +_isr28: + cli + pushl $0 + pushl $28 + jmp isr_stub +_isr29: + cli + pushl $0 + pushl $29 + jmp isr_stub +_isr30: + cli + pushl $0 + pushl $30 + jmp isr_stub +_isr31: + cli + pushl $0 + pushl $31 + jmp isr_stub diff --git a/arch/i686/isr.c b/arch/i686/isr.c new file mode 100644 index 0000000..e6887c6 --- /dev/null +++ b/arch/i686/isr.c @@ -0,0 +1,60 @@ +#include +#include +#include "isr.h" +#include "idt.h" +#include "panic.h" + +void (*int_callbacks[256])(struct regs_t*) = { NULL }; + +void set_interrupt_handler(uint8_t n, void (*callback)(struct regs_t*)) +{ + int_callbacks[n] = callback; +} + +void isr_handler(struct regs_t *regs) +{ + if(int_callbacks[regs->int_no]) + { + int_callbacks[regs->int_no](regs); + } + else + { + printf("WARNING: unhandled ISR 0x%x!\n", regs->int_no); + } +} + +void isr_init(void) +{ + idt_set_gate(0, (uint32_t)_isr0, 0x08, 0x8E); + idt_set_gate(1, (uint32_t)_isr1, 0x08, 0x8E); + idt_set_gate(2, (uint32_t)_isr2, 0x08, 0x8E); + idt_set_gate(3, (uint32_t)_isr3, 0x08, 0x8E); + idt_set_gate(4, (uint32_t)_isr4, 0x08, 0x8E); + idt_set_gate(5, (uint32_t)_isr5, 0x08, 0x8E); + idt_set_gate(6, (uint32_t)_isr6, 0x08, 0x8E); + idt_set_gate(7, (uint32_t)_isr7, 0x08, 0x8E); + idt_set_gate(8, (uint32_t)_isr8, 0x08, 0x8E); + idt_set_gate(9, (uint32_t)_isr9, 0x08, 0x8E); + idt_set_gate(10, (uint32_t)_isr10, 0x08, 0x8E); + idt_set_gate(11, (uint32_t)_isr11, 0x08, 0x8E); + idt_set_gate(12, (uint32_t)_isr12, 0x08, 0x8E); + idt_set_gate(13, (uint32_t)_isr13, 0x08, 0x8E); + idt_set_gate(14, (uint32_t)_isr14, 0x08, 0x8E); + idt_set_gate(15, (uint32_t)_isr15, 0x08, 0x8E); + idt_set_gate(16, (uint32_t)_isr16, 0x08, 0x8E); + idt_set_gate(17, (uint32_t)_isr17, 0x08, 0x8E); + idt_set_gate(18, (uint32_t)_isr18, 0x08, 0x8E); + idt_set_gate(19, (uint32_t)_isr19, 0x08, 0x8E); + idt_set_gate(20, (uint32_t)_isr20, 0x08, 0x8E); + idt_set_gate(21, (uint32_t)_isr21, 0x08, 0x8E); + idt_set_gate(22, (uint32_t)_isr22, 0x08, 0x8E); + idt_set_gate(23, (uint32_t)_isr23, 0x08, 0x8E); + idt_set_gate(24, (uint32_t)_isr24, 0x08, 0x8E); + idt_set_gate(25, (uint32_t)_isr25, 0x08, 0x8E); + idt_set_gate(26, (uint32_t)_isr26, 0x08, 0x8E); + idt_set_gate(27, (uint32_t)_isr27, 0x08, 0x8E); + idt_set_gate(28, (uint32_t)_isr28, 0x08, 0x8E); + idt_set_gate(29, (uint32_t)_isr29, 0x08, 0x8E); + idt_set_gate(30, (uint32_t)_isr30, 0x08, 0x8E); + idt_set_gate(31, (uint32_t)_isr31, 0x08, 0x8E); +} diff --git a/arch/i686/linker.ld b/arch/i686/linker.ld new file mode 100644 index 0000000..c032991 --- /dev/null +++ b/arch/i686/linker.ld @@ -0,0 +1,45 @@ +/* The bootloader will look at this image and start execution at the symbol + designated as the entry point. */ +ENTRY(_start) + +/* Tell where the various sections of the object files will be put in the final + kernel image. */ +SECTIONS +{ + /* Begin putting sections at 1 MiB, a conventional place for kernels to be + loaded at by the bootloader. */ + . = 1M; + + /* First put the multiboot header, as it is required to be put very early + early in the image or the bootloader won't recognize the file format. + Next we'll put the .text section. */ + .text BLOCK(4K) : ALIGN(4K) + { + *(.multiboot) + *(.text) + } + + /* Read-only data. */ + .rodata BLOCK(4K) : ALIGN(4K) + { + *(.rodata) + } + + /* Read-write data (initialized) */ + .data BLOCK(4K) : ALIGN(4K) + { + *(.data) + } + + /* Read-write data (uninitialized) and stack */ + .bss BLOCK(4K) : ALIGN(4K) + { + *(COMMON) + *(.bss) + *(.bootstrap_stack) + } + + /* The compiler may produce other sections, by default it will put them in + a segment with the same name. Simply add stuff here as needed. */ + link_mem_end = .; +} diff --git a/arch/i686/paging-as.S b/arch/i686/paging-as.S new file mode 100644 index 0000000..cafaab4 --- /dev/null +++ b/arch/i686/paging-as.S @@ -0,0 +1,9 @@ + .global do_paging_enable +do_paging_enable: + movl 4(%esp), %eax # loads page directory address + mov %eax, %cr3 + mov %cr0, %eax + orl $0x80000000, %eax # set PG bit + sti + mov %eax, %cr0 + ret diff --git a/arch/i686/paging.c b/arch/i686/paging.c new file mode 100644 index 0000000..9d748ab --- /dev/null +++ b/arch/i686/paging.c @@ -0,0 +1,64 @@ +#include +#include +#include +#include +#include "heap.h" +#include "isr.h" +#include "paging.h" +#include "panic.h" + +uint32_t *current_directory; + +static void page_fault(struct regs_t *regs) +{ + volatile uint32_t fault_addr; + asm("mov %%cr2, %0" : "=r"(fault_addr)); + printf("=== Page Fault ===\n"); + printf("Faulting address: 0x%x\n", fault_addr); + /* dump the regs */ + printf("EAX: 0x%x EBX: 0x%x\n", regs->eax, regs->ebx); + printf("ECX: 0x%x EDX: 0x%x\n", regs->ecx, regs->edx); + printf("ESP: 0x%x EBP: 0x%x\n", regs->esp, regs->ebp); + printf("ESI: 0x%x EDI: 0x%x\n", regs->esi, regs->edi); + printf("EIP: 0x%x\n", regs->eip); + panic("Page fault!\n"); +} + + void paging_switch_directory(uint32_t *dir) +{ + current_directory = dir; + extern void do_paging_enable(uint32_t); + do_paging_enable((uint32_t)current_directory); +} + +static uint32_t *identity_map_table(uint32_t start, int flags) +{ + /* make a page table */ + uint32_t *table = kmalloc_a(0x1000); + /* identity map 4MB */ + for(uint32_t i = start; i < start + 1024; ++i) + { + table[i - start] = (i * PAGE_SIZE) | flags; + } + return table; +} + +void paging_init(void) +{ + uint32_t *kernel_directory = kmalloc_a(0x1000); + memset(kernel_directory, 0, 0x1000); + /* blank the kernel directory */ + for(int i = 0; i < 1024; ++i) + { + kernel_directory[i] = PAGE_RW; + } + + /* identity map all 4GB (and allocate all page tables) */ + for(int i = 0; i < 1024; ++i) + kernel_directory[i] = (uint32_t)identity_map_table(i * 1024, PAGE_PRESENT | PAGE_RW) | + PAGE_PRESENT | PAGE_RW; + + set_interrupt_handler(14, page_fault); + + paging_switch_directory(kernel_directory); +} diff --git a/boot/head.S b/boot/head.S deleted file mode 100644 index 9118c20..0000000 --- a/boot/head.S +++ /dev/null @@ -1,41 +0,0 @@ - .set ALIGN, 1<<0 - .set MEMINFO, 1<<1 - .set GFXMODE, 1<<2 # this flag enables the graphics fields - .set FLAGS, ALIGN | MEMINFO | GFXMODE - .set MAGIC, 0x1BADB002 # multiboot magic - .set CHECKSUM, -(MAGIC + FLAGS) - -.section .multiboot - .align 4 -multiboot_header: - .long MAGIC - .long FLAGS - .long CHECKSUM - .long 0 - .long 0 - .long 0 - .long 0 - .long 0 - .long 0 # 1=text mode, 0=graphics mode - .long 0 # screen width (don't care) - .long 0 # screen height (don't care) - .long 32 # screen BPP: MUST be 32 - -.section .stack -stack_bottom: # Stack grows up in addresses, so bottom is - # lower in memory than the top - .skip 32768 # 32KB stack -stack_top: - -.section .text - .global _start -_start: - cli - movl $stack_top, %esp - push %eax # multiboot magic - push %ebx # multiboot header - call main -.Lhang: # Idle - cli - hlt - jmp .Lhang diff --git a/drivers/gfx-as.S b/drivers/gfx-as.S deleted file mode 100644 index a58fa12..0000000 --- a/drivers/gfx-as.S +++ /dev/null @@ -1,101 +0,0 @@ - .extern fb_width - .extern fb_height - .extern fb_stride - .extern fb_bpp - .extern _gfx_fgcol - .extern _gfx_bgcol - .extern framebuffer - - .global gfx_clear_packed -gfx_clear_packed: - movl framebuffer, %eax - movzwl fb_stride, %ecx - movzwl fb_height, %edx - imull %ecx, %edx - addl %eax, %edx - pushl %ebx - movzwl fb_bpp, %ebx - movl _gfx_bgcol, %ecx -.L1: - movl %ecx, (%eax) - addl %ebx, %eax - cmpl %eax, %edx - ja .L1 -.L2: - popl %ebx - ret - - .global gfx_hline_fast - -gfx_hline_fast: - int $0x80 - pushl %ebx - movl 8(%esp), %eax - movl 12(%esp), %ecx - cmpl %eax, %ecx - jge .L3 - xchgl %eax, %ecx -.L3: - movzwl fb_stride, %edx - movzbl fb_bpp, %ebx - imull 16(%esp), %edx - addl framebuffer, %edx - imull %ebx, %ecx - imull %ebx, %eax - addl %edx, %eax - addl %ecx, %edx - movl _gfx_fgcol, %ecx - cmpl %edx, %eax - jnb .L5 -.L4: - movl %ecx, (%eax) - addl %ebx, %eax - cmpl %eax, %edx - ja .L4 -.L5: - popl %ebx - ret - - .global gfx_vline_fast - -gfx_vline_fast: - pushl %esi - pushl %ebx - movl 12(%esp), %eax - movl 16(%esp), %edx - cmpl %eax, %edx - jge .L6 - xchgl %eax, %edx -.L6: - movzwl fb_stride, %ebx - movzbl fb_bpp, %ecx - imull 20(%esp), %ecx - movl framebuffer, %esi - imull %ebx, %edx - imull %ebx, %eax - addl %ecx, %eax - addl %edx, %ecx - leal (%esi,%ecx), %edx - addl %esi, %eax - movl _gfx_fgcol, %ecx - cmpl %edx, %eax - jnb .L8 -.L7: - movl %ecx, (%eax) - addl %ebx, %eax - cmpl %eax, %edx - ja .L7 -.L8: - popl %ebx - popl %esi - ret - - .global gfx_drawpixel_32bpp -gfx_drawpixel_32bpp: - movzwl fb_stride32, %eax - movl framebuffer, %edx - imull 8(%esp), %eax - movl _gfx_fgcol, %ecx - addl 4(%esp), %eax - movl %ecx, (%edx,%eax,4) - ret diff --git a/drivers/gfx.c b/drivers/gfx.c deleted file mode 100644 index 2f4864b..0000000 --- a/drivers/gfx.c +++ /dev/null @@ -1,540 +0,0 @@ -#include -#include -#include -#include -#include -#include "gfx_font.h" -#include "log.h" -#include "multiboot.h" -#include "paging.h" -#include "panic.h" -#include "gfx.h" - -uint8_t *real_framebuffer = NULL; -uint8_t *temp_framebuffer = NULL; -uint8_t *framebuffer = NULL; -bool double_buffer = false; -uint16_t fb_width; -uint16_t fb_height; - -/* this is BYTES per pixel */ -uint8_t fb_bpp; -uint16_t fb_stride; -/* fb_stride / 4 */ -uint16_t fb_stride32; -const uint8_t *gfx_bpp = &fb_bpp; - -const uint16_t *gfx_width = &fb_width; -const uint16_t *gfx_height = &fb_height; - -static int cursor_x, cursor_y; -uint32_t _gfx_fgcol, _gfx_bgcol; - -void (*gfx_clear)(void); -void (*gfx_drawpixel)(int x, int y); -void (*gfx_hline)(int x1, int x2, int y); -void (*gfx_vline)(int y1, int y2, int x); - -void gfx_set_background(uint32_t col) -{ - _gfx_bgcol = col; -} - -uint32_t gfx_get_background(void) -{ - return _gfx_bgcol; -} - -void gfx_set_foreground(uint32_t col) -{ - _gfx_fgcol = col; -} - -uint32_t gfx_get_foreground(void) -{ - return _gfx_fgcol; -} - -/* assembly */ -void gfx_drawpixel_32bpp_checked(int x, int y) -{ - if(0 <= x && x < fb_width && - 0 <= y && y < fb_height) - ((uint32_t*)framebuffer)[y * fb_stride32 + x] = _gfx_fgcol; - else - panic("pixel OOB!\n"); -} - -/* implemented in assembly now */ -/* -void gfx_clear(uint32_t col) -{ - uint8_t *p = framebuffer; - uint8_t *stop = framebuffer + fb_width * fb_height * fb_bpp; - while(p < stop) - { - *(uint32_t*)p = col; - p += fb_bpp; - } -} -*/ - -void gfx_clear_unpacked(void) -{ - uint8_t *fb = framebuffer; - const uint32_t bg = _gfx_bgcol; - - const uint16_t padding = fb_stride - (fb_bpp * fb_width); - - for(int y = 0; y < fb_height; ++y) - { - for(int x = 0; x < fb_width; ++x) - { - *(uint32_t*)fb++ = bg; - } - fb += padding; - } -} - -void gfx_reset(void) -{ - _gfx_fgcol = VGA_RGBPACK(0xff, 0xff, 0xff); - _gfx_bgcol = VGA_RGBPACK(0, 0, 0); - gfx_clear(); - cursor_y = 0; - cursor_x = 0; -} - -void gfx_drawchar(int x, int y, int c) -{ - uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride); - const uint32_t fg = _gfx_fgcol; - const uint16_t stride = fb_stride; - const uint8_t stop_y = MIN(FONT_HEIGHT, fb_height - y); - const uint8_t stop_x = MIN(FONT_WIDTH, fb_width - x); - if(c < 0 || c > 132) - return; - for(int i = 0; i < stop_y; ++i) - { - uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1}; - for(int j = 0; j < stop_x; ++j) - { - if(gfx_font[c][i] & mask_table[j]) - ((uint32_t*)line_addr)[j] = fg; - } - line_addr += stride; - } -} - -void gfx_drawchar_bg(int x, int y, int c) -{ - uint8_t *line_addr = framebuffer + (x * fb_bpp) + (y * fb_stride); - const uint32_t fg = _gfx_fgcol; - const uint16_t stride = fb_stride; - const uint8_t stop_y = MIN(FONT_HEIGHT, fb_height - y); - const uint8_t stop_x = MIN(FONT_WIDTH, fb_width - x); - if(c < 0 || c > 132) - return; - for(int i = 0; i < stop_y; ++i) - { - uint8_t mask_table[8] = {128, 64, 32, 16, 8, 4, 2, 1}; - for(int j = 0; j < stop_x; ++j) - { - if(gfx_font[c][i] & mask_table[j]) - ((uint32_t*)line_addr)[j] = fg; - else - ((uint32_t*)line_addr)[j] = _gfx_bgcol; - } - line_addr += stride; - } -} - -void gfx_putchar(int ch) -{ - if(ch != '\n' && ch != '\b') - { - gfx_drawchar(cursor_x, cursor_y, ch); - cursor_x += FONT_WIDTH; - if(cursor_x >= fb_width) - { - cursor_x = 0; - cursor_y += FONT_HEIGHT; - if(cursor_y >= fb_height) - { - gfx_clear(); - cursor_y = 0; - } - } - } - else if(ch == '\n') - { - cursor_x = 0; - cursor_y += FONT_HEIGHT; - if(cursor_y >= fb_height) - { - gfx_clear(); - cursor_y = 0; - } - } - else if(ch == '\b') - { - int temp_x = cursor_x - FONT_WIDTH; - if(temp_x >= 0) - cursor_x = temp_x; - gfx_drawchar_bg(cursor_x, cursor_y, ' '); - } -} - -void gfx_puts(const char* str) -{ - while(*str) - { - gfx_putchar(*str++); - } -} - -/* implemented in assembly now */ -void gfx_hline_checked(int x1, int x2, int y) -{ - /* make sure x1 is to the left of x2 */ - if(x2 < x1) - { - int temp = x1; - x1 = x2; - x2 = temp; - } - - x1 = MAX(0, x1); - x2 = MIN(x2, fb_width); - - if(0 <= y && y < fb_height) - { - - uint8_t *base = framebuffer + y * fb_stride; - - uint8_t *dest = base + x1 * fb_bpp; - uint8_t *stop = base + x2 * fb_bpp; - const uint32_t col = _gfx_fgcol; - while(dest < stop) - { - *(uint32_t*)dest = col; - dest += fb_bpp; - } - } -} - -void gfx_vline_checked(int y1, int y2, int x) -{ - /* make sure y1 is above y2 */ - if(y2 < y1) - { - int temp = y1; - y1 = y2; - y2 = temp; - } - - y1 = MAX(0, y1); - y2 = MIN(y2, fb_height); - - if(0 <= x && x < fb_width) - { - uint8_t *dest = framebuffer + y1 * fb_stride + x * fb_bpp; - uint8_t *stop = framebuffer + y2 * fb_stride + x * fb_bpp; - const uint32_t col = _gfx_fgcol; - const uint16_t stride = fb_stride; - while(dest < stop) - { - *(uint32_t*)dest = col; - dest += stride; - } - } -} - -void gfx_fillrect(int x, int y, int w, int h) -{ - for(int i = 0; i < h; ++i) - { - gfx_hline(x, x + w, y + i); - } -} - -void gfx_drawline(int x1, int y1, int x2, int y2) -{ - int dx = abs(x2 - x1); - int sx = x1 < x2 ? 1 : -1; - int dy = -abs(y2 - y1); - int sy = y1 < y2 ? 1 : -1; - int err = dx + dy; - int e2; /* error value e_xy */ - - while(1) - { - gfx_drawpixel(x1, y1); - if (x1 == x2 && y1 == y2) - break; - e2 = err << 1; - if (e2 >= dy) - { - err += dy; - x1 += sx; - } - if (e2 <= dx) - { - err += dx; - y1 += sy; - } - } -} - -void gfx_drawcircle(int cx, int cy, int r) -{ - int d = 3 - (r * 2); - int x = 0; - int y = r; - while(x <= y) - { - gfx_drawpixel(cx + x, cy + y); - gfx_drawpixel(cx - x, cy + y); - gfx_drawpixel(cx + x, cy - y); - gfx_drawpixel(cx - x, cy - y); - gfx_drawpixel(cx + y, cy + x); - gfx_drawpixel(cx - y, cy + x); - gfx_drawpixel(cx + y, cy - x); - gfx_drawpixel(cx - y, cy - x); - if(d < 0) - { - d += (x * 4) + 6; - } - else - { - d += ((x - y) * 4) + 10; - --y; - } - ++x; - } -} - -void gfx_fillcircle(int cx, int cy, int r) -{ - int d = 3 - (r * 2); - int x = 0; - int y = r; - while(x <= y) - { - gfx_hline(cx - x, cx + x, cy + y); - gfx_hline(cx - x, cx + x, cy - y); - gfx_hline(cx - y, cx + y, cy + x); - gfx_hline(cx - y, cx + y, cy - x); - if(d < 0) - { - d += (x * 4) + 6; - } - else - { - d += ((x - y) * 4) + 10; - --y; - } - ++x; - } -} - -/* these next two functions were taken directly from the Rockbox project's XLCD - * library. - * Copyright (C) 2005 Jens Arnold */ - -/* sort the given coordinates by increasing x value */ -static void sort_points_by_increasing_y(int* y1, int* x1, - int* y2, int* x2, - int* y3, int* x3) -{ - int x, y; - if (*x1 > *x3) - { - if (*x2 < *x3) /* x2 < x3 < x1 */ - { - x = *x1; *x1 = *x2; *x2 = *x3; *x3 = x; - y = *y1; *y1 = *y2; *y2 = *y3; *y3 = y; - } - else if (*x2 > *x1) /* x3 < x1 < x2 */ - { - x = *x1; *x1 = *x3; *x3 = *x2; *x2 = x; - y = *y1; *y1 = *y3; *y3 = *y2; *y2 = y; - } - else /* x3 <= x2 <= x1 */ - { - x = *x1; *x1 = *x3; *x3 = x; - y = *y1; *y1 = *y3; *y3 = y; - } - } - else - { - if (*x2 < *x1) /* x2 < x1 <= x3 */ - { - x = *x1; *x1 = *x2; *x2 = x; - y = *y1; *y1 = *y2; *y2 = y; - } - else if (*x2 > *x3) /* x1 <= x3 < x2 */ - { - x = *x2; *x2 = *x3; *x3 = x; - y = *y2; *y2 = *y3; *y3 = y; - } - /* else already sorted */ - } -} - -/* draw a filled triangle, using horizontal lines for speed */ -void gfx_filltriangle(int x1, int y1, - int x2, int y2, - int x3, int y3) -{ - long fp_x1, fp_x2, fp_dx1, fp_dx2; - int y; - sort_points_by_increasing_y(&x1, &y1, &x2, &y2, &x3, &y3); - - if (y1 < y3) /* draw */ - { - fp_dx1 = ((x3 - x1) << 16) / (y3 - y1); - fp_x1 = (x1 << 16) + (1<<15) + (fp_dx1 >> 1); - - if (y1 < y2) /* first part */ - { - fp_dx2 = ((x2 - x1) << 16) / (y2 - y1); - fp_x2 = (x1 << 16) + (1<<15) + (fp_dx2 >> 1); - for (y = y1; y < y2; y++) - { - gfx_hline(fp_x1 >> 16, fp_x2 >> 16, y); - fp_x1 += fp_dx1; - fp_x2 += fp_dx2; - } - } - if (y2 < y3) /* second part */ - { - fp_dx2 = ((x3 - x2) << 16) / (y3 - y2); - fp_x2 = (x2 << 16) + (1<<15) + (fp_dx2 >> 1); - for (y = y2; y < y3; y++) - { - gfx_hline(fp_x1 >> 16, fp_x2 >> 16, y); - fp_x1 += fp_dx1; - fp_x2 += fp_dx2; - } - } - } -} - -static void gfx_bitmap32(int x, int y, const struct bitmap_t *bmp) -{ - /* SLOOW */ - uint8_t *data = bmp->data; - for(unsigned int i = y; i < y + bmp->h && i < fb_height; ++i) - { - for(unsigned int j = x; j < x + bmp->w && j < fb_width; ++j) - { - uint8_t r = *data++; - uint8_t g = *data++; - uint8_t b = *data++; - gfx_set_foreground(VGA_RGBPACK(r, g, b)); - gfx_drawpixel(j, i); - } - } -} - -void gfx_bitmap(int x, int y, const struct bitmap_t *bmp) -{ - gfx_bitmap32(x, y, bmp); -} - -void gfx_drawrect(int x, int y, int w, int h) -{ - gfx_hline(MAX(0, x), MIN(x + w, fb_width), MAX(0, y)); - gfx_hline(MAX(0, x), MIN(x + w, fb_width), MIN(y + h, fb_height)); - gfx_vline(MAX(0, y), MIN(y + h, fb_height),MAX(0, x)); - gfx_vline(MAX(0, y), MIN(y + h, fb_height),MIN(x + w, fb_width)); -} - -void gfx_update(void) -{ - memcpy(real_framebuffer, framebuffer, fb_height * fb_stride); -} - -void gfx_set_doublebuffer(bool yesno) -{ - if(yesno) - framebuffer = temp_framebuffer; - else - framebuffer = real_framebuffer; -} - -bool gfx_get_doublebuffer(void) -{ - if(framebuffer == temp_framebuffer) - return true; - else - return false; -} - -void gfx_putsxy(int x, int y, const char* str) -{ - while(*str) - { - gfx_drawchar(x, y, *str); - x += FONT_WIDTH; - str++; - } -} - -void gfx_putsxy_bg(int x, int y, const char* str) -{ - while(*str) - { - gfx_drawchar_bg(x, y, *str); - x += FONT_WIDTH; - str++; - } -} - -bool gfx_init(struct vbe_info_t *vbe_mode_info) -{ - real_framebuffer = (uint8_t*)vbe_mode_info->physbase; - gfx_set_doublebuffer(false); - fb_width = vbe_mode_info->Xres; - fb_height = vbe_mode_info->Yres; - fb_bpp = vbe_mode_info->bpp / 8; - fb_stride = vbe_mode_info->pitch; - fb_stride32 = fb_stride / sizeof(uint32_t); - gfx_hline = gfx_hline_checked; - gfx_vline = gfx_vline_checked; - temp_framebuffer = malloc(fb_height * fb_stride); - if(fb_bpp != 4) - { - printf("WARNING: BPP != 32, falling back to text mode...\n"); - return false; - } - else - { - extern void gfx_drawpixel_32bpp(int, int); - gfx_drawpixel = &gfx_drawpixel_32bpp; - } - - set_putchar(gfx_putchar); - set_puts(gfx_puts); - - /* A bit of fragile code here... don't call gfx_reset() before setting gfx_clear! */ - - if(fb_stride != fb_bpp * fb_width) - { - gfx_clear = &gfx_clear_unpacked; - gfx_reset(); - printf("WARNING: Internal framebuffer padding detected, support is experimental.\n"); - } - else - { - /* assembly */ - extern void gfx_clear_packed(void); - gfx_clear = &gfx_clear_packed; - gfx_reset(); - } - - printf("Real FB addr: 0x%x\n", (uint32_t)real_framebuffer); - - return true; -} diff --git a/drivers/include/gfx.h b/drivers/include/gfx.h deleted file mode 100644 index 5e97100..0000000 --- a/drivers/include/gfx.h +++ /dev/null @@ -1,105 +0,0 @@ -#ifndef _GFX_H_ -#define _GFX_H_ - -#include -#include - -enum vga_color_t { - VGA_BLACK = 0, - VGA_BLUE = 1, - VGA_GREEN = 2, - VGA_CYAN = 3, - VGA_RED = 4, - VGA_MAGENTA = 5, - VGA_BROWN = 6, - VGA_LIGHT_GRAY = 7, - VGA_DARK_GRAY = 8, - VGA_LIGHT_BLUE = 9, - VGA_LIGHT_GREEN = 10, - VGA_LIGHT_CYAN = 11, - VGA_LIGHT_RED = 12, - VGA_LIGHT_MAGENTA = 13, - VGA_LIGHT_BROWN = 14, - VGA_WHITE = 15 -}; - -#define VGA_WIDTH 80 -#define VGA_HEIGHT 25 - -#define VGA_MAKE_COLOR(fg, bg) (fg | bg << 4) -#define VGA_MAKE_ENTRY(ch, col) (((uint16_t)ch)|((uint16_t)col<<8)) -#define VGA_RGBPACK(r, g, b) ((r << 16)|(g << 8)|(b << 0)) - -#define GFX_WHITE 0xFFFFFF -#define GFX_BLACK 0x000000 - -struct vbe_info_t; - -bool gfx_init(struct vbe_info_t *vbe_mode_info); - -extern void (*gfx_drawpixel)(int x, int y); - -/* transparent background */ -void gfx_drawchar(int x, int y, int ch); - -/* fills the background with bgcolor */ -void gfx_drawchar_bg(int x, int y, int ch); - -void gfx_putchar(int ch); - -void gfx_puts(const char* str); - -/* this function can be different from resolution to resolution */ -extern void (*gfx_clear)(void); - -void gfx_reset(void); - -void gfx_set_foreground(uint32_t); - -uint32_t gfx_get_foreground(void); - -void gfx_set_background(uint32_t); - -uint32_t gfx_get_background(void); - -void (*gfx_hline)(int x1, int x2, int y); - -void (*gfx_vline)(int y1, int y2, int x); - -void gfx_fillrect(int x1, int y1, int w, int h); - -void gfx_drawline(int x1, int y1, int x2, int y2); - -/* these circle algorithms are very fast */ -void gfx_drawcircle(int cx, int cy, int rad); - -void gfx_fillcircle(int cx, int cy, int rad); - -void gfx_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3); - -extern const uint16_t *gfx_width, *gfx_height; - -/* this is _BYTES_ per pixel, NOT BITS per pixel! */ -extern const uint8_t *gfx_bpp; - -struct bitmap_t { - unsigned int w, h; - unsigned int bpp; - uint8_t *data; -}; - -void gfx_bitmap(int x, int y, const struct bitmap_t*); - -void gfx_drawrect(int x, int y, int w, int h); - -void gfx_set_doublebuffer(bool); - -bool gfx_get_doublebuffer(void); - -/* don't call this wo/ double buffering! */ -void gfx_update(void); - -void gfx_putsxy(int, int, const char*); - -void gfx_putsxy_bg(int, int, const char*); -#endif diff --git a/drivers/include/gfx_font.h b/drivers/include/gfx_font.h deleted file mode 100644 index f7db9d7..0000000 --- a/drivers/include/gfx_font.h +++ /dev/null @@ -1,4 +0,0 @@ -#include -#define FONT_WIDTH 8 -#define FONT_HEIGHT 12 -extern const uint8_t gfx_font[][FONT_HEIGHT]; diff --git a/drivers/include/pcspkr.h b/drivers/include/pcspkr.h deleted file mode 100644 index 84e640f..0000000 --- a/drivers/include/pcspkr.h +++ /dev/null @@ -1,3 +0,0 @@ -#include - -void pcspkr_play(uint32_t freq); diff --git a/drivers/include/ps2_keymaps.h b/drivers/include/ps2_keymaps.h deleted file mode 100644 index 0e8ae26..0000000 --- a/drivers/include/ps2_keymaps.h +++ /dev/null @@ -1,39 +0,0 @@ -#include - -#define EXTENDED_SCANCODE 0xE0 - -#define ERROR_KEY 0 -#define PRINTING_KEY 1 -#define SPECIAL_KEY 2 - -#define SPECIAL_NONE 0 -#define SPECIAL_SHIFT 1 -#define SPECIAL_CTRL 2 -#define SPECIAL_BKSP 3 -#define SPECIAL_ALT 4 -#define SPECIAL_GUI 5 -#define SPECIAL_NUMLOCK 6 -#define SPECIAL_CAPLOCK 7 -#define SPECIAL_SCRLLOCK 8 -#define SPECIAL_UPARROW 9 -#define SPECIAL_DNARROW 10 -#define SPECIAL_LFTARROW 11 -#define SPECIAL_RTARROW 12 -#define SPECIAL_ESC 13 -#define SPECIAL_F1 21 -#define SPECIAL_F2 22 -#define SPECIAL_F3 23 -#define SPECIAL_F4 24 -#define SPECIAL_F5 25 -#define SPECIAL_F6 26 -#define SPECIAL_F7 27 -#define SPECIAL_F8 28 -#define SPECIAL_F9 29 -#define SPECIAL_F10 30 -#define SPECIAL_F11 31 -#define SPECIAL_F12 32 - -extern uint8_t ps2_set1_scancodes[128]; -extern char ps2_set1_ascii[128]; -extern char ps2_set1_shift[128]; -extern uint8_t ps2_set1_special[128]; diff --git a/drivers/include/ps2kbd.h b/drivers/include/ps2kbd.h deleted file mode 100644 index 9e353ee..0000000 --- a/drivers/include/ps2kbd.h +++ /dev/null @@ -1,66 +0,0 @@ -/* this is both a PS/2 keyboard AND a PS/2 MOUSE driver */ -#ifndef _PS2KBD_H_ -#define _PS2KBD_H_ - -#include -#include - -#define PS2_SCROLL_LOCK (1 << 0) -#define PS2_NUM_LOCK (1 << 1) -#define PS2_CAPS_LOCK (1 << 2) - -#define BUTTON_UP (1 << 0) -#define BUTTON_LEFT (1 << 1) -#define BUTTON_DOWN (1 << 2) -#define BUTTON_RIGHT (1 << 3) - -#define MODIFIER_NONE 0 -#define MODIFIER_SHIFT (1 << 0) -#define MODIFIER_CTRL (1 << 1) -#define MODIFIER_ALT (1 << 2) - -struct ps2_specialkeys_t { - int shift :1; - int ctrl :1; - int bksp :1; - int alt :1; - int gui :1; - int numlock :1; - int capslock :1; - int scrllock :1; - int uparrow :1; - int downarrow :1; - int leftarrow :1; - int rightarrow :1; - int esc :1; - int f1 :1; - int f2 :1; - int f3 :1; - int f4 :1; - int f5 :1; - int f6 :1; - int f7 :1; - int f8 :1; - int f9 :1; - int f10 :1; - int f11 :1; - int f12 :1; -}; - -struct ps2_keyevent { - const struct ps2_specialkeys_t *special_keys; - char ascii; -}; - -/* returns which arrow keys are down */ -uint8_t ps2kbd_button_get(void); - -uint8_t ps2kbd_modifier_get(void); - -void ps2kbd_set_leds(uint8_t status); - -void ps2kbd_set_handler(void (*h)(const struct ps2_keyevent*)); - -void ps2kbd_init(void); - -#endif diff --git a/drivers/include/vgatext.h b/drivers/include/vgatext.h deleted file mode 100644 index 1cfe4c4..0000000 --- a/drivers/include/vgatext.h +++ /dev/null @@ -1,9 +0,0 @@ -#include - -void vgatext_init(void); -void vgatext_clear(void); -void vgatext_set_color(uint8_t); -uint8_t vgatext_get_color(void); -void vgatext_putchar_at(int ch, uint8_t color, int x, int y); -void vgatext_putchar(int ch); -void vgatext_puts(const char*); diff --git a/drivers/pcspkr.c b/drivers/pcspkr.c deleted file mode 100644 index 33c0540..0000000 --- a/drivers/pcspkr.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "io.h" -#include "pcspkr.h" - -void pcspkr_play(uint32_t freq) -{ - uint32_t div; - uint8_t tmp; - - div = 1193180 / freq; - outb(0x43, 0xb6); - outb(0x42, (uint8_t)(div)); - outb(0x42, (uint8_t)(div >> 8)); - - tmp = inb(0x61); - if (tmp != (tmp | 3)) { - outb(0x61, tmp | 3); - } -} diff --git a/drivers/ps2kbd.c b/drivers/ps2kbd.c deleted file mode 100644 index 29d02dc..0000000 --- a/drivers/ps2kbd.c +++ /dev/null @@ -1,212 +0,0 @@ -/* this is a PS/2 keyboard driver */ -#include -#include -#include -#include "io.h" -#include "isr.h" -#include "ps2kbd.h" -#include "ps2_keymaps.h" - -static void ps2_wait(void) -{ - /* wait for the keyboard */ - while(1) - if ((inb(0x64) & 2) == 0) break; -} - -void ps2kbd_set_leds(uint8_t status) -{ - ps2_wait(); - outb(0x60, 0xED); - outb(0x60, status); -} - -#define IDX_UP 0 -#define IDX_LEFT 1 -#define IDX_DOWN 2 -#define IDX_RIGHT 3 - -static uint8_t ps2_arrowkeys[4]; - -uint8_t ps2kbd_button_get(void) -{ - uint8_t ret = 0; - if(ps2_arrowkeys[IDX_UP]) - ret |= BUTTON_UP; - if(ps2_arrowkeys[IDX_LEFT]) - ret |= BUTTON_LEFT; - if(ps2_arrowkeys[IDX_DOWN]) - ret |= BUTTON_DOWN; - if(ps2_arrowkeys[IDX_RIGHT]) - ret |= BUTTON_RIGHT; - return ret; -} - -static uint8_t ps2_ctrl; -static uint8_t ps2_shift; -static uint8_t ps2_alt; - -uint8_t ps2kbd_modifier_get(void) -{ - uint8_t ret = 0; - if(ps2_ctrl) - ret |= MODIFIER_CTRL; - if(ps2_shift) - ret |= MODIFIER_SHIFT; - if(ps2_alt) - ret |= MODIFIER_ALT; - return ret; -} - -static struct ps2_specialkeys_t special_keys; - -static void handle_special_key(uint8_t scancode, int release) -{ - int press = ~release; - switch(ps2_set1_special[scancode]) - { - case SPECIAL_SHIFT: - special_keys.shift = press; - break; - case SPECIAL_CTRL: - special_keys.ctrl = press; - break; - case SPECIAL_BKSP: - special_keys.bksp = press; - break; - case SPECIAL_ALT: - special_keys.alt = press; - break; - case SPECIAL_NUMLOCK: - special_keys.numlock = ~special_keys.numlock; - ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); - break; - case SPECIAL_CAPLOCK: - special_keys.capslock = ~special_keys.capslock; - ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); - break; - case SPECIAL_SCRLLOCK: - special_keys.scrllock = ~special_keys.scrllock; - ps2kbd_set_leds((special_keys.capslock << 2) | (special_keys.numlock << 1) | special_keys.scrllock); - break; - case SPECIAL_ESC: - special_keys.esc = press; - break; - case SPECIAL_F1: - special_keys.f1 = press; - break; - case SPECIAL_F2: - special_keys.f2 = press; - break; - case SPECIAL_F3: - special_keys.f3 = press; - break; - case SPECIAL_F4: - special_keys.f4 = press; - break; - case SPECIAL_F5: - special_keys.f5 = press; - break; - case SPECIAL_F6: - special_keys.f6 = press; - break; - case SPECIAL_F7: - special_keys.f7 = press; - break; - case SPECIAL_F8: - special_keys.f8 = press; - break; - case SPECIAL_F9: - special_keys.f9 = press; - break; - case SPECIAL_F10: - special_keys.f10 = press; - break; - case SPECIAL_F11: - special_keys.f11 = press; - break; - case SPECIAL_F12: - special_keys.f12 = press; - break; - } -} - -static void handle_extended_scancode(void) -{ - uint8_t temp = inb(0x60); - (void) temp; - //printf("Extended scancode: 0x%x\n", temp); -} - -void (*keyevent_handler)(const struct ps2_keyevent*); - -static void key_handler(struct regs_t *regs) -{ - (void) regs; - uint8_t scancode = inb(0x60); - //printf("INTR SCAN: 0x%x\n", scancode); - if(scancode == EXTENDED_SCANCODE) - { - handle_extended_scancode(); - return; - } - - /* AND by 0x7F to get in the range of [0,128) */ - - int type = ps2_set1_scancodes[scancode & 0x7F]; - int release = (scancode & (1<<7)) >> 7; - char ascii = '\0'; - switch(type) - { - case PRINTING_KEY: - { - if(!release) - { - int capitals = special_keys.capslock; - if(special_keys.shift) - capitals = ~capitals; - if(capitals) - ascii = ps2_set1_shift[scancode]; - else - ascii = ps2_set1_ascii[scancode]; - } - break; - } - case SPECIAL_KEY: - handle_special_key(scancode & 0x7F, release); - break; - } - if(special_keys.bksp) - ascii = '\b'; - if(keyevent_handler) - { - struct ps2_keyevent ev; - ev.special_keys = &special_keys; - ev.ascii = ascii; - keyevent_handler(&ev); - } -} - -static void ps2_set_scancode_set(uint8_t set) -{ - ps2_wait(); - outb(0x60, 0xF0); - outb(0x60, set); -} - -static void keyboard_init(void) -{ - set_interrupt_handler(IRQ(1), key_handler); - ps2_set_scancode_set(1); - memset(&special_keys, 0, sizeof(special_keys)); -} - -void ps2kbd_set_handler(void (*handler)(const struct ps2_keyevent*)) -{ - keyevent_handler = handler; -} - -void ps2kbd_init(void) -{ - keyboard_init(); -} diff --git a/drivers/vgatext.c b/drivers/vgatext.c deleted file mode 100644 index d0633af..0000000 --- a/drivers/vgatext.c +++ /dev/null @@ -1,124 +0,0 @@ -#include -#include -#include "gfx.h" -#include "io.h" -#include "panic.h" -#include "vgatext.h" - -static int term_x, term_y; -static uint8_t term_col; -/* VGA buffer starts at 0xB8000 on color or 0xB0000 on monochrome */ -static uint16_t *term_buf; - -static uint16_t video_detect_hardware(void) -{ - const uint16_t *ptr = (const uint16_t*)0x410; - return *ptr; -} - -void vgatext_init(void) -{ - uint16_t vid_type = video_detect_hardware() & 0x30; - if(vid_type == 0x20) - { - /* color */ - term_buf = (uint16_t*)0xB8000; - } - else if(vid_type == 0x30) - { - term_buf = (uint16_t*)0xB0000; - } - else - { - /* none */ - panic("VGATEXT init failed!"); - } - vgatext_set_color(VGA_MAKE_COLOR(VGA_LIGHT_GRAY, VGA_BLACK)); - vgatext_clear(); - set_putchar(vgatext_putchar); - set_puts(vgatext_puts); -} - -static void move_cursor(uint16_t cursor_idx) -{ - outb(0x3D4, 14); - outb(0x3D5, cursor_idx >> 8); // high byte - outb(0x3D4, 15); - outb(0x3D5, cursor_idx); // low byte -} - -static void update_cursor(void) -{ - move_cursor(term_y * VGA_WIDTH + term_x); -} - -void vgatext_clear(void) -{ - term_x = 0; - term_y = 0; - for(int y = 0; y < VGA_HEIGHT; ++y) - { - for(int x = 0; x < VGA_WIDTH; ++x) - { - term_buf[y * VGA_WIDTH + x] = VGA_MAKE_ENTRY(' ', term_col); - } - } -} - -void vgatext_set_color(uint8_t color) -{ - term_col = color; -} - -uint8_t vgatext_get_color(void) -{ - return term_col; -} - -void vgatext_putchar_at(int ch, uint8_t col, int x, int y) -{ - term_buf[y * VGA_WIDTH + x] = VGA_MAKE_ENTRY((char)ch, col); -} - -void vgatext_putchar(int ch) -{ - if(ch != '\n' && ch != '\b') - { - vgatext_putchar_at(ch, term_col, term_x, term_y); - if(++term_x == VGA_WIDTH) - { - term_x = 0; - if(++term_y == VGA_HEIGHT) - { - vgatext_clear(); - term_y = 0; - } - } - } - else if(ch == '\n') - { - term_x = 0; - if(++term_y == VGA_HEIGHT) - { - vgatext_clear(); - term_y = 0; - } - } - else if(ch == '\b') - { - int temp_x = term_x - 1; - if(temp_x >= 0) - term_x = temp_x; - vgatext_putchar_at(' ', term_col, term_x, term_y); - } - - update_cursor(); -} - -void vgatext_puts(const char *str) -{ - while(*str) - { - vgatext_putchar(*str++); - } -} diff --git a/include/arch/i686/drivers/gfx.h b/include/arch/i686/drivers/gfx.h new file mode 100644 index 0000000..5e97100 --- /dev/null +++ b/include/arch/i686/drivers/gfx.h @@ -0,0 +1,105 @@ +#ifndef _GFX_H_ +#define _GFX_H_ + +#include +#include + +enum vga_color_t { + VGA_BLACK = 0, + VGA_BLUE = 1, + VGA_GREEN = 2, + VGA_CYAN = 3, + VGA_RED = 4, + VGA_MAGENTA = 5, + VGA_BROWN = 6, + VGA_LIGHT_GRAY = 7, + VGA_DARK_GRAY = 8, + VGA_LIGHT_BLUE = 9, + VGA_LIGHT_GREEN = 10, + VGA_LIGHT_CYAN = 11, + VGA_LIGHT_RED = 12, + VGA_LIGHT_MAGENTA = 13, + VGA_LIGHT_BROWN = 14, + VGA_WHITE = 15 +}; + +#define VGA_WIDTH 80 +#define VGA_HEIGHT 25 + +#define VGA_MAKE_COLOR(fg, bg) (fg | bg << 4) +#define VGA_MAKE_ENTRY(ch, col) (((uint16_t)ch)|((uint16_t)col<<8)) +#define VGA_RGBPACK(r, g, b) ((r << 16)|(g << 8)|(b << 0)) + +#define GFX_WHITE 0xFFFFFF +#define GFX_BLACK 0x000000 + +struct vbe_info_t; + +bool gfx_init(struct vbe_info_t *vbe_mode_info); + +extern void (*gfx_drawpixel)(int x, int y); + +/* transparent background */ +void gfx_drawchar(int x, int y, int ch); + +/* fills the background with bgcolor */ +void gfx_drawchar_bg(int x, int y, int ch); + +void gfx_putchar(int ch); + +void gfx_puts(const char* str); + +/* this function can be different from resolution to resolution */ +extern void (*gfx_clear)(void); + +void gfx_reset(void); + +void gfx_set_foreground(uint32_t); + +uint32_t gfx_get_foreground(void); + +void gfx_set_background(uint32_t); + +uint32_t gfx_get_background(void); + +void (*gfx_hline)(int x1, int x2, int y); + +void (*gfx_vline)(int y1, int y2, int x); + +void gfx_fillrect(int x1, int y1, int w, int h); + +void gfx_drawline(int x1, int y1, int x2, int y2); + +/* these circle algorithms are very fast */ +void gfx_drawcircle(int cx, int cy, int rad); + +void gfx_fillcircle(int cx, int cy, int rad); + +void gfx_filltriangle(int x1, int y1, int x2, int y2, int x3, int y3); + +extern const uint16_t *gfx_width, *gfx_height; + +/* this is _BYTES_ per pixel, NOT BITS per pixel! */ +extern const uint8_t *gfx_bpp; + +struct bitmap_t { + unsigned int w, h; + unsigned int bpp; + uint8_t *data; +}; + +void gfx_bitmap(int x, int y, const struct bitmap_t*); + +void gfx_drawrect(int x, int y, int w, int h); + +void gfx_set_doublebuffer(bool); + +bool gfx_get_doublebuffer(void); + +/* don't call this wo/ double buffering! */ +void gfx_update(void); + +void gfx_putsxy(int, int, const char*); + +void gfx_putsxy_bg(int, int, const char*); +#endif diff --git a/include/arch/i686/drivers/gfx_font.h b/include/arch/i686/drivers/gfx_font.h new file mode 100644 index 0000000..f7db9d7 --- /dev/null +++ b/include/arch/i686/drivers/gfx_font.h @@ -0,0 +1,4 @@ +#include +#define FONT_WIDTH 8 +#define FONT_HEIGHT 12 +extern const uint8_t gfx_font[][FONT_HEIGHT]; diff --git a/include/arch/i686/drivers/pcspkr.h b/include/arch/i686/drivers/pcspkr.h new file mode 100644 index 0000000..84e640f --- /dev/null +++ b/include/arch/i686/drivers/pcspkr.h @@ -0,0 +1,3 @@ +#include + +void pcspkr_play(uint32_t freq); diff --git a/include/arch/i686/drivers/ps2_keymaps.h b/include/arch/i686/drivers/ps2_keymaps.h new file mode 100644 index 0000000..0e8ae26 --- /dev/null +++ b/include/arch/i686/drivers/ps2_keymaps.h @@ -0,0 +1,39 @@ +#include + +#define EXTENDED_SCANCODE 0xE0 + +#define ERROR_KEY 0 +#define PRINTING_KEY 1 +#define SPECIAL_KEY 2 + +#define SPECIAL_NONE 0 +#define SPECIAL_SHIFT 1 +#define SPECIAL_CTRL 2 +#define SPECIAL_BKSP 3 +#define SPECIAL_ALT 4 +#define SPECIAL_GUI 5 +#define SPECIAL_NUMLOCK 6 +#define SPECIAL_CAPLOCK 7 +#define SPECIAL_SCRLLOCK 8 +#define SPECIAL_UPARROW 9 +#define SPECIAL_DNARROW 10 +#define SPECIAL_LFTARROW 11 +#define SPECIAL_RTARROW 12 +#define SPECIAL_ESC 13 +#define SPECIAL_F1 21 +#define SPECIAL_F2 22 +#define SPECIAL_F3 23 +#define SPECIAL_F4 24 +#define SPECIAL_F5 25 +#define SPECIAL_F6 26 +#define SPECIAL_F7 27 +#define SPECIAL_F8 28 +#define SPECIAL_F9 29 +#define SPECIAL_F10 30 +#define SPECIAL_F11 31 +#define SPECIAL_F12 32 + +extern uint8_t ps2_set1_scancodes[128]; +extern char ps2_set1_ascii[128]; +extern char ps2_set1_shift[128]; +extern uint8_t ps2_set1_special[128]; diff --git a/include/arch/i686/drivers/ps2kbd.h b/include/arch/i686/drivers/ps2kbd.h new file mode 100644 index 0000000..9e353ee --- /dev/null +++ b/include/arch/i686/drivers/ps2kbd.h @@ -0,0 +1,66 @@ +/* this is both a PS/2 keyboard AND a PS/2 MOUSE driver */ +#ifndef _PS2KBD_H_ +#define _PS2KBD_H_ + +#include +#include + +#define PS2_SCROLL_LOCK (1 << 0) +#define PS2_NUM_LOCK (1 << 1) +#define PS2_CAPS_LOCK (1 << 2) + +#define BUTTON_UP (1 << 0) +#define BUTTON_LEFT (1 << 1) +#define BUTTON_DOWN (1 << 2) +#define BUTTON_RIGHT (1 << 3) + +#define MODIFIER_NONE 0 +#define MODIFIER_SHIFT (1 << 0) +#define MODIFIER_CTRL (1 << 1) +#define MODIFIER_ALT (1 << 2) + +struct ps2_specialkeys_t { + int shift :1; + int ctrl :1; + int bksp :1; + int alt :1; + int gui :1; + int numlock :1; + int capslock :1; + int scrllock :1; + int uparrow :1; + int downarrow :1; + int leftarrow :1; + int rightarrow :1; + int esc :1; + int f1 :1; + int f2 :1; + int f3 :1; + int f4 :1; + int f5 :1; + int f6 :1; + int f7 :1; + int f8 :1; + int f9 :1; + int f10 :1; + int f11 :1; + int f12 :1; +}; + +struct ps2_keyevent { + const struct ps2_specialkeys_t *special_keys; + char ascii; +}; + +/* returns which arrow keys are down */ +uint8_t ps2kbd_button_get(void); + +uint8_t ps2kbd_modifier_get(void); + +void ps2kbd_set_leds(uint8_t status); + +void ps2kbd_set_handler(void (*h)(const struct ps2_keyevent*)); + +void ps2kbd_init(void); + +#endif diff --git a/include/arch/i686/drivers/vgatext.h b/include/arch/i686/drivers/vgatext.h new file mode 100644 index 0000000..1cfe4c4 --- /dev/null +++ b/include/arch/i686/drivers/vgatext.h @@ -0,0 +1,9 @@ +#include + +void vgatext_init(void); +void vgatext_clear(void); +void vgatext_set_color(uint8_t); +uint8_t vgatext_get_color(void); +void vgatext_putchar_at(int ch, uint8_t color, int x, int y); +void vgatext_putchar(int ch); +void vgatext_puts(const char*); diff --git a/include/arch/i686/fpu.h b/include/arch/i686/fpu.h new file mode 100644 index 0000000..0eb448a --- /dev/null +++ b/include/arch/i686/fpu.h @@ -0,0 +1,2 @@ +void fpu_enable(void); +void fpu_disable(void); diff --git a/include/arch/i686/gdt.h b/include/arch/i686/gdt.h new file mode 100644 index 0000000..4cf7c4f --- /dev/null +++ b/include/arch/i686/gdt.h @@ -0,0 +1,23 @@ +#include + +struct gdt_entry { + uint16_t limit_low; + uint16_t base_low; + uint8_t base_middle; + uint8_t access; + uint8_t granularity; + uint8_t base_high; +} __attribute__((packed)); + +struct gdt_ptr { + uint16_t limit; + uint32_t base; +} __attribute__((packed)); + +struct gdt_entry gdt[3]; +struct gdt_ptr gp; + +/* assembly */ +extern void gdt_flush(uint32_t); + +void gdt_init(void); diff --git a/include/arch/i686/idt.h b/include/arch/i686/idt.h new file mode 100644 index 0000000..250ab82 --- /dev/null +++ b/include/arch/i686/idt.h @@ -0,0 +1,23 @@ +#include + +struct idt_entry { + uint16_t base_lo; + uint16_t sel; + uint8_t zero; + uint8_t flags; + uint16_t base_hi; +} __attribute__((packed)); + +struct idt_ptr { + uint16_t limit; + uint32_t base; +} __attribute__((packed)); + +struct idt_entry idt[0x100]; +struct idt_ptr idt_pt; + +void idt_init(void); + +extern void idt_flush(uint32_t); + +void idt_set_gate(uint8_t idx, uint32_t base, uint16_t sel, uint8_t flags); diff --git a/include/arch/i686/irq.h b/include/arch/i686/irq.h new file mode 100644 index 0000000..13461e9 --- /dev/null +++ b/include/arch/i686/irq.h @@ -0,0 +1,19 @@ +extern void _irq0(void); +extern void _irq1(void); +extern void _irq2(void); +extern void _irq3(void); +extern void _irq4(void); +extern void _irq5(void); +extern void _irq6(void); +extern void _irq7(void); +extern void _irq8(void); +extern void _irq9(void); +extern void _irq10(void); +extern void _irq11(void); +extern void _irq12(void); +extern void _irq13(void); +extern void _irq14(void); +extern void _irq15(void); +extern void _int0x80(void); + +void irq_init(void); diff --git a/include/arch/i686/isr.h b/include/arch/i686/isr.h new file mode 100644 index 0000000..4cc7f1b --- /dev/null +++ b/include/arch/i686/isr.h @@ -0,0 +1,51 @@ +#include + +/* these are all implemented in isr-as.S */ +extern void _isr0(void); +extern void _isr1(void); +extern void _isr2(void); +extern void _isr3(void); +extern void _isr4(void); +extern void _isr5(void); +extern void _isr6(void); +extern void _isr7(void); +extern void _isr8(void); +extern void _isr9(void); +extern void _isr10(void); +extern void _isr11(void); +extern void _isr12(void); +extern void _isr13(void); +extern void _isr14(void); +extern void _isr15(void); +extern void _isr16(void); +extern void _isr17(void); +extern void _isr18(void); +extern void _isr19(void); +extern void _isr20(void); +extern void _isr21(void); +extern void _isr22(void); +extern void _isr23(void); +extern void _isr24(void); +extern void _isr25(void); +extern void _isr26(void); +extern void _isr27(void); +extern void _isr28(void); +extern void _isr29(void); +extern void _isr30(void); +extern void _isr31(void); + +/* installs ISR's 0-31 */ +void isr_init(void); + +/* This defines what the stack looks like after an ISR was running */ +struct regs_t { + uint32_t gs, fs, es, ds; /* pushed the segs last */ + uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ + uint32_t int_no; /* interrupt stubs do this */ + uint32_t err_code; /* exceptions push this */ + uint32_t eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ +} __attribute__((packed)); + +#define IRQ(x) (32+x) + +void set_interrupt_handler(uint8_t interrupt, void (*func)(struct regs_t*)); diff --git a/include/arch/i686/paging.h b/include/arch/i686/paging.h new file mode 100644 index 0000000..0481069 --- /dev/null +++ b/include/arch/i686/paging.h @@ -0,0 +1,8 @@ +#define PAGE_PRESENT (1<<0) +#define PAGE_RW (1<<1) +#define PAGE_USER (1<<2) + +#define PAGE_MASK 0xFFFFF000 +#define PAGE_SIZE 0x1000 + +void paging_init(void); diff --git a/include/arch/i686/timer.h b/include/arch/i686/timer.h new file mode 100644 index 0000000..7a15949 --- /dev/null +++ b/include/arch/i686/timer.h @@ -0,0 +1,13 @@ +#include + +#define HZ 100 +#define PIT_FREQ 1193182 + +extern volatile const uint64_t *current_tick; + +struct regs_t; + +void timer_init(uint32_t freq); + +/* NOTE: enables interrupts by default */ +void timer_delay(uint64_t ticks); diff --git a/include/kernel/heap.h b/include/kernel/heap.h new file mode 100644 index 0000000..dfadf36 --- /dev/null +++ b/include/kernel/heap.h @@ -0,0 +1,5 @@ +#include +void *kmalloc(size_t); +void *kmalloc_a(size_t); +void *kmalloc_p(size_t, void**); +void *kmalloc_ap(size_t, void**); diff --git a/include/kernel/io.h b/include/kernel/io.h new file mode 100644 index 0000000..d1177ac --- /dev/null +++ b/include/kernel/io.h @@ -0,0 +1,5 @@ +#include +void outb(uint16_t port, uint8_t val); +void outw(uint16_t port, uint16_t val); +uint8_t inb(uint16_t port); +uint16_t inw(uint16_t port); diff --git a/include/kernel/log.h b/include/kernel/log.h new file mode 100644 index 0000000..1a28c0d --- /dev/null +++ b/include/kernel/log.h @@ -0,0 +1,3 @@ +void log_putchar(int); +void log_puts(const char*); +void log(const char*, ...); diff --git a/include/kernel/multiboot.h b/include/kernel/multiboot.h new file mode 100644 index 0000000..e1f7cf0 --- /dev/null +++ b/include/kernel/multiboot.h @@ -0,0 +1,90 @@ +#include + +struct multiboot_aout_symbol_table_t +{ + uint32_t tabsize; + uint32_t strsize; + uint32_t addr; + uint32_t reserved; +} __attribute__((packed)); + +struct multiboot_elf_section_header_table_t +{ + uint32_t num; + uint32_t size; + uint32_t addr; + uint32_t shndx; +} __attribute__((packed)); + +struct vbe_info_t { + uint16_t attributes; + uint8_t winA, winB; + uint16_t granularity; + uint16_t winsize; + uint16_t segmentA, segmentB; + uint32_t realFctPtr; + uint16_t pitch; + uint16_t Xres, Yres; + uint8_t Wchar, Ychar, planes, bpp, banks; + uint8_t memory_model, bank_size, image_pages; + uint8_t reserved0; + uint8_t red_mask, red_position; + uint8_t green_mask, green_position; + uint8_t blue_mask, blue_position; + uint8_t rsv_mask, rsv_position; + uint8_t directcolor_attributes; + uint32_t physbase; + uint32_t reserved1; + uint16_t reserved2; +} __attribute__((packed)); + +struct multiboot_info_t +{ + /* Multiboot info version number */ + uint32_t flags; + + /* Available memory from BIOS */ + uint32_t mem_lower; + uint32_t mem_upper; + + /* "root" partition */ + uint32_t boot_device; + + /* Kernel command line */ + uint32_t cmdline; + + /* Boot-Module list */ + uint32_t mods_count; + uint32_t mods_addr; + + union + { + struct multiboot_aout_symbol_table_t aout_sym; + struct multiboot_elf_section_header_table_t elf_sec; + } u; + + /* Memory Mapping buffer */ + uint32_t mmap_length; + uint32_t mmap_addr; + + /* Drive Info buffer */ + uint32_t drives_length; + uint32_t drives_addr; + + /* ROM configuration table */ + uint32_t config_table; + + /* Boot Loader Name */ + uint32_t boot_loader_name; + + /* APM table */ + uint32_t apm_table; + + /* Video */ + uint32_t vbe_control_info; + uint32_t vbe_mode_info; + uint16_t vbe_mode; + uint16_t vbe_interface_seg; + uint16_t vbe_interface_off; + uint16_t vbe_interface_len; +} __attribute__((packed)); diff --git a/include/kernel/panic.h b/include/kernel/panic.h new file mode 100644 index 0000000..db53e8e --- /dev/null +++ b/include/kernel/panic.h @@ -0,0 +1 @@ +void panic(const char*, ...); diff --git a/include/kernel/task.c b/include/kernel/task.c new file mode 100644 index 0000000..ecc0042 --- /dev/null +++ b/include/kernel/task.c @@ -0,0 +1,16 @@ +#include "task.h" + +void task_create(struct task_t *task, void (*func)(void), uint32_t flags, uint32_t *pagedir) +{ + task->regs.eax = 0; + task->regs.ebx = 0; + task->regs.ecx = 0; + task->regs.edx = 0; + task->regs.esi = 0; + task->regs.edi = 0; + task->regs.eflags = flags; + task->regs.eip = (uint32_t)main; + task->regs.cr3 = (uint32_t)pagedir; + task->regs.esp = kmalloc(0x1000) + 0x1000; + task->next = NULL; +} diff --git a/include/kernel/task.h b/include/kernel/task.h new file mode 100644 index 0000000..86beed3 --- /dev/null +++ b/include/kernel/task.h @@ -0,0 +1,10 @@ +#include + +struct taskregs_t { + uint32_t eax, ebx, ecx, edx, esi, edi, esp, ebp, eip, eflags, cr3; +}; + +struct task_t { + struct taskregs_t regs; + struct task_t *next; +}; diff --git a/include/kernel/version.h b/include/kernel/version.h new file mode 100644 index 0000000..8fff367 --- /dev/null +++ b/include/kernel/version.h @@ -0,0 +1,2 @@ +#define KAPPA_KERNEL_VERSION "0.0.1-alpha" +#define KAPPA_KERNEL_CODENAME "Ayatollah's Buybacks" diff --git a/include/stdio.h b/include/stdio.h new file mode 100644 index 0000000..49966cf --- /dev/null +++ b/include/stdio.h @@ -0,0 +1,7 @@ +int printf(const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));; +int puts(const char*); +int putchar(int); + +/* sets the I/O functions, allows easy switching between text mode and VBE */ +void set_putchar(void (*func)(int)); +void set_puts(void (*func)(const char*)); diff --git a/include/stdlib.h b/include/stdlib.h new file mode 100644 index 0000000..f55f0f5 --- /dev/null +++ b/include/stdlib.h @@ -0,0 +1,30 @@ +#ifndef _STDLIB_H_ +#define _STDLIB_H_ + +#include +#include +#include + +/* this is by no means standards-compliant... but who cares? :P */ + +/* NOT reentrant! */ +char* itoa(int val, int base); + +#define RAND_MAX ((1U << 31) - 1) + +#define MIN(x,y) ((xy)?x:y) + +uint64_t rand64(void); +unsigned int rand(void); +void srand(uint64_t); +int abs(int); +void *malloc(size_t); +int snprintf(char*, int, const char*, ...); +void assert_fail(const char*, const char*, int); +int toupper(int); +int tolower(int); + +#define assert(x) if(!(x))assert_fail(__func__, __FILE__, __LINE__); + +#endif diff --git a/include/string.h b/include/string.h new file mode 100644 index 0000000..05050a0 --- /dev/null +++ b/include/string.h @@ -0,0 +1,4 @@ +#include +int strlen(const char*); +void* memset(void*, int, size_t); +void* memcpy(void*, void*, size_t); diff --git a/kernel/fpu.c b/kernel/fpu.c deleted file mode 100644 index f5512d6..0000000 --- a/kernel/fpu.c +++ /dev/null @@ -1,25 +0,0 @@ -/* Copyright (C) 2011-2013 Kevin Lange */ -/* this code from toaruos */ -#include -#include "fpu.h" - -/** - * Enable the FPU and SSE - */ -void fpu_enable(void) { - asm volatile ("clts"); - size_t t; - asm volatile ("mov %%cr4, %0" : "=r"(t)); - t |= 3 << 9; - asm volatile ("mov %0, %%cr4" :: "r"(t)); -} - -/** - * Disable FPU and SSE so it traps to the kernel - */ -void fpu_disable(void) { - size_t t; - asm volatile ("mov %%cr0, %0" : "=r"(t)); - t |= 1 << 3; - asm volatile ("mov %0, %%cr0" :: "r"(t)); -} diff --git a/kernel/gdt-as.S b/kernel/gdt-as.S deleted file mode 100644 index 5a481e3..0000000 --- a/kernel/gdt-as.S +++ /dev/null @@ -1,14 +0,0 @@ - .global gdt_flush -gdt_flush: # prototype: void gdt_flush(uint32) - movl 4(%esp), %eax - lgdt (%eax) - # 0x8 is the code segment selector - jmp $0x8, $.flush -.flush: - mov $0x10, %ax # 0x10 is the data segment selector - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %ax, %ss - ret diff --git a/kernel/gdt.c b/kernel/gdt.c deleted file mode 100644 index 36a0cda..0000000 --- a/kernel/gdt.c +++ /dev/null @@ -1,34 +0,0 @@ -#include "gdt.h" - -static void gdt_set_gate(int idx, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran) -{ - /* Setup the descriptor base address */ - gdt[idx].base_low = (base & 0xFFFF); - gdt[idx].base_middle = (base >> 16) & 0xFF; - gdt[idx].base_high = (base >> 24) & 0xFF; - - /* Setup the descriptor limits */ - gdt[idx].limit_low = (limit & 0xFFFF); - gdt[idx].granularity = ((limit >> 16) & 0x0F); - - /* Finally, set up the granularity and access flags */ - gdt[idx].granularity |= (gran & 0xF0); - gdt[idx].access = access; -} - -void gdt_init(void) -{ - gp.limit = sizeof(gdt) - 1; - gp.base = (uint32_t)&gdt; - - /* null segment */ - gdt_set_gate(0, 0, 0, 0, 0); - - /* code segment */ - gdt_set_gate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF); - - /* data segment */ - gdt_set_gate(2, 0, 0xFFFFFFFF, 0x92, 0xCF); - - gdt_flush((uint32_t)&gp); -} diff --git a/kernel/idt-as.S b/kernel/idt-as.S deleted file mode 100644 index d1ab7e2..0000000 --- a/kernel/idt-as.S +++ /dev/null @@ -1,6 +0,0 @@ - .global idt_flush - .type idt_flush, @function -idt_flush: # prototype: void idt_flush(uint32) - movl 4(%esp), %eax - lidt (%eax) - ret diff --git a/kernel/idt.c b/kernel/idt.c deleted file mode 100644 index 0108991..0000000 --- a/kernel/idt.c +++ /dev/null @@ -1,24 +0,0 @@ -#include -#include -#include "idt.h" -#include "isr.h" -#include "irq.h" - -void idt_set_gate(uint8_t idx, uint32_t base, uint16_t sel, uint8_t flags) -{ - idt[idx].base_lo = base & 0xFFFF; - idt[idx].base_hi = base >> 16; - idt[idx].sel = sel; - idt[idx].zero = 0; - idt[idx].flags = flags; -} - -void idt_init(void) -{ - idt_pt.limit = sizeof(idt) - 1; - idt_pt.base = (uint32_t)&idt; - - memset(&idt, 0, sizeof(idt)); - - idt_flush((uint32_t)&idt_pt); -} diff --git a/kernel/include/fpu.h b/kernel/include/fpu.h deleted file mode 100644 index 0eb448a..0000000 --- a/kernel/include/fpu.h +++ /dev/null @@ -1,2 +0,0 @@ -void fpu_enable(void); -void fpu_disable(void); diff --git a/kernel/include/gdt.h b/kernel/include/gdt.h deleted file mode 100644 index 4cf7c4f..0000000 --- a/kernel/include/gdt.h +++ /dev/null @@ -1,23 +0,0 @@ -#include - -struct gdt_entry { - uint16_t limit_low; - uint16_t base_low; - uint8_t base_middle; - uint8_t access; - uint8_t granularity; - uint8_t base_high; -} __attribute__((packed)); - -struct gdt_ptr { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); - -struct gdt_entry gdt[3]; -struct gdt_ptr gp; - -/* assembly */ -extern void gdt_flush(uint32_t); - -void gdt_init(void); diff --git a/kernel/include/heap.h b/kernel/include/heap.h deleted file mode 100644 index dfadf36..0000000 --- a/kernel/include/heap.h +++ /dev/null @@ -1,5 +0,0 @@ -#include -void *kmalloc(size_t); -void *kmalloc_a(size_t); -void *kmalloc_p(size_t, void**); -void *kmalloc_ap(size_t, void**); diff --git a/kernel/include/idt.h b/kernel/include/idt.h deleted file mode 100644 index 250ab82..0000000 --- a/kernel/include/idt.h +++ /dev/null @@ -1,23 +0,0 @@ -#include - -struct idt_entry { - uint16_t base_lo; - uint16_t sel; - uint8_t zero; - uint8_t flags; - uint16_t base_hi; -} __attribute__((packed)); - -struct idt_ptr { - uint16_t limit; - uint32_t base; -} __attribute__((packed)); - -struct idt_entry idt[0x100]; -struct idt_ptr idt_pt; - -void idt_init(void); - -extern void idt_flush(uint32_t); - -void idt_set_gate(uint8_t idx, uint32_t base, uint16_t sel, uint8_t flags); diff --git a/kernel/include/io.h b/kernel/include/io.h deleted file mode 100644 index d1177ac..0000000 --- a/kernel/include/io.h +++ /dev/null @@ -1,5 +0,0 @@ -#include -void outb(uint16_t port, uint8_t val); -void outw(uint16_t port, uint16_t val); -uint8_t inb(uint16_t port); -uint16_t inw(uint16_t port); diff --git a/kernel/include/irq.h b/kernel/include/irq.h deleted file mode 100644 index 13461e9..0000000 --- a/kernel/include/irq.h +++ /dev/null @@ -1,19 +0,0 @@ -extern void _irq0(void); -extern void _irq1(void); -extern void _irq2(void); -extern void _irq3(void); -extern void _irq4(void); -extern void _irq5(void); -extern void _irq6(void); -extern void _irq7(void); -extern void _irq8(void); -extern void _irq9(void); -extern void _irq10(void); -extern void _irq11(void); -extern void _irq12(void); -extern void _irq13(void); -extern void _irq14(void); -extern void _irq15(void); -extern void _int0x80(void); - -void irq_init(void); diff --git a/kernel/include/isr.h b/kernel/include/isr.h deleted file mode 100644 index 4cc7f1b..0000000 --- a/kernel/include/isr.h +++ /dev/null @@ -1,51 +0,0 @@ -#include - -/* these are all implemented in isr-as.S */ -extern void _isr0(void); -extern void _isr1(void); -extern void _isr2(void); -extern void _isr3(void); -extern void _isr4(void); -extern void _isr5(void); -extern void _isr6(void); -extern void _isr7(void); -extern void _isr8(void); -extern void _isr9(void); -extern void _isr10(void); -extern void _isr11(void); -extern void _isr12(void); -extern void _isr13(void); -extern void _isr14(void); -extern void _isr15(void); -extern void _isr16(void); -extern void _isr17(void); -extern void _isr18(void); -extern void _isr19(void); -extern void _isr20(void); -extern void _isr21(void); -extern void _isr22(void); -extern void _isr23(void); -extern void _isr24(void); -extern void _isr25(void); -extern void _isr26(void); -extern void _isr27(void); -extern void _isr28(void); -extern void _isr29(void); -extern void _isr30(void); -extern void _isr31(void); - -/* installs ISR's 0-31 */ -void isr_init(void); - -/* This defines what the stack looks like after an ISR was running */ -struct regs_t { - uint32_t gs, fs, es, ds; /* pushed the segs last */ - uint32_t edi, esi, ebp, esp, ebx, edx, ecx, eax; /* pushed by 'pusha' */ - uint32_t int_no; /* interrupt stubs do this */ - uint32_t err_code; /* exceptions push this */ - uint32_t eip, cs, eflags, useresp, ss; /* pushed by the processor automatically */ -} __attribute__((packed)); - -#define IRQ(x) (32+x) - -void set_interrupt_handler(uint8_t interrupt, void (*func)(struct regs_t*)); diff --git a/kernel/include/log.h b/kernel/include/log.h deleted file mode 100644 index 1a28c0d..0000000 --- a/kernel/include/log.h +++ /dev/null @@ -1,3 +0,0 @@ -void log_putchar(int); -void log_puts(const char*); -void log(const char*, ...); diff --git a/kernel/include/multiboot.h b/kernel/include/multiboot.h deleted file mode 100644 index e1f7cf0..0000000 --- a/kernel/include/multiboot.h +++ /dev/null @@ -1,90 +0,0 @@ -#include - -struct multiboot_aout_symbol_table_t -{ - uint32_t tabsize; - uint32_t strsize; - uint32_t addr; - uint32_t reserved; -} __attribute__((packed)); - -struct multiboot_elf_section_header_table_t -{ - uint32_t num; - uint32_t size; - uint32_t addr; - uint32_t shndx; -} __attribute__((packed)); - -struct vbe_info_t { - uint16_t attributes; - uint8_t winA, winB; - uint16_t granularity; - uint16_t winsize; - uint16_t segmentA, segmentB; - uint32_t realFctPtr; - uint16_t pitch; - uint16_t Xres, Yres; - uint8_t Wchar, Ychar, planes, bpp, banks; - uint8_t memory_model, bank_size, image_pages; - uint8_t reserved0; - uint8_t red_mask, red_position; - uint8_t green_mask, green_position; - uint8_t blue_mask, blue_position; - uint8_t rsv_mask, rsv_position; - uint8_t directcolor_attributes; - uint32_t physbase; - uint32_t reserved1; - uint16_t reserved2; -} __attribute__((packed)); - -struct multiboot_info_t -{ - /* Multiboot info version number */ - uint32_t flags; - - /* Available memory from BIOS */ - uint32_t mem_lower; - uint32_t mem_upper; - - /* "root" partition */ - uint32_t boot_device; - - /* Kernel command line */ - uint32_t cmdline; - - /* Boot-Module list */ - uint32_t mods_count; - uint32_t mods_addr; - - union - { - struct multiboot_aout_symbol_table_t aout_sym; - struct multiboot_elf_section_header_table_t elf_sec; - } u; - - /* Memory Mapping buffer */ - uint32_t mmap_length; - uint32_t mmap_addr; - - /* Drive Info buffer */ - uint32_t drives_length; - uint32_t drives_addr; - - /* ROM configuration table */ - uint32_t config_table; - - /* Boot Loader Name */ - uint32_t boot_loader_name; - - /* APM table */ - uint32_t apm_table; - - /* Video */ - uint32_t vbe_control_info; - uint32_t vbe_mode_info; - uint16_t vbe_mode; - uint16_t vbe_interface_seg; - uint16_t vbe_interface_off; - uint16_t vbe_interface_len; -} __attribute__((packed)); diff --git a/kernel/include/paging.h b/kernel/include/paging.h deleted file mode 100644 index 0481069..0000000 --- a/kernel/include/paging.h +++ /dev/null @@ -1,8 +0,0 @@ -#define PAGE_PRESENT (1<<0) -#define PAGE_RW (1<<1) -#define PAGE_USER (1<<2) - -#define PAGE_MASK 0xFFFFF000 -#define PAGE_SIZE 0x1000 - -void paging_init(void); diff --git a/kernel/include/panic.h b/kernel/include/panic.h deleted file mode 100644 index db53e8e..0000000 --- a/kernel/include/panic.h +++ /dev/null @@ -1 +0,0 @@ -void panic(const char*, ...); diff --git a/kernel/include/timer.h b/kernel/include/timer.h deleted file mode 100644 index 7a15949..0000000 --- a/kernel/include/timer.h +++ /dev/null @@ -1,13 +0,0 @@ -#include - -#define HZ 100 -#define PIT_FREQ 1193182 - -extern volatile const uint64_t *current_tick; - -struct regs_t; - -void timer_init(uint32_t freq); - -/* NOTE: enables interrupts by default */ -void timer_delay(uint64_t ticks); diff --git a/kernel/include/version.h b/kernel/include/version.h deleted file mode 100644 index 8fff367..0000000 --- a/kernel/include/version.h +++ /dev/null @@ -1,2 +0,0 @@ -#define KAPPA_KERNEL_VERSION "0.0.1-alpha" -#define KAPPA_KERNEL_CODENAME "Ayatollah's Buybacks" diff --git a/kernel/irq-as.S b/kernel/irq-as.S deleted file mode 100644 index 1d16392..0000000 --- a/kernel/irq-as.S +++ /dev/null @@ -1,146 +0,0 @@ - .extern irq_handler - -irq_stub: - - pusha - push %ds - push %es - push %fs - push %gs - mov $0x10, %ax - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %esp, %eax # push the stack - push %eax - mov $irq_handler, %eax - call *%eax - pop %eax - pop %gs - pop %fs - pop %es - pop %ds - popa - addl $8, %esp - iret - - .global _irq0 - .global _irq1 - .global _irq2 - .global _irq3 - .global _irq4 - .global _irq5 - .global _irq6 - .global _irq7 - .global _irq8 - .global _irq9 - .global _irq10 - .global _irq11 - .global _irq12 - .global _irq13 - .global _irq14 - .global _irq15 - .global _int0x80 - -_irq0: - cli - pushl $0 - pushl $32 - jmp irq_stub - -_irq1: - cli - pushl $0 - pushl $33 - jmp irq_stub - -_irq2: - cli - pushl $0 - pushl $34 - jmp irq_stub - -_irq3: - cli - pushl $0 - pushl $35 - jmp irq_stub - -_irq4: - cli - pushl $0 - pushl $36 - jmp irq_stub - -_irq5: - cli - pushl $0 - pushl $37 - jmp irq_stub - -_irq6: - cli - pushl $0 - pushl $38 - jmp irq_stub - -_irq7: - cli - pushl $0 - pushl $39 - jmp irq_stub - -_irq8: - cli - pushl $0 - pushl $40 - jmp irq_stub - -_irq9: - cli - pushl $0 - pushl $41 - jmp irq_stub - -_irq10: - cli - pushl $0 - pushl $42 - jmp irq_stub - -_irq11: - cli - pushl $0 - pushl $43 - jmp irq_stub - -_irq12: - cli - pushl $0 - pushl $44 - jmp irq_stub - -_irq13: - cli - pushl $0 - pushl $45 - jmp irq_stub - -_irq14: - cli - pushl $0 - pushl $46 - jmp irq_stub - -_irq15: - cli - pushl $0 - pushl $47 - jmp irq_stub - -_int0x80: - cli - pushl $0 - pushl $0x80 - jmp irq_stub diff --git a/kernel/irq.c b/kernel/irq.c deleted file mode 100644 index c6dbf4c..0000000 --- a/kernel/irq.c +++ /dev/null @@ -1,73 +0,0 @@ -#include -#include -#include -#include "idt.h" -#include "io.h" -#include "irq.h" -#include "isr.h" -#include "panic.h" - -/* in isr.c */ -extern void *int_callbacks[256]; - -void irq_remap(void) -{ - outb(0x20, 0x11); - outb(0xA0, 0x11); - outb(0x21, 0x20); - outb(0xA1, 0x28); - outb(0x21, 0x04); - outb(0xA1, 0x02); - outb(0x21, 0x01); - outb(0xA1, 0x01); - outb(0x21, 0x0); - outb(0xA1, 0x0); -} - -void irq_init(void) -{ - irq_remap(); - idt_set_gate(32, (uint32_t)_irq0, 0x08, 0x8E); - idt_set_gate(33, (uint32_t)_irq1, 0x08, 0x8E); - idt_set_gate(34, (uint32_t)_irq2, 0x08, 0x8E); - idt_set_gate(35, (uint32_t)_irq3, 0x08, 0x8E); - idt_set_gate(36, (uint32_t)_irq4, 0x08, 0x8E); - idt_set_gate(37, (uint32_t)_irq5, 0x08, 0x8E); - idt_set_gate(38, (uint32_t)_irq6, 0x08, 0x8E); - idt_set_gate(39, (uint32_t)_irq7, 0x08, 0x8E); - idt_set_gate(40, (uint32_t)_irq8, 0x08, 0x8E); - idt_set_gate(41, (uint32_t)_irq9, 0x08, 0x8E); - idt_set_gate(42, (uint32_t)_irq10, 0x08, 0x8E); - idt_set_gate(43, (uint32_t)_irq11, 0x08, 0x8E); - idt_set_gate(44, (uint32_t)_irq12, 0x08, 0x8E); - idt_set_gate(45, (uint32_t)_irq13, 0x08, 0x8E); - idt_set_gate(46, (uint32_t)_irq14, 0x08, 0x8E); - idt_set_gate(47, (uint32_t)_irq15, 0x08, 0x8E); - idt_set_gate(128,(uint32_t)_int0x80, 0x08, 0x8E); -} - -void irq_handler(struct regs_t *regs) -{ - void (*handler)(struct regs_t *r); - - handler = int_callbacks[regs->int_no]; - - if(handler) - { - handler(regs); - } - else - { - } - - /* If the IDT entry that was invoked was greater than 40 - * (meaning IRQ8 - 15), then we need to send an EOI to - * the slave controller */ - if (regs->int_no >= 40) - { - outb(0xA0, 0x20); - } - - /* send an EOI to the master controller */ - outb(0x20, 0x20); -} diff --git a/kernel/isr-as.S b/kernel/isr-as.S deleted file mode 100644 index 858ce47..0000000 --- a/kernel/isr-as.S +++ /dev/null @@ -1,214 +0,0 @@ - .extern isr_handler -isr_stub: - pusha - push %ds - push %es - push %fs - push %gs - mov $0x10, %ax # Load the Kernel Data Segment descriptor! - mov %ax, %ds - mov %ax, %es - mov %ax, %fs - mov %ax, %gs - mov %esp, %eax # Push us the stack - push %eax - call isr_handler - pop %eax - pop %gs - pop %fs - pop %es - pop %ds - popa - add $8, %esp - iret - - # stub ISR's: - .global _isr0 - .global _isr1 - .global _isr2 - .global _isr3 - .global _isr4 - .global _isr5 - .global _isr6 - .global _isr7 - .global _isr8 - .global _isr9 - .global _isr10 - .global _isr11 - .global _isr12 - .global _isr13 - .global _isr14 - .global _isr15 - .global _isr16 - .global _isr17 - .global _isr18 - .global _isr19 - .global _isr20 - .global _isr21 - .global _isr22 - .global _isr23 - .global _isr24 - .global _isr25 - .global _isr26 - .global _isr27 - .global _isr28 - .global _isr29 - .global _isr30 - .global _isr31 - - # Interrupts 8, 10, 11, 12, 13, and 14 push error codes onto the stack - -_isr0: - cli - pushl $0 - pushl $0 - jmp isr_stub -_isr1: - cli - pushl $0 - pushl $1 - jmp isr_stub -_isr2: - cli - pushl $0 - pushl $2 - jmp isr_stub -_isr3: - cli - pushl $0 - pushl $3 - jmp isr_stub -_isr4: - cli - pushl $0 - pushl $4 - jmp isr_stub -_isr5: - cli - pushl $0 - pushl $5 - jmp isr_stub -_isr6: - cli - pushl $0 - pushl $6 - jmp isr_stub -_isr7: - cli - pushl $0 - pushl $7 - jmp isr_stub -_isr8: - cli - pushl $8 - jmp isr_stub -_isr9: - cli - pushl $0 - pushl $9 - jmp isr_stub -_isr10: - cli - pushl $10 - jmp isr_stub -_isr11: - cli - pushl $11 - jmp isr_stub -_isr12: - cli - pushl $12 - jmp isr_stub -_isr13: - cli - pushl $13 - jmp isr_stub -_isr14: - cli - pushl $14 - jmp isr_stub -_isr15: - cli - pushl $0 - pushl $15 - jmp isr_stub -_isr16: - cli - pushl $0 - pushl $16 - jmp isr_stub -_isr17: - cli - pushl $0 - pushl $17 - jmp isr_stub -_isr18: - cli - pushl $0 - pushl $18 - jmp isr_stub -_isr19: - cli - pushl $0 - pushl $19 - jmp isr_stub -_isr20: - cli - pushl $0 - pushl $20 - jmp isr_stub -_isr21: - cli - pushl $0 - pushl $21 - jmp isr_stub -_isr22: - cli - pushl $0 - pushl $22 - jmp isr_stub -_isr23: - cli - pushl $0 - pushl $23 - jmp isr_stub -_isr24: - cli - pushl $0 - pushl $24 - jmp isr_stub -_isr25: - cli - pushl $0 - pushl $25 - jmp isr_stub -_isr26: - cli - pushl $0 - pushl $26 - jmp isr_stub -_isr27: - cli - pushl $0 - pushl $27 - jmp isr_stub -_isr28: - cli - pushl $0 - pushl $28 - jmp isr_stub -_isr29: - cli - pushl $0 - pushl $29 - jmp isr_stub -_isr30: - cli - pushl $0 - pushl $30 - jmp isr_stub -_isr31: - cli - pushl $0 - pushl $31 - jmp isr_stub diff --git a/kernel/isr.c b/kernel/isr.c deleted file mode 100644 index e6887c6..0000000 --- a/kernel/isr.c +++ /dev/null @@ -1,60 +0,0 @@ -#include -#include -#include "isr.h" -#include "idt.h" -#include "panic.h" - -void (*int_callbacks[256])(struct regs_t*) = { NULL }; - -void set_interrupt_handler(uint8_t n, void (*callback)(struct regs_t*)) -{ - int_callbacks[n] = callback; -} - -void isr_handler(struct regs_t *regs) -{ - if(int_callbacks[regs->int_no]) - { - int_callbacks[regs->int_no](regs); - } - else - { - printf("WARNING: unhandled ISR 0x%x!\n", regs->int_no); - } -} - -void isr_init(void) -{ - idt_set_gate(0, (uint32_t)_isr0, 0x08, 0x8E); - idt_set_gate(1, (uint32_t)_isr1, 0x08, 0x8E); - idt_set_gate(2, (uint32_t)_isr2, 0x08, 0x8E); - idt_set_gate(3, (uint32_t)_isr3, 0x08, 0x8E); - idt_set_gate(4, (uint32_t)_isr4, 0x08, 0x8E); - idt_set_gate(5, (uint32_t)_isr5, 0x08, 0x8E); - idt_set_gate(6, (uint32_t)_isr6, 0x08, 0x8E); - idt_set_gate(7, (uint32_t)_isr7, 0x08, 0x8E); - idt_set_gate(8, (uint32_t)_isr8, 0x08, 0x8E); - idt_set_gate(9, (uint32_t)_isr9, 0x08, 0x8E); - idt_set_gate(10, (uint32_t)_isr10, 0x08, 0x8E); - idt_set_gate(11, (uint32_t)_isr11, 0x08, 0x8E); - idt_set_gate(12, (uint32_t)_isr12, 0x08, 0x8E); - idt_set_gate(13, (uint32_t)_isr13, 0x08, 0x8E); - idt_set_gate(14, (uint32_t)_isr14, 0x08, 0x8E); - idt_set_gate(15, (uint32_t)_isr15, 0x08, 0x8E); - idt_set_gate(16, (uint32_t)_isr16, 0x08, 0x8E); - idt_set_gate(17, (uint32_t)_isr17, 0x08, 0x8E); - idt_set_gate(18, (uint32_t)_isr18, 0x08, 0x8E); - idt_set_gate(19, (uint32_t)_isr19, 0x08, 0x8E); - idt_set_gate(20, (uint32_t)_isr20, 0x08, 0x8E); - idt_set_gate(21, (uint32_t)_isr21, 0x08, 0x8E); - idt_set_gate(22, (uint32_t)_isr22, 0x08, 0x8E); - idt_set_gate(23, (uint32_t)_isr23, 0x08, 0x8E); - idt_set_gate(24, (uint32_t)_isr24, 0x08, 0x8E); - idt_set_gate(25, (uint32_t)_isr25, 0x08, 0x8E); - idt_set_gate(26, (uint32_t)_isr26, 0x08, 0x8E); - idt_set_gate(27, (uint32_t)_isr27, 0x08, 0x8E); - idt_set_gate(28, (uint32_t)_isr28, 0x08, 0x8E); - idt_set_gate(29, (uint32_t)_isr29, 0x08, 0x8E); - idt_set_gate(30, (uint32_t)_isr30, 0x08, 0x8E); - idt_set_gate(31, (uint32_t)_isr31, 0x08, 0x8E); -} diff --git a/kernel/linker.ld b/kernel/linker.ld deleted file mode 100644 index c032991..0000000 --- a/kernel/linker.ld +++ /dev/null @@ -1,45 +0,0 @@ -/* The bootloader will look at this image and start execution at the symbol - designated as the entry point. */ -ENTRY(_start) - -/* Tell where the various sections of the object files will be put in the final - kernel image. */ -SECTIONS -{ - /* Begin putting sections at 1 MiB, a conventional place for kernels to be - loaded at by the bootloader. */ - . = 1M; - - /* First put the multiboot header, as it is required to be put very early - early in the image or the bootloader won't recognize the file format. - Next we'll put the .text section. */ - .text BLOCK(4K) : ALIGN(4K) - { - *(.multiboot) - *(.text) - } - - /* Read-only data. */ - .rodata BLOCK(4K) : ALIGN(4K) - { - *(.rodata) - } - - /* Read-write data (initialized) */ - .data BLOCK(4K) : ALIGN(4K) - { - *(.data) - } - - /* Read-write data (uninitialized) and stack */ - .bss BLOCK(4K) : ALIGN(4K) - { - *(COMMON) - *(.bss) - *(.bootstrap_stack) - } - - /* The compiler may produce other sections, by default it will put them in - a segment with the same name. Simply add stuff here as needed. */ - link_mem_end = .; -} diff --git a/kernel/main.c b/kernel/main.c index 76c62f8..540bdcc 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -266,7 +266,9 @@ static void keyhandler(const struct ps2_keyevent *ev) putchar(toupper(ev->ascii)); } else + { putchar(ev->ascii); + } } } diff --git a/kernel/paging-as.S b/kernel/paging-as.S deleted file mode 100644 index cafaab4..0000000 --- a/kernel/paging-as.S +++ /dev/null @@ -1,9 +0,0 @@ - .global do_paging_enable -do_paging_enable: - movl 4(%esp), %eax # loads page directory address - mov %eax, %cr3 - mov %cr0, %eax - orl $0x80000000, %eax # set PG bit - sti - mov %eax, %cr0 - ret diff --git a/kernel/paging.c b/kernel/paging.c deleted file mode 100644 index 9d748ab..0000000 --- a/kernel/paging.c +++ /dev/null @@ -1,64 +0,0 @@ -#include -#include -#include -#include -#include "heap.h" -#include "isr.h" -#include "paging.h" -#include "panic.h" - -uint32_t *current_directory; - -static void page_fault(struct regs_t *regs) -{ - volatile uint32_t fault_addr; - asm("mov %%cr2, %0" : "=r"(fault_addr)); - printf("=== Page Fault ===\n"); - printf("Faulting address: 0x%x\n", fault_addr); - /* dump the regs */ - printf("EAX: 0x%x EBX: 0x%x\n", regs->eax, regs->ebx); - printf("ECX: 0x%x EDX: 0x%x\n", regs->ecx, regs->edx); - printf("ESP: 0x%x EBP: 0x%x\n", regs->esp, regs->ebp); - printf("ESI: 0x%x EDI: 0x%x\n", regs->esi, regs->edi); - printf("EIP: 0x%x\n", regs->eip); - panic("Page fault!\n"); -} - - void paging_switch_directory(uint32_t *dir) -{ - current_directory = dir; - extern void do_paging_enable(uint32_t); - do_paging_enable((uint32_t)current_directory); -} - -static uint32_t *identity_map_table(uint32_t start, int flags) -{ - /* make a page table */ - uint32_t *table = kmalloc_a(0x1000); - /* identity map 4MB */ - for(uint32_t i = start; i < start + 1024; ++i) - { - table[i - start] = (i * PAGE_SIZE) | flags; - } - return table; -} - -void paging_init(void) -{ - uint32_t *kernel_directory = kmalloc_a(0x1000); - memset(kernel_directory, 0, 0x1000); - /* blank the kernel directory */ - for(int i = 0; i < 1024; ++i) - { - kernel_directory[i] = PAGE_RW; - } - - /* identity map all 4GB (and allocate all page tables) */ - for(int i = 0; i < 1024; ++i) - kernel_directory[i] = (uint32_t)identity_map_table(i * 1024, PAGE_PRESENT | PAGE_RW) | - PAGE_PRESENT | PAGE_RW; - - set_interrupt_handler(14, page_fault); - - paging_switch_directory(kernel_directory); -} diff --git a/kernel/ssp.c b/kernel/ssp.c deleted file mode 100644 index ad47bb4..0000000 --- a/kernel/ssp.c +++ /dev/null @@ -1,19 +0,0 @@ -#include -#include "panic.h" - -#if UINT32_MAX == UINTPTR_MAX -#define STACK_CHK_GUARD 0xdeadbeef -#else -#define STACK_CHK_GUARD 0x0ddc0ffeebadf00d -#endif - -uintptr_t __stack_chk_guard = STACK_CHK_GUARD; - -__attribute__((noreturn)) void __stack_chk_fail(void) -{ -#if __STDC_HOSTED__ - abort(); -#else - panic("Stack smashing detected"); -#endif -} diff --git a/libc/include/stdio.h b/libc/include/stdio.h deleted file mode 100644 index 49966cf..0000000 --- a/libc/include/stdio.h +++ /dev/null @@ -1,7 +0,0 @@ -int printf(const char* fmt, ...) __attribute__ ((format (printf, 1, 2)));; -int puts(const char*); -int putchar(int); - -/* sets the I/O functions, allows easy switching between text mode and VBE */ -void set_putchar(void (*func)(int)); -void set_puts(void (*func)(const char*)); diff --git a/libc/include/stdlib.h b/libc/include/stdlib.h deleted file mode 100644 index f55f0f5..0000000 --- a/libc/include/stdlib.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef _STDLIB_H_ -#define _STDLIB_H_ - -#include -#include -#include - -/* this is by no means standards-compliant... but who cares? :P */ - -/* NOT reentrant! */ -char* itoa(int val, int base); - -#define RAND_MAX ((1U << 31) - 1) - -#define MIN(x,y) ((xy)?x:y) - -uint64_t rand64(void); -unsigned int rand(void); -void srand(uint64_t); -int abs(int); -void *malloc(size_t); -int snprintf(char*, int, const char*, ...); -void assert_fail(const char*, const char*, int); -int toupper(int); -int tolower(int); - -#define assert(x) if(!(x))assert_fail(__func__, __FILE__, __LINE__); - -#endif diff --git a/libc/include/string.h b/libc/include/string.h deleted file mode 100644 index 05050a0..0000000 --- a/libc/include/string.h +++ /dev/null @@ -1,4 +0,0 @@ -#include -int strlen(const char*); -void* memset(void*, int, size_t); -void* memcpy(void*, void*, size_t); -- cgit v1.1