summaryrefslogtreecommitdiff
path: root/kernel/arch/x86/include
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/arch/x86/include')
-rw-r--r--kernel/arch/x86/include/kernel/asm.h167
-rw-r--r--kernel/arch/x86/include/kernel/gdt.h53
-rw-r--r--kernel/arch/x86/include/kernel/idt.h31
-rw-r--r--kernel/arch/x86/include/kernel/paging.h45
-rw-r--r--kernel/arch/x86/include/kernel/pic.h44
-rw-r--r--kernel/arch/x86/include/kernel/pmem.h19
-rw-r--r--kernel/arch/x86/include/kernel/syscall.h34
-rw-r--r--kernel/arch/x86/include/kernel/timer.h9
-rw-r--r--kernel/arch/x86/include/kernel/vmem.h17
9 files changed, 419 insertions, 0 deletions
diff --git a/kernel/arch/x86/include/kernel/asm.h b/kernel/arch/x86/include/kernel/asm.h
new file mode 100644
index 0000000..18f53c4
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/asm.h
@@ -0,0 +1,167 @@
+#ifndef I386_ASM_H
+#define I386_ASM_H
+
+#include <kernel/gdt.h>
+#include <stdint.h>
+#include <cpuid.h>
+
+#define PCI_CONFIG_ADDR 0xCF8
+#define PCI_CONFIG_DATA 0xCFC
+
+#define COM_PORT 0x3F8
+
+#define MAX_ISR 256
+
+struct regs {
+ uint32_t eax;
+ uint32_t ebx;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t ebp;
+ uint32_t esp;
+
+ uint32_t cr0;
+ uint32_t cr2;
+ uint32_t cr3;
+ uint32_t cr4;
+};
+
+struct isr_frame {
+ uint32_t cr4;
+ uint32_t cr3;
+ uint32_t cr2;
+ uint32_t cr0;
+
+ uint32_t edi;
+ uint32_t esi;
+ uint32_t edx;
+ uint32_t ecx;
+ uint32_t ebx;
+ uint32_t eax;
+
+ uint32_t isr_vector;
+ uint32_t isr_err;
+ uint32_t eip;
+ uint32_t cs;
+ uint32_t eflags;
+} __attribute__((packed));
+
+struct cpuid_info {
+ char vendorID[12];
+ uint32_t feat_ecx;
+ uint32_t feat_edx;
+};
+
+void isr_stub_0(void);
+void isr_stub_1(void);
+void isr_stub_2(void);
+void isr_stub_3(void);
+void isr_stub_4(void);
+void isr_stub_5(void);
+void isr_stub_6(void);
+void isr_stub_7(void);
+void isr_stub_8(void);
+void isr_stub_9(void);
+void isr_stub_10(void);
+void isr_stub_11(void);
+void isr_stub_12(void);
+void isr_stub_13(void);
+void isr_stub_14(void);
+void isr_stub_15(void);
+void isr_stub_16(void);
+void isr_stub_17(void);
+void isr_stub_18(void);
+void isr_stub_19(void);
+void isr_stub_20(void);
+void isr_stub_21(void);
+void isr_stub_22(void);
+void isr_stub_23(void);
+void isr_stub_24(void);
+void isr_stub_25(void);
+void isr_stub_26(void);
+void isr_stub_27(void);
+void isr_stub_28(void);
+void isr_stub_29(void);
+void isr_stub_30(void);
+void isr_stub_31(void);
+
+void irq_stub_0(void);
+void irq_stub_1(void);
+void irq_stub_2(void);
+void irq_stub_3(void);
+void irq_stub_4(void);
+void irq_stub_5(void);
+void irq_stub_6(void);
+void irq_stub_7(void);
+void irq_stub_8(void);
+void irq_stub_9(void);
+void irq_stub_10(void);
+void irq_stub_11(void);
+void irq_stub_12(void);
+void irq_stub_13(void);
+void irq_stub_14(void);
+void irq_stub_15(void);
+
+void isr_stub_128(void);
+
+void enable_paging(uint32_t new_cr3);
+int cpuid_check(void);
+void flush_gdt(void);
+
+static inline void cpuid(int code, uint32_t *ecx, uint32_t *ebx) {
+ __asm__ volatile("cpuid" : "=a"(*ecx), "=d"(*ebx) : "a"(code) : "ecx","ebx");
+}
+
+static inline void outb(uint16_t port, uint8_t value) {
+ __asm__ volatile("outb %0, %1" : : "a"(value), "Nd"(port));
+}
+
+static inline void outw(uint16_t port, uint16_t value) {
+ __asm__ volatile("outw %0, %1" : : "a"(value), "Nd"(port));
+}
+
+static inline void outl(uint16_t port, uint32_t value) {
+ __asm__ volatile("outl %0, %1" : : "a"(value), "Nd"(port));
+}
+
+static inline uint8_t inb(uint16_t port) {
+ uint8_t ret;
+ __asm__ volatile("inb %1, %0" : "=a"(ret) : "Nd"(port));
+ return ret;
+}
+
+static inline uint16_t inw(uint16_t port) {
+ uint16_t ret;
+ __asm__ volatile("inw %1, %0" : "=a"(ret) : "Nd"(port));
+ return ret;
+}
+
+static inline uint32_t inl(uint16_t port) {
+ uint32_t ret;
+ __asm__ volatile("inl %1, %0" : "=a"(ret) : "Nd"(port));
+ return ret;
+}
+
+static inline void enable_ints(void) {
+ __asm__ volatile("sti");
+}
+
+static inline void disable_ints(void) {
+ __asm__ volatile("cli");
+}
+
+static inline void flush_tss(void) {
+ __asm__ volatile("movw $0x28, %ax; ltr %ax");
+}
+
+static inline void flush_tlb(void) {
+ __asm__ volatile("movl %cr3, %eax; movl %eax, %cr3");
+}
+
+static inline void invlpg(void *addr) {
+ __asm__ volatile("invlpg (%0)" : : "b"(addr) : "memory");
+}
+
+#endif
diff --git a/kernel/arch/x86/include/kernel/gdt.h b/kernel/arch/x86/include/kernel/gdt.h
new file mode 100644
index 0000000..aa05408
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/gdt.h
@@ -0,0 +1,53 @@
+#ifndef I386_GDT_H
+#define I386_GDT_H
+
+#include <stdint.h>
+
+struct gdt_entry {
+ uint16_t limit_low;
+ uint16_t base_low;
+ uint8_t base_middle;
+ uint8_t access;
+ uint8_t gran;
+ uint8_t base_high;
+} __attribute__((packed));
+
+struct gdt_ptr {
+ uint16_t limit;
+ uint64_t base;
+} __attribute__((packed));
+
+struct tss_entry {
+ uint32_t link;
+ uint32_t esp0;
+ uint32_t ss0;
+ uint32_t esp1;
+ uint32_t ss2;
+ uint32_t cr3;
+ uint32_t eip;
+ uint32_t eflags;
+ uint32_t eax;
+ uint32_t ecx;
+ uint32_t edx;
+ uint32_t ebx;
+ uint32_t esp;
+ uint32_t ebp;
+ uint32_t esi;
+ uint32_t edi;
+ uint32_t es;
+ uint32_t cs;
+ uint32_t ss;
+ uint32_t ds;
+ uint32_t fs;
+ uint32_t gs;
+ uint32_t ldtr;
+ uint16_t trap;
+ uint16_t iomap_base;
+} __attribute__((packed));
+
+void gdt_set_gate(int num, uint32_t base, uint32_t limit, uint8_t access, uint8_t gran);
+void write_tss(int num, uint32_t ss0, uint32_t esp0);
+void set_kernel_esp(uint32_t esp);
+void gdt_install(void);
+
+#endif
diff --git a/kernel/arch/x86/include/kernel/idt.h b/kernel/arch/x86/include/kernel/idt.h
new file mode 100644
index 0000000..29ec39f
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/idt.h
@@ -0,0 +1,31 @@
+#ifndef I386_IDT_H
+#define I386_IDT_H
+
+#include <stdint.h>
+
+#define SEGMENT_PRESENT 0x80
+#define SEGMENT_RING0 0x00
+#define SEGMENT_RING3 0x60
+#define SEGMENT_STORAGE 0x00
+#define SEGMENT_INTERRUPT 0x0E
+#define IDT_EXCEPTION (SEGMENT_PRESENT | SEGMENT_INTERRUPT)
+#define IDT_INTERRUPT (SEGMENT_PRESENT | SEGMENT_INTERRUPT)
+
+#define IDT_MAX_DESCRIPTORS 256
+
+struct idt_entry {
+ uint16_t isr_low;
+ uint16_t kernel_cs;
+ uint8_t reserved;
+ uint8_t flags;
+ uint16_t isr_high;
+} __attribute__((packed));
+
+struct idt_ptr {
+ uint16_t limit;
+ uint32_t base;
+} __attribute__((packed));
+
+void idt_install(void);
+
+#endif
diff --git a/kernel/arch/x86/include/kernel/paging.h b/kernel/arch/x86/include/kernel/paging.h
new file mode 100644
index 0000000..3a3c298
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/paging.h
@@ -0,0 +1,45 @@
+#ifndef I386_PAGING_H
+#define I386_PAGING_H
+
+#include <kernel/asm.h>
+#include <stdint.h>
+
+#define PAGE_SIZE 4096
+
+#define PD_PRES 0x0001
+#define PD_RW 0x0002
+#define PD_USR 0x0004
+#define PD_PWT 0x0008
+#define PD_PCD 0x0010
+#define PD_ACC 0x0020
+#define PD_DIRTY 0x0040
+#define PD_PS 0x0080
+#define PD_GLOB 0x0100
+#define PD_PAT 0x1000
+
+#define ERR_PRESENT 0x1
+#define ERR_RW 0x2
+#define ERR_USER 0x4
+#define ERR_RESERVED 0x8
+#define ERR_INST 0x10
+
+#define PGROUNDUP(size) (((size)+PAGE_SIZE-1) & ~(PAGE_SIZE-1))
+#define PGROUNDDN(size) (((size)) & ~(PAGE_SIZE-1))
+
+#define GET_PADDR(x) (((uint32_t)(x)) - 0xC0000000)
+#define GET_VADDR(x) (((uint32_t)(x)) + 0xC0000000)
+
+#define GET_PDX(x) ((uintptr_t)(x) >> 22)
+#define GET_PTX(x) (((uintptr_t)(x) >> 12) & 0x03FF)
+
+uintptr_t get_physaddr(void *vaddr);
+
+void paging_init(void);
+
+uintptr_t init_page_directory(void);
+void map_page(uintptr_t paddr, uintptr_t vaddr, uint32_t flags);
+void unmap_page(uintptr_t vaddr);
+
+void page_fault_handler(struct isr_frame *frame);
+
+#endif
diff --git a/kernel/arch/x86/include/kernel/pic.h b/kernel/arch/x86/include/kernel/pic.h
new file mode 100644
index 0000000..187d553
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/pic.h
@@ -0,0 +1,44 @@
+#ifndef I386_PIC_H
+#define I386_PIC_H
+
+#include <kernel/asm.h>
+#include <stdint.h>
+
+#define PIC1 0x20
+#define PIC2 0x28
+#define PIC1_COMMAND PIC1
+#define PIC1_DATA (PIC1+1)
+#define PIC2_COMMAND PIC2
+#define PIC2_DATA (PIC2+1)
+
+#define ICW1_ICW4 0x01
+#define ICW1_SINGLE 0x02
+#define ICW1_INTERVAL4 0x04
+#define ICW1_LEVEL 0x08
+#define ICW1_INIT 0x10
+
+#define ICW4_8086 0x01
+#define ICW4_AUTO 0x02
+#define ICW4_BUF_SLAVE 0x08
+#define ICW4_BUF_MASTER 0x0C
+#define ICW4_SFNM 0x10
+
+#define PIC_READ_IRR 0x0A
+#define PIC_READ_ISR 0x0B
+
+static inline void io_wait(void) {
+ outb(0x80, 0);
+}
+
+void pic_eoi(uint8_t irq);
+void pic_remap(void);
+uint16_t pic_get_irr(void);
+uint16_t pic_get_isr(void);
+
+void register_irq_handler(uint8_t irq, void (*handler)(struct isr_frame *frame));
+void irq_dispatch(struct isr_frame *frame);
+
+void irq_set_mask(uint8_t irq);
+void irq_clear_mask(uint8_t irq);
+
+#endif
diff --git a/kernel/arch/x86/include/kernel/pmem.h b/kernel/arch/x86/include/kernel/pmem.h
new file mode 100644
index 0000000..ea4fe29
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/pmem.h
@@ -0,0 +1,19 @@
+#ifndef I386_PMEM_H
+#define I386_PMEM_H
+
+#include <stdint.h>
+#include <stddef.h>
+
+struct pfa_page {
+ struct pfa_page *next;
+};
+
+void pfa_init(struct mboot_info *header);
+
+uintptr_t pfa_alloc_dma(size_t num_pages);
+uintptr_t pfa_alloc(size_t num_pages);
+
+void pfa_free_dma(uintptr_t paddr, size_t num_pages);
+void pfa_free(uintptr_t paddr, size_t num_pages);
+
+#endif
diff --git a/kernel/arch/x86/include/kernel/syscall.h b/kernel/arch/x86/include/kernel/syscall.h
new file mode 100644
index 0000000..a657527
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/syscall.h
@@ -0,0 +1,34 @@
+#ifndef I386_SYSCALL_H
+#define I386_SYSCALL_H
+
+#include <kernel/asm.h>
+#include <stdint.h>
+#include <stddef.h>
+
+// Unix standard calls
+#define SYS_FORK 1
+#define SYS_EXIT 2
+#define SYS_WAIT 3
+#define SYS_PIPE 4
+#define SYS_READ 5
+#define SYS_WRITE 6
+#define SYS_KILL 7
+#define SYS_FSTAT 8
+#define SYS_CHDIR 9
+#define SYS_DUP 10
+#define SYS_GETPID 11
+#define SYS_SLEEP 12
+#define SYS_OPEN 13
+#define SYS_MKNOD 14
+#define SYS_UNLINK 15
+#define SYS_LINK 16
+#define SYS_MKDIR 17
+#define SYS_CLOSE 18
+#define SYS_EXEC 19
+
+#define SYS_HALT 87
+#define SYS_REBOOT 88
+
+void handle_syscall(struct isr_frame *frame);
+
+#endif
diff --git a/kernel/arch/x86/include/kernel/timer.h b/kernel/arch/x86/include/kernel/timer.h
new file mode 100644
index 0000000..c0b3a73
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/timer.h
@@ -0,0 +1,9 @@
+#ifndef I386_TIMER_H
+#define I386_TIMER_H
+
+#include <kernel/asm.h>
+
+void timer_handler(struct isr_frame *frame);
+void timer_init(void);
+
+#endif
diff --git a/kernel/arch/x86/include/kernel/vmem.h b/kernel/arch/x86/include/kernel/vmem.h
new file mode 100644
index 0000000..94aa32d
--- /dev/null
+++ b/kernel/arch/x86/include/kernel/vmem.h
@@ -0,0 +1,17 @@
+#ifndef I386_VMEM_H
+#define I386_VMEM_H
+
+extern uintptr_t _kernel_start;
+extern uintptr_t _kernel_end;
+
+#define KSTART ((uintptr_t)&_kernel_start)
+#define KEND ((uintptr_t)&_kernel_end - 0xC0000000)
+
+#define KHEAP_START (GET_VADDR(KEND) + 0x2000)
+#define KHEAP_STOP 0xFF7FF000
+
+#define PAGE_DIR_MAP 0xFFFFF000
+#define PAGE_TAB_MAP 0xFFC00000
+#define PAGE_TMP_MAP 0xFFBFF000
+
+#endif