diff options
Diffstat (limited to 'kernel/arch/x86/include')
-rw-r--r-- | kernel/arch/x86/include/kernel/asm.h | 167 | ||||
-rw-r--r-- | kernel/arch/x86/include/kernel/gdt.h | 53 | ||||
-rw-r--r-- | kernel/arch/x86/include/kernel/idt.h | 31 | ||||
-rw-r--r-- | kernel/arch/x86/include/kernel/paging.h | 45 | ||||
-rw-r--r-- | kernel/arch/x86/include/kernel/pic.h | 44 | ||||
-rw-r--r-- | kernel/arch/x86/include/kernel/pmem.h | 19 | ||||
-rw-r--r-- | kernel/arch/x86/include/kernel/syscall.h | 34 | ||||
-rw-r--r-- | kernel/arch/x86/include/kernel/timer.h | 9 | ||||
-rw-r--r-- | kernel/arch/x86/include/kernel/vmem.h | 17 |
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 |