diff options
author | Anton Kling <anton@kling.gg> | 2023-10-30 22:12:14 +0100 |
---|---|---|
committer | Anton Kling <anton@kling.gg> | 2023-10-31 00:18:38 +0100 |
commit | 8a9208612eec8ddae4c418485d848ecfa0613699 (patch) | |
tree | 2f4b29200c2f0c19ae52f45bdb9b38a41b356e30 /cpu | |
parent | ca76600acc8bf7a02346efa5bd8f17072210ec01 (diff) |
Meta: Move kernel and userland to their own folders.
This is to allow both the kernel and the userland to share certain
header files and to make the folder structure a bit more clear.
Diffstat (limited to 'cpu')
-rw-r--r-- | cpu/gdt.c | 72 | ||||
-rw-r--r-- | cpu/gdt.h | 76 | ||||
-rw-r--r-- | cpu/idt.c | 195 | ||||
-rw-r--r-- | cpu/idt.h | 70 | ||||
-rw-r--r-- | cpu/int_syscall.s | 20 | ||||
-rw-r--r-- | cpu/io.h | 15 | ||||
-rw-r--r-- | cpu/io.s | 147 | ||||
-rw-r--r-- | cpu/reload_gdt.s | 17 | ||||
-rw-r--r-- | cpu/spinlock.c | 2 | ||||
-rw-r--r-- | cpu/spinlock.h | 5 | ||||
-rw-r--r-- | cpu/syscall.c | 183 | ||||
-rw-r--r-- | cpu/syscall.h | 59 |
12 files changed, 0 insertions, 861 deletions
diff --git a/cpu/gdt.c b/cpu/gdt.c deleted file mode 100644 index 28853cf..0000000 --- a/cpu/gdt.c +++ /dev/null @@ -1,72 +0,0 @@ -#include "gdt.h" - -extern void flush_tss(void); -extern void load_gdt(void *); - -typedef struct tss_entry_struct tss_entry_t; - -tss_entry_t tss_entry; - -typedef union { - struct GDT_Entry s; - uint64_t raw; -} GDT_Entry; - -GDT_Entry gdt_entries[6] = {0}; -GDT_Pointer gdtr; - -extern uint32_t inital_esp; -void write_tss(struct GDT_Entry *gdt_entry) { - uint32_t base = (uint32_t)&tss_entry; - uint32_t limit = sizeof(tss_entry); - - gdt_entry->limit_low = limit; - gdt_entry->base_low = base; - gdt_entry->accessed = 1; - gdt_entry->read_write = 0; - gdt_entry->conforming_expand_down = 0; - gdt_entry->code = 1; - gdt_entry->code_data_segment = 0; - gdt_entry->DPL = 0; - gdt_entry->present = 1; - gdt_entry->limit_high = limit >> 16; - gdt_entry->available = 0; - gdt_entry->long_mode = 0; - gdt_entry->big = 0; - gdt_entry->gran = 0; - gdt_entry->base_high = (base & ((uint32_t)0xff << 24)) >> 24; - - memset(&tss_entry, 0, sizeof tss_entry); - tss_entry.ss0 = GDT_KERNEL_DATA_SEGMENT * GDT_ENTRY_SIZE; - register uint32_t esp asm("esp"); - tss_entry.esp0 = esp; -} - -void gdt_init() { - gdt_entries[GDT_NULL_SEGMENT].raw = 0x0; - gdt_entries[GDT_KERNEL_CODE_SEGMENT].raw = - 0xCF9A000000FFFF; // Kernel code segment - gdt_entries[GDT_KERNEL_DATA_SEGMENT].raw = - 0xCF92000000FFFF; // Kernel data segment - - // Usermode code segment - memcpy(&gdt_entries[GDT_USERMODE_CODE_SEGMENT], - &gdt_entries[GDT_KERNEL_CODE_SEGMENT], GDT_ENTRY_SIZE); - - // Usermode data segment - memcpy(&gdt_entries[GDT_USERMODE_DATA_SEGMENT], - &gdt_entries[GDT_KERNEL_DATA_SEGMENT], GDT_ENTRY_SIZE); - - // Set DPL to 3 to indicate that the segment is in ring 3 - gdt_entries[GDT_USERMODE_CODE_SEGMENT].s.DPL = 3; - gdt_entries[GDT_USERMODE_DATA_SEGMENT].s.DPL = 3; - - write_tss((struct GDT_Entry *)&gdt_entries[GDT_TSS_SEGMENT]); - - gdtr.offset = (uint32_t)&gdt_entries; - gdtr.size = sizeof(gdt_entries) - 1; - - asm("cli"); - load_gdt(&gdtr); - flush_tss(); -} diff --git a/cpu/gdt.h b/cpu/gdt.h deleted file mode 100644 index a490dea..0000000 --- a/cpu/gdt.h +++ /dev/null @@ -1,76 +0,0 @@ -#ifndef GDT_H -#define GDT_H -#include <stdint.h> -#include <string.h> - -#define GDT_ENTRY_SIZE 0x8 -#define GDT_NULL_SEGMENT 0x0 -#define GDT_KERNEL_CODE_SEGMENT 0x1 -#define GDT_KERNEL_DATA_SEGMENT 0x2 -#define GDT_USERMODE_CODE_SEGMENT 0x3 -#define GDT_USERMODE_DATA_SEGMENT 0x4 -#define GDT_TSS_SEGMENT 0x5 - -struct GDT_Entry -{ - uint16_t limit_low; - uint32_t base_low : 24; - uint32_t accessed : 1; - uint32_t read_write : 1; // readable for code, writable for data - uint32_t conforming_expand_down : 1; // conforming for code, expand down for data - uint32_t code : 1; // 1 for code, 0 for data - uint32_t code_data_segment : 1; // should be 1 for everything but TSS and LDT - uint32_t DPL : 2; // privilege level - uint32_t present : 1; - uint32_t limit_high : 4; - uint32_t available : 1; // only used in software; has no effect on hardware - uint32_t long_mode : 1; - uint32_t big : 1; // 32-bit opcodes for code, uint32_t stack for data - uint32_t gran : 1; // 1 to use 4k page addressing, 0 for byte addressing - uint8_t base_high; -}__attribute__((packed)); - -typedef struct GDT_Pointer -{ - uint16_t size; - uint32_t offset; -}__attribute__((packed)) GDT_Pointer; - -struct tss_entry_struct -{ - uint32_t prev_tss; // The previous TSS - with hardware task switching these form a kind of backward linked list. - uint32_t esp0; // The stack pointer to load when changing to kernel mode. - uint32_t ss0; // The stack segment to load when changing to kernel mode. - // Everything below here is unused. - uint32_t esp1; // esp and ss 1 and 2 would be used when switching to rings 1 or 2. - uint32_t ss1; - uint32_t esp2; - 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 ldt; - uint16_t trap; - uint16_t iomap_base; -} __attribute__((packed)); - -void gdt_init(); - -uint8_t gen_access_byte(uint8_t priv, uint8_t s, uint8_t ex, uint8_t dc, uint8_t rw); -uint64_t gen_gdt_entry(uint32_t base, uint32_t limit, uint8_t access_byte, uint8_t flag); -uint8_t gen_flag(uint8_t gr, uint8_t sz); -#endif diff --git a/cpu/idt.c b/cpu/idt.c deleted file mode 100644 index abcafad..0000000 --- a/cpu/idt.c +++ /dev/null @@ -1,195 +0,0 @@ -#include <cpu/idt.h> -#include <sched/scheduler.h> -#include <stdio.h> - -#define MASTER_PIC_COMMAND_PORT 0x20 -#define MASTER_PIC_DATA_PORT 0x21 -#define SLAVE_PIC_COMMAND_PORT 0xA0 -#define SLAVE_PIC_DATA_PORT 0xA1 -#define KEYBOARD_DATA_PORT 0x60 -#define KEYBOARD_STATUS_PORT 0x64 -#define KERNEL_CODE_SEGMENT_OFFSET GDT_ENTRY_SIZE *GDT_KERNEL_CODE_SEGMENT - -#define IDT_MAX_ENTRY 256 - -struct IDT_Descriptor { - uint16_t low_offset; - uint16_t code_segment_selector; - uint8_t zero; // Always should be zero - uint8_t type_attribute; - uint16_t high_offset; -} __attribute__((packed)) __attribute__((aligned(4))); - -struct IDT_Pointer { - uint16_t size; - struct IDT_Descriptor **interrupt_table; -} __attribute__((packed)); - -struct IDT_Descriptor IDT_Entry[IDT_MAX_ENTRY]; -struct IDT_Pointer idtr; - -extern void load_idtr(void *idtr); - -void format_descriptor(uint32_t offset, uint16_t code_segment, - uint8_t type_attribute, - struct IDT_Descriptor *descriptor) { - descriptor->low_offset = offset & 0xFFFF; - descriptor->high_offset = offset >> 16; - descriptor->type_attribute = type_attribute; - descriptor->code_segment_selector = code_segment; - descriptor->zero = 0; -} - -void install_handler(void (*handler_function)(), uint16_t type_attribute, - uint8_t entry) { - format_descriptor((uint32_t)handler_function, KERNEL_CODE_SEGMENT_OFFSET, - type_attribute, &IDT_Entry[entry]); -} - -__attribute__((no_caller_saved_registers)) void EOI(uint8_t irq) { - if (irq > 7) - outb(SLAVE_PIC_COMMAND_PORT, 0x20); - - outb(MASTER_PIC_COMMAND_PORT, 0x20); -} - -__attribute__((interrupt)) void general_protection_fault(registers_t *regs) { - klog("General Protetion Fault", 0x1); - kprintf(" Error Code: %x\n", regs->error_code); - kprintf("Instruction Pointer: %x\n", regs->eip); - dump_backtrace(12); - asm("hlt"); - for (;;) - ; - EOI(0xD - 8); -} - -__attribute__((interrupt)) void double_fault(registers_t *regs) { - (void)regs; - klog("DOUBLE FAULT", LOG_ERROR); - asm("hlt"); - for (;;) - ; -} -__attribute__((interrupt)) void page_fault(registers_t *regs) { - if (0xFFFFDEAD == regs->eip) { - asm("sti"); - for (;;) - switch_task(); - } - klog("Page Fault", LOG_ERROR); - if (get_current_task()) { - kprintf("PID: %x\n", get_current_task()->pid); - kprintf("Name: %s\n", get_current_task()->program_name); - } - kprintf("Error Code: %x\n", regs->error_code); - kprintf("Instruction Pointer: %x\n", regs->eip); - - if (regs->error_code & (1 << 0)) - kprintf("page-protection violation\n"); - else - kprintf("non-present page\n"); - - if (regs->error_code & (1 << 1)) - kprintf("write access\n"); - else - kprintf("read access\n"); - - if (regs->error_code & (1 << 2)) - kprintf("CPL = 3\n"); - - if (regs->error_code & (1 << 4)) - kprintf("Attempted instruction fetch\n"); - - dump_backtrace(5); - asm("hlt"); - for (;;) - ; -} - -static inline void io_wait(void) { outb(0x80, 0); } - -#define ICW1_ICW4 0x01 /* ICW4 (not) needed */ -#define ICW1_SINGLE 0x02 /* Single (cascade) mode */ -#define ICW1_INTERVAL4 0x04 /* Call address interval 4 (8) */ -#define ICW1_LEVEL 0x08 /* Level triggered (edge) mode */ -#define ICW1_INIT 0x10 /* Initialization - required! */ - -#define ICW4_8086 0x01 /* 8086/88 (MCS-80/85) mode */ -#define ICW4_AUTO 0x02 /* Auto (normal) EOI */ -#define ICW4_BUF_SLAVE 0x08 /* Buffered mode/slave */ -#define ICW4_BUF_MASTER 0x0C /* Buffered mode/master */ -#define ICW4_SFNM 0x10 /* Special fully nested (not) */ - -void PIC_remap(int offset) { - unsigned char a1, a2; - a1 = inb(MASTER_PIC_DATA_PORT); - a2 = inb(SLAVE_PIC_DATA_PORT); - - // Send ICW1 and tell the PIC that we will issue a ICW4 - // Since there is no ICW1_SINGLE sent to indicate it is cascaded - // it means we will issue a ICW3. - outb(MASTER_PIC_COMMAND_PORT, ICW1_INIT | ICW1_ICW4); - io_wait(); - outb(SLAVE_PIC_COMMAND_PORT, ICW1_INIT | ICW1_ICW4); - io_wait(); - - // As a part of ICW2 this sends the offsets(the position to put IRQ0) of the - // vector tables. - outb(MASTER_PIC_DATA_PORT, offset); - io_wait(); - outb(SLAVE_PIC_DATA_PORT, offset + 0x8); - io_wait(); - - // This tells the master on which lines it is having slaves - outb(MASTER_PIC_DATA_PORT, 4); - io_wait(); - // This tells the slave the cascading identity. - outb(SLAVE_PIC_DATA_PORT, 2); - io_wait(); - - outb(MASTER_PIC_DATA_PORT, ICW4_8086); - io_wait(); - outb(SLAVE_PIC_DATA_PORT, ICW4_8086); - io_wait(); - - outb(MASTER_PIC_DATA_PORT, a1); - outb(SLAVE_PIC_DATA_PORT, a2); -} - -void IRQ_set_mask(unsigned char IRQline) { - uint16_t port; - uint8_t value; - port = (IRQline < 8) ? MASTER_PIC_DATA_PORT : SLAVE_PIC_DATA_PORT; - if (IRQline >= 8) - IRQline -= 8; - value = inb(port) | (1 << IRQline); - outb(port, value); -} - -void IRQ_clear_mask(unsigned char IRQline) { - uint16_t port; - uint8_t value; - port = (IRQline < 8) ? MASTER_PIC_DATA_PORT : SLAVE_PIC_DATA_PORT; - if (IRQline >= 8) { - IRQline -= 8; - } - value = inb(port) & ~(1 << IRQline); - outb(port, value); -} - -void idt_init(void) { - install_handler(page_fault, INT_32_INTERRUPT_GATE(0x0), 0xE); - install_handler(double_fault, INT_32_INTERRUPT_GATE(0x0), 0x8); - install_handler(general_protection_fault, INT_32_INTERRUPT_GATE(0x0), 0xD); - - PIC_remap(0x20); - IRQ_clear_mask(0xb); - IRQ_set_mask(0xe); - IRQ_set_mask(0xf); - IRQ_clear_mask(2); - - idtr.interrupt_table = (struct IDT_Descriptor **)&IDT_Entry; - idtr.size = (sizeof(struct IDT_Descriptor) * IDT_MAX_ENTRY) - 1; - load_idtr(&idtr); -} diff --git a/cpu/idt.h b/cpu/idt.h deleted file mode 100644 index 025ba75..0000000 --- a/cpu/idt.h +++ /dev/null @@ -1,70 +0,0 @@ -typedef struct kernel_registers kernel_registers_t; -typedef struct registers registers_t; -#ifndef IDT_H -#define IDT_H -#include <cpu/gdt.h> -#include <cpu/io.h> -#include <log.h> -#include <stdint.h> -#include <stdio.h> - -/* - * the type_attribute in the IDT_Entry struct - * is divded like this - * 7 0 - * +---+---+---+---+---+---+---+---+ - * | P | DPL | S | GateType | - * +---+---+---+---+---+---+---+---+ - * It is 8 bits(1 byte) long - * - * P - * Present bit. Should be zero for unused - * interrupts. - * - * DPL - * Specifices the maximum ring(0 to 3) the - * interrupt can be called from. - * - * S - * Storage segment. This should be set to - * zero for all interrupt and trap gates. - * - * GateType - * Possible IDT gate types: - * 0b0101 0x5 5 80386 32 bit task gate - * 0b0110 0x6 6 80286 16-bit interrupt gate - * 0b0111 0x7 7 80286 16-bit trap gate - * 0b1110 0xE 14 80386 32-bit interrupt gate - * 0b1111 0xF 15 80386 32-bit trap gate - */ - -// This enables the present bit. -#define INT_PRESENT 0x80 /* 0b10000000 */ - -#define INT_32_TASK_GATE(min_privlege) \ - (INT_PRESENT | 0x05 | (min_privlege << 5)) -#define INT_16_INTERRUPT_GATE(min_privlege) \ - (INT_PRESENT | 0x06 | (min_privlege << 5)) -#define INT_16_TRAP_GATE(min_privlege) \ - (INT_PRESENT | 0x07 | (min_privlege << 5)) -#define INT_32_INTERRUPT_GATE(min_privlege) \ - (INT_PRESENT | 0x0E | (min_privlege << 5)) -#define INT_32_TRAP_GATE(min_privlege) \ - (INT_PRESENT | 0x0F | (min_privlege << 5)) - -struct interrupt_frame; - -struct registers { - uint32_t error_code; - uint32_t eip; - uint32_t cs; - uint32_t eflags; - uint32_t esp; - uint32_t ss; -}; - -void idt_init(void); -__attribute__((no_caller_saved_registers)) void EOI(unsigned char irq); -void install_handler(void (*handler_function)(), uint16_t type_attribute, - uint8_t entry); -#endif diff --git a/cpu/int_syscall.s b/cpu/int_syscall.s deleted file mode 100644 index 8c3c25f..0000000 --- a/cpu/int_syscall.s +++ /dev/null @@ -1,20 +0,0 @@ -.intel_syntax noprefix -.global int_syscall -.extern syscall_function_handler -int_syscall: - push ebp - push edi - push esi - push edx - push ecx - push ebx - push eax - call syscall_function_handler - add esp, 4 - pop ebx - pop ecx - pop edx - pop esi - pop edi - pop ebp - iretd diff --git a/cpu/io.h b/cpu/io.h deleted file mode 100644 index 38858a4..0000000 --- a/cpu/io.h +++ /dev/null @@ -1,15 +0,0 @@ -#include <stdint.h> - -extern void outsw(uint16_t, uint32_t); -extern void outb(uint16_t, uint8_t); -extern void outw(uint16_t, uint16_t); -extern void outl(uint16_t, uint32_t); - -extern uint32_t inl(uint16_t); -extern uint16_t inw(uint16_t); -extern uint16_t inb(uint16_t); - -extern void rep_outsw(uint16_t count, uint16_t port, volatile void *addy); -__attribute__((no_caller_saved_registers)) extern void -rep_insw(uint16_t count, uint16_t port, volatile void *addy); -extern void jump_usermode(void (*address)(), uint32_t stack_pointer); diff --git a/cpu/io.s b/cpu/io.s deleted file mode 100644 index 31e9df0..0000000 --- a/cpu/io.s +++ /dev/null @@ -1,147 +0,0 @@ -.intel_syntax noprefix -.global outsw -.global outb -.global outw -.global outl -.global inb -.global inw -.global inl -.global rep_outsw -.global rep_insw -.global flush_tss -.global load_idtr - -# ebx, esi, edi, ebp, and esp; -outsw: - push ebp - mov ebp, esp - push esi - mov dx, [ebp + 4+4] - mov esi, [ebp + 8+4] - outsw - pop esi - mov esp, ebp - pop ebp - ret - -outl: - mov eax, [esp + 8] - mov dx, [esp + 4] - out dx, eax - ret - -outb: - mov al, [esp + 8] - mov dx, [esp + 4] - out dx, al - ret - -outw: - mov ax, [esp + 8] - mov dx, [esp + 4] - out dx, ax - ret - -inl: - mov dx, [esp + 4] - in eax, dx - ret - -inw: - mov dx, [esp + 4] - in ax, dx - ret - -inb: - mov dx, [esp + 4] - in al, dx - ret - -rep_outsw: - push ebp - mov ebp, esp - push edi - mov ecx, [ebp + 4+4] #ECX is counter for OUTSW - mov edx, [ebp + 8+4] #Data port, in and out - mov edi, [ebp + 12+4] #Memory area - rep outsw #in to [RDI] - pop edi - mov esp, ebp - pop ebp - ret - -rep_insw: - push ebp - mov ebp, esp - push edi - mov ecx, [ebp + 4+4] #ECX is counter for INSW - mov edx, [ebp + 8+4] #Data port, in and out - mov edi, [ebp + 12+4] #Memory area - rep insw #in to [RDI] - pop edi - mov esp, ebp - pop ebp - ret - -flush_tss: - mov ax, 40 - ltr ax - ret - -load_idtr: - mov edx, [esp + 4] - lidt [edx] - ret - -test_user_function: - mov eax, 0x00 - int 0x80 - mov ecx, 0x03 - mov ebx, 0x04 - mov eax, 0x02 - int 0x80 - mov ebx, eax - mov eax, 0x01 - int 0x80 -loop: - jmp loop - ret - -.global spin_lock -.global spin_unlock -.extern locked - -spin_lock: - mov eax, 1 - xchg eax, ebx - test eax, eax - jnz spin_lock - ret - -spin_unlock: - xor eax, eax - xchg eax, ebx - ret - - -.global jump_usermode -jump_usermode: - mov ax, (4 * 8) | 3 # user data segment with RPL 3 - mov ds, ax - mov es, ax - mov fs, ax - mov gs, ax # sysexit sets SS - - # setup wrmsr inputs - xor edx, edx # not necessary; set to 0 - mov eax, 0x100008 # SS=0x10+0x10=0x20, CS=0x8+0x10=0x18 - mov ecx, 0x174 # MSR specifier: IA32_SYSENTER_CS - wrmsr # set sysexit segments - - # setup sysexit inputs - mov edx, [esp + 4] # to be loaded into EIP - mov ecx, [esp + 8] # to be loaded into ESP - mov esp, ecx - mov ebp, ecx - sti - sysexit diff --git a/cpu/reload_gdt.s b/cpu/reload_gdt.s deleted file mode 100644 index 3a0119b..0000000 --- a/cpu/reload_gdt.s +++ /dev/null @@ -1,17 +0,0 @@ -.section .text -.global load_gdt - -load_gdt: - mov 4(%esp), %eax - lgdt (%eax) - - mov $0x10, %eax - mov %eax, %ds - mov %eax, %es - mov %eax, %fs - mov %eax, %gs - mov %eax, %ss - jmp $0x8, $.long_jump -.long_jump: - ret - diff --git a/cpu/spinlock.c b/cpu/spinlock.c deleted file mode 100644 index 3f87423..0000000 --- a/cpu/spinlock.c +++ /dev/null @@ -1,2 +0,0 @@ -#include <stdint.h> -uint8_t locked; diff --git a/cpu/spinlock.h b/cpu/spinlock.h deleted file mode 100644 index 93290c4..0000000 --- a/cpu/spinlock.h +++ /dev/null @@ -1,5 +0,0 @@ -#ifndef SPINLOCK_H -#define SPINLOCK_H -void spin_lock(int *l); -void spin_unlock(int *l); -#endif diff --git a/cpu/syscall.c b/cpu/syscall.c deleted file mode 100644 index 4978732..0000000 --- a/cpu/syscall.c +++ /dev/null @@ -1,183 +0,0 @@ -// FIXME: Make sure that the args variabel actually points to something -// valid. -#include <assert.h> -#include <cpu/syscall.h> -#include <drivers/pst.h> -#include <errno.h> -#include <fs/tmpfs.h> -#include <fs/vfs.h> -#include <kmalloc.h> -#include <scalls/accept.h> -#include <scalls/bind.h> -#include <scalls/ftruncate.h> -#include <scalls/kill.h> -#include <scalls/mkdir.h> -#include <scalls/mmap.h> -#include <scalls/msleep.h> -#include <scalls/ppoll.h> -#include <scalls/recvfrom.h> -#include <scalls/sendto.h> -#include <scalls/shm.h> -#include <scalls/socket.h> -#include <scalls/stat.h> -#include <scalls/uptime.h> -#include <scalls/sigaction.h> -#include <stdint.h> -#include <string.h> - -#pragma GCC diagnostic ignored "-Wpedantic" - -int syscall_open(SYS_OPEN_PARAMS *args) { - char file[256]; - strcpy(file, args->file); - // const char *file = copy_and_allocate_user_string(args->file); - int flags = args->flags; - int mode = args->mode; - int rc = vfs_open(file, flags, mode); - // kfree((void *)file); - return rc; -} - -int syscall_exec(SYS_EXEC_PARAMS *args) { - const char *filename = copy_and_allocate_user_string(args->path); - - int argc = 0; - for (; args->argv[argc];) { - argc++; - } - - char **new_argv = kallocarray(argc + 1, sizeof(char *)); - for (int i = 0; i < argc; i++) - new_argv[i] = copy_and_allocate_user_string(args->argv[i]); - - new_argv[argc] = NULL; - - exec(filename, new_argv); - kfree((void *)filename); - for (int i = 0; i < argc; i++) - kfree(new_argv[i]); - kfree(new_argv); - return -1; -} - -int syscall_pipe(int fd[2]) { - pipe(fd); // FIXME: Error checking - return 0; -} - -int syscall_pread(SYS_PREAD_PARAMS *args) { - return vfs_pread(args->fd, args->buf, args->count, args->offset); -} - -int syscall_read(SYS_READ_PARAMS *args) { - if (!get_vfs_fd(args->fd)) - return -EBADF; - int rc = vfs_pread(args->fd, args->buf, args->count, - get_current_task()->file_descriptors[args->fd]->offset); - get_current_task()->file_descriptors[args->fd]->offset += rc; - return rc; -} - -int syscall_pwrite(SYS_PWRITE_PARAMS *args) { - return vfs_pwrite(args->fd, args->buf, args->count, args->offset); -} - -int syscall_write(int fd, const char *buf, size_t count) { - if (!get_vfs_fd(fd)) - return -EBADF; - int rc = vfs_pwrite(fd, (char *)buf, count, - get_current_task()->file_descriptors[fd]->offset); - get_current_task()->file_descriptors[fd]->offset += rc; - return rc; -} - -int syscall_dup2(SYS_DUP2_PARAMS *args) { - return vfs_dup2(args->org_fd, args->new_fd); -} - -void syscall_exit(int status) { - exit(status); - assert(0); -} - -void syscall_wait(int *status) { - asm("cli"); - if (!get_current_task()->child) { - if (status) - *status = -1; - return; - } - if (get_current_task()->child->dead) { - if (status) - *status = get_current_task()->child_rc; - return; - } - get_current_task()->halts[WAIT_CHILD_HALT] = 1; - switch_task(); - if (status) - *status = get_current_task()->child_rc; -} - -int syscall_fork(void) { return fork(); } - -int syscall_getpid(void) { return get_current_task()->pid; } - -void *align_page(void *a); - -int syscall_brk(void *addr) { - void *end = get_current_task()->data_segment_end; - if (!mmu_allocate_region(end, addr - end, MMU_FLAG_RW, NULL)) - return -ENOMEM; - get_current_task()->data_segment_end = align_page(addr); - return 0; -} - -void *syscall_sbrk(uintptr_t increment) { - asm("cli"); - void *rc = get_current_task()->data_segment_end; - void *n = - (void *)((uintptr_t)(get_current_task()->data_segment_end) + increment); - int rc2; - if (0 > (rc2 = syscall_brk(n))) - return (void *)rc2; - return rc; -} - -int syscall_close(int fd) { return vfs_close(fd); } - -int syscall_openpty(SYS_OPENPTY_PARAMS *args) { - assert(is_valid_userpointer(args, sizeof(SYS_OPENPTY_PARAMS))); - return openpty(args->amaster, args->aslave, args->name, args->termp, - args->winp); -} - -void (*syscall_functions[])() = { - (void(*))syscall_open, (void(*))syscall_read, - (void(*))syscall_write, (void(*))syscall_pread, - (void(*))syscall_pwrite, (void(*))syscall_fork, - (void(*))syscall_exec, (void(*))syscall_getpid, - (void(*))syscall_exit, (void(*))syscall_wait, - (void(*))syscall_brk, (void(*))syscall_sbrk, - (void(*))syscall_pipe, (void(*))syscall_dup2, - (void(*))syscall_close, (void(*))syscall_openpty, - (void(*))syscall_poll, (void(*))syscall_mmap, - (void(*))syscall_accept, (void(*))syscall_bind, - (void(*))syscall_socket, (void(*))syscall_shm_open, - (void(*))syscall_ftruncate, (void(*))syscall_stat, - (void(*))syscall_msleep, (void(*))syscall_uptime, - (void(*))syscall_mkdir, (void(*))syscall_recvfrom, - (void(*))syscall_sendto, (void(*))syscall_kill, - (void(*))syscall_sigaction, -}; - -void syscall_function_handler(uint32_t eax, uint32_t arg1, uint32_t arg2, - uint32_t arg3, uint32_t arg4, uint32_t arg5) { - assert(eax < sizeof(syscall_functions) / sizeof(syscall_functions[0])); - syscall_functions[eax](arg1, arg2, arg3, arg4, arg5); -} - -extern void int_syscall(void); - -void syscalls_init(void) { - install_handler(int_syscall, INT_32_INTERRUPT_GATE(0x3), 0x80); -} diff --git a/cpu/syscall.h b/cpu/syscall.h deleted file mode 100644 index 51d50f2..0000000 --- a/cpu/syscall.h +++ /dev/null @@ -1,59 +0,0 @@ -#include "idt.h" -#include <stddef.h> -#include <stdint.h> - -void syscalls_init(void); - -typedef struct SYS_OPEN_PARAMS { - char *file; - int flags; - int mode; -} __attribute__((packed)) SYS_OPEN_PARAMS; - -typedef struct SYS_PREAD_PARAMS { - int fd; - void *buf; - size_t count; - size_t offset; -} __attribute__((packed)) SYS_PREAD_PARAMS; - -typedef struct SYS_READ_PARAMS { - int fd; - void *buf; - size_t count; -} __attribute__((packed)) SYS_READ_PARAMS; - -typedef struct SYS_PWRITE_PARAMS { - int fd; - void *buf; - size_t count; - size_t offset; -} __attribute__((packed)) SYS_PWRITE_PARAMS; - -typedef struct SYS_WRITE_PARAMS { - int fd; - void *buf; - size_t count; -} __attribute__((packed)) SYS_WRITE_PARAMS; - -typedef struct SYS_EXEC_PARAMS { - char *path; - char **argv; -} __attribute__((packed)) SYS_EXEC_PARAMS; - -typedef struct SYS_WAIT_PARAMS { - int *status; -} __attribute__((packed)) SYS_WAIT_PARAMS; - -typedef struct SYS_DUP2_PARAMS { - int org_fd; - int new_fd; -} __attribute__((packed)) SYS_DUP2_PARAMS; - -typedef struct SYS_OPENPTY_PARAMS { - int *amaster; - int *aslave; - char *name; - /*const struct termios*/ void *termp; - /*const struct winsize*/ void *winp; -} __attribute__((packed)) SYS_OPENPTY_PARAMS; |