From 5ca090ba6c467e1a4b3506fb16bd1406e835fcbc Mon Sep 17 00:00:00 2001 From: Andrew Waterman Date: Tue, 18 Apr 2017 13:04:39 -0700 Subject: Use uint64_t, not uintptr_t, to represent FDT addresses/sizes This fixes RV32 pk. --- machine/fdt.c | 37 ++++++++++++++++++++----------------- machine/fdt.h | 4 ++-- machine/uart.c | 4 ++-- 3 files changed, 24 insertions(+), 21 deletions(-) diff --git a/machine/fdt.c b/machine/fdt.c index cfa7ee9..4f72f73 100644 --- a/machine/fdt.c +++ b/machine/fdt.c @@ -21,6 +21,7 @@ static uint32_t *fdt_scan_helper( int last = 0; child.parent = node; + // these are the default cell counts, as per the FDT spec child.address_cells = 2; child.size_cells = 1; prop.node = node; @@ -92,17 +93,19 @@ uint32_t fdt_size(uintptr_t fdt) return bswap(header->totalsize); } -const uint32_t *fdt_get_address(const struct fdt_scan_node *node, const uint32_t *value, uintptr_t *result) +const uint32_t *fdt_get_address(const struct fdt_scan_node *node, const uint32_t *value, uint64_t *result) { *result = 0; - for (int cells = node->address_cells; cells > 0; --cells) *result += bswap(*value++); + for (int cells = node->address_cells; cells > 0; --cells) + *result = (*result << 32) + bswap(*value++); return value; } -const uint32_t *fdt_get_size(const struct fdt_scan_node *node, const uint32_t *value, uintptr_t *result) +const uint32_t *fdt_get_size(const struct fdt_scan_node *node, const uint32_t *value, uint64_t *result) { *result = 0; - for (int cells = node->size_cells; cells > 0; --cells) *result += bswap(*value++); + for (int cells = node->size_cells; cells > 0; --cells) + *result = (*result << 32) + bswap(*value++); return value; } @@ -155,7 +158,7 @@ static void mem_done(const struct fdt_scan_node *node, void *extra) assert (scan->reg_value && scan->reg_len % 4 == 0); while (end - value > 0) { - uintptr_t base, size; + uint64_t base, size; value = fdt_get_address(node->parent, value, &base); value = fdt_get_size (node->parent, value, &size); if (base <= self && self <= base + size) { mem_size = size; } @@ -218,7 +221,7 @@ static void hart_prop(const struct fdt_scan_prop *prop, void *extra) } else if (!strcmp(prop->name, "phandle")) { scan->phandle = bswap(prop->value[0]); } else if (!strcmp(prop->name, "reg")) { - uintptr_t reg; + uint64_t reg; fdt_get_address(prop->node->parent, prop->value, ®); scan->hart = reg; } @@ -276,7 +279,7 @@ void query_harts(uintptr_t fdt) struct clint_scan { int compat; - uintptr_t reg; + uint64_t reg; const uint32_t *int_value; int int_len; int done; @@ -315,7 +318,7 @@ static void clint_done(const struct fdt_scan_node *node, void *extra) assert (!scan->done); // only one clint scan->done = 1; - mtime = (void*)(scan->reg + 0xbff8); + mtime = (void*)((uintptr_t)scan->reg + 0xbff8); for (int index = 0; end - value > 0; ++index) { uint32_t phandle = bswap(value[0]); @@ -325,8 +328,8 @@ static void clint_done(const struct fdt_scan_node *node, void *extra) break; if (hart < MAX_HARTS) { hls_t *hls = OTHER_HLS(hart); - hls->ipi = (void*)(scan->reg + index * 4); - hls->timecmp = (void*)(scan->reg + 0x4000 + (index * 8)); + hls->ipi = (void*)((uintptr_t)scan->reg + index * 4); + hls->timecmp = (void*)((uintptr_t)scan->reg + 0x4000 + (index * 8)); } value += 4; } @@ -353,7 +356,7 @@ void query_clint(uintptr_t fdt) struct plic_scan { int compat; - uintptr_t reg; + uint64_t reg; uint32_t *int_value; int int_len; int done; @@ -401,7 +404,7 @@ static void plic_done(const struct fdt_scan_node *node, void *extra) assert (!scan->done); // only one plic scan->done = 1; - plic_priorities = (uint32_t*)scan->reg; + plic_priorities = (uint32_t*)(uintptr_t)scan->reg; plic_ndevs = scan->ndev; for (int index = 0; end - value > 0; ++index) { @@ -414,11 +417,11 @@ static void plic_done(const struct fdt_scan_node *node, void *extra) if (hart < MAX_HARTS) { hls_t *hls = OTHER_HLS(hart); if (cpu_int == IRQ_M_EXT) { - hls->plic_m_ie = (uintptr_t*)(scan->reg + ENABLE_BASE + ENABLE_SIZE * index); - hls->plic_m_thresh = (uint32_t*) (scan->reg + HART_BASE + HART_SIZE * index); + hls->plic_m_ie = (uintptr_t*)((uintptr_t)scan->reg + ENABLE_BASE + ENABLE_SIZE * index); + hls->plic_m_thresh = (uint32_t*) ((uintptr_t)scan->reg + HART_BASE + HART_SIZE * index); } else if (cpu_int == IRQ_S_EXT) { - hls->plic_s_ie = (uintptr_t*)(scan->reg + ENABLE_BASE + ENABLE_SIZE * index); - hls->plic_s_thresh = (uint32_t*) (scan->reg + HART_BASE + HART_SIZE * index); + hls->plic_s_ie = (uintptr_t*)((uintptr_t)scan->reg + ENABLE_BASE + ENABLE_SIZE * index); + hls->plic_s_thresh = (uint32_t*) ((uintptr_t)scan->reg + HART_BASE + HART_SIZE * index); } else { printm("PLIC wired hart %d to wrong interrupt %d", hart, cpu_int); } @@ -553,7 +556,7 @@ static void hart_filter_prop(const struct fdt_scan_prop *prop, void *extra) if (!strcmp(prop->name, "device_type") && !strcmp((const char*)prop->value, "cpu")) { filter->compat = 1; } else if (!strcmp(prop->name, "reg")) { - uintptr_t reg; + uint64_t reg; fdt_get_address(prop->node->parent, prop->value, ®); filter->hart = reg; } else if (!strcmp(prop->name, "status")) { diff --git a/machine/fdt.h b/machine/fdt.h index 0581e95..c12905e 100644 --- a/machine/fdt.h +++ b/machine/fdt.h @@ -50,8 +50,8 @@ void fdt_scan(uintptr_t fdt, const struct fdt_cb *cb); uint32_t fdt_size(uintptr_t fdt); // Extract fields -const uint32_t *fdt_get_address(const struct fdt_scan_node *node, const uint32_t *base, uintptr_t *value); -const uint32_t *fdt_get_size(const struct fdt_scan_node *node, const uint32_t *base, uintptr_t *value); +const uint32_t *fdt_get_address(const struct fdt_scan_node *node, const uint32_t *base, uint64_t *value); +const uint32_t *fdt_get_size(const struct fdt_scan_node *node, const uint32_t *base, uint64_t *value); int fdt_string_list_index(const struct fdt_scan_prop *prop, const char *str); // -1 if not found // Setup memory+clint+plic diff --git a/machine/uart.c b/machine/uart.c index a55e27e..0645500 100644 --- a/machine/uart.c +++ b/machine/uart.c @@ -31,7 +31,7 @@ int uart_getchar() struct uart_scan { int compat; - uintptr_t reg; + uint64_t reg; }; static void uart_open(const struct fdt_scan_node *node, void *extra) @@ -56,7 +56,7 @@ static void uart_done(const struct fdt_scan_node *node, void *extra) if (!scan->compat || !scan->reg || uart) return; // Enable Rx/Tx channels - uart = (void*)scan->reg; + uart = (void*)(uintptr_t)scan->reg; uart[UART_REG_TXCTRL] = UART_TXEN; uart[UART_REG_RXCTRL] = UART_RXEN; } -- cgit v1.1