From 236963e7563be3e3f8220dac7bb4af446928e194 Mon Sep 17 00:00:00 2001 From: Ian Moffett Date: Mon, 24 Jun 2024 22:55:29 -0400 Subject: Clean out for expt Signed-off-by: Ian Moffett --- sys/arch/amd64/amd64/bus_machdep.c | 83 ------- sys/arch/amd64/amd64/cpu.c | 40 ---- sys/arch/amd64/amd64/cpu_mp.c | 142 ------------ sys/arch/amd64/amd64/gdt.c | 85 -------- sys/arch/amd64/amd64/hpet.c | 208 ------------------ sys/arch/amd64/amd64/idt.c | 66 ------ sys/arch/amd64/amd64/ioapic.c | 200 ----------------- sys/arch/amd64/amd64/lapic.c | 435 ------------------------------------- sys/arch/amd64/amd64/local_intr.S | 47 ---- sys/arch/amd64/amd64/machdep.c | 401 ---------------------------------- sys/arch/amd64/amd64/pmap.c | 389 --------------------------------- sys/arch/amd64/amd64/spectre.S | 54 ----- sys/arch/amd64/amd64/spectre.c | 85 -------- sys/arch/amd64/amd64/syscall.S | 43 ---- sys/arch/amd64/amd64/syscall.c | 54 ----- sys/arch/amd64/amd64/trap.S | 155 ------------- sys/arch/amd64/amd64/trap.c | 269 ----------------------- sys/arch/amd64/amd64/tss.S | 41 ---- sys/arch/amd64/amd64/tss.c | 174 --------------- sys/arch/amd64/amd64/uart.c | 98 --------- sys/arch/amd64/conf/GENERIC | 9 - sys/arch/amd64/isa/i8042.c | 297 ------------------------- sys/arch/amd64/isa/i8254.c | 75 ------- sys/arch/amd64/isa/spkr.c | 68 ------ 24 files changed, 3518 deletions(-) delete mode 100644 sys/arch/amd64/amd64/bus_machdep.c delete mode 100644 sys/arch/amd64/amd64/cpu.c delete mode 100644 sys/arch/amd64/amd64/cpu_mp.c delete mode 100644 sys/arch/amd64/amd64/gdt.c delete mode 100644 sys/arch/amd64/amd64/hpet.c delete mode 100644 sys/arch/amd64/amd64/idt.c delete mode 100644 sys/arch/amd64/amd64/ioapic.c delete mode 100644 sys/arch/amd64/amd64/lapic.c delete mode 100644 sys/arch/amd64/amd64/local_intr.S delete mode 100644 sys/arch/amd64/amd64/machdep.c delete mode 100644 sys/arch/amd64/amd64/pmap.c delete mode 100644 sys/arch/amd64/amd64/spectre.S delete mode 100644 sys/arch/amd64/amd64/spectre.c delete mode 100644 sys/arch/amd64/amd64/syscall.S delete mode 100644 sys/arch/amd64/amd64/syscall.c delete mode 100644 sys/arch/amd64/amd64/trap.S delete mode 100644 sys/arch/amd64/amd64/trap.c delete mode 100644 sys/arch/amd64/amd64/tss.S delete mode 100644 sys/arch/amd64/amd64/tss.c delete mode 100644 sys/arch/amd64/amd64/uart.c delete mode 100644 sys/arch/amd64/conf/GENERIC delete mode 100644 sys/arch/amd64/isa/i8042.c delete mode 100644 sys/arch/amd64/isa/i8254.c delete mode 100644 sys/arch/amd64/isa/spkr.c (limited to 'sys/arch') diff --git a/sys/arch/amd64/amd64/bus_machdep.c b/sys/arch/amd64/amd64/bus_machdep.c deleted file mode 100644 index 91e7963..0000000 --- a/sys/arch/amd64/amd64/bus_machdep.c +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Map a physical device address into the kernel address - * space. - * - * @addr: Physical address to map. - * @size: Size to map. - * @flags: Mapping flags. - * @vap: Resulting virtual address. - */ -int -bus_map(bus_addr_t addr, size_t size, int flags, void **vap) -{ - struct vm_ctx *vmctx = vm_get_ctx(); - struct vas vas; - size_t pagesize; - vaddr_t va; - int status; - - pagesize = vm_get_page_size(); - size = __ALIGN_UP(size, pagesize); - - va = (vaddr_t)PHYS_TO_VIRT(addr); - vas = pmap_read_vas(); - - /* Ensure the size is valid */ - if (size == 0) { - return -EINVAL; - } - - /* Map the device address to our new VA */ - if ((status = vm_map_create(vas, va, addr, PROT_WRITE, size)) != 0) { - return status; - } - - /* - * Mark the memory as uncachable because this is - * for device I/O - */ - if ((status = pmap_set_cache(vmctx, vas, va, VM_CACHE_UC)) != 0) { - return status; - } - - *vap = (void *)va; - return 0; -} diff --git a/sys/arch/amd64/amd64/cpu.c b/sys/arch/amd64/amd64/cpu.c deleted file mode 100644 index e608535..0000000 --- a/sys/arch/amd64/amd64/cpu.c +++ /dev/null @@ -1,40 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include - -__KERNEL_META("$Hyra$: cpu.c, Ian Marco Moffett, " - "AMD64 CPU abstraction module"); - -struct cpu_info * -amd64_this_cpu(void) -{ - return (void *)amd64_read_gs_base(); -} diff --git a/sys/arch/amd64/amd64/cpu_mp.c b/sys/arch/amd64/amd64/cpu_mp.c deleted file mode 100644 index b9de227..0000000 --- a/sys/arch/amd64/amd64/cpu_mp.c +++ /dev/null @@ -1,142 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -__MODULE_NAME("cpu_mp"); -__KERNEL_META("$Hyra$: cpu_mp.c, Ian Marco Moffett, " - "SMP related code"); - -#define pr_trace(fmt, ...) kprintf("cpu_mp: " fmt, ##__VA_ARGS__) - -static volatile struct limine_smp_request g_smp_req = { - .id = LIMINE_SMP_REQUEST, - .revision = 0 -}; - -static bool is_mp_supported = false; -static struct intr_info *tmr_irqlist[MAXCPUS]; - -void handle_local_tmr(void); - -/* - * Add local timer IRQ stat - */ -static inline void -tmr_irqstat_add(struct cpu_info *ci) -{ - tmr_irqlist[ci->idx] = intr_info_alloc("LAPIC", "LAPIC-TMR"); - tmr_irqlist[ci->idx]->affinity = ci->idx; - intr_register(tmr_irqlist[ci->idx]); -} - -/* - * Update local timer IRQ stats from - * interrupt. - */ -void -handle_local_tmr(void) -{ - struct cpu_info *ci = this_cpu(); - - ++tmr_irqlist[ci->idx]->count; -} - -static void -ap_trampoline(struct limine_smp_info *si) -{ - static struct spinlock lock = {0}; - struct cpu_info *ci; - - spinlock_acquire(&lock); - - pre_init(); - processor_init(); - - ci = this_cpu(); - cpu_attach(ci); - tmr_irqstat_add(ci); - - spinlock_release(&lock); - sched_enter(); - - /* Should not be reached */ - __assert(0); - __builtin_unreachable(); -} - -/* - * Returns true if SMP is supported. - */ -bool -mp_supported(void) -{ - return is_mp_supported; -} - -void -ap_bootstrap(struct cpu_info *ci) -{ - struct limine_smp_response *resp = g_smp_req.response; - struct limine_smp_info **cpus; - size_t cpu_init_counter; - - /* Should not happen */ - __assert(resp != NULL); - - cpus = resp->cpus; - cpu_init_counter = resp->cpu_count - 1; - - cpu_attach(ci); - tmr_irqstat_add(ci); - - if (resp->cpu_count == 1) { - pr_trace("CPU has 1 core, no APs to bootstrap...\n"); - return; - } - - pr_trace("Bootstrapping %d cores...\n", cpu_init_counter); - for (size_t i = 0; i < resp->cpu_count; ++i) { - if (ci->id == cpus[i]->lapic_id) { - pr_trace("Skip %d (BSP)... continue\n", ci->id); - continue; - } - - cpus[i]->goto_address = ap_trampoline; - } -} diff --git a/sys/arch/amd64/amd64/gdt.c b/sys/arch/amd64/amd64/gdt.c deleted file mode 100644 index f48e27a..0000000 --- a/sys/arch/amd64/amd64/gdt.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -struct gdt_entry g_gdt[256] = { - /* Null */ - {0}, - - /* Kernel code (0x8) */ - { - .limit = 0x0000, - .base_low = 0x0000, - .base_mid = 0x00, - .access = 0x9A, - .granularity = 0x20, - .base_hi = 0x00 - }, - - /* Kernel data (0x10) */ - { - .limit = 0x0000, - .base_low = 0x0000, - .base_mid = 0x00, - .access = 0x92, - .granularity = 0x00, - .base_hi = 0x00 - }, - - /* User code (0x18) */ - { - .limit = 0x0000, - .base_low = 0x0000, - .base_mid = 0x00, - .access = 0xFA, - .granularity = 0xAF, - .base_hi = 0x00 - }, - - /* User data (0x20) */ - { - .limit = 0x0000, - .base_low = 0x0000, - .base_mid = 0x00, - .access = 0xF2, - .granularity = 0x00, - .base_hi = 0x00 - }, - - /* TSS segment (0x28) */ - {0} -}; - -struct gdt_entry *g_gdt_tss = &g_gdt[GDT_TSS]; - -struct gdtr g_gdtr = { - .limit = sizeof(struct gdt_entry) * 256 - 1, - .offset = (uintptr_t)&g_gdt[0] -}; diff --git a/sys/arch/amd64/amd64/hpet.c b/sys/arch/amd64/amd64/hpet.c deleted file mode 100644 index 69dc0dd..0000000 --- a/sys/arch/amd64/amd64/hpet.c +++ /dev/null @@ -1,208 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -__MODULE_NAME("hpet"); -__KERNEL_META("$Hyra$: hpet.c, Ian Marco Moffett, " - "HPET driver"); - -#define pr_trace(fmt, ...) kprintf("hpet: " fmt, ##__VA_ARGS__) -#define pr_error(...) pr_trace(__VA_ARGS__) - -#define HPET_REG_CAPS 0x00 -#define HPET_GENERAL_CONFIG 0x10 -#define HPET_REG_MAIN_COUNTER 0xF0 - -#define CAP_REV_ID(caps) __SHIFTOUT(caps, 0xFF) -#define CAP_NUM_TIM(caps) __SHIFTOUT(caps, 0x1F << 8) -#define CAP_COUNT_SIZE(caps) __SHIFTOUT(caps, __BIT(13)) -#define CAP_VENDOR_ID(caps) __SHIFTOUT(caps, 0xFFFF << 16) -#define CAP_CLK_PERIOD(caps) (caps >> 32) - -#define FSEC_PER_SECOND 1000000000000000ULL -#define USEC_PER_SECOND 1000000ULL - -static struct timer timer = { 0 }; -static struct hpet *acpi_hpet = NULL; -static void *hpet_base = NULL; -static bool is_faulty = false; - -/* - * Read from HPET register space. - * - * @reg: Register to read from. - */ -static inline uint64_t -hpet_read(uint32_t reg) -{ - void *addr; - - addr = (void *)((uintptr_t)hpet_base + reg); - return mmio_read64(addr); -} - -/* - * Write to HPET register space. - * - * @reg: Register to write to. - * @val: Value to write. - */ -static inline void -hpet_write(uint32_t reg, uint64_t val) -{ - void *addr; - - addr = (void *)((uintptr_t)hpet_base + reg); - mmio_write64(addr, val); -} - -static int -hpet_sleep(uint64_t n, uint64_t units) -{ - uint64_t caps; - uint32_t period; - uint64_t counter_val; - volatile size_t ticks; - - /* Don't even try if faulty, would probably cause deadlock */ - if (is_faulty) { - return EXIT_FAILURE; - } - - caps = hpet_read(HPET_REG_CAPS); - period = CAP_CLK_PERIOD(caps); - counter_val = hpet_read(HPET_REG_MAIN_COUNTER); - - ticks = counter_val + (n * (units / period)); - - while (hpet_read(HPET_REG_MAIN_COUNTER) < ticks) { - hint_spinwait(); - } - - return EXIT_SUCCESS; -} - -int -hpet_msleep(size_t ms) -{ - return hpet_sleep(ms, 1000000000000); -} - -int -hpet_usleep(size_t us) -{ - return hpet_sleep(us, 1000000000); -} - -int -hpet_nsleep(size_t ns) -{ - return hpet_sleep(ns, 1000000); -} - -static size_t -hpet_time_usec(void) -{ - uint64_t period, freq, caps; - uint64_t counter; - - caps = hpet_read(HPET_REG_CAPS); - period = CAP_CLK_PERIOD(caps); - freq = FSEC_PER_SECOND / period; - - counter = hpet_read(HPET_REG_MAIN_COUNTER); - return (counter * USEC_PER_SECOND) / freq; -} - -static size_t -hpet_time_sec(void) -{ - return hpet_time_usec() / USEC_PER_SECOND; -} - -int -hpet_init(void) -{ - struct acpi_gas *gas; - uint64_t caps; - - acpi_hpet = acpi_query("HPET"); - if (acpi_hpet == NULL) - return 1; /* Not found */ - - gas = &acpi_hpet->gas; - hpet_base = (void *)gas->address; - caps = hpet_read(HPET_REG_CAPS); - - /* Ensure caps aren't bogus */ - if (CAP_REV_ID(caps) == 0) { - pr_error("Found bogus revision, assuming faulty\n"); - is_faulty = true; - return 1; - } - if (CAP_CLK_PERIOD(caps) > 0x05F5E100) { - /* - * The spec states this counter clk period - * must be <= 0x05F5E100. So we'll consider it - * as bogus if it exceeds this value - */ - pr_error("Found bogus COUNTER_CLK_PERIOD, assuming faulty\n"); - pr_trace("HPET REV - 0x%x\n", CAP_REV_ID(caps)); - pr_trace("COUNTER_CLK_PERIOD - 0x%x\n", CAP_CLK_PERIOD(caps)); - is_faulty = true; - return 1; - } - - pr_trace("HPET integrity verified\n"); - - hpet_write(HPET_REG_MAIN_COUNTER, 0); - hpet_write(HPET_GENERAL_CONFIG, 1); - - /* Setup the timer descriptor */ - timer.name = "HIGH_PRECISION_EVENT_TIMER"; - timer.msleep = hpet_msleep; - timer.usleep = hpet_usleep; - timer.nsleep = hpet_nsleep; - timer.get_time_usec = hpet_time_usec; - timer.get_time_sec = hpet_time_sec; - register_timer(TIMER_GP, &timer); - - /* Not faulty */ - is_faulty = false; - return 0; -} diff --git a/sys/arch/amd64/amd64/idt.c b/sys/arch/amd64/amd64/idt.c deleted file mode 100644 index 03a2af0..0000000 --- a/sys/arch/amd64/amd64/idt.c +++ /dev/null @@ -1,66 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -static struct idt_entry idt[256]; -static struct idtr idtr = { - .limit = sizeof(struct idt_entry) * 256 - 1, - .offset = (uintptr_t)&idt[0] -}; - -void -idt_load(void) -{ - LIDT(idtr); -} - -void -idt_set_desc(uint8_t vec, uint8_t type, uintptr_t isr, uint8_t ist) -{ - struct idt_entry *desc; - - if (vec >= 255) { - /* Invalid vector */ - return; - } - - desc = &idt[vec]; - desc->off_lo = __SHIFTOUT(isr, __MASK(16)); - desc->off_mid = __SHIFTOUT(isr, __MASK(16) << 16); - desc->off_hi = __SHIFTOUT(isr, __MASK(32) << 32); - desc->segsel = 0x8; /* Kernel CS */ - desc->type = type; - desc->dpl = 3; - desc->p = 1; - desc->zero = 0; - desc->zero1 = 0; - desc->reserved = 0; - desc->ist = ist; -} diff --git a/sys/arch/amd64/amd64/ioapic.c b/sys/arch/amd64/amd64/ioapic.c deleted file mode 100644 index 5dfdfa8..0000000 --- a/sys/arch/amd64/amd64/ioapic.c +++ /dev/null @@ -1,200 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -__MODULE_NAME("ioapic"); -__KERNEL_META("$Hyra$: ioapic.c, Ian Marco Moffett, " - "I/O APIC driver"); - -#define pr_trace(fmt, ...) kprintf("ioapic: " fmt, ##__VA_ARGS__) -#define IOAPIC_BASE_OFF(off) ((void *)((uintptr_t)ioapic_base + off)) - -static void *ioapic_base = NULL; - -/* - * Reads a 32 bit value from the IOAPIC - * register space. - * - * @reg: Register to read from. - */ -static uint32_t -ioapic_readl(uint16_t reg) -{ - mmio_write32(IOAPIC_BASE_OFF(IOREGSEL), reg); - return mmio_read32(IOAPIC_BASE_OFF(IOWIN)); -} - -/* - * Writes a 32 bit value to the IOAPIC - * register space. - * - * @reg: Register to write to. - * @val: Value to write. - */ -static void -ioapic_writel(uint16_t reg, uint32_t val) -{ - mmio_write32(IOAPIC_BASE_OFF(IOREGSEL), reg); - mmio_write32(IOAPIC_BASE_OFF(IOWIN), val); -} - -/* - * Reads an I/O APIC redirection entry. - * - * @entry: Entry variable to read into. - * @index: Index to read. - */ -static void -ioapic_read_redentry(union ioapic_redentry *entry, uint8_t index) -{ - uint32_t lo, hi; - - lo = ioapic_readl(IOREDTBL + index * 2); - hi = ioapic_readl(IOREDTBL + index * 2 + 1); - - entry->value = ((uint64_t)hi << 32) | lo; -} - -/* - * Writes an I/O APIC redirection entry. - * - * @entry: Entry variable to write. - * @index: Index to write to. - */ -static void -ioapic_write_redentry(const union ioapic_redentry *entry, uint8_t index) -{ - ioapic_writel(IOREDTBL + index * 2, (uint32_t)entry->value); - ioapic_writel(IOREDTBL + index * 2 + 1, (uint32_t)(entry->value >> 32)); -} - -/* - * Mask I/O APIC pin with "raw" pin number - * (Global System Interrupt) - * - * @gsi: Global System Interrupt number - */ -void -ioapic_gsi_mask(uint8_t gsi) -{ - union ioapic_redentry redentry; - - ioapic_read_redentry(&redentry, gsi); - redentry.interrupt_mask = 1; - ioapic_write_redentry(&redentry, gsi); -} - -/* - * Unmask I/O APIC pin with "raw" pin number - * (Global System Interrupt) - * - * @gsi: Global System Interrupt number - */ -void -ioapic_gsi_unmask(uint8_t gsi) -{ - union ioapic_redentry redentry; - - ioapic_read_redentry(&redentry, gsi); - redentry.interrupt_mask = 0; - ioapic_write_redentry(&redentry, gsi); -} - -/* - * Masks I/O APIC pin via IRQ number - * - * @irq: Interrupt Request number - */ -void -ioapic_irq_mask(uint8_t irq) -{ - uint8_t gsi; - - gsi = irq_to_gsi(irq); - ioapic_gsi_mask(gsi); -} - -/* - * Unmasks I/O APIC pin via IRQ number - * - * @irq: Interrupt Request number - */ -void -ioapic_irq_unmask(uint8_t irq) -{ - uint8_t gsi; - - gsi = irq_to_gsi(irq); - ioapic_gsi_unmask(gsi); -} - -void -ioapic_set_base(void *mmio_base) -{ - if (ioapic_base == NULL) - ioapic_base = mmio_base; -} - -void -ioapic_set_vec(uint8_t irq, uint8_t vector) -{ - union ioapic_redentry redentry; - uint8_t gsi = irq_to_gsi(irq); - - ioapic_read_redentry(&redentry, gsi); - redentry.vector = vector; - ioapic_write_redentry(&redentry, gsi); -} - -void -ioapic_init(void) -{ - size_t tmp; - uint8_t redir_entry_cnt; - - /* Sanity check */ - if (ioapic_base == NULL) - panic("ioapic base not set!\n"); - - tmp = ioapic_readl(IOAPICVER); - redir_entry_cnt = __SHIFTOUT(tmp, 0xFF << 16) + 1; - - pr_trace("Masking %d GSIs...\n", redir_entry_cnt); - - for (uint8_t i = 0; i < redir_entry_cnt; ++i) { - ioapic_gsi_mask(i); - } -} diff --git a/sys/arch/amd64/amd64/lapic.c b/sys/arch/amd64/amd64/lapic.c deleted file mode 100644 index 81432dd..0000000 --- a/sys/arch/amd64/amd64/lapic.c +++ /dev/null @@ -1,435 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -__MODULE_NAME("lapic"); -__KERNEL_META("$Hyra$: lapic.c, Ian Marco Moffett, " - "Local APIC driver"); - -#define pr_trace(fmt, ...) kprintf("lapic: " fmt, ##__VA_ARGS__) -#define pr_error(...) pr_trace(__VA_ARGS__) - -/* - * Only calls pr_trace if we are the BSP. - */ -#define BSP_TRACE(...) do { \ - uint64_t msr_val; \ - \ - msr_val = rdmsr(IA32_APIC_BASE_MSR); \ - if (__TEST(msr_val, 1 << 8)) { \ - pr_trace(__VA_ARGS__); \ - } \ - } while (0); - -static struct timer lapic_timer = { 0 }; - -__naked void lapic_tmr_isr(void); - -/* - * Returns true if LAPIC is supported. - * - * LAPIC is supported if CPUID.(EAX=1H):EDX[9] == 1 - */ -static inline bool -lapic_check_support(void) -{ - uint32_t eax, edx, tmp; - - __CPUID(0x00000001, eax, tmp, tmp, edx); - return __TEST(edx, 1 << 9); -} - -/* - * Reads a 32 bit value from Local APIC - * register space. - * - * @reg: Register to read from. - */ -static inline uint64_t -lapic_readl(uint32_t reg) -{ - void *addr; - const struct cpu_info *ci = this_cpu(); - - if (!ci->has_x2apic) { - addr = (void *)((uintptr_t)ci->lapic_base + reg); - return mmio_read32(addr); - } else { - reg >>= 4; - return rdmsr(x2APIC_MSR_BASE + reg); - } -} - -/* - * Writes a 32 bit value to Local APIC - * register space. - * - * @reg: Register to write to. - */ -static inline void -lapic_writel(uint32_t reg, uint64_t val) -{ - void *addr; - const struct cpu_info *ci = this_cpu(); - - if (!ci->has_x2apic) { - addr = (void *)((uintptr_t)ci->lapic_base + reg); - mmio_write32(addr, val); - } else { - reg >>= 4; - wrmsr(x2APIC_MSR_BASE + reg, val); - } -} - -/* - * Calibrates the Local APIC timer - Timer abstraction - */ -static size_t -lapic_timer_calibrate(void) -{ - size_t freq; - - lapic_timer_init(&freq); - return freq; -} - -/* - * Stops the Local APIC timer - Timer abstraction - */ -static void -lapic_timer_stop(void) -{ - lapic_writel(LAPIC_INIT_CNT, 0); - lapic_writel(LAPIC_LVT_TMR, LAPIC_LVT_MASK); -} - -/* - * Set bits within a LAPIC register - * without overwriting the whole thing. - * - * @reg: Reg with bits to be set. - * @value: Value in reg will be ORd with this. - */ -static inline void -lapic_reg_set(uint32_t reg, uint32_t value) -{ - uint32_t old; - - old = lapic_readl(reg); - lapic_writel(reg, old | value); -} - -/* - * Clear bits within a LAPIC register - * without overwriting the whole thing. - * - * @reg: Reg with bits to be cleared. - * @value: Value in reg will be cleared by this value. - */ -static inline void -lapic_reg_clear(uint32_t reg, uint32_t value) -{ - uint32_t old; - - old = lapic_readl(reg); - lapic_writel(reg, old & ~(value)); -} - -/* - * Reads the Local APIC ID of the - * current processor. - */ -static inline uint32_t -lapic_get_id(const struct cpu_info *ci) -{ - if (!ci->has_x2apic) { - return (lapic_readl(LAPIC_ID) >> 24) & 0xF; - } else { - return lapic_readl(LAPIC_ID); - } -} - -/* - * Checks if the processor supports x2APIC - * mode. Returns true if so. - */ -static inline bool -has_x2apic(void) -{ - uint32_t ecx, tmp; - - __CPUID(0x00000001, tmp, tmp, ecx, tmp); - return __TEST(ecx, 1 << 21); -} - -/* - * Updates LDR to LAPIC_STARTUP_LID. - * - * XXX: This does *not* happen with x2APIC - * as the LDR register in x2APIC mode - * is readonly. - */ -static inline void -lapic_set_ldr(struct cpu_info *ci) -{ - if (!ci->has_x2apic) - lapic_writel(LAPIC_LDR, LAPIC_STARTUP_LID); -} - -/* - * Starts the Local APIC countdown timer... - * - * @mask: True to mask timer. - * @mode: Timer mode. - * @count: Count to start at. - */ -static inline void -lapic_timer_start(bool mask, uint8_t mode, uint32_t count) -{ - uint32_t tmp; - - tmp = (mode << 17) | (mask << 16) | SYSVEC_LAPIC_TIMER; - lapic_writel(LAPIC_LVT_TMR, tmp); - lapic_writel(LAPIC_DCR, 0); - lapic_writel(LAPIC_INIT_CNT, count); -} - -/* - * Start Local APIC timer oneshot with number - * of ticks to count down from. - * - * @mask: If `true', timer will be masked, `count' should be 0. - * @count: Number of ticks. - */ -void -lapic_timer_oneshot(bool mask, uint32_t count) -{ - lapic_timer_start(mask, LVT_TMR_ONESHOT, count); -} - -/* - * Start Local APIC timer oneshot in microseconds. - * - * @us: Microseconds. - */ -void -lapic_timer_oneshot_us(size_t us) -{ - uint64_t ticks; - struct cpu_info *ci = this_cpu(); - - ticks = us * (ci->lapic_tmr_freq / 1000000); - lapic_timer_oneshot(false, ticks); -} - -/* - * Send an Interprocessor interrupt. - * - * @id: Target LAPIC ID - * @shorthand: Dest shorthand - * @vector: Interrupt vector - */ -void -lapic_send_ipi(uint8_t id, uint8_t shorthand, uint8_t vector) -{ - const uint32_t x2APIC_IPI_SELF = 0x3F0; - uint64_t icr_lo = vector | IPI_DEST_PHYSICAL; - bool x2apic_supported = has_x2apic(); - - if (x2apic_supported && shorthand == IPI_SHORTHAND_SELF) { - lapic_writel(x2APIC_IPI_SELF, vector); - return; - } - - switch (shorthand) { - case IPI_SHORTHAND_SELF: - icr_lo |= (1 << 18); - break; - case IPI_SHORTHAND_ALL: - icr_lo |= (2 << 18); - break; - case IPI_SHORTHAND_OTHERS: - icr_lo |= (3 << 18); - break; - } - - /* - * In contrast to xAPICs two 32-bit ICR registers, the x2APIC - * ICR register is one big 64-bit register, thus requiring only - * a single write. In xAPIC mode, the Delivery Status bit (bit 12) - * must be polled until clear. However, in x2APIC mode, this bit - * does not exist meaning we do not need to worry about it. - */ - if (x2apic_supported) { - lapic_writel(LAPIC_ICRLO, ((uint64_t)id << 32) | icr_lo); - } else { - lapic_writel(LAPIC_ICRHI, ((uint32_t)id << 24)); - lapic_writel(LAPIC_ICRLO, icr_lo); - while (__TEST(lapic_readl(LAPIC_ICRLO), __BIT(12))); - } -} - -void -lapic_send_eoi(void) -{ - lapic_writel(LAPIC_EOI, 0); -} - -/* - * Calibrates the Local APIC timer - * - * TODO: Disable interrupts and put them back in - * old state. - * - * XXX: Will unmask IRQs if masked; will restore - * IRQ mask state after. - */ -void -lapic_timer_init(size_t *freq_out) -{ - struct cpu_info *ci; - bool irq_mask = is_intr_mask(); - uint16_t init_tick, final_tick; - size_t total_ticks; - const uint16_t SAMPLES = 0xFFFF; - - ci = this_cpu(); - - if (irq_mask) { - __ASMV("sti"); - } - - /* Stop the timer */ - lapic_timer_oneshot(true, 0); - - i8254_set_reload(SAMPLES); - init_tick = i8254_get_count(); - - lapic_writel(LAPIC_INIT_CNT, SAMPLES); - while (lapic_readl(LAPIC_CUR_CNT) != 0); - - final_tick = i8254_get_count(); - total_ticks = init_tick - final_tick; - - /* Calculate the frequency */ - CPU_INFO_LOCK(ci); - ci->lapic_tmr_freq = (SAMPLES / total_ticks) * i8254_DIVIDEND; - if (freq_out != NULL) *freq_out = ci->lapic_tmr_freq; - CPU_INFO_UNLOCK(ci); - - /* Stop timer again */ - lapic_timer_oneshot(true, 0); - - if (irq_mask) { - __ASMV("cli"); - } -} - -void -lapic_init(void) -{ - struct cpu_info *ci; - union tss_stack tmr_stack; - uint64_t tmp; - - if (!lapic_check_support()) { - /* - * Hyra currently depends on the existance - * of a Local APIC. - */ - panic("This machine does not support LAPIC!\n"); - } - - /* Get the current processor, and lock its structure */ - ci = this_cpu(); - CPU_INFO_LOCK(ci); - - ci->has_x2apic = has_x2apic(); - - /* Sanity check */ - if (ci->lapic_base == NULL) { - panic("LAPIC base not set!\n"); - } - - /* Hardware enable the Local APIC */ - tmp = rdmsr(IA32_APIC_BASE_MSR); - tmp |= ci->has_x2apic << x2APIC_ENABLE_SHIFT; - wrmsr(IA32_APIC_BASE_MSR, tmp | LAPIC_HW_ENABLE); - - /* Software enable the Local APIC via SVR */ - lapic_reg_set(LAPIC_SVR, LAPIC_SW_ENABLE); - - BSP_TRACE("Enabled Local APIC for BSP\n"); - lapic_set_ldr(ci); - - /* Setup the timer descriptor */ - lapic_timer.name = "LAPIC_INTEGRATED_TIMER"; - lapic_timer.calibrate = lapic_timer_calibrate; - lapic_timer.stop = lapic_timer_stop; - lapic_timer.oneshot_us = lapic_timer_oneshot_us; - - /* Register the timer for scheduler usage */ - register_timer(TIMER_SCHED, &lapic_timer); - - /* Set the Local APIC ID */ - ci->id = lapic_get_id(ci); - BSP_TRACE("BSP Local APIC ID: %d\n", ci->id); - - /* Setup LAPIC Timer TSS stack */ - if (tss_alloc_stack(&tmr_stack, vm_get_page_size()) != 0) { - panic("Failed to allocate LAPIC TMR stack! (1 page of mem)\n"); - } - tss_update_ist(ci, tmr_stack, IST_SCHED); - CPU_INFO_UNLOCK(ci); - - /* Calibrate timer */ - lapic_timer_init(NULL); - - /* Setup LAPIC Timer ISR */ - idt_set_desc(SYSVEC_LAPIC_TIMER, IDT_INT_GATE_FLAGS, - (uintptr_t)lapic_tmr_isr, IST_SCHED); - - BSP_TRACE("LAPIC Timer on Interrupt Stack %d (IST_SCHED) with vector 0x%x\n", - IST_SCHED, SYSVEC_LAPIC_TIMER); -} diff --git a/sys/arch/amd64/amd64/local_intr.S b/sys/arch/amd64/amd64/local_intr.S deleted file mode 100644 index c2d53e9..0000000 --- a/sys/arch/amd64/amd64/local_intr.S +++ /dev/null @@ -1,47 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -__KERNEL_META "$Hyra$: local_intr.S, Ian Marco Moffett, \ - Routines for handling Local Interrupts" - -.text - .globl lapic_tmr_isr - -lapic_tmr_isr: - push_trapframe $0 - mov %rsp, %rdi - call sched_context_switch - call handle_local_tmr - call lapic_send_eoi - pop_trapframe - iretq diff --git a/sys/arch/amd64/amd64/machdep.c b/sys/arch/amd64/amd64/machdep.c deleted file mode 100644 index 0c2718a..0000000 --- a/sys/arch/amd64/amd64/machdep.c +++ /dev/null @@ -1,401 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -__MODULE_NAME("machdep"); -__KERNEL_META("$Hyra$: machdep.c, Ian Marco Moffett, " - "Core machine dependent code"); - -#define ISR(func) ((uintptr_t)func) -#define INIT_FLAG_IOAPIC 0x00000001U -#define INIT_FLAG_ACPI 0x00000002U - -/* Set by kconf(1) */ -#define PANIC_BEEP_HZ __PANIC_BEEP_HZ -#define PANIC_BEEP __PANIC_BEEP - -void syscall_isr(void); - -__attr(interrupt) -static void -halt_isr(void *sf) -{ - processor_halt(); -} - -static inline void -init_tss(struct cpu_info *cur_cpu) -{ - struct tss_desc *desc; - - desc = (struct tss_desc *)g_gdt_tss; - write_tss(cur_cpu, desc); - tss_load(); -} - -static void -interrupts_init(void) -{ - idt_set_desc(0x0, IDT_TRAP_GATE_FLAGS, ISR(arith_err), 0); - idt_set_desc(0x2, IDT_TRAP_GATE_FLAGS, ISR(nmi), 0); - idt_set_desc(0x3, IDT_TRAP_GATE_FLAGS, ISR(breakpoint_handler), 0); - idt_set_desc(0x4, IDT_TRAP_GATE_FLAGS, ISR(overflow), 0); - idt_set_desc(0x5, IDT_TRAP_GATE_FLAGS, ISR(bound_range), 0); - idt_set_desc(0x6, IDT_TRAP_GATE_FLAGS, ISR(invl_op), 0); - idt_set_desc(0x8, IDT_TRAP_GATE_FLAGS, ISR(double_fault), 0); - idt_set_desc(0xA, IDT_TRAP_GATE_FLAGS, ISR(invl_tss), 0); - idt_set_desc(0xB, IDT_TRAP_GATE_FLAGS, ISR(segnp), 0); - idt_set_desc(0xC, IDT_TRAP_GATE_FLAGS, ISR(ss_fault), 0); - idt_set_desc(0xD, IDT_TRAP_GATE_FLAGS, ISR(general_prot), 0); - idt_set_desc(0xE, IDT_TRAP_GATE_FLAGS, ISR(page_fault), 0); - idt_set_desc(0x80, IDT_INT_GATE_USER, ISR(syscall_isr), 0); - idt_set_desc(SYSVEC_HLT, IDT_INT_GATE_FLAGS, ISR(halt_isr), 0); - idt_load(); -} - -static bool -is_sse_supported(void) -{ - uint32_t edx, unused; - - __CPUID(0x00000001, unused, unused, unused, edx); - return __TEST(edx, __BIT(25)) && __TEST(edx, __BIT(26)); -} - -static const char* -backtrace_addr_to_name(uintptr_t addr, off_t *off) -{ - uintptr_t prev_addr = 0; - const char *name = NULL; - - for (size_t i = 0;;) { - if (g_ksym_table[i].addr > addr) { - *off = addr - prev_addr; - return name; - } - - prev_addr = g_ksym_table[i].addr; - name = g_ksym_table[i].name; - if (g_ksym_table[i++].addr == (uint64_t)-1) - break; - } - - return NULL; -} - -static void -backtrace(void) -{ - uintptr_t *rbp; - uintptr_t rip; - - off_t off; - const char *name; - - kprintf(OMIT_TIMESTAMP "** Backtrace **\n"); - __ASMV("mov %%rbp, %0" : "=r" (rbp) :: "memory"); - - while (1) { - rip = rbp[1]; - rbp = (uintptr_t *)rbp[0]; - name = backtrace_addr_to_name(rip, &off); - - if (rbp == NULL) - break; - if (name == NULL) - name = "???"; - - kprintf(OMIT_TIMESTAMP "[0x%p] <%s+0x%x>\n", rip, name, off); - } -} - -static void -panic_beep(void) -{ - struct timer tmr = {0}; - bool has_timer = true; - - if (req_timer(TIMER_GP, &tmr) != TMRR_SUCCESS) - has_timer = false; - if (tmr.msleep == NULL) - has_timer = false; - - /* - * If we can use the timer, beep twice to - * alert the user. - */ - if (has_timer) { - for (int i = 0; i < 2; ++i) { - pcspkr_tone(PANIC_BEEP_HZ, 200); - tmr.msleep(100); - } - } -} - -void -processor_halt(void) -{ - __ASMV("cli; hlt"); -} - -/* - * Send char to serial for debugging purposes. - */ -void -serial_dbgch(char c) -{ - uart8250_write(c); -} - -void -chips_init(void) -{ - /* Hyra requires HPET on x86_64 */ - if (hpet_init() != 0) - panic("Machine does not support HPET!\n"); - - pci_init(); -} - -/* - * These are critical things that need to be set up as soon as possible - * way before the processor_init() call. - */ -void -pre_init(void) -{ - static bool is_bsp = true; - - /* - * Certain things like serial ports, virtual memory, - * etc, need to be set up only once! These things - * are to be done on the BSP only... - */ - if (is_bsp) { - is_bsp = false; - - uart8250_try_init(); - vm_physseg_init(); - vm_init(); - } - interrupts_init(); - gdt_load(&g_gdtr); -} - -void -intr_mask(void) -{ - __ASMV("cli"); -} - -void -intr_unmask(void) -{ - __ASMV("sti"); -} - -/* - * Called last within panic() - */ -void -machine_panic(void) -{ - backtrace(); - - if (PANIC_BEEP) - panic_beep(); - - processor_halt(); -} - -void -cpu_halt_others(void) -{ - struct cpu_info *ci = this_cpu(); - - /* Is the current CPU structure even valid? */ - if (ci == NULL) - return; - - /* - * If the Local APIC base address is NULL, we can't - * use lapic_send_ipi() but we we can assume the APs - * are still parked. - */ - if (ci->lapic_base != NULL) - lapic_send_ipi(0, IPI_SHORTHAND_OTHERS, SYSVEC_HLT); -} - -int -processor_init_pcb(struct proc *proc) -{ - struct pcb *pcb = &proc->pcb; - const uint16_t FPU_FCW = 0x33F; - const uint32_t SSE_MXCSR = 0x1F80; - - /* Allocate FPU save area, aligned on a 16 byte boundary */ - pcb->fpu_state = PHYS_TO_VIRT(vm_alloc_pageframe(1)); - if (pcb->fpu_state == NULL) { - return -1; - } - - /* - * Setup x87 FPU control word and SSE MXCSR bits - * as per the sysv ABI - */ - __ASMV("fldcw %0\n" - "ldmxcsr %1" - :: "m" (FPU_FCW), - "m" (SSE_MXCSR) : "memory"); - - amd64_fxsave(pcb->fpu_state); - return 0; -} - -int -processor_free_pcb(struct proc *proc) -{ - struct pcb *pcb = &proc->pcb; - - if (pcb->fpu_state == NULL) { - return -1; - } - - vm_free_pageframe(VIRT_TO_PHYS(pcb->fpu_state), 1); - return 0; -} - -void -processor_switch_to(struct proc *old_td, struct proc *new_td) -{ - struct pcb *old_pcb = (old_td != NULL) ? &old_td->pcb : NULL; - struct pcb *new_pcb = &new_td->pcb; - - if (old_pcb != NULL) { - amd64_fxsave(old_pcb->fpu_state); - } - amd64_fxrstor(new_pcb->fpu_state); -} - -void -cpu_reset(void) -{ - for (;;) { - /* Pulse the reset line */ - outb(0x64, 0xFE); - } -} - -void -processor_init(void) -{ - /* Indicates what doesn't need to be init anymore */ - static uint8_t init_flags = 0; - static uint64_t reg_tmp; - struct cpu_info *cur_cpu; - - /* Create our cpu_info structure */ - cur_cpu = dynalloc(sizeof(struct cpu_info)); - __assert(cur_cpu != NULL); - memset(cur_cpu, 0, sizeof(struct cpu_info)); - - /* Set %GS to cpu_info */ - amd64_write_gs_base((uintptr_t)cur_cpu); - - /* Try to enable SSE/SSE2 */ - if (is_sse_supported()) { - reg_tmp = amd64_read_cr0(); - reg_tmp &= ~(__BIT(2)); - reg_tmp |= __BIT(1); - amd64_write_cr0(reg_tmp); - - /* Enable FXSAVE/FXRSTOR */ - reg_tmp = amd64_read_cr4(); - reg_tmp |= 3 << 9; - amd64_write_cr4(reg_tmp); - } else { - panic("SSE/SSE2 not supported!\n"); - } - - CPU_INFO_LOCK(cur_cpu); - init_tss(cur_cpu); - - /* Set up some ACPI things */ - if (!__TEST(init_flags, INIT_FLAG_ACPI)) { - /* - * Parse the MADT... This is needed to fetch required information - * to set up the Local APIC(s) and I/O APIC(s)... - */ - init_flags |= INIT_FLAG_ACPI; - acpi_parse_madt(cur_cpu); - } - - /* Setup I/O APIC */ - if (!__TEST(init_flags, INIT_FLAG_IOAPIC)) { - init_flags |= INIT_FLAG_IOAPIC; - ioapic_init(); - } - - cur_cpu->lapic_base = acpi_get_lapic_base(); - CPU_INFO_UNLOCK(cur_cpu); - lapic_init(); - - /* Use spectre mitigation if enabled */ - if (try_spectre_mitigate != NULL) - try_spectre_mitigate(); - - __ASMV("sti"); -} diff --git a/sys/arch/amd64/amd64/pmap.c b/sys/arch/amd64/amd64/pmap.c deleted file mode 100644 index 9443727..0000000 --- a/sys/arch/amd64/amd64/pmap.c +++ /dev/null @@ -1,389 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -/* - * Page-Table Entry (PTE) flags - * - * See Intel SDM Vol 3A, Section 4.5, Table 4-19 - */ -#define PTE_ADDR_MASK 0x000FFFFFFFFFF000 -#define PTE_P __BIT(0) /* Present */ -#define PTE_RW __BIT(1) /* Writable */ -#define PTE_US __BIT(2) /* User r/w allowed */ -#define PTE_PWT __BIT(3) /* Page-level write-through */ -#define PTE_PCD __BIT(4) /* Page-level cache disable */ -#define PTE_ACC __BIT(5) /* Accessed */ -#define PTE_DIRTY __BIT(6) /* Dirty (written-to page) */ -#define PTE_PAT __BIT(7) -#define PTE_GLOBAL __BIT(8) -#define PTE_NX __BIT(63) /* Execute-disable */ - -__attr(interrupt) static void -tlb_shootdown_isr(void *sf) -{ - struct cpu_info *ci = this_cpu(); - struct intr_info *intr_info = ci->tlb_shootdown; - - /* Setup interrupt information if needed */ - if (ci->tlb_shootdown == NULL) { - intr_info = intr_info_alloc("TLB-Shootdown", "LAPIC-IPI"); - intr_info->affinity = ci->id; - - ci->tlb_shootdown = intr_info; - intr_register(intr_info); - } - - ++intr_info->count; - tlb_flush(ci->tlb_flush_ptr); - - ci->tlb_flush_ptr = 0; - lapic_send_eoi(); -} - -static void -tlb_shootdown(vaddr_t flush_va) -{ - struct cpu_info *curcpu, *ci = NULL; - size_t idx = 0; - - curcpu = this_cpu(); - while ((ci = cpu_get(idx++)) != NULL) { - if (ci->id == curcpu->id) - continue; - - ci->tlb_flush_ptr = flush_va; - } - - lapic_send_ipi(0, IPI_SHORTHAND_OTHERS, SYSVEC_TLB); -} - -/* - * Convert pmap prot flags to PTE flags. - */ -static uint64_t -pmap_prot_to_pte(vm_prot_t prot) -{ - uint64_t pte_flags = PTE_P | PTE_NX; - - if (__TEST(prot, PROT_WRITE)) - pte_flags |= PTE_RW; - if (__TEST(prot, PROT_EXEC)) - pte_flags &= ~(PTE_NX); - if (__TEST(prot, PROT_USER)) - pte_flags |= PTE_US; - - return pte_flags; -} - -/* - * Returns index for a specific pagemap level. - * - * @level: Requested level. - * @va: Virtual address. - */ -static size_t -pmap_get_level_index(uint8_t level, vaddr_t va) -{ - /* TODO: Make this bullshit assertion better */ - __assert(level <= 4 && level != 0); - - switch (level) { - case 4: - return (va >> 39) & 0x1FF; - case 3: - return (va >> 30) & 0x1FF; - case 2: - return (va >> 21) & 0x1FF; - case 1: - return (va >> 12) & 0x1FF; - default: /* Should not be reachable */ - return 0; - } -} - -static inline uintptr_t * -pmap_extract(uint8_t level, vaddr_t va, uintptr_t *pmap, bool allocate) -{ - uintptr_t next; - uintptr_t level_alloc; - size_t idx; - - idx = pmap_get_level_index(level, va); - - if (__TEST(pmap[idx], PTE_P)) { - next = pmap[idx] & PTE_ADDR_MASK; - return PHYS_TO_VIRT(next); - } - - if (!allocate) { - return 0; - } - - /* - * TODO: If we are out of pageframes here, we don't want to panic - * here. We need to have some sort of clean error reporting. - */ - level_alloc = vm_alloc_pageframe(1); - __assert(level_alloc != 0); - - /* Zero the memory */ - memset(PHYS_TO_VIRT(level_alloc), 0, vm_get_page_size()); - - pmap[idx] = level_alloc | (PTE_P | PTE_RW | PTE_US); - return PHYS_TO_VIRT(level_alloc); -} - -/* - * Modify a page table by writing `val' to it. - * - * @ctx: Virtual memory context. - * @vas: Virtual address space. - * @va: Virtual address. - * @alloc: True to alloc new entries. - * @res: Result - */ -static int -pmap_get_tbl(struct vm_ctx *ctx, struct vas vas, vaddr_t va, bool alloc, - uintptr_t **res) -{ - uintptr_t *pml4 = PHYS_TO_VIRT(vas.top_level); - uintptr_t *pdpt, *pd, *tbl; - int status = 0; - - pdpt = pmap_extract(4, va, pml4, alloc); - if (pdpt == NULL) { - status = 1; - goto done; - } - - pd = pmap_extract(3, va, pdpt, alloc); - if (pd == NULL) { - status = 1; - goto done; - } - - tbl = pmap_extract(2, va, pd, alloc); - if (tbl == NULL) { - status = 1; - goto done; - } - - *res = tbl; -done: - return status; -} - -/* - * Flush a virtual address. - * - * @va: VA to flush from TLB. - */ -static void -pmap_flush(vaddr_t va) -{ - /* - * Do TLB shootdown if multiple CPUs are listed. - * - * XXX: Some might not be listed during early - * startup. - */ - if (cpu_count() > 1) { - tlb_shootdown(va); - } - - tlb_flush(va); -} - -/* - * Modify a page table by writing `val' to it. - * - * TODO: Ensure operations here are serialized. - */ -static int -pmap_modify_tbl(struct vm_ctx *ctx, struct vas vas, vaddr_t va, size_t val) -{ - uintptr_t *tbl; - int status; - - if ((status = pmap_get_tbl(ctx, vas, va, true, &tbl) != 0)) { - return status; - } - - /* Map our page */ - tbl[pmap_get_level_index(1, va)] = val; - pmap_flush(va); - return 0; -} - -int -pmap_set_cache(struct vm_ctx *ctx, struct vas vas, vaddr_t va, int type) -{ - uintptr_t *tbl; - int status; - size_t idx; - - if ((status = pmap_get_tbl(ctx, vas, va, false, &tbl)) != 0) { - return status; - } - - idx = pmap_get_level_index(1, va); - - /* Set the policy based on the type */ - switch (type) { - case VM_CACHE_UC: - tbl[idx] |= PTE_PCD; - tbl[idx] &= ~(PTE_PWT); - break; - case VM_CACHE_WT: - tbl[idx] &= ~(PTE_PCD); - tbl[idx] |= PTE_PWT; - break; - default: - /* Invalid type */ - return 1; - } - - pmap_flush(va); - return 0; -} - -int -pmap_map(struct vm_ctx *ctx, struct vas vas, vaddr_t va, paddr_t pa, - vm_prot_t prot) -{ - uint32_t flags = pmap_prot_to_pte(prot); - - return pmap_modify_tbl(ctx, vas, va, (pa | flags)); -} - -int -pmap_unmap(struct vm_ctx *ctx, struct vas vas, vaddr_t va) -{ - return pmap_modify_tbl(ctx, vas, va, 0); -} - -int -pmap_create_vas(struct vm_ctx *ctx, struct vas *res) -{ - struct vas current_vas = pmap_read_vas(); - struct vas new_vas = {0}; - uint64_t *src, *dest; - - /* - * We want to allocate a zeroed pageframe - * and copy the higher half to it. The lower - * half can remain zero for userland. - */ - new_vas.top_level = vm_alloc_pageframe(1); - - if (new_vas.top_level == 0) { - return -1; - } - - src = PHYS_TO_VIRT(current_vas.top_level); - dest = PHYS_TO_VIRT(new_vas.top_level); - - /* - * Copy the top half and zero the bottom - * half. - */ - for (size_t i = 0; i < 512; ++i) { - if (i < 256) { - dest[i] = 0; - continue; - } - dest[i] = src[i]; - } - - *res = new_vas; - return 0; -} - -void -pmap_switch_vas(struct vm_ctx *ctx, struct vas vas) -{ - uintptr_t cr3_val = vas.cr3_flags | vas.top_level; - - __ASMV("mov %0, %%cr3" - : - : "r" (cr3_val) - : "memory"); -} - -/* - * TODO: During the mapping of a virtual address, a level - * may be allocated. This function does not handle the - * freeing of allocated levels. We should keep track - * of levels allocated and free them here. - */ -int -pmap_free_vas(struct vm_ctx *ctx, struct vas vas) -{ - vm_free_pageframe(vas.top_level, 1); - return 0; -} - -struct vas -pmap_read_vas(void) -{ - struct vas vas; - uintptr_t cr3_raw; - - __ASMV("mov %%cr3, %0" - : "=r" (cr3_raw) - ); - - vas.cr3_flags = cr3_raw & ~PTE_ADDR_MASK; - vas.top_level = cr3_raw & PTE_ADDR_MASK; - vas.use_l5_paging = false; /* TODO: Check for support */ - vas.lock.lock = 0; - return vas; -} - -int -pmap_init(struct vm_ctx *ctx) -{ - idt_set_desc(SYSVEC_TLB, IDT_INT_GATE_FLAGS, - (uintptr_t)tlb_shootdown_isr, 0); - - return 0; -} diff --git a/sys/arch/amd64/amd64/spectre.S b/sys/arch/amd64/amd64/spectre.S deleted file mode 100644 index 08ff9f8..0000000 --- a/sys/arch/amd64/amd64/spectre.S +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -__KERNEL_META "$Hyra$: spectre.S, Ian Marco Moffett, \ - Spectre mitigation detection" - -.text -.globl __can_mitigate_spectre - -__can_mitigate_spectre: - xor %ecx, %ecx // NULL out ECX - mov $0x7, %eax // 0x7 (Check IBRS) - cpuid - - /* Check if supported (if EDX[26] == 1) */ - mov $1, %ebx - shl $26, %ebx - test %ebx, %edx - jnz supported -not_supported: - xor %rax, %rax - jmp 1f -supported: - mov $1, %rax -1: - ret diff --git a/sys/arch/amd64/amd64/spectre.c b/sys/arch/amd64/amd64/spectre.c deleted file mode 100644 index 05aa557..0000000 --- a/sys/arch/amd64/amd64/spectre.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include - -__MODULE_NAME("spectre"); -__KERNEL_META("$Hyra$: spectre.c, Ian Marco Moffett, " - "Spectre mitigation support"); - -#if __SPECTRE_MITIGATION == 1 - -/* - * Returns true if Indirect Branch Restricted Speculation (IBRS) - * is supported. - */ -__naked bool -__can_mitigate_spectre(void); - -/* - * Returns EXIT_FAILURE if not supported, returns - * EXIT_SUCCESS if mitigation is now active. - * - * This function will be NULL if spectre mitigation isn't enabled; - * therefore it is wise to verify to prevent access violations and - * undefined behaviour. - * - * This behaviour is governed by the __SPECTRE_MITIGATION define - * - * TODO: Try to enable others, not just IBRS - */ -__weak int -try_spectre_mitigate(void) -{ - uint64_t tmp; - static bool should_log = true; - - if (!__can_mitigate_spectre()) { - KINFO("IBRS not supported; spectre mitigation NOT enabled\n"); - return EXIT_FAILURE; - } - - /* This is called per processor, only log once */ - if (should_log) { - KINFO("IBRS supported; spectre mitigation enabled\n"); - should_log = false; - } - - tmp = rdmsr(IA32_SPEC_CTL); - tmp |= __BIT(0); /* IBRS */ - wrmsr(IA32_SPEC_CTL, tmp); - - return EXIT_SUCCESS; -} - -#endif /* __SPECTRE_MITIGATION == 1 */ diff --git a/sys/arch/amd64/amd64/syscall.S b/sys/arch/amd64/amd64/syscall.S deleted file mode 100644 index fe70523..0000000 --- a/sys/arch/amd64/amd64/syscall.S +++ /dev/null @@ -1,43 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - #include - #include - -__KERNEL_META "$Hyra$: syscall.S, Ian Marco Moffett, \ - Syscall ISR code" - -.text -.globl syscall_isr -syscall_isr: - push_trapframe $0 - mov %rsp, %rdi - call __syscall - pop_trapframe - iretq diff --git a/sys/arch/amd64/amd64/syscall.c b/sys/arch/amd64/amd64/syscall.c deleted file mode 100644 index 264c8df..0000000 --- a/sys/arch/amd64/amd64/syscall.c +++ /dev/null @@ -1,54 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -void -__syscall(struct trapframe *tf) -{ - struct syscall_args args = { - .code = tf->rax, - .arg0 = tf->rdi, - .arg1 = tf->rsi, - .arg2 = tf->rdx, - .arg3 = tf->r10, - .arg4 = tf->r9, - .arg5 = tf->r8, - .sp = tf->rsp, - .ip = tf->rip - }; - - if (args.code < __MAX_SYSCALLS && args.code > 0) { - args.code -= 1; - tf->rax = g_syscall_table[args.code](&args); - } - - tf->rip = args.ip; - tf->rsp = args.sp; -} diff --git a/sys/arch/amd64/amd64/trap.S b/sys/arch/amd64/amd64/trap.S deleted file mode 100644 index 3cf6888..0000000 --- a/sys/arch/amd64/amd64/trap.S +++ /dev/null @@ -1,155 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include - -__KERNEL_META "$Hyra$: trap.S, Ian Marco Moffett, \ - Trap handling routines" - -.text -.globl breakpoint_handler -breakpoint_handler: - push_trapframe_ec $TRAP_BREAKPOINT - - handle_trap - - /* TODO */ - cli - hlt - -.globl arith_err -arith_err: - push_trapframe_ec $TRAP_ARITH_ERR - - handle_trap - - /* TODO */ - cli - hlt - -.globl overflow -overflow: - push_trapframe_ec $TRAP_OVERFLOW - - handle_trap - - /* TODO */ - cli - hlt - -.globl bound_range -bound_range: - push_trapframe_ec $TRAP_BOUND_RANGE - - handle_trap - - /* TODO */ - cli - hlt - -.globl invl_op -invl_op: - push_trapframe_ec $TRAP_INVLOP - - handle_trap - - /* TODO */ - cli - hlt - -.globl double_fault -double_fault: - push_trapframe_ec $TRAP_DOUBLE_FAULT - - handle_trap - - /* TODO */ - cli - hlt - -.globl invl_tss -invl_tss: - push_trapframe_ec $TRAP_INVLTSS - - handle_trap - - /* TODO */ - cli - hlt - -.globl segnp -segnp: - push_trapframe_ec $TRAP_SEGNP - - handle_trap - - /* TODO */ - cli - hlt - -.globl general_prot -general_prot: - push_trapframe_ec $TRAP_PROTFLT - - handle_trap - - /* TODO */ - cli - hlt - -.globl page_fault -page_fault: - push_trapframe_ec $TRAP_PAGEFLT - - handle_trap - - pop_trapframe - iretq - -.globl nmi -nmi: - push_trapframe_ec $TRAP_NMI - - handle_trap - - /* TODO */ - cli - hlt - -.globl ss_fault -ss_fault: - push_trapframe_ec $TRAP_SS - - handle_trap - - /* TODO */ - cli - hlt diff --git a/sys/arch/amd64/amd64/trap.c b/sys/arch/amd64/amd64/trap.c deleted file mode 100644 index 531f2f5..0000000 --- a/sys/arch/amd64/amd64/trap.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -__MODULE_NAME("trap"); -__KERNEL_META("$Hyra$: trap.c, Ian Marco Moffett, " - "Trap handling"); - -#define pr_error(fmt, ...) kprintf("trap: " fmt, ##__VA_ARGS__) - -static const char *trap_type[] = { - [TRAP_BREAKPOINT] = "breakpoint", - [TRAP_ARITH_ERR] = "arithmetic error", - [TRAP_OVERFLOW] = "overflow", - [TRAP_BOUND_RANGE] = "bound range exceeded", - [TRAP_INVLOP] = "invalid opcode", - [TRAP_DOUBLE_FAULT] = "double fault", - [TRAP_INVLTSS] = "invalid TSS", - [TRAP_SEGNP] = "segment not present", - [TRAP_PROTFLT] = "general protection", - [TRAP_PAGEFLT] = "page fault", - [TRAP_NMI] = "non-maskable interrupt", - [TRAP_SS] = "stack-segment fault" -}; - -static const int TRAP_COUNT = __ARRAY_COUNT(trap_type); - -static inline vaddr_t -pf_faultaddr(void) -{ - uintptr_t cr2; - __ASMV("mov %%cr2, %0\n" : "=r" (cr2) :: "memory"); - return cr2; -} - -static inline vm_prot_t -pf_accesstype(struct trapframe *tf) -{ - vm_prot_t prot = 0; - uint64_t ec = tf->error_code; - - if (__TEST(ec, __BIT(1))) - prot |= PROT_WRITE; - if (__TEST(ec, __BIT(2))) - prot |= PROT_USER; - if (__TEST(ec, __BIT(4))) - prot |= PROT_EXEC; - - return prot; -} - -static void -dbg_errcode(struct trapframe *tf) -{ - uint64_t ec = tf->error_code; - - switch (tf->trapno) { - case TRAP_PAGEFLT: - kprintf(OMIT_TIMESTAMP - "bits (pwui): %c%c%c%c\n", - __TEST(ec, __BIT(0)) ? 'p' : '-', - __TEST(ec, __BIT(1)) ? 'w' : '-', - __TEST(ec, __BIT(2)) ? 'u' : '-', - __TEST(ec, __BIT(4)) ? 'i' : '-'); - break; - case TRAP_SS: - kprintf(OMIT_TIMESTAMP "ss: 0x%x\n", ec); - break; - } -} - -static void -trap_print(struct trapframe *tf) -{ - if (tf->trapno < TRAP_COUNT) { - kprintf(OMIT_TIMESTAMP "** Fatal %s **\n", trap_type[tf->trapno]); - } else { - kprintf(OMIT_TIMESTAMP "** Unknown trap %d **\n", tf->trapno); - } - - dbg_errcode(tf); -} - -static void -regdump(struct trapframe *tf) -{ - uintptr_t cr3, cr2 = pf_faultaddr(); - - __ASMV("mov %%cr3, %0\n" - : "=r" (cr3) - : - : "memory" - ); - - kprintf(OMIT_TIMESTAMP - "RAX=%p RCX=%p RDX=%p\n" - "RBX=%p RSI=%p RDI=%p\n" - "RFL=%p CR2=%p CR3=%p\n" - "RBP=%p RSP=%p RIP=%p\n", - tf->rax, tf->rcx, tf->rdx, - tf->rbx, tf->rsi, tf->rdi, - tf->rflags, cr2, cr3, - tf->rbp, tf->rsp, tf->rip); -} - -static inline void -handle_fatal(struct trapframe *tf) -{ - trap_print(tf); - regdump(tf); - panic("Halted\n"); -} - -/* - * Raise a fatal signal. - * - * @curtd: Current thread. - * @sched_tmr: Scheduler timer. - * @sig: Signal to raise. - */ -static void -raise_fatal(struct proc *curtd, struct timer *sched_tmr, int sig) -{ - /* - * trap_handler() disables interrupts. We will be - * killing the current process but before we do that - * we need to make sure interrupts are running and the - * scheduler timer is still going... - */ - intr_unmask(); - sched_tmr->oneshot_us(DEFAULT_TIMESLICE_USEC); - signal_raise(curtd, sig); -} - -/* - * Handle a pagefault occuring in the userland - * - * @curtd: Current thread. - * @tf: Trapframe. - * @sched_tmr: Scheduler timer. - */ -static void -handle_user_pf(struct proc *curtd, struct trapframe *tf, - struct timer *sched_tmr) -{ - uintptr_t fault_addr; - vm_prot_t access_type; - int s; - - fault_addr = pf_faultaddr(); - access_type = pf_accesstype(tf); - s = vm_fault(fault_addr, access_type); - - if (s != 0) { - pr_error("Got page fault @ 0x%p\n", fault_addr); - pr_error("Fault access mask: 0x%x\n", access_type); - pr_error("Raising SIGSEGV to PID %d...\n", curtd->pid); - regdump(tf); - raise_fatal(curtd, sched_tmr, SIGSEGV); - } -} - -/* - * Handles traps. - */ -void -trap_handler(struct trapframe *tf) -{ - struct proc *curtd = this_td(); - struct timer sched_tmr; - tmrr_status_t tmrr_s; - - /* - * Mask interrupts so we don't get put in a funky - * state as we are dealing with this trap. Then the next - * thing we want to do is fetch the sched timer so we can - * ensure it is running after we unmask the interrupts. - */ - intr_mask(); - tmrr_s = req_timer(TIMER_SCHED, &sched_tmr); - if (__unlikely(tmrr_s != TMRR_SUCCESS)) { - trap_print(tf); - panic("Could not fetch TIMER_SCHED (tmrr_s=0x%x)\n", tmrr_s); - } - - /* - * We should be able to perform a usec oneshot but - * make sure just in case. - */ - if (__unlikely(sched_tmr.oneshot_us == NULL)) { - trap_print(tf); - panic("Timer oneshot_us is NULL!\n"); - } - - /* - * XXX: Handle NMIs better. For now we just - * panic. - */ - if (tf->trapno == TRAP_NMI) { - trap_print(tf); - kprintf(OMIT_TIMESTAMP "Possible hardware failure?\n"); - panic(OMIT_TIMESTAMP "Caught NMI; bailing out\n"); - } - - if (curtd == NULL) { - handle_fatal(tf); - } else if (!curtd->is_user) { - handle_fatal(tf); - } - - switch (tf->trapno) { - case TRAP_ARITH_ERR: - pr_error("Got arithmetic error - raising SIGFPE...\n"); - pr_error("SIGFPE -> PID %d\n", curtd->pid); - raise_fatal(curtd, &sched_tmr, SIGFPE); - break; - case TRAP_PAGEFLT: - handle_user_pf(curtd, tf, &sched_tmr); - break; - default: - pr_error("Got %s - raising SIGSEGV...\n", trap_type[tf->trapno]); - pr_error("SIGSEGV -> PID %d\n", curtd->pid); - regdump(tf); - raise_fatal(curtd, &sched_tmr, SIGSEGV); - break; - } - - /* All good, unmask and start sched timer */ - intr_unmask(); - sched_tmr.oneshot_us(DEFAULT_TIMESLICE_USEC); -} diff --git a/sys/arch/amd64/amd64/tss.S b/sys/arch/amd64/amd64/tss.S deleted file mode 100644 index 8cff06b..0000000 --- a/sys/arch/amd64/amd64/tss.S +++ /dev/null @@ -1,41 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include - -__KERNEL_META "$Hyra$: tss.S, Ian Marco Moffett, \ - Low level TSS code" - -.globl tss_load -tss_load: - str %ax /* Store task register value into AX */ - mov $0x28, %ax /* Store TSS GDT selector into AX */ - or $3, %ax - ltr %ax /* Load the task register */ - retq diff --git a/sys/arch/amd64/amd64/tss.c b/sys/arch/amd64/amd64/tss.c deleted file mode 100644 index c9fc3bb..0000000 --- a/sys/arch/amd64/amd64/tss.c +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include - -__MODULE_NAME("TSS"); -__KERNEL_META("$Hyra$: tss.c, Ian Marco Moffett, " - "AMD64 Task state segment code"); - -static void -alloc_resources(struct cpu_info *cpu) -{ - struct tss_entry *tss; - const size_t STACK_SIZE = 0x1000; - static uintptr_t rsp0_base = 0, rsp0 = 0; - - /* - * Allocate TSS entries for this CPU - */ - if (cpu->tss == NULL) { - /* Allocate a TSS for this CPU */ - tss = dynalloc(sizeof(*tss)); - - if (tss == NULL) - panic("Failed to alloc %d bytes for TSS\n", sizeof(*tss)); - - memset(tss, 0, sizeof(*tss)); - rsp0_base = (uintptr_t)dynalloc_memalign(STACK_SIZE, 16); - - if (rsp0_base == 0) - panic("Could not allocate rsp0 base\n"); - - rsp0 = rsp0_base + STACK_SIZE; - tss->rsp0_lo = __SHIFTOUT(rsp0, __MASK(32)); - tss->rsp0_hi = __SHIFTOUT(rsp0, __MASK(32) << 32); - cpu->tss = tss; - } -} - -/* - * Update interrupt stack table entry `istno' with `stack' - * - * @stack: Interrupt stack. - * @istno: IST number, must be 1-based. - * - * Returns 0 on success. - */ -int -tss_update_ist(struct cpu_info *ci, union tss_stack stack, uint8_t istno) -{ - volatile struct tss_entry *tss = ci->tss; - - __assert(tss != NULL); - - switch (istno) { - case 1: - tss->ist1_lo = stack.top_lo; - tss->ist1_hi = stack.top_hi; - break; - case 2: - tss->ist2_lo = stack.top_lo; - tss->ist2_hi = stack.top_hi; - break; - case 3: - tss->ist3_lo = stack.top_lo; - tss->ist3_hi = stack.top_hi; - break; - case 4: - tss->ist4_lo = stack.top_lo; - tss->ist4_hi = stack.top_hi; - break; - case 5: - tss->ist5_lo = stack.top_lo; - tss->ist5_hi = stack.top_hi; - break; - case 6: - tss->ist6_lo = stack.top_lo; - tss->ist6_hi = stack.top_hi; - break; - case 7: - tss->ist7_lo = stack.top_lo; - tss->ist7_hi = stack.top_hi; - break; - default: - return -EXIT_FAILURE; - }; - - return 0; -} - -/* - * Allocates TSS stack. - * - * Returns 0 on success. - * - * @entry_out: Pointer to location where allocated entry - * will be sent. - */ -int -tss_alloc_stack(union tss_stack *entry_out, size_t size) -{ - uintptr_t base = (uintptr_t)dynalloc_memalign(size, 16); - - if (base == 0) { - return -EXIT_FAILURE; - } - - entry_out->top = base + size; - return 0; -} - -void -write_tss(struct cpu_info *cpu, struct tss_desc *desc) -{ - volatile struct tss_entry *tss; - uintptr_t tss_base; - - alloc_resources(cpu); - - tss_base = (uintptr_t)cpu->tss; - - /* - * XXX: The AVL (Available for use by system software) - * bit is ignored by hardware and it is up to us - * to decide how to use it... As of now, it is useless - * to us and shall remain 0. - */ - desc->seglimit = sizeof(struct tss_entry); - desc->p = 1; /* Must be present to be valid! */ - desc->g = 0; /* Granularity -> 0 */ - desc->avl = 0; /* Not used */ - desc->dpl = 0; /* Descriptor Privilege Level -> 0 */ - desc->type = 0x9; /* For TSS -> 0x9 (0b1001) */ - - desc->base_lo16 = __SHIFTOUT(tss_base, __MASK(16)); - desc->base_mid8 = __SHIFTOUT(tss_base, __MASK(8) << 16); - desc->base_hi_mid8 = __SHIFTOUT(tss_base, __MASK(8) << 24); - desc->base_hi32 = __SHIFTOUT(tss_base, __MASK(32) << 32); - - tss = cpu->tss; - tss->io_base = 0xFF; /* Disallow ring 3 port I/O */ -} diff --git a/sys/arch/amd64/amd64/uart.c b/sys/arch/amd64/amd64/uart.c deleted file mode 100644 index 0bf0236..0000000 --- a/sys/arch/amd64/amd64/uart.c +++ /dev/null @@ -1,98 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -#define UART_COM1 0x3F8 - -#define UART_PORTNO(OFFSET) (UART_COM1 + 1) - -static bool -uart8250_transmit_empty(void) -{ - return __TEST(UART_PORTNO(5), __BIT(5)); -} - -void -uart8250_write(char byte) -{ - while (!uart8250_transmit_empty()); - outb(UART_COM1, byte); -} - -int -uart8250_try_init(void) -{ - /* Disable interrutps */ - outb(UART_PORTNO(1), 0x00); - - /* Enable DLAB to set divisor latches */ - outb(UART_PORTNO(3), 0x80); - - /* Set to 38400 baud via divisor latches (DLL and DLH)*/ - outb(UART_PORTNO(0), 0x03); - outb(UART_PORTNO(1), 0x00); - - /* - * Set Data Word Length to 8 bits... - * - * XXX: Our write does not preserve the DLAB bit... - * We want to clear it to make the baud latches - * readonly - */ - outb(UART_PORTNO(3), 0x03); - - /* - * We want FIFO to be enabled, and want to clear the - * TX/RX queues. We also want to set the interrupt - * watermark at 14 bytes. - */ - outb(UART_PORTNO(2), 0xC7); - - /* - * Enable auxiliary output 2 (used as interrupt line) and - * mark data terminal ready. - */ - outb(UART_PORTNO(4), 0x0B); - - /* Enable interrupts */ - outb(UART_PORTNO(1), 0x01); - - /* Put chip in loopback mode... test chip w/ test byte */ - outb(UART_PORTNO(4), 0x1E); - outb(UART_PORTNO(0), 0xAE); - if (inb(UART_PORTNO(0) != 0xAE)) { - /* Not the same byte, something is wrong */ - return 1; - } - return 0; -} diff --git a/sys/arch/amd64/conf/GENERIC b/sys/arch/amd64/conf/GENERIC deleted file mode 100644 index 032519d..0000000 --- a/sys/arch/amd64/conf/GENERIC +++ /dev/null @@ -1,9 +0,0 @@ -// Kernel options -option SPECTRE_MITIGATION no -option SERIAL_DEBUG yes -option PANIC_BEEP yes - -// Kernel constants -setval PANIC_BEEP_HZ 1050 -setval SCHED_NQUEUE 4 -setval KMSG_BUF_SHIFT 16 diff --git a/sys/arch/amd64/isa/i8042.c b/sys/arch/amd64/isa/i8042.c deleted file mode 100644 index 8c790ec..0000000 --- a/sys/arch/amd64/isa/i8042.c +++ /dev/null @@ -1,297 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -__MODULE_NAME("i8042"); -__KERNEL_META("$Hyra$: i8042.c, Ian Marco Moffett, " - "i8042 PS/2 driver"); - -static struct spinlock data_lock; -static bool shift_key = false; -static bool capslock = false; -static bool capslock_released = true; -static struct intr_info *irq_info; - -static int dev_send(bool aux, uint8_t data); - -static char keytab[] = { - '\0', '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', - '-', '=', '\b', '\t', 'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', - 'o', 'p', '[', ']', '\n', '\0', 'a', 's', 'd', 'f', 'g', 'h', - 'j', 'k', 'l', ';', '\'', '`', '\0', '\\', 'z', 'x', 'c', 'v', - 'b', 'n', 'm', ',', '.', '/', '\0', '\0', '\0', ' ' -}; - -static char keytab_shift[] = { - '\0', '\0', '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', - '_', '+', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '{', '}', '\n', '\0', 'A', 'S', 'D', 'F', 'G', 'H', - 'J', 'K', 'L', ':', '\"', '~', '\0', '|', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', '<', '>', '?', '\0', '\0', '\0', ' ' -}; - -static char keytab_caps[] = { - '\0', '\0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', - '-','=', '\b', '\t', 'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', - 'O', 'P', '[', ']', '\n', '\0', 'A', 'S', 'D', 'F', 'G', 'H', - 'J', 'K', 'L', ';', '\'', '`', '\0', '\\', 'Z', 'X', 'C', 'V', - 'B', 'N', 'M', ',', '.', '/', '\0', '\0', '\0', ' ' -}; - -static void -kbd_set_leds(uint8_t mask) -{ - dev_send(false, 0xED); - dev_send(false, mask); -} - -/* - * Convert scancode to character - * - * @sc: Scancode - * @chr: Character output - * - * Returns 0 when a char is given back. - */ -static int -scancode_to_chr(uint8_t sc, char *chr) -{ - bool release = __TEST(sc, __BIT(7)); - - switch (sc) { - /* Capslock pressed */ - case 0x3A: - /* - * If we are holding down caps-lock, we do not - * want a stream of presses that constantly cause - * it to toggle, only toggle if released then pushed - * again. - */ - if (!capslock_released) - return -EAGAIN; - - capslock_released = false; - capslock = !capslock; - - if (!capslock) { - kbd_set_leds(0); - } else { - kbd_set_leds(I8042_LED_CAPS); - } - return -EAGAIN; - /* Capslock released */ - case 0xBA: - capslock_released = true; - return -EAGAIN; - /* Shift */ - case 0x36: - case 0xAA: - case 0x2A: - case 0xB6: - if (!release) { - shift_key = true; - } else { - shift_key = false; - } - return -EAGAIN; - } - - if (release) { - return -EAGAIN; - } - - if (capslock) { - *chr = keytab_caps[sc]; - return 0; - } - - if (shift_key) { - *chr = keytab_shift[sc]; - return 0; - } - - *chr = keytab[sc]; - return 0; -} - -/* - * Write to an i8042 register. - * - * @port: I/O port - * @val: Value to write - */ -static void -i8042_write(uint16_t port, uint8_t val) -{ - while (__TEST(I8042_STATUS, I8042_IBUF_FULL)); - outb(port, val); -} - -/* - * Read the i8042 config register - */ -static uint8_t -i8042_read_conf(void) -{ - i8042_write(I8042_COMMAND, I8042_GET_CONFB); - return inb(I8042_DATA); -} - -/* - * Write the i8042 config register - */ -static void -i8042_write_conf(uint8_t value) -{ - i8042_write(I8042_COMMAND, I8042_SET_CONFB); - i8042_write(I8042_DATA, value); -} - -/* - * Flush the data register until it is empty. - */ -static void -i8042_drain(void) -{ - spinlock_acquire(&data_lock); - while (__TEST(inb(I8042_STATUS), I8042_OBUF_FULL)) { - inb(I8042_DATA); - } - - spinlock_release(&data_lock); -} - -/* - * Send a data to a device - * - * @aux: If true, send to aux device (mouse) - * @data: Data to send. - */ -static int -dev_send(bool aux, uint8_t data) -{ - if (aux) { - i8042_write(I8042_COMMAND, I8042_PORT1_SEND); - } - - for (;;) { - if (!__TEST(inb(I8042_STATUS), I8042_IBUF_FULL)) { - break; - } - } - - i8042_write(I8042_DATA, data); - inb(0x80); /* Waste a cycle */ - return inb(I8042_DATA); -} - -__attr(interrupt) -static void -kb_isr(void *sf) -{ - uint8_t data; - char c; - - spinlock_acquire(&irq_info->lock); - ++irq_info->count; - spinlock_release(&irq_info->lock); - - spinlock_acquire(&data_lock); - while (__TEST(inb(I8042_STATUS), I8042_OBUF_FULL)) { - data = inb(I8042_DATA); - if (scancode_to_chr(data, &c) == 0) { - tty_putc(&g_root_tty, c, TTY_SOURCE_DEV); - } - } - spinlock_release(&data_lock); - lapic_send_eoi(); -} - -static int -i8042_init(void) -{ - uint8_t conf; - - /* - * Disable the ports and drain the output buffer - * to avoid interferance with the initialization - * process. - */ - i8042_write(I8042_COMMAND, I8042_DISABLE_PORT0); - i8042_write(I8042_COMMAND, I8042_DISABLE_PORT1); - i8042_drain(); - - /* Disable aux data streaming */ - dev_send(true, I8042_AUX_DISABLE); - i8042_drain(); - - /* Setup kbd interrupts */ - idt_set_desc(SYSVEC_PCKBD, IDT_INT_GATE_FLAGS, (uintptr_t)kb_isr, 0); - ioapic_set_vec(1, SYSVEC_PCKBD); - ioapic_irq_unmask(1); - - /* Register the interrupt */ - irq_info = intr_info_alloc("IOAPIC", "i8042"); - irq_info->affinity = 0; - intr_register(irq_info); - - /* Setup config bits */ - conf = i8042_read_conf(); - conf |= I8042_PORT0_INTR; - conf &= ~I8042_PORT1_INTR; - i8042_write_conf(conf); - - /* Enable the keyboard */ - i8042_write(I8042_COMMAND, I8042_ENABLE_PORT0); - - /* - * It seems one I/O bus cycle isn't enough to wait for data - * to accumulate on some machines... Give it around 50ms then - * drain the output buffer. - */ - hpet_msleep(50); - i8042_drain(); - return 0; -} - -DRIVER_EXPORT(i8042_init); diff --git a/sys/arch/amd64/isa/i8254.c b/sys/arch/amd64/isa/i8254.c deleted file mode 100644 index f19fb6b..0000000 --- a/sys/arch/amd64/isa/i8254.c +++ /dev/null @@ -1,75 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include - -/* - * Fetches the current count. - */ -uint16_t -i8254_get_count(void) -{ - uint8_t lo, hi; - - outb(i8254_COMMAND, 0x00); - lo = inb(0x40); - hi = inb(0x40); - return __COMBINE8(hi, lo); -} - -/* - * Set the reload value - * - * The reload value is where the i8254's counter - * starts... - */ -void -i8254_set_reload(uint16_t val) -{ - /* Channel 0, lo/hi access, rate generator */ - outb(i8254_COMMAND, 0x34); - - outb(0x40, (val & 0xFF)); - outb(0x40, (val >> 8) & 0xFF); -} - -void -i8254_set_frequency(uint64_t freq_hz) -{ - uint64_t divisor = i8254_DIVIDEND / freq_hz; - - if ((i8254_DIVIDEND % freq_hz) > (freq_hz / 2)) { - ++divisor; - } - - i8254_set_reload(freq_hz); -} diff --git a/sys/arch/amd64/isa/spkr.c b/sys/arch/amd64/isa/spkr.c deleted file mode 100644 index 109054e..0000000 --- a/sys/arch/amd64/isa/spkr.c +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright (c) 2023-2024 Ian Marco Moffett and the Osmora Team. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. Neither the name of Hyra nor the names of its - * contributors may be used to endorse or promote products derived from - * this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -#include -#include -#include -#include -#include -#include - -#define DIVIDEND 1193180 -#define CTRL_PORT 0x61 - -int -pcspkr_tone(uint16_t freq, uint32_t msec) -{ - uint32_t divisor; - uint8_t tmp; - struct timer tmr; - - if (req_timer(TIMER_GP, &tmr) != TMRR_SUCCESS) - return -ENOTSUP; - if (__unlikely(tmr.msleep == NULL)) - return -ENOTSUP; - - divisor = DIVIDEND / freq; - outb(i8254_COMMAND, 0xB6); - outb(i8254_CHANNEL_2, divisor & 0xFF); - outb(i8254_CHANNEL_2, (divisor >> 8) & 0xFF); - - /* Oscillate the speaker */ - tmp = inb(CTRL_PORT); - if (!__TEST(tmp, 3)) { - tmp |= 3; - outb(CTRL_PORT, tmp); - } - - /* Sleep then turn off the speaker */ - tmr.msleep(msec); - outb(CTRL_PORT, tmp & ~3); - return 0; -} -- cgit v1.2.3