Skip to content

Commit

Permalink
uacpi: Fix incorrect IO functions
Browse files Browse the repository at this point in the history
  • Loading branch information
marv7000 committed Feb 19, 2025
1 parent 98c6203 commit 3902918
Show file tree
Hide file tree
Showing 8 changed files with 83 additions and 32 deletions.
18 changes: 12 additions & 6 deletions include/menix/system/time/clock.h
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,14 @@
#define clock_timeout_poll(timeout_ns, condition, fail_case) \
do \
{ \
usize check_start = clock_get_elapsed() + (timeout_ns); \
while (clock_get_elapsed() < check_start) \
usize check_start = clock_get_elapsed_ns() + (timeout_ns); \
while (clock_get_elapsed_ns() < check_start) \
{ \
if (condition) \
break; \
asm_pause(); \
} \
if (clock_get_elapsed() >= check_start) \
if (clock_get_elapsed_ns() >= check_start) \
{ \
fail_case \
} \
Expand All @@ -26,15 +26,21 @@ typedef struct
const char* name;

// Returns how many nanoseconds have elapsed since initialization.
usize (*get_elapsed_ns)();
usize (*get_elapsed_ns)(void);

// Resets the clock's counter.
void (*reset)(void);
} ClockSource;

// Registers a `source` as the new time
void clock_register(ClockSource* source);

// If a clock source is available, returns the current time elapsed since init.
// If not, returns 0.
usize clock_get_elapsed();
usize clock_get_elapsed_ns();

// Updates the base of the counter.
void clock_set_elapsed_ns(usize value);

// Waits `ns` nanoseconds.
// Spins for `ns` nanoseconds.
void clock_wait(usize ns);
19 changes: 16 additions & 3 deletions include/menix/util/log.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,11 +8,10 @@
#include <menix/system/sch/thread.h>
#include <menix/system/time/clock.h>

#if !defined(NDEBUG)
#define kassert(expr, msg, ...) \
do \
{ \
if (!(expr)) \
if (unlikely(!(expr))) \
{ \
print_error("Environment is unsound! Assertion \"%s\" failed!\n", #expr); \
print_error("In function \"%s\" (%s:%u):\n", __FUNCTION__, __FILE__, __LINE__); \
Expand All @@ -21,8 +20,22 @@
kabort(); \
} \
} while (0)

#if !defined(NDEBUG)
#define kassert_debug(expr, msg, ...) \
do \
{ \
if (unlikely(!(expr))) \
{ \
print_error("Environment is unsound! Debug assertion \"%s\" failed!\n", #expr); \
print_error("In function \"%s\" (%s:%u):\n", __FUNCTION__, __FILE__, __LINE__); \
print_error(msg "\n", ##__VA_ARGS__); \
ktrace(NULL); \
kabort(); \
} \
} while (0)
#else
#define kassert(expr, msg, ...) \
#define kassert_debug(expr, msg, ...) \
do \
{ \
(void)(expr); \
Expand Down
18 changes: 14 additions & 4 deletions kernel/arch/x86_64/system/acpi/hpet.c
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,10 @@ typedef struct
} Hpet;

static usize hpet_get_elapsed_ns();
static void hpet_reset();

static Hpet hpet = {
.cs = {"hpet", hpet_get_elapsed_ns},
.cs = {.name = "hpet", .get_elapsed_ns = hpet_get_elapsed_ns, .reset = hpet_reset},
};

static usize hpet_get_elapsed_ns()
Expand All @@ -28,8 +29,14 @@ static usize hpet_get_elapsed_ns()
return hpet.regs->main_counter * (hpet.period / 1000000);
}

static void hpet_reset()
{
hpet.regs->main_counter = 0;
}

static void hpet_setup(PhysAddr addr)
{
print_log("acpi: HPET at 0x%p\n", addr);
hpet.regs = pm_get_phys_base() + addr;

// Get the period.
Expand All @@ -46,10 +53,13 @@ static void hpet_setup(PhysAddr addr)
void hpet_init()
{
uacpi_table hpet_table;
kassert(!uacpi_table_find_by_signature("HPET", &hpet_table), "Failed to get the HPET table!");
struct acpi_hpet* hpet = hpet_table.ptr;
if (uacpi_table_find_by_signature("HPET", &hpet_table) != UACPI_STATUS_OK)
{
print_error("acpi: Failed to get the HPET table!\n");
return;
}

print_log("acpi: HPET at 0x%p\n", hpet);
struct acpi_hpet* hpet = hpet_table.ptr;

hpet_setup(hpet->address.address);
uacpi_table_unref(&hpet_table);
Expand Down
9 changes: 7 additions & 2 deletions kernel/arch/x86_64/system/acpi/madt.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@
#include <uacpi/acpi.h>
#include <uacpi/tables.h>

#include "uacpi/status.h"

struct acpi_madt* madt;
PhysAddr lapic_addr;

Expand All @@ -23,8 +25,11 @@ void madt_init()
list_new(madt_nmi_list, 0);

uacpi_table madt_table;
kassert(!uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE, &madt_table),
"ACPI tables don't contain a MADT! This is faulty behavior!");
if (uacpi_table_find_by_signature(ACPI_MADT_SIGNATURE, &madt_table) != UACPI_STATUS_OK)
{
print_error("acpi: Can't find the MADT table! This is faulty behavior!\n");
return;
}

madt = madt_table.ptr;

Expand Down
7 changes: 3 additions & 4 deletions kernel/memory/pm.c
Original file line number Diff line number Diff line change
Expand Up @@ -146,9 +146,8 @@ PhysAddr pm_alloc(usize amount)
mem = get_free_pages(amount, last_page);
}

if (free_before - amount != num_free_pages)
print_warn("pm: We allocated more pages than asked for! Difference of %zu pages!\n",
free_before - num_free_pages);
kassert_debug(free_before - amount == num_free_pages,
"We allocated more pages than asked for! Difference of %zu pages!", free_before - num_free_pages);

if (mem == 0)
{
Expand All @@ -168,7 +167,7 @@ void pm_free(PhysAddr addr, usize amount)
const usize page_idx = addr / arch_page_size;
for (usize i = page_idx; i < page_idx + amount; i++)
{
kassert(bitmap_get(bit_map, i), "Double free of a physical page! Environment is unsound!");
kassert_debug(bitmap_get(bit_map, i), "Double free of a physical page! Environment is unsound!");
bitmap_clear(bit_map, i);
}
num_free_pages += 1;
Expand Down
22 changes: 14 additions & 8 deletions kernel/system/acpi/uacpi_interface.c
Original file line number Diff line number Diff line change
Expand Up @@ -137,7 +137,13 @@ uacpi_status uacpi_kernel_pci_write32(uacpi_handle device, uacpi_size offset, ua

uacpi_status uacpi_kernel_io_map(uacpi_io_addr base, uacpi_size len, uacpi_handle* out_handle)
{
*out_handle = vm_map_memory(base, len, VMProt_Read | VMProt_Write);
// On x86, this function does port IO.
#if defined(__x86_64__)
if (base > 0xFFFF)
return UACPI_STATUS_INVALID_ARGUMENT;
#endif

*out_handle = (uacpi_handle)base;
return UACPI_STATUS_OK;
}

Expand All @@ -148,47 +154,47 @@ void uacpi_kernel_io_unmap(uacpi_handle handle)
uacpi_status uacpi_kernel_io_read8(uacpi_handle h, uacpi_size offset, uacpi_u8* out_value)
{
#ifdef __x86_64
*out_value = asm_read8(offset);
*out_value = asm_read8((usize)h + offset);
#endif
return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_io_read16(uacpi_handle h, uacpi_size offset, uacpi_u16* out_value)
{
#ifdef __x86_64
*out_value = asm_read16(offset);
*out_value = asm_read16((usize)h + offset);
#endif
return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_io_read32(uacpi_handle h, uacpi_size offset, uacpi_u32* out_value)
{
#ifdef __x86_64
*out_value = asm_read32(offset);
*out_value = asm_read32((usize)h + offset);
#endif
return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_io_write8(uacpi_handle h, uacpi_size offset, uacpi_u8 in_value)
{
#ifdef __x86_64
asm_write8(offset, in_value);
asm_write8((usize)h + offset, in_value);
#endif
return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_io_write16(uacpi_handle h, uacpi_size offset, uacpi_u16 in_value)
{
#ifdef __x86_64
asm_write16(offset, in_value);
asm_write16((usize)h + offset, in_value);
#endif
return UACPI_STATUS_OK;
}

uacpi_status uacpi_kernel_io_write32(uacpi_handle h, uacpi_size offset, uacpi_u32 in_value)
{
#ifdef __x86_64
asm_write32(offset, in_value);
asm_write32((usize)h + offset, in_value);
#endif
return UACPI_STATUS_OK;
}
Expand Down Expand Up @@ -216,7 +222,7 @@ void uacpi_kernel_log(uacpi_log_level level, const uacpi_char* msg)

uacpi_u64 uacpi_kernel_get_nanoseconds_since_boot(void)
{
return clock_get_elapsed();
return clock_get_elapsed_ns();
}

void uacpi_kernel_stall(uacpi_u8 usec)
Expand Down
2 changes: 1 addition & 1 deletion kernel/system/logger.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ SpinLock kmesg_lock;

void kmesg_direct(const char* fmt, ...)
{
usize __time = clock_get_elapsed();
usize __time = clock_get_elapsed_ns();
usize __secs = (__time / 1000000000);
usize __millis = ((__time / 1000) % 1000000);
CpuInfo* __cpu = arch_current_cpu();
Expand Down
20 changes: 16 additions & 4 deletions kernel/system/time/clock.c
Original file line number Diff line number Diff line change
Expand Up @@ -6,24 +6,36 @@
#include <menix/util/log.h>

static ClockSource* current_source = NULL;
static usize clock_base_ns = 0; // Base counter in nanoseconds.

void clock_register(ClockSource* source)
{
if (source == NULL || source->get_elapsed_ns == NULL)
if (source == NULL || source->get_elapsed_ns == NULL || source->reset == NULL)
return;

print_log("clock: Switching to new source \"%s\"\n", source->name);

// Move the current value over to the new counter.
const usize timer = clock_get_elapsed_ns();
current_source = source;
clock_set_elapsed_ns(timer);
}

usize clock_get_elapsed()
usize clock_get_elapsed_ns()
{
if (current_source != NULL)
return current_source->get_elapsed_ns();

return 0;
}

void clock_set_elapsed_ns(usize value)
{
clock_base_ns = value;
if (current_source != NULL)
current_source->reset();
}

void clock_wait(usize ns)
{
if (current_source == NULL)
Expand All @@ -34,8 +46,8 @@ void clock_wait(usize ns)
return;
}

usize time = clock_get_elapsed() + ns;
while (time > clock_get_elapsed())
usize time = clock_get_elapsed_ns() + ns;
while (time > clock_get_elapsed_ns())
{
asm_pause();
}
Expand Down

0 comments on commit 3902918

Please sign in to comment.