diff --git a/aux/bochsrc.txt b/aux/bochsrc.txt index c429ee3..f7a0a44 100644 --- a/aux/bochsrc.txt +++ b/aux/bochsrc.txt @@ -2,7 +2,7 @@ cpu: model=p4_prescott_celeron_336 memory: guest=4096 host=2048 -romimage: file=/usr/share/bochs/BIOS-bochs-latest, options=fastboot +romimage: file=/usr/share/bochs/BIOS-bochs-latest vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest.bin ata0: enabled=1 diff --git a/aux/qemu_amd64.sh b/aux/qemu_amd64.sh index 5e627a1..7c5e62d 100755 --- a/aux/qemu_amd64.sh +++ b/aux/qemu_amd64.sh @@ -1,3 +1,3 @@ #!/bin/sh -qemu-system-x86_64 -M q35 -m 4G -serial mon:stdio -cdrom mop3.iso +qemu-system-x86_64 -M q35 -m 4G -serial mon:stdio -enable-kvm -cdrom mop3.iso diff --git a/kernel/amd64/bootmain.c b/kernel/amd64/bootmain.c index 10121db..ab54260 100644 --- a/kernel/amd64/bootmain.c +++ b/kernel/amd64/bootmain.c @@ -23,13 +23,14 @@ void bootmain (void) { amd64_ioapic_init (); amd64_hpet_init (); - int* a = malloc (sizeof (int)); - *a = 6969; - DEBUG ("a=%p, *a=%d\n", a, *a); + /* int* a = malloc (sizeof (int)); */ + /* *a = 6969; */ + /* DEBUG ("a=%p, *a=%d\n", a, *a); */ - amd64_hpet_sleep_micro (3000000); - - DEBUG ("woke up!!!\n"); + for (size_t i = 0; i < 1000; i++) { + DEBUG ("i=%zu\n", i); + amd64_hpet_sleep_micro (1000000); + } for (;;) ; diff --git a/kernel/amd64/hpet.c b/kernel/amd64/hpet.c index 7295ce2..c83b971 100644 --- a/kernel/amd64/hpet.c +++ b/kernel/amd64/hpet.c @@ -1,6 +1,7 @@ #include #include #include +#include #include #include #include @@ -15,9 +16,12 @@ static bool hpet_32bits = 1; static uintptr_t hpet_paddr; static uint64_t hpet_clock_nano; +static spin_lock_t hpet_lock = SPIN_LOCK_INIT; extern void amd64_spin (void); +/* These functions assume hpet_lock is held by the caller! */ + static uint64_t amd64_hpet_read (uint32_t reg) { struct limine_hhdm_response* hhdm = limine_hhdm_request.response; uintptr_t hpet_vaddr = hpet_paddr + (uintptr_t)hhdm->offset; @@ -36,13 +40,27 @@ static void amd64_hpet_write (uint32_t reg, uint64_t value) { static uint64_t amd64_hpet_timestamp (void) { return amd64_hpet_read (HPET_MCVR); } -uint64_t amd64_hpet_current_nano (void) { return amd64_hpet_timestamp () * hpet_clock_nano; } +uint64_t amd64_hpet_current_nano (bool lock) { + if (lock) + spin_lock (&hpet_lock); + + uint64_t t = amd64_hpet_timestamp () * hpet_clock_nano; + + if (lock) + spin_unlock (&hpet_lock); + + return t; +} void amd64_hpet_sleep_micro (uint64_t us) { + spin_lock (&hpet_lock); + uint64_t start = amd64_hpet_timestamp (); uint64_t conv = us * 1000; while (((amd64_hpet_timestamp () - start) * hpet_clock_nano) < conv) __asm__ volatile ("pause" ::: "memory"); + + spin_unlock (&hpet_lock); } void amd64_hpet_init (void) { @@ -61,7 +79,19 @@ void amd64_hpet_init (void) { hpet_32bits = (amd64_hpet_read (HPET_GCIDR) & (1 << 13)) ? 0 : 1; - amd64_hpet_write (HPET_GCR, amd64_hpet_read (HPET_GCR) | 0x01); + /* reset */ + amd64_hpet_write (HPET_GCR, 0); + amd64_hpet_write (HPET_MCVR, 0); + amd64_hpet_write (HPET_GCR, 1); - hpet_clock_nano = amd64_hpet_read (HPET_GCIDR + 4) / 1000000; + uint64_t gcidr = amd64_hpet_read (HPET_GCIDR); + if (hpet_32bits) { + uint32_t low = (uint32_t)gcidr; + uint32_t high = (uint32_t)amd64_hpet_read (HPET_GCIDR + 4); + gcidr = (((uint64_t)high << 32) | low); + } + + uint64_t period_fs = (gcidr >> 32); + + hpet_clock_nano = period_fs / 1000000; } diff --git a/kernel/amd64/hpet.h b/kernel/amd64/hpet.h index c4aad4f..48e5920 100644 --- a/kernel/amd64/hpet.h +++ b/kernel/amd64/hpet.h @@ -3,7 +3,7 @@ #include -uint64_t amd64_hpet_current_nano (void); +uint64_t amd64_hpet_current_nano (bool lock); void amd64_hpet_sleep_micro (uint64_t us); void amd64_hpet_init (void);