diff --git a/device/uart/kvprintf.c b/device/uart/kvprintf.c index 38498bfd..de6f3eea 100644 --- a/device/uart/kvprintf.c +++ b/device/uart/kvprintf.c @@ -33,7 +33,7 @@ syscall kvprintf(const char *format, va_list ap) * it prevents kprintf()'s from stepping on each other toes if you happen to * call kprintf() from an interrupt handler. */ im = disable(); - retval = _doprnt(format, ap, (int (*)(int, int))kputc, (int)&devtab[SERIAL0]); + retval = _doprnt(format, ap, (int (*)(int, uintptr_t))kputc, (uintptr_t)&devtab[SERIAL0]); restore(im); return retval; } diff --git a/include/dtb.h b/include/dtb.h new file mode 100644 index 00000000..7b2dd92f --- /dev/null +++ b/include/dtb.h @@ -0,0 +1,26 @@ +/** + * @file dhcpc.h + * + * Devicetree parser interface + */ +/* Embedded Xinu, Copyright (C) 2018. All rights reserved. */ + +#ifndef _DTB_H_ +#define _DTB_H_ + + +/* parse dtb tree: + Arguments: pointer to the in-memory flat device tree + pointer to callback that will handle parsed properties + pointer to callback that will handle reserved memory blocks +*/ +int parse_dtb(void *dtbptr, + void (*prop_handler)(char *node_name, + char *property_name, + unsigned char *val, + uint32_t len), + void (*rsv_handler)(uint64_t address, + uint64_t size)); +uint64_t dtb_read_uint64(uint32_t* dataptr); + +#endif diff --git a/include/endianness.h b/include/endianness.h index eb1f5337..daa7dd97 100644 --- a/include/endianness.h +++ b/include/endianness.h @@ -23,6 +23,20 @@ bswap32(uint32_t n) return (n << 24) | ((n & 0xff00) << 8) | ((n & 0xff0000) >> 8) | (n >> 24); } +static inline uint64_t +bswap64(uint64_t n) +{ + return((n & 0xff00000000000000) >> 56) + | ((n & 0x00ff000000000000) >> 40) + | ((n & 0x0000ff0000000000) >> 24) + | ((n & 0x000000ff00000000) >> 8) + | ((n & 0x00000000ff000000) << 8) + | ((n & 0x0000000000ff0000) << 24) + | ((n & 0x000000000000ff00) << 40) + | ((n & 0x00000000000000ff) << 56); +} + + #if BYTE_ORDER == BIG_ENDIAN /* Big-endian CPU */ @@ -30,14 +44,18 @@ bswap32(uint32_t n) /* big endian to big endian: no-op */ # define cpu_to_be16(n) n # define cpu_to_be32(n) n +# define cpu_to_be64(n) n # define be16_to_cpu(n) n # define be32_to_cpu(n) n +# define be64_to_cpu(n) n /* big endian to little endian and vice versa */ # define cpu_to_le16(n) bswap16(n) # define cpu_to_le32(n) bswap32(n) +# define cpu_to_le64(n) bswap64(n) # define le16_to_cpu(n) bswap16(n) # define le32_to_cpu(n) bswap32(n) +# define le64_to_cpu(n) bswap64(n) #else /* BYTE_ORDER == BIG_ENDIAN */ @@ -46,14 +64,18 @@ bswap32(uint32_t n) /* little endian to big endian and vice versa */ # define cpu_to_be16(n) bswap16(n) # define cpu_to_be32(n) bswap32(n) +# define cpu_to_be64(n) bswap64(n) # define be16_to_cpu(n) bswap16(n) # define be32_to_cpu(n) bswap32(n) +# define be64_to_cpu(n) bswap64(n) /* little endian to little endian: no-op */ # define cpu_to_le16(n) n # define cpu_to_le32(n) n +# define cpu_to_le64(n) n # define le16_to_cpu(n) n # define le32_to_cpu(n) n +# define le64_to_cpu(n) n #endif /* BYTE_ORDER != BIG_ENDIAN */ diff --git a/include/limits.h b/include/limits.h index 4a062a2d..c0b9d9b6 100644 --- a/include/limits.h +++ b/include/limits.h @@ -28,7 +28,11 @@ #define INT_MIN (-INT_MAX-1) /**< minimum value of int */ #define UINT_MAX (2U*INT_MAX+1) /**< maximum value of unsigned int */ +#ifdef __LP64__ /* 64 bit arch */ +#define LONG_MAX 9223372036854775807L /**< maximum value of long */ +#else /* 32 bit arch */ #define LONG_MAX 2147483647 /**< maximum value of long */ +#endif #define LONG_MIN (-LONG_MAX-1) /**< minimum value of long */ #define ULONG_MAX (2UL*LONG_MAX+1) /**< maximum value of unsigned long */ diff --git a/include/memory.h b/include/memory.h index da80fc82..b001b1b1 100644 --- a/include/memory.h +++ b/include/memory.h @@ -9,11 +9,13 @@ #define _MEMORY_H_ #include +#include +#define MEMORY_DMBDEC (2*sizeof(uintptr_t)-1) /* roundmb - round address up to size of memblock */ -#define roundmb(x) (void *)( (7 + (ulong)(x)) & ~0x07 ) +#define roundmb(x) (void *)( (MEMORY_DMBDEC + (ulong)(x)) & ~MEMORY_DMBDEC ) /* truncmb - truncate address down to size of memblock */ -#define truncmb(x) (void *)( ((ulong)(x)) & ~0x07 ) +#define truncmb(x) (void *)( ((ulong)(x)) & ~MEMORY_DMBDEC ) /** * @ingroup memory_mgmt @@ -38,7 +40,7 @@ struct memblock { struct memblock *next; /**< pointer to next memory block */ - uint length; /**< size of memory block (with struct) */ + uintptr_t length; /**< size of memory block (with struct) */ }; extern struct memblock memlist; /**< head of free memory list */ @@ -50,8 +52,8 @@ extern void *_etext; /**< linker provides end of text segment */ extern void *memheap; /**< bottom of heap */ /* Memory function prototypes */ -void *memget(uint); -syscall memfree(void *, uint); -void *stkget(uint); +void *memget(uintptr_t); +syscall memfree(void *, uintptr_t); +void *stkget(uintptr_t); #endif /* _MEMORY_H_ */ diff --git a/include/stdint.h b/include/stdint.h index 43278866..e0b18e5b 100644 --- a/include/stdint.h +++ b/include/stdint.h @@ -18,4 +18,12 @@ typedef unsigned short uint16_t; typedef unsigned int uint32_t; typedef unsigned long long uint64_t; +#if __LP64__ +typedef long int intptr_t; +typedef unsigned long int uintptr_t; +#else +typedef int intptr_t; +typedef unsigned int uintptr_t; +#endif + #endif /* _STDINT_H_ */ diff --git a/include/stdio.h b/include/stdio.h index 66616c97..5846dcc3 100644 --- a/include/stdio.h +++ b/include/stdio.h @@ -6,6 +6,7 @@ #ifndef _STDIO_H_ #define _STDIO_H_ +#include #include #include #include /* For thrtab and thrcurrent. */ @@ -31,8 +32,8 @@ /* Formatted input */ int _doscan(const char *fmt, va_list ap, - int (*getch) (int, int), int (*ungetch) (int, int), - int arg1, int arg2); + int (*getch) (int, uintptr_t), int (*ungetch) (int, uintptr_t), + int arg1, uintptr_t arg2); int fscanf(int dev, const char *format, ...); @@ -45,7 +46,7 @@ int sscanf(const char *str, const char *format, ...); /* Formatted output */ int _doprnt(const char *format, va_list, - int (*putc_func)(int, int), int putc_arg); + int (*putc_func)(int, uintptr_t), uintptr_t putc_arg); int fprintf(int dev, const char *format, ...) __printf_format(2, 3); int printf(const char *format, ...) __printf_format(1, 2); diff --git a/lib/libxc/doprnt.c b/lib/libxc/doprnt.c index b7158a56..e9506664 100644 --- a/lib/libxc/doprnt.c +++ b/lib/libxc/doprnt.c @@ -84,7 +84,7 @@ enum integer_size { * number of characters written on success, or @c EOF on failure */ int _doprnt(const char *fmt, va_list ap, - int (*putc_func) (int, int), int putc_arg) + int (*putc_func) (int, uintptr_t), uintptr_t putc_arg) { int chars_written = 0; /* Number of characters written so far */ diff --git a/lib/libxc/doscan.c b/lib/libxc/doscan.c index c50c5d35..9ed6ccab 100644 --- a/lib/libxc/doscan.c +++ b/lib/libxc/doscan.c @@ -20,15 +20,15 @@ enum integer_size { static int scan_string(char *ptr, int type, uint maxlen, const uchar *stopchar_tab, - int (*getch) (int, int), int (*ungetch) (int, int), - int arg1, int arg2, bool *eofptr); + int (*getch) (int, uintptr_t), int (*ungetch) (int, uintptr_t), + int arg1, uintptr_t arg2, bool *eofptr); static int scan_number_or_string(void *ptr, uchar type, uint maxlen, enum integer_size size, const uchar *stopchar_tab, - int (*getch) (int, int), - int (*ungetch) (int, int), - int arg1, int arg2, bool *eofptr); + int (*getch) (int, uintptr_t), + int (*ungetch) (int, uintptr_t), + int arg1, uintptr_t arg2, bool *eofptr); static const uchar *build_stopchar_tab(const uchar *ufmt, uchar *stopchar_tab); @@ -81,8 +81,8 @@ static const uchar *build_stopchar_tab(const uchar *ufmt, uchar *stopchar_tab); * returned. */ int _doscan(const char *fmt, va_list ap, - int (*getch) (int, int), int (*ungetch) (int, int), - int arg1, int arg2) + int (*getch) (int, uintptr_t), int (*ungetch) (int, uintptr_t), + int arg1, uintptr_t arg2) { int nmatch; uint maxlen; @@ -235,8 +235,8 @@ int _doscan(const char *fmt, va_list ap, } static int scan_string(char *ptr, int type, uint maxlen, const uchar *stopchar_tab, - int (*getch) (int, int), int (*ungetch) (int, int), - int arg1, int arg2, bool *eofptr) + int (*getch) (int, uintptr_t), int (*ungetch) (int, uintptr_t), + int arg1, uintptr_t arg2, bool *eofptr) { uint len; int c; @@ -290,9 +290,9 @@ static int scan_string(char *ptr, int type, uint maxlen, const uchar *stopchar_t static int scan_number_or_string(void *ptr, uchar type, uint maxlen, enum integer_size size, const uchar *stopchar_tab, - int (*getch) (int, int), - int (*ungetch) (int, int), - int arg1, int arg2, bool *eofptr) + int (*getch) (int, uintptr_t), + int (*ungetch) (int,uintptr_t), + int arg1, uintptr_t arg2, bool *eofptr) { int c = EOF; ulong n; diff --git a/lib/libxc/fprintf.c b/lib/libxc/fprintf.c index 746a7e94..10c4791c 100644 --- a/lib/libxc/fprintf.c +++ b/lib/libxc/fprintf.c @@ -30,7 +30,7 @@ int fprintf(int dev, const char *format, ...) int ret; va_start(ap, format); - ret = _doprnt(format, ap, fputc, dev); + ret = _doprnt(format, ap, (int (*)(int, uintptr_t)) fputc, (uintptr_t) dev); va_end(ap); return ret; } diff --git a/lib/libxc/fscanf.c b/lib/libxc/fscanf.c index 301422bc..f83a16fe 100644 --- a/lib/libxc/fscanf.c +++ b/lib/libxc/fscanf.c @@ -6,8 +6,8 @@ #include #include -static int getch(int, int); -static int ungetch(int, int); +static int getch(int, uintptr_t); +static int ungetch(int, uintptr_t); struct ch_buf { @@ -44,14 +44,14 @@ int fscanf(int dev, const char *format, ...) buf.ch_avail = FALSE; va_start(ap, format); - ret = _doscan(format, ap, getch, ungetch, dev, (int)&buf); + ret = _doscan(format, ap, getch, ungetch, dev, (uintptr_t)&buf); va_end(ap); return ret; } /* Get a character from the device, storing it in the character buffer in case * an unget is requested. */ -static int getch(int dev, int _ch_buf) +static int getch(int dev, uintptr_t _ch_buf) { struct ch_buf *buf = (struct ch_buf *)_ch_buf; int c; @@ -72,7 +72,7 @@ static int getch(int dev, int _ch_buf) } /* Put back a character. */ -static int ungetch(int dev, int _chbuf) +static int ungetch(int dev, uintptr_t _chbuf) { struct ch_buf *buf = (struct ch_buf *)_chbuf; diff --git a/lib/libxc/malloc.c b/lib/libxc/malloc.c index 8f23528f..0b71f7ec 100644 --- a/lib/libxc/malloc.c +++ b/lib/libxc/malloc.c @@ -35,7 +35,7 @@ void *malloc(size_t size) /* acquire memory from kernel */ pmem = (struct memblock *)memget(size); - if (SYSERR == (uint)pmem) + if (SYSERR == (intptr_t)pmem) { return NULL; } diff --git a/lib/libxc/printf.c b/lib/libxc/printf.c index a6ce1265..617fdde6 100644 --- a/lib/libxc/printf.c +++ b/lib/libxc/printf.c @@ -28,7 +28,7 @@ int printf(const char *format, ...) int ret; va_start(ap, format); - ret = _doprnt(format, ap, fputc, stdout); + ret = _doprnt(format, ap, (int (*)(int, uintptr_t)) fputc, (uintptr_t)stdout); va_end(ap); return ret; diff --git a/lib/libxc/sprintf.c b/lib/libxc/sprintf.c index a79e8fa9..3d2ad6c7 100644 --- a/lib/libxc/sprintf.c +++ b/lib/libxc/sprintf.c @@ -6,7 +6,7 @@ #include #include -static int sprntf(int, int); +static int sprntf(int, uintptr_t); /** * @ingroup libxc @@ -33,7 +33,7 @@ int sprintf(char *str, const char *format, ...) s = str; va_start(ap, format); - _doprnt(format, ap, sprntf, (int)&s); + _doprnt(format, ap, sprntf, (uintptr_t) &s); va_end(ap); *s = '\0'; @@ -43,7 +43,7 @@ int sprintf(char *str, const char *format, ...) /* * Routine called by _doprnt() to output each character. */ -static int sprntf(int c, int _sptr) +static int sprntf(int c, uintptr_t _sptr) { char **sptr = (char **)_sptr; char *s = *sptr; diff --git a/lib/libxc/sscanf.c b/lib/libxc/sscanf.c index f0dccde8..cc000be1 100644 --- a/lib/libxc/sscanf.c +++ b/lib/libxc/sscanf.c @@ -8,8 +8,8 @@ #include #include -static int sgetch(int, int); -static int sungetch(int, int); +static int sgetch(int, uintptr_t); +static int sungetch(int, uintptr_t); /** * @ingroup libxc @@ -36,7 +36,7 @@ int sscanf(const char *str, const char *format, ...) int ret; va_start(ap, format); - ret = _doscan(format, ap, sgetch, sungetch, 0, (int)&str); + ret = _doscan(format, ap, sgetch, sungetch, 0, (uintptr_t) &str); va_end(ap); return ret; @@ -45,7 +45,7 @@ int sscanf(const char *str, const char *format, ...) /* The first argument to the below functions is ignored, as we only need one * argument to specify the current position in the string. */ -static int sgetch(int _ignored, int _str_p) +static int sgetch(int _ignored, uintptr_t _str_p) { const char **str_p = (const char **)_str_p; const char *str = *str_p; @@ -63,7 +63,7 @@ static int sgetch(int _ignored, int _str_p) return c; } -static int sungetch(int _ignored, int _str_p) +static int sungetch(int _ignored, uintptr_t _str_p) { const char **str_p = (const char**)_str_p; const char *str = *str_p; diff --git a/mailbox/mailboxAlloc.c b/mailbox/mailboxAlloc.c index 0f0cdc07..c07180cd 100644 --- a/mailbox/mailboxAlloc.c +++ b/mailbox/mailboxAlloc.c @@ -42,7 +42,7 @@ syscall mailboxAlloc(uint count) mbxptr->msgs = memget(sizeof(int) * count); /* check if memory was allocated correctly */ - if (SYSERR == (int)mbxptr->msgs) + if (SYSERR == (intptr_t)mbxptr->msgs) { break; } diff --git a/shell/xsh_memstat.c b/shell/xsh_memstat.c index 2c633373..8bec1b01 100644 --- a/shell/xsh_memstat.c +++ b/shell/xsh_memstat.c @@ -19,6 +19,12 @@ #define PRINT_REGION 0x04 #define PRINT_THREAD 0x08 +#if __LP64__ +#define HEXWIDTH 16 +#else +#define HEXWIDTH 8 +#endif + extern char *maxaddr; extern void _start(void); @@ -41,6 +47,8 @@ static void usage(char *command) printf("\t--help\t\tdisplay this help and exit\n"); } + + /** * @ingroup shell * @@ -129,17 +137,17 @@ shellcmd xsh_memstat(int nargs, char *args[]) static void printMemUsage(void) { int i; - uint phys = 0; /* total physical memory */ - uint resrv = 0; /* total reserved system memory */ - uint code = 0; /* total Xinu code memory */ - uint stack = 0; /* total stack memory */ - uint kheap = 0; /* total kernel heap memory */ - uint kused = 0; /* total used kernel heap memory */ - uint kfree = 0; /* total free memory */ + uintptr_t phys = 0; /* total physical memory */ + uintptr_t resrv = 0; /* total reserved system memory */ + uintptr_t code = 0; /* total Xinu code memory */ + uintptr_t stack = 0; /* total stack memory */ + uintptr_t kheap = 0; /* total kernel heap memory */ + uintptr_t kused = 0; /* total used kernel heap memory */ + uintptr_t kfree = 0; /* total free memory */ struct memblock *block; /* memory block pointer */ #ifdef UHEAP_SIZE - uint uheap = 0; /* total user heap memory */ - uint uused = 0; /* total used user heap memory */ + uintptr_t uheap = 0; /* total user heap memory */ + uintptr_t uused = 0; /* total used user heap memory */ struct memregion *regptr; /* point to memory region */ #endif /* UHEAP_SIZE */ @@ -179,7 +187,7 @@ static void printMemUsage(void) /* Calculate amount of user heap memory */ #ifdef UHEAP_SIZE /* determine used user heap amount */ - for (regptr = regalloclist; (int)regptr != SYSERR; + for (regptr = regalloclist; (uintptr_t)regptr != SYSERR; regptr = regptr->next) { uused += regptr->length; @@ -187,7 +195,7 @@ static void printMemUsage(void) /* determine total user heap size */ uheap = uused; - for (regptr = regfreelist; (int)regptr != SYSERR; + for (regptr = regfreelist; (uintptr_t)regptr != SYSERR; regptr = regptr->next) { uheap += regptr->length; @@ -200,16 +208,16 @@ static void printMemUsage(void) /* Ouput current memory usage */ printf("Current System Memory Usage:\n"); - printf("----------------------------\n"); - printf("%10d bytes system area\n", resrv); - printf("%10d bytes Xinu code\n", code); - printf("%10d bytes stack space\n", stack); - printf("%10d bytes kernel heap space (%d used)\n", kheap, kused); + printf("-----------------------------------------------------\n"); + printf("%20ld bytes system area\n", (ulong)resrv); + printf("%20ld bytes Xinu code\n", (ulong)code); + printf("%20ld bytes stack space\n", (ulong)stack); + printf("%20ld bytes kernel heap space (%ld used)\n", (ulong)kheap, (ulong)kused); #ifdef UHEAP_SIZE - printf("%10d bytes user heap space (%d used)\n", uheap, uused); + printf("%20ld bytes user heap space (%ld used)\n", (ulong)uheap, (ulong)uused); #endif /* UHEAP_SIZE */ - printf("----------------------------\n"); - printf("%10d bytes physical memory\n\n", phys); + printf("-----------------------------------------------------\n"); + printf("%20ld bytes physical memory\n\n", (ulong)phys); } /** @@ -223,15 +231,15 @@ static void printRegAllocList(void) /* Output free list */ printf("Region Allocated List:\n"); - printf("Index Start Length TID\n"); - printf("----- ---------- -------- ---\n"); + printf("Index Start Length TID\n"); + printf("----- ------------------- ------------------- ---\n"); - for (regptr = regalloclist; (int)regptr != SYSERR; + for (regptr = regalloclist; (uintptr_t)regptr != SYSERR; regptr = regptr->next) { - index = ((uint)regptr - (uint)regtab) / sizeof(struct memregion); - printf("%5d 0x%08x %8d %3d\n", index, regptr->start, - regptr->length, regptr->thread_id); + index = ((uintptr_t)regptr - (uintptr_t)regtab) / sizeof(struct memregion); + printf("%5d 0x%*lx %20ld %3d\n", index, HEXWIDTH, (ulong)regptr->start, + (ulong)regptr->length, regptr->thread_id); } printf("\n"); #else @@ -250,20 +258,21 @@ static void printRegFreeList(void) /* Output free list */ printf("Region Free List:\n"); - printf("Index Start Length \n"); - printf("----- ---------- --------\n"); + printf("Index Start Length\n"); + printf("----- --------------- -----------------\n"); for (regptr = regfreelist; (int)regptr != SYSERR; regptr = regptr->next) { - index = ((uint)regptr - (uint)regtab) / sizeof(struct memregion); - printf("%5d 0x%08x %8d\n", index, regptr->start, - regptr->length); + index = ((uintptr_t)regptr - (uintptr_t)regtab) / sizeof(struct memregion); + printf("%5d 0x%0*lx %20ld\n", index, HEXWIDTH, (ulong)regptr->start, + (ulong)regptr->length); } printf("\n"); #endif /* UHEAP_SIZE */ } + /** * Dump the current free list of a specific thread. * @param tid Id of thread to dump free list. @@ -274,11 +283,11 @@ static void printFreeList(struct memblock *base, char *ident) /* Output free list */ printf("Free List (%s):\n", ident); - printf("BLOCK START LENGTH \n"); - printf("----------- --------\n"); + printf("BLOCK START LENGTH \n"); + printf("------------------ --------------------\n"); for (block = base->next; block != NULL; block = block->next) { - printf("0x%08lX %8u\n", (ulong)block, block->length); + printf("0x%0*lX %20lu\n", HEXWIDTH, (ulong)block, (ulong)block->length); } printf("\n"); } diff --git a/system/Makerules b/system/Makerules index d6024839..97221bf2 100644 --- a/system/Makerules +++ b/system/Makerules @@ -38,6 +38,9 @@ C_FILES += minijava.c # Files for reading tape archives C_FILES += tar.c +# Files for reading device tree +C_FILES += dtb.c + # Add the files to the compile source path DIR = ${TOPDIR}/${COMP} COMP_SRC += ${C_FILES:%=${DIR}/%} diff --git a/system/create.c b/system/create.c index 2f0aa4c5..5b582d40 100644 --- a/system/create.c +++ b/system/create.c @@ -48,7 +48,7 @@ tid_typ create(void *procaddr, uint ssize, int priority, /* Allocate new stack. */ saddr = stkget(ssize); - if (SYSERR == (int)saddr) + if (SYSERR == (intptr_t)saddr) { restore(im); return SYSERR; diff --git a/system/dtb.c b/system/dtb.c new file mode 100644 index 00000000..7da5455f --- /dev/null +++ b/system/dtb.c @@ -0,0 +1,234 @@ +/** + * @file dtb.c This file provides support for parsing in-memory Flat + * Devicetree data structure. For more information see the Devicetree + * Specification at https://www.devicetree.org/ + */ + +/* Embedded Xinu, Copyright (C) 2009. All rights reserved. */ + +#include +#include +#include +#include +#include +#include +#include + +#define FDT_MAGIC 0xd00dfeed +#define FDT_LAST_COMP_VERSION 2 + +/* print the tree as it's being parsed */ +#define FDT_DETAILS 1 + +#if FDT_DETAILS +#define dtb_debug(format, ...) kprintf (format, ##__VA_ARGS__) +#else +#define dtb_debug(format, ...) +#endif + +struct fdt_header { + uint32_t magic; + uint32_t totalsize; + uint32_t off_dt_struct; + uint32_t off_dt_strings; + uint32_t off_mem_rsvmap; + uint32_t version; + uint32_t last_comp_version; + uint32_t boot_cpuid_phys; + uint32_t size_dt_strings; + uint32_t size_dt_struct; +}; + +struct fdt_reserve_entry { + uint64_t address; + uint64_t size; +}; + +void process_rsvmap(struct fdt_reserve_entry* eptr, + void (*rsv_handler)(uint64_t address, + uint64_t size)) { + while ( eptr->address || eptr->size) { + dtb_debug(" protected region at %lX of size %lX", + be64_to_cpu(eptr->address), + be64_to_cpu(eptr->size)); + if (NULL != rsv_handler) { + rsv_handler(be64_to_cpu(eptr->address), + be64_to_cpu(eptr->address)); + } + eptr++; + } +} + +#define FDT_BEGIN_NODE 0x1 +#define FDT_END_NODE 0x2 +#define FDT_PROP 0x3 +#define FDT_NOP 0x4 +#define FDT_END 0x9 + + + + +struct fdt_prop { + uint32_t len; + uint32_t nameoff; +}; + +uint32_t c2ioff(uint32_t charoff) { + return (charoff / 4) + ((charoff % 4) ? 1 : 0); +} + +#if FDT_DETAILS +/* known properties that we know how to interpret */ +static char* fdt_string_prop_names[] = {"bootargs", + "compatible", + "device_type", + "stdout-path", + "stdin-path", + "model", + "status", + "name", + "mmu-type", + "riscv,isa", + NULL}; +static char* fdt_u32_prop_names[] = {"reg", + "timebase-frequency", + "phandle", + "interrupts", + "interrupt-parent", + "#address-cells", + "#size-cell", + "clock-frequency", + NULL}; + + +int fdt_prop_in_list(char* prop, char**lst) { + int i; + for(i = 0; NULL!= *(lst+i); i++) { + if (!strcmp(prop, *(lst+i))) { + return 1; + } + } + return 0; +} + +void fdt_print_prop(char* node_name, + char *prop_name, + unsigned char *prop_val, + uint32_t prop_len) { + dtb_debug(" node=%s prop_name='%s' len=%u%s", + node_name, prop_name, prop_len, (prop_len ? " value=" : "")); + // how do we know data type? only by name? + int j; + if (fdt_prop_in_list(prop_name, fdt_string_prop_names)) { + dtb_debug("'%s'", prop_val); + } else if (fdt_prop_in_list(prop_name, fdt_u32_prop_names)) { + dtb_debug("<"); + for (j = 0 ; j < prop_len; j+=4) { + dtb_debug("%s0x%x", + (j ? " " : ""), + be32_to_cpu(*((uint32_t*)(prop_val + j)))); + } + dtb_debug(">"); + } else { + for (j = 0 ; j < prop_len; j++) { + dtb_debug("%s%02x", (j ? " " : ""), *(prop_val + j)); + } + } + dtb_debug("\n"); +} +#endif + +int process_fdt_nodes(void* fdt_strb_ptr, uint32_t *startptr, + void (*handler)(char* nname, + char *pname, + unsigned char *val, + uint32_t len)) { + uint32_t i = 0; + char *node_name = NULL; + while (1) { + //dtb_debug(" process_fdt_nodes: offset=%0u\n", i); + uint32_t*tokptr = startptr + i; + //dtb_debug(" process_fdt_nodes: tokptr 0x%lX\n", tokptr); + uint32_t token = be32_to_cpu(*tokptr); + //dtb_debug(" process_fdt_nodes: token=0x%X\n", token); + switch(token) { + case FDT_BEGIN_NODE: + // FDT_BEGIN_NODE followed by 0 term. name + node_name = (char*)(tokptr+1); + dtb_debug(" begin node at %lX: '%s'\n", tokptr, node_name); + i += 1 + c2ioff(1 + strlen((char*)(tokptr+1))); + continue; + case FDT_PROP: + ; /* ; keeps compiler happy, var decls aren't statements + and can't be labeled */ + struct fdt_prop *propptr = (struct fdt_prop*)(tokptr+1); + uint32_t prop_len = be32_to_cpu(propptr->len); + char *prop_name = (char*)(fdt_strb_ptr + be32_to_cpu(propptr->nameoff)); + unsigned char *prop_val = ((unsigned char*)propptr) + sizeof(struct fdt_prop); +#if FDT_DETAILS + fdt_print_prop(node_name, prop_name, prop_val, prop_len); +#endif + if (NULL != handler) { + handler(node_name, prop_name, prop_val, prop_len); + } + i+= 1 + c2ioff(sizeof(struct fdt_prop) + prop_len); + + continue; + case FDT_END_NODE: + node_name = NULL; + case FDT_NOP: + i++; + continue; + case FDT_END: + dtb_debug(" FDT end at %lX\n", tokptr); + return 0; + default: + dtb_debug(" unknown token '%x' at %lX\n", token, tokptr+i); + return 1; + } + + } + return 0; +} + + +int parse_dtb(void *dtbptr, + void (*prop_handler)(char *nname, + char *pname, + unsigned char *val, + uint32_t len), + void (*rsv_handler)(uint64_t address, + uint64_t size)) { + struct fdt_header* h = (struct fdt_header*)dtbptr; + dtb_debug("* Dump of dtb at 0x%0lX\n", dtbptr); + dtb_debug(" magic: 0x%x\n", be32_to_cpu(h->magic)); + if (FDT_MAGIC!=be32_to_cpu(h->magic)) { + dtb_debug("Error: magic is invalid: got 0x%X, but 0x%X was expected\n", + h->magic, FDT_MAGIC); + return SYSERR; + } + dtb_debug(" version: %u\n", be32_to_cpu(h->version)); + int lcompver = be32_to_cpu(h->last_comp_version); + dtb_debug(" last compatible version: %u\n", lcompver); + if (lcompver < FDT_LAST_COMP_VERSION) { + dtb_debug("WARNING: unexpected last_comp_version: got %u, but only %u is supported, parsing mail fail!", + lcompver, FDT_LAST_COMP_VERSION); + } + dtb_debug(" memory reservations map is at offset: 0x%x\n", be32_to_cpu(h->off_mem_rsvmap)); + process_rsvmap((struct fdt_reserve_entry*)(dtbptr + be32_to_cpu(h->off_mem_rsvmap)), + rsv_handler); + dtb_debug(" structure block is at offset: 0x%x\n", be32_to_cpu(h->off_dt_struct)); + dtb_debug(" strings block is at offset: 0x%x\n", be32_to_cpu(h->off_dt_strings)); + process_fdt_nodes((void*) (dtbptr + be32_to_cpu(h->off_dt_strings)), + (uint32_t*)(dtbptr+ be32_to_cpu(h->off_dt_struct)), + prop_handler); + return 0; +} + +uint64_t dtb_read_uint64(uint32_t* dataptr) { + return ((((uint64_t)be32_to_cpu(*dataptr))<<32) | ((uint64_t)be32_to_cpu(*(dataptr+1)))); +} + + + + diff --git a/system/initialize.c b/system/initialize.c index 7802b955..381e6930 100644 --- a/system/initialize.c +++ b/system/initialize.c @@ -106,9 +106,9 @@ static int sysinit(void) memheap = roundmb(memheap); platform.maxaddr = truncmb(platform.maxaddr); memlist.next = pmblock = (struct memblock *)memheap; - memlist.length = (uint)(platform.maxaddr - memheap); + memlist.length = (uintptr_t)(platform.maxaddr - memheap); pmblock->next = NULL; - pmblock->length = (uint)(platform.maxaddr - memheap); + pmblock->length = (uintptr_t)(platform.maxaddr - memheap); /* Initialize thread table */ for (i = 0; i < NTHREAD; i++) diff --git a/system/main.c b/system/main.c index b4fa84b3..4ca20d18 100644 --- a/system/main.c +++ b/system/main.c @@ -129,6 +129,19 @@ thread main(void) return 0; } + +#ifdef DETAIL +extern ulong cpuid; +#endif + +#if __LP64__ +#define HEXWIDTH 16 +#define DECWIDTH 20 +#else +#define HEXWIDTH 8 +#define DECWIDTH 10 +#endif + /* Start of kernel in memory (provided by linker) */ extern void _start(void); @@ -139,44 +152,49 @@ static void print_os_info(void) #ifdef DETAIL /* Output detected platform. */ - kprintf("Processor identification: 0x%08X\r\n", cpuid); + kprintf("Processor identification: 0x%lX\r\n", cpuid); kprintf("Detected platform as: %s, %s\r\n\r\n", platform.family, platform.name); #endif /* Output Xinu memory layout */ - kprintf("%10d bytes physical memory.\r\n", - (ulong)platform.maxaddr - (ulong)platform.minaddr); + kprintf("%*ld bytes physical memory.\r\n", + DECWIDTH, (uintptr_t)platform.maxaddr - (uintptr_t)platform.minaddr); #ifdef DETAIL - kprintf(" [0x%08X to 0x%08X]\r\n", - (ulong)platform.minaddr, (ulong)(platform.maxaddr - 1)); + kprintf(" [0x%0*X to 0x%0*X]\r\n", + HEXWIDTH, (uintptr_t)platform.minaddr, + HEXWIDTH, (uintptr_t)(platform.maxaddr - 1)); #endif - - kprintf("%10d bytes reserved system area.\r\n", - (ulong)_start - (ulong)platform.minaddr); + kprintf("%*ld bytes reserved system area.\r\n", + DECWIDTH, (uintptr_t)_start - (uintptr_t)platform.minaddr); #ifdef DETAIL - kprintf(" [0x%08X to 0x%08X]\r\n", - (ulong)platform.minaddr, (ulong)_start - 1); + kprintf(" [0x%0*lX to 0x%0*lX]\r\n", + HEXWIDTH, (uintptr_t)platform.minaddr, + HEXWIDTH, (uintptr_t)_start - 1); #endif - kprintf("%10d bytes Xinu code.\r\n", (ulong)&_etext - (ulong)_start); + kprintf("%*ld bytes Xinu code.\r\n", DECWIDTH, (uintptr_t)&_etext - (uintptr_t)_start); #ifdef DETAIL - kprintf(" [0x%08X to 0x%08X]\r\n", - (ulong)_start, (ulong)&_end - 1); + kprintf(" [0x%0*lX to 0x%0*lX]\r\n", + HEXWIDTH, (uintptr_t)_start, + HEXWIDTH, (uintptr_t)&_end - 1); #endif - kprintf("%10d bytes stack space.\r\n", (ulong)memheap - (ulong)&_end); + kprintf("%*ld bytes stack space.\r\n", + DECWIDTH, (uintptr_t)memheap - (uintptr_t)&_end); #ifdef DETAIL - kprintf(" [0x%08X to 0x%08X]\r\n", - (ulong)&_end, (ulong)memheap - 1); + kprintf(" [0x%0*lX to 0x%0*lX]\r\n", + HEXWIDTH, (uintptr_t)&_end, + HEXWIDTH, (uintptr_t)memheap - 1); #endif - kprintf("%10d bytes heap space.\r\n", - (ulong)platform.maxaddr - (ulong)memheap); + kprintf("%*ld bytes heap space.\r\n", + DECWIDTH, (uintptr_t)platform.maxaddr - (uintptr_t)memheap); #ifdef DETAIL - kprintf(" [0x%08X to 0x%08X]\r\n\r\n", - (ulong)memheap, (ulong)platform.maxaddr - 1); + kprintf(" [0x%0*lX to 0x%0*lX]\r\n\r\n", + HEXWIDTH, (uintptr_t)memheap, + HEXWIDTH, (uintptr_t)platform.maxaddr - 1); #endif kprintf("\r\n"); } diff --git a/system/memfree.c b/system/memfree.c index c70c9f7e..860ea00c 100644 --- a/system/memfree.c +++ b/system/memfree.c @@ -23,7 +23,7 @@ * ::OK on success; ::SYSERR on failure. This function can only fail * because of memory corruption or specifying an invalid memory block. */ -syscall memfree(void *memptr, uint nbytes) +syscall memfree(void *memptr, uintptr_t nbytes) { register struct memblock *block, *next, *prev; irqmask im; diff --git a/system/memget.c b/system/memget.c index 05780e5b..07251cb3 100644 --- a/system/memget.c +++ b/system/memget.c @@ -21,7 +21,7 @@ * The returned pointer is guaranteed to be 8-byte aligned. Free the block * with memfree() when done with it. */ -void *memget(uint nbytes) +void *memget(uintptr_t nbytes) { register struct memblock *prev, *curr, *leftover; irqmask im; diff --git a/system/stkget.c b/system/stkget.c index 9a8c4e63..a43aaa79 100644 --- a/system/stkget.c +++ b/system/stkget.c @@ -24,7 +24,7 @@ * the base of a stack growing down. Free the stack with stkfree() when * done with it. */ -void *stkget(uint nbytes) +void *stkget(uintptr_t nbytes) { irqmask im; struct memblock *prev, *next, *fits, *fitsprev; @@ -35,7 +35,7 @@ void *stkget(uint nbytes) } /* round to multiple of memblock size */ - nbytes = (uint)roundmb(nbytes); + nbytes = (uintptr_t)roundmb(nbytes); im = disable(); @@ -76,5 +76,5 @@ void *stkget(uint nbytes) memlist.length -= nbytes; restore(im); - return (void *)((ulong)fits + nbytes - sizeof(int)); + return (void *)((ulong)fits + nbytes - sizeof(void*)); } diff --git a/test/test_libStdio.c b/test/test_libStdio.c index 6cdaf059..742daf59 100644 --- a/test/test_libStdio.c +++ b/test/test_libStdio.c @@ -235,7 +235,7 @@ static const struct { const char *format; const char *expected_output; uint nargs; - uint args[4]; /* Assumes all args are 4 bytes. */ + uintptr_t args[4]; /* Assumes all args are 4 bytes. */ } fprintf_specs[] = { { /* Empty string */ .format = "", @@ -247,7 +247,7 @@ static const struct { .format = "%s", .expected_output = "", .nargs = 1, - .args = {(uint)""}, + .args = {(uintptr_t)""}, }, { /* Binary number */ .format = "%b", @@ -295,7 +295,7 @@ static const struct { .format = "%s", .expected_output = "aoeu", .nargs = 1, - .args = {(uint)"aoeu"}, + .args = {(uintptr_t)"aoeu"}, }, { /* Null string */ .format = "%s", @@ -325,55 +325,55 @@ static const struct { .format = "%.5s", .expected_output = "trunc", .nargs = 1, - .args = {(uint)"truncate me"}, + .args = {(uintptr_t)"truncate me"}, }, { /* Truncated string, max-width specified as vararg */ .format = "%.*s", .expected_output = "trunc", .nargs = 2, - .args = {5, (uint)"truncate me"}, + .args = {5, (uintptr_t)"truncate me"}, }, { /* Non-truncated string, negative max-width has no effect */ .format = "%.*s", .expected_output = "truncate me", .nargs = 2, - .args = {-1, (uint)"truncate me"}, + .args = {-1, (uintptr_t)"truncate me"}, }, { /* Truncated string, implicit zero max-width */ .format = "%.s", .expected_output = "", .nargs = 1, - .args = {(uint)"truncate me"}, + .args = {(uintptr_t)"truncate me"}, }, { /* Right justified string */ .format = "%10s", .expected_output = " right", .nargs = 1, - .args = {(uint)"right"}, + .args = {(uintptr_t)"right"}, }, { /* Right justified string, min-width specified as vararg */ .format = "%*s", .expected_output = " right", .nargs = 2, - .args = {10, (uint)"right"}, + .args = {10, (uintptr_t)"right"}, }, { /* Left justified string */ .format = "%-8s", .expected_output = "left ", .nargs = 1, - .args = {(uint)"left"}, + .args = {(uintptr_t)"left"}, }, { /* Left justified string, min-width specified as vararg */ .format = "%-*s", .expected_output = "left ", .nargs = 2, - .args = {8, (uint)"left"}, + .args = {8, (uintptr_t)"left"}, }, { /* Left justified string via negative min-width specified as vararg */ .format = "%*s", .expected_output = "left ", .nargs = 2, - .args = {-8, (uint)"left"}, + .args = {-8, (uintptr_t)"left"}, }, { /* Negative integer */ .format = "%d", @@ -397,7 +397,7 @@ static const struct { .format = "%u", .expected_output = "2147483648", .nargs = 1, - .args = {(uint)INT_MAX + 1}, + .args = {(uintptr_t)INT_MAX + 1}, }, { /* min width (left justified, overriding zero padding) */ .format = "%-06d", /* '-' overrides '0' */ @@ -433,13 +433,13 @@ static const struct { .format = "%23s", .expected_output = " "" "" "" ""123", .nargs = 1, - .args = {(uint)"123"}, + .args = {(uintptr_t)"123"}, }, { /* Large max width */ .format = "%.23s", .expected_output = "abcdefghijklmnopqrstuvw", .nargs = 1, - .args = {(uint)"abcdefghijklmnopqrstuvwxyz"}, + .args = {(uintptr_t)"abcdefghijklmnopqrstuvwxyz"}, }, { /* Zero */ .format = "%d", @@ -517,7 +517,7 @@ static const struct { .format = "literal %08d\t%-8s\t%c%cliteral", .expected_output = "literal 00004000\tfoobar \t\xfeXliteral", .nargs = 4, - .args = {4000, (uint)"foobar", 0xfe, 'X'}, + .args = {4000, (uintptr_t)"foobar", 0xfe, 'X'}, }, }; @@ -532,7 +532,7 @@ static bool do_detailed_fprintf_tests(bool verbose, bool passed) const char *format = fprintf_specs[i].format; const char *expected_output = fprintf_specs[i].expected_output; uint nargs = fprintf_specs[i].nargs; - const uint *args = fprintf_specs[i].args; + const uintptr_t *args = fprintf_specs[i].args; int ret; int len = strlen(expected_output); uchar obuf[len + 1]; diff --git a/test/test_memory.c b/test/test_memory.c index 8640182e..8af3dd6f 100644 --- a/test/test_memory.c +++ b/test/test_memory.c @@ -20,7 +20,7 @@ thread test_memory(bool verbose) /* Allocate a small piece of memory */ testPrint(verbose, "Allocate small piece"); testblock = (struct memblock *)memget(1); - if (SYSERR == (uint)testblock) + if (SYSERR == (intptr_t)testblock) { passed = FALSE; testFail(verbose, "memget SYSERR"); @@ -68,7 +68,7 @@ thread test_memory(bool verbose) } saddr = stkget(1); - if (SYSERR == (uint)saddr) + if (SYSERR == (intptr_t)saddr) { passed = FALSE; testFail(verbose, "\nstkget SYSERR");