diff options
Diffstat (limited to 'kernel/src/arch/x86_64')
| -rw-r--r-- | kernel/src/arch/x86_64/cpu/gdt.cpp | 2 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/cpu/idt.cpp | 2 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/cpu/lapic.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/cpu/sse.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/cpu_local.hpp | 22 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/drivers/hpet.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/drivers/ioapic.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/drivers/pvclock.cpp | 40 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/drivers/tsc.cpp | 4 | ||||
| -rw-r--r-- | kernel/src/arch/x86_64/schedule_timer.cpp | 4 |
10 files changed, 62 insertions, 28 deletions
diff --git a/kernel/src/arch/x86_64/cpu/gdt.cpp b/kernel/src/arch/x86_64/cpu/gdt.cpp index 0498c21..f2adea1 100644 --- a/kernel/src/arch/x86_64/cpu/gdt.cpp +++ b/kernel/src/arch/x86_64/cpu/gdt.cpp @@ -47,6 +47,6 @@ void x86_64::gdt::init() { cpudata->timer_ist_stack = (std::uint64_t)(pmm::buddy::alloc(KERNEL_STACK_SIZE).phys + etc::hhdm()); static bool is_print = 0; - if(!is_print) { klibc::printf("GDT: tss->rsp0 0x%p tss->ist0 0x%p\r\n",tss->rsp[0],tss->ist[0],tss->ist[1],tss->ist[2],tss->ist[3],cpudata->timer_ist_stack); is_print = 1; } + if(!is_print) { log("gdt", "tss->rsp0 0x%p tss->ist0 0x%p",tss->rsp[0],tss->ist[0],tss->ist[1],tss->ist[2],tss->ist[3],cpudata->timer_ist_stack); is_print = 1; } }
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/cpu/idt.cpp b/kernel/src/arch/x86_64/cpu/idt.cpp index c62b1e6..def3341 100644 --- a/kernel/src/arch/x86_64/cpu/idt.cpp +++ b/kernel/src/arch/x86_64/cpu/idt.cpp @@ -43,7 +43,7 @@ void x86_64::idt::init() { load(); - if(!is_print) {klibc::printf("IDT: IDTR is 0x%p\r\n",&idtr); is_print = 1;} + if(!is_print) {log("idt", "idtr is 0x%p",&idtr); is_print = 1;} } void x86_64::idt::load() { diff --git a/kernel/src/arch/x86_64/cpu/lapic.cpp b/kernel/src/arch/x86_64/cpu/lapic.cpp index 3bea37c..da98bfd 100644 --- a/kernel/src/arch/x86_64/cpu/lapic.cpp +++ b/kernel/src/arch/x86_64/cpu/lapic.cpp @@ -32,7 +32,7 @@ std::uint64_t x86_64::lapic::init(std::uint32_t us) { if(c & (1 << 21)) { // x2apic present - if(!is_print) klibc::printf("X2APIC: Enabling x2apic (base is 0x%p)\r\n",0x800); + if(!is_print) log("x2apic", "enabling x2apic (base is 0x%p)",0x800); assembly::wrmsr(0x1B,assembly::rdmsr(0x1B) | (1 << 10) | (1 << 11)); is_x2apic = 1; } else { @@ -52,7 +52,7 @@ std::uint64_t x86_64::lapic::init(std::uint32_t us) { write(0x380,ticks); if(!is_lapic_init) { - if(!is_print) klibc::printf("LAPIC: Calibration time is %lli, ticks %lli\r\n",us,ticks); + if(!is_print) log("lapic", "calibration time is %lli, ticks %lli",us,ticks); is_print = 1; is_lapic_init = 1; } diff --git a/kernel/src/arch/x86_64/cpu/sse.cpp b/kernel/src/arch/x86_64/cpu/sse.cpp index 73d53ae..b71ed10 100644 --- a/kernel/src/arch/x86_64/cpu/sse.cpp +++ b/kernel/src/arch/x86_64/cpu/sse.cpp @@ -120,8 +120,8 @@ void x86_64::sse::print_sse_features() { std::uint32_t a,b,c,d; assembly::cpuid(1,0,&a,&b,&c,&d); - klibc::printf( - "SSE: Supported features:" "%s%s%s%s%s%s\n", + log( "sse", + "supported features:" "%s%s%s%s%s%s", (d & (1 << 25)) ? " SSE" : "\0", (d & (1 << 26)) ? " SSE2" : "\0", (c & (1 << 0)) ? " SSE3\0" : "\0", diff --git a/kernel/src/arch/x86_64/cpu_local.hpp b/kernel/src/arch/x86_64/cpu_local.hpp index d5add64..152e6fc 100644 --- a/kernel/src/arch/x86_64/cpu_local.hpp +++ b/kernel/src/arch/x86_64/cpu_local.hpp @@ -7,9 +7,11 @@ #include <generic/scheduling.hpp> #include <klibc/string.hpp> #include <klibc/stdio.hpp> +#include <cstddef> +#include <type_traits> #include <generic/arch.hpp> -typedef struct { +struct cpudata_t { std::uint64_t user_stack; std::uint64_t kernel_stack; std::uint64_t timer_ist_stack; @@ -17,7 +19,7 @@ typedef struct { std::uint64_t tsc_freq; void* pvclock_buffer; thread* current_thread; -} cpudata_t; +}; namespace x86_64 { @@ -45,4 +47,20 @@ namespace x86_64 { } return (cpudata_t*)cpudata; } + + template <typename T, std::size_t Offset> [[nodiscard]] static inline T cpu_local_read() { + T out; + asm volatile("mov %%gs:%c1, %0" : "=r"(out) : "i"(Offset)); + return out; + } + + template <typename T, std::size_t Offset, typename V> static inline void cpu_local_write(V&& value) { + static_assert(std::is_same_v<std::remove_cvref_t<V>, std::remove_cv_t<T>>, "member type and value type are not compatible"); + T v = static_cast<T>(value); + asm volatile("mov %0, %%gs:%c1" : : "r"(v), "i"(Offset)); + } + }; + +#define CPU_LOCAL_READ(field) x86_64::cpu_local_read<decltype(((cpudata_t*) nullptr)->field), offsetof(cpudata_t, field)>() +#define CPU_LOCAL_WRITE(field, value) x86_64::cpu_local_write<decltype(((cpudata_t*) nullptr)->field), offsetof(cpudata_t, field)>((value))
\ No newline at end of file diff --git a/kernel/src/arch/x86_64/drivers/hpet.cpp b/kernel/src/arch/x86_64/drivers/hpet.cpp index 152f0d9..5421157 100644 --- a/kernel/src/arch/x86_64/drivers/hpet.cpp +++ b/kernel/src/arch/x86_64/drivers/hpet.cpp @@ -23,7 +23,7 @@ void drivers::hpet::init() { uacpi_table hpet; uacpi_status ret = uacpi_table_find_by_signature("HPET",&hpet); if(ret != UACPI_STATUS_OK) { - klibc::printf("HPET: hpet is not detected with status %d\r\n",ret); + log("hpet", "hpet is not detected with status %d",ret); return; } @@ -36,7 +36,7 @@ void drivers::hpet::init() { hpet_clock_nano = (*(volatile uint32_t*)(hpet_base + 4)) / 1000000; hpet_timer* new_hpet_inst = new hpet_timer; time::setup_timer(new_hpet_inst); - klibc::printf("HPET: Detected %s hpet, current timestamp in nano %lli (hpet_base 0x%p)\r\n",hpet_is_32_bit ? "32 bit" : "64 bit", new_hpet_inst->current_nano(),hpet_base); + log("hpet", "Detected %s hpet, current timestamp in nano %lli (hpet_base 0x%p)",hpet_is_32_bit ? "32 bit" : "64 bit", new_hpet_inst->current_nano(),hpet_base); } namespace drivers { diff --git a/kernel/src/arch/x86_64/drivers/ioapic.cpp b/kernel/src/arch/x86_64/drivers/ioapic.cpp index 4b9c04a..ee5170f 100644 --- a/kernel/src/arch/x86_64/drivers/ioapic.cpp +++ b/kernel/src/arch/x86_64/drivers/ioapic.cpp @@ -41,13 +41,13 @@ void drivers::ioapic::init() { struct acpi_madt_ioapic* cur_ioapic = (acpi_madt_ioapic*)current; paging::map_range(gobject::kernel_root,cur_ioapic->address,cur_ioapic->address + etc::hhdm(),PAGE_SIZE,PAGING_PRESENT | PAGING_RW); apics[apic_ent++] = *cur_ioapic; - klibc::printf("IOAPIC: Found ioapic with gsi base %d, address 0x%p, id %d\r\n",cur_ioapic->gsi_base,cur_ioapic->address,cur_ioapic->id); + log("ioapic", "Found ioapic with gsi base %d, address 0x%p, id %d",cur_ioapic->gsi_base,cur_ioapic->address,cur_ioapic->id); break; } case ACPI_MADT_ENTRY_TYPE_INTERRUPT_SOURCE_OVERRIDE: { struct acpi_madt_interrupt_source_override* cur_iso = (struct acpi_madt_interrupt_source_override*)current; iso[iso_ent++] = *cur_iso; - klibc::printf("IOAPIC: Found ISO with bus %d, irq %d, gsi base %d, flags %d\r\n",cur_iso->bus,cur_iso->source,cur_iso->gsi,cur_iso->flags); + log("ioapic", "Found ISO with bus %d, irq %d, gsi base %d, flags %d",cur_iso->bus,cur_iso->source,cur_iso->gsi,cur_iso->flags); break; } } diff --git a/kernel/src/arch/x86_64/drivers/pvclock.cpp b/kernel/src/arch/x86_64/drivers/pvclock.cpp index d77ef0f..db19120 100644 --- a/kernel/src/arch/x86_64/drivers/pvclock.cpp +++ b/kernel/src/arch/x86_64/drivers/pvclock.cpp @@ -43,26 +43,42 @@ void drivers::pvclock::bsp_init() { drivers::pvclock_timer* timer = new drivers::pvclock_timer; time::setup_timer(timer); - klibc::printf("pvclock: pointer to buffer 0x%p\r\n",x86_64::cpu_data()->pvclock_buffer); + log("pvclock", "pointer to buffer 0x%p",x86_64::cpu_data()->pvclock_buffer); } namespace drivers { std::uint64_t pvclock_timer::current_nano() { - uint32_t lo, hi; - asm volatile ("rdtsc" : "=a"(lo), "=d"(hi)); - std::uint64_t tsc_v = ((uint64_t)hi << 32) | lo; - pvclock_vcpu_time_info* kvmclock_info = (pvclock_vcpu_time_info*)(x86_64::cpu_data()->pvclock_buffer); - std::uint64_t time0 = tsc_v - kvmclock_info->tsc_timestamp; - if(kvmclock_info->tsc_shift >= 0) - time0 <<= kvmclock_info->tsc_shift; - else - time0 >>= -kvmclock_info->tsc_shift; - time0 = (time0 * kvmclock_info->tsc_to_system_mul) >> 32; - time0 = time0 + kvmclock_info->system_time; + auto* info = (pvclock_vcpu_time_info*)CPU_LOCAL_READ(pvclock_buffer); + uint32_t version; + uint64_t time0; + + do { + version = info->version; + std::atomic_thread_fence(std::memory_order_acquire); + + uint32_t lo, hi; + asm volatile ("rdtsc" : "=a"(lo), "=d"(hi) : : "memory"); + uint64_t tsc_v = (static_cast<uint64_t>(hi) << 32) | lo; + + uint64_t delta = tsc_v - info->tsc_timestamp; + + if (info->tsc_shift >= 0) + delta <<= info->tsc_shift; + else + delta >>= -info->tsc_shift; + + uint64_t scaled_delta = (static_cast<unsigned __int128>(delta) * info->tsc_to_system_mul) >> 32; + + time0 = info->system_time + scaled_delta; + + std::atomic_thread_fence(std::memory_order_acquire); + } while ((info->version & 1) || (info->version != version)); + return time0; } + void pvclock_timer::sleep(std::uint64_t us) { std::uint64_t current = this->current_nano(); std::uint64_t end_ns = us * 1000; diff --git a/kernel/src/arch/x86_64/drivers/tsc.cpp b/kernel/src/arch/x86_64/drivers/tsc.cpp index 3776144..4203d76 100644 --- a/kernel/src/arch/x86_64/drivers/tsc.cpp +++ b/kernel/src/arch/x86_64/drivers/tsc.cpp @@ -17,7 +17,7 @@ static inline uint64_t rdtsc() { void drivers::tsc::init() { if(time::timer == nullptr) { - klibc::printf("TSC: Can't initialize without timer !\n"); + log("tsc", "can't initialize without timer !"); } uint64_t tsc_start, tsc_end; @@ -55,7 +55,7 @@ void drivers::tsc::init() { x86_64::cpu_data()->tsc_freq = tsc_freq; static bool is_print = 0; - if(!is_print) {klibc::printf("TSC: TSC Frequency is %llu\r\n", tsc_freq); is_print = 1;} + if(!is_print) {log("tsc", "tsc frequency is %llu", tsc_freq); is_print = 1;} drivers::tsc_timer* tsc_timer = new drivers::tsc_timer; time::setup_timer(tsc_timer); } diff --git a/kernel/src/arch/x86_64/schedule_timer.cpp b/kernel/src/arch/x86_64/schedule_timer.cpp index 97882c7..60bb649 100644 --- a/kernel/src/arch/x86_64/schedule_timer.cpp +++ b/kernel/src/arch/x86_64/schedule_timer.cpp @@ -35,12 +35,12 @@ void x86_64::schedule_timer::off() { std::uint32_t timeout = 10; - klibc::printf("Poweroff: Waiting for all cpus to done work\r\n"); // used from poweroff so + log("poweroff", "waiting for all cpus to done work"); // used from poweroff so while(stfu_cpus != (std::int32_t)(mp::cpu_count() - 1)) { arch::memory_barrier(); if(--timeout == 0) { - klibc::printf("Poweroff: Can't wait longer, forching them to be disabled\r\n"); + log("poweroff", "poweroff: Can't wait longer, forcing them to be disabled"); x86_64::lapic::off(); return; } |
