diff options
author | Palmer Dabbelt <palmer@dabbelt.com> | 2017-08-05 15:53:27 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-08-05 15:53:27 -0700 |
commit | 6b501de8e8512abd969199c57c5531737e52a105 (patch) | |
tree | 6b3afe9e5df25ca40d021c97e1d9553ecdb5b9e9 | |
parent | 2187c4512db64656896f4b455628a2567984eba1 (diff) | |
parent | ca24f3c904186cb6babfc74fd6c4e133e4542b5e (diff) | |
download | pk-6b501de8e8512abd969199c57c5531737e52a105.zip pk-6b501de8e8512abd969199c57c5531737e52a105.tar.gz pk-6b501de8e8512abd969199c57c5531737e52a105.tar.bz2 |
Merge pull request #59 from riscv/print-device-tree
Add the '--enable-print-device-tree' argument
-rw-r--r-- | bbl/bbl.c | 11 | ||||
-rw-r--r-- | config.h.in | 3 | ||||
-rwxr-xr-x | configure | 16 | ||||
-rw-r--r-- | configure.ac | 5 | ||||
-rw-r--r-- | machine/fdt.c | 127 | ||||
-rw-r--r-- | machine/fdt.h | 5 | ||||
-rw-r--r-- | machine/mtrap.c | 12 | ||||
-rw-r--r-- | machine/mtrap.h | 2 |
8 files changed, 174 insertions, 7 deletions
@@ -17,7 +17,7 @@ static uintptr_t dtb_output() return (end + MEGAPAGE_SIZE - 1) / MEGAPAGE_SIZE * MEGAPAGE_SIZE; } -static void filter_dtb(uintptr_t source) +static uintptr_t filter_dtb(uintptr_t source) { uintptr_t dest = dtb_output(); uint32_t size = fdt_size(source); @@ -28,6 +28,8 @@ static void filter_dtb(uintptr_t source) filter_plic(dest); filter_compat(dest, "riscv,clint0"); filter_compat(dest, "riscv,debug-013"); + + return dest; } void boot_other_hart(uintptr_t dtb) @@ -37,16 +39,19 @@ void boot_other_hart(uintptr_t dtb) entry = entry_point; mb(); } while (!entry); - enter_supervisor_mode(entry, read_csr(mhartid), dtb_output()); + enter_supervisor_mode(entry, read_csr(mhartid), dtb); } void boot_loader(uintptr_t dtb) { extern char _payload_start; - filter_dtb(dtb); + dtb = filter_dtb(dtb); #ifdef PK_ENABLE_LOGO print_logo(); #endif +#ifdef PK_PRINT_DEVICE_TREE + fdt_print(dtb); +#endif mb(); entry_point = &_payload_start; boot_other_hart(dtb); diff --git a/config.h.in b/config.h.in index 9557930..179cbf0 100644 --- a/config.h.in +++ b/config.h.in @@ -39,6 +39,9 @@ /* Define if virtual memory support is enabled */ #undef PK_ENABLE_VM +/* Define if the DTS is to be displayed */ +#undef PK_PRINT_DEVICE_TREE + /* Define if subproject MCPPBS_SPROJ_NORM is enabled */ #undef PLATFORM_ENABLED @@ -671,6 +671,7 @@ enable_option_checking enable_stow enable_32bit with_platform +enable_print_device_tree enable_optional_subprojects enable_vm enable_logo @@ -1318,6 +1319,8 @@ Optional Features: --enable-FEATURE[=ARG] include FEATURE [ARG=yes] --enable-stow Enable stow-based install --enable-32bit Build a 32-bit pk + --enable-print-device-tree + Print DTS when booting --enable-optional-subprojects Enable all optional subprojects --disable-vm Disable virtual memory @@ -4103,6 +4106,19 @@ fi PLATFORM_NAME=$PLATFORM_NAME +# Check whether --enable-print-device-tree was given. +if test "${enable_print_device_tree+set}" = set; then : + enableval=$enable_print_device_tree; +fi + +if test "x$enable_print_device_tree" == "xyes"; then : + + +$as_echo "#define PK_PRINT_DEVICE_TREE /**/" >>confdefs.h + + +fi + LIBS="-lgcc" diff --git a/configure.ac b/configure.ac index 5813f3b..31b275f 100644 --- a/configure.ac +++ b/configure.ac @@ -105,6 +105,11 @@ AC_ARG_WITH([platform], PLATFORM_NAME=spike) AC_SUBST(PLATFORM_NAME, $PLATFORM_NAME) +AC_ARG_ENABLE([print-device-tree], AS_HELP_STRING([--enable-print-device-tree], [Print DTS when booting])) +AS_IF([test "x$enable_print_device_tree" == "xyes"], [ + AC_DEFINE([PK_PRINT_DEVICE_TREE],,[Define if the DTS is to be displayed]) +]) + AC_SUBST(CFLAGS) AC_SUBST(LDFLAGS) AC_SUBST([LIBS], ["-lgcc"]) diff --git a/machine/fdt.c b/machine/fdt.c index 4f72f73..35681f8 100644 --- a/machine/fdt.c +++ b/machine/fdt.c @@ -1,5 +1,6 @@ #include <stdint.h> #include <string.h> +#include "config.h" #include "fdt.h" #include "mtrap.h" @@ -10,6 +11,19 @@ static inline uint32_t bswap(uint32_t x) return z; } +static inline int isstring(char c) +{ + if (c >= 'A' && c <= 'Z') + return 1; + if (c >= 'a' && c <= 'z') + return 1; + if (c >= '0' && c <= '9') + return 1; + if (c == '\0' || c == ' ' || c == ',' || c == '-') + return 1; + return 0; +} + static uint32_t *fdt_scan_helper( uint32_t *lex, const char *strings, @@ -593,3 +607,116 @@ void filter_harts(uintptr_t fdt, unsigned long hart_mask) filter.mask = hart_mask; fdt_scan(fdt, &cb); } + +//////////////////////////////////////////// PRINT ////////////////////////////////////////////// + +#ifdef PK_PRINT_DEVICE_TREE +#define FDT_PRINT_MAX_DEPTH 32 + +struct fdt_print_info { + int depth; + const struct fdt_scan_node *stack[FDT_PRINT_MAX_DEPTH]; +}; + +void fdt_print_printm(struct fdt_print_info *info, const char *format, ...) +{ + va_list vl; + + for (int i = 0; i < info->depth; ++i) + printm(" "); + + va_start(vl, format); + vprintm(format, vl); + va_end(vl); +} + +static void fdt_print_open(const struct fdt_scan_node *node, void *extra) +{ + struct fdt_print_info *info = (struct fdt_print_info *)extra; + + while (node->parent != NULL && info->stack[info->depth-1] != node->parent) { + info->depth--; + fdt_print_printm(info, "}\r\n"); + } + + fdt_print_printm(info, "%s {\r\n", node->name); + info->stack[info->depth] = node; + info->depth++; +} + +static void fdt_print_prop(const struct fdt_scan_prop *prop, void *extra) +{ + struct fdt_print_info *info = (struct fdt_print_info *)extra; + int asstring = 1; + char *char_data = (char *)(prop->value); + + fdt_print_printm(info, "%s", prop->name); + + if (prop->len == 0) { + printm(";\r\n"); + return; + } else { + printm(" = "); + } + + /* It appears that dtc uses a hueristic to detect strings so I'm using a + * similar one here. */ + for (int i = 0; i < prop->len; ++i) { + if (!isstring(char_data[i])) + asstring = 0; + if (i > 0 && char_data[i] == '\0' && char_data[i-1] == '\0') + asstring = 0; + } + + if (asstring) { + for (size_t i = 0; i < prop->len; i += strlen(char_data + i) + 1) { + if (i != 0) + printm(", "); + printm("\"%s\"", char_data + i); + } + } else { + printm("<"); + for (size_t i = 0; i < prop->len/4; ++i) { + if (i != 0) + printm(" "); + printm("0x%08x", bswap(prop->value[i])); + } + printm(">"); + } + + printm(";\r\n"); +} + +static void fdt_print_done(const struct fdt_scan_node *node, void *extra) +{ + struct fdt_print_info *info = (struct fdt_print_info *)extra; +} + +static int fdt_print_close(const struct fdt_scan_node *node, void *extra) +{ + struct fdt_print_info *info = (struct fdt_print_info *)extra; + return 0; +} + +void fdt_print(uintptr_t fdt) +{ + struct fdt_print_info info; + struct fdt_cb cb; + + info.depth = 0; + + memset(&cb, 0, sizeof(cb)); + cb.open = fdt_print_open; + cb.prop = fdt_print_prop; + cb.done = fdt_print_done; + cb.close = fdt_print_close; + cb.extra = &info; + + fdt_scan(fdt, &cb); + + while (info.depth > 0) { + info.depth--; + fdt_print_printm(&info, "}\r\n"); + } +} +#endif diff --git a/machine/fdt.h b/machine/fdt.h index c12905e..5932e17 100644 --- a/machine/fdt.h +++ b/machine/fdt.h @@ -68,4 +68,9 @@ void filter_compat(uintptr_t fdt, const char *compat); // The hartids of available harts extern uint64_t hart_mask; +#ifdef PK_PRINT_DEVICE_TREE +// Prints the device tree to the console as a DTS +void fdt_print(uintptr_t fdt); +#endif + #endif diff --git a/machine/mtrap.c b/machine/mtrap.c index 62137ff..a72b373 100644 --- a/machine/mtrap.c +++ b/machine/mtrap.c @@ -42,16 +42,20 @@ void putstring(const char* s) mcall_console_putchar(*s++); } -void printm(const char* s, ...) +void vprintm(const char* s, va_list vl) { char buf[256]; + vsnprintf(buf, sizeof buf, s, vl); + putstring(buf); +} + +void printm(const char* s, ...) +{ va_list vl; va_start(vl, s); - vsnprintf(buf, sizeof buf, s, vl); + vprintm(s, vl); va_end(vl); - - putstring(buf); } static void send_ipi(uintptr_t recipient, int event) diff --git a/machine/mtrap.h b/machine/mtrap.h index 4ec0924..a15b265 100644 --- a/machine/mtrap.h +++ b/machine/mtrap.h @@ -13,6 +13,7 @@ #include <stdint.h> #include <stddef.h> +#include <stdarg.h> #define read_const_csr(reg) ({ unsigned long __tmp; \ asm ("csrr %0, " #reg : "=r"(__tmp)); \ @@ -57,6 +58,7 @@ hls_t* hls_init(uintptr_t hart_id); void parse_config_string(); void poweroff(void) __attribute((noreturn)); void printm(const char* s, ...); +void vprintm(const char *s, va_list args); void putstring(const char* s); #define assert(x) ({ if (!(x)) die("assertion failed: %s", #x); }) #define die(str, ...) ({ printm("%s:%d: " str "\n", __FILE__, __LINE__, ##__VA_ARGS__); poweroff(); }) |