From add751549f34c5b40ab1c8b389f81b3a889cf0c8 Mon Sep 17 00:00:00 2001 From: Korobov Nikita Date: Sat, 27 May 2017 04:54:01 +0300 Subject: [PATCH] [MAJOR] Added a simple device tree parser --- minix/include/minix/board.h | 29 ++++++++++++++- minix/kernel/arch/earm/Makefile.inc | 2 +- minix/kernel/arch/earm/fdt.c | 47 ++++++++++++++++++++++++ minix/kernel/arch/earm/head.S | 13 ++++--- minix/kernel/arch/earm/include/fdt.h | 9 +++++ minix/kernel/arch/earm/pre_init.c | 53 +++++----------------------- 6 files changed, 100 insertions(+), 53 deletions(-) create mode 100644 minix/kernel/arch/earm/fdt.c create mode 100644 minix/kernel/arch/earm/include/fdt.h diff --git a/minix/include/minix/board.h b/minix/include/minix/board.h index 10374682c..ac6c18c74 100644 --- a/minix/include/minix/board.h +++ b/minix/include/minix/board.h @@ -168,7 +168,6 @@ struct shortname2id unsigned int id; }; - /* mapping from fields given by the bootloader to board id's */ static struct shortname2id shortname2id[] = { {.name = "BBXM",.id = BOARD_ID_BBXM}, @@ -178,6 +177,21 @@ static struct shortname2id shortname2id[] = { {.name = "RPI_3_B",.id = BOARD_ID_RPI_3_B}, }; +struct longname2id +{ + const char name[40]; + unsigned int id; +}; + +/* mapping from fields given by the device tree to board id's */ +static struct longname2id longname2id[] = { + {.name = "BBXM",.id = BOARD_ID_BBXM}, + {.name = "A335BONE",.id = BOARD_ID_BBW}, + {.name = "A335BNLT",.id = BOARD_ID_BBB}, + {.name = "Raspberry Pi 2 Model B Rev 1.1",.id = BOARD_ID_RPI_2_B}, + {.name = "Raspberry Pi 3 Model B Rev 1.2",.id = BOARD_ID_RPI_3_B}, +}; + struct board_id2name { unsigned int id; @@ -218,6 +232,19 @@ get_board_id_by_short_name(const char *name) return 0; } +/* returns 0 if no board was found that match that id */ +static int +get_board_id_by_long_name(const char *name) +{ + int x; + for (x = 0; x < sizeof(longname2id) / sizeof(longname2id[0]); x++) { + if (strncmp(name, longname2id[x].name, 15) == 0) { + return longname2id[x].id; + } + } + return 0; +} + /* returns 0 if no board was found that match that id */ static int get_board_id_by_name(const char *name) diff --git a/minix/kernel/arch/earm/Makefile.inc b/minix/kernel/arch/earm/Makefile.inc index 6caf1bc28..c5599f43a 100644 --- a/minix/kernel/arch/earm/Makefile.inc +++ b/minix/kernel/arch/earm/Makefile.inc @@ -28,7 +28,7 @@ CLEANFILES+= ${ORIG_UNPAGED_OBJS} SRCS+= mpx.S arch_clock.c arch_do_vmctl.c arch_system.c do_padconf.c \ exception.c hw_intr.c klib.S memory.c pre_init.c \ protect.c direct_tty_utils.c arch_reset.c \ - pg_utils.c phys_copy.S phys_memset.S exc.S + pg_utils.c fdt.c phys_copy.S phys_memset.S exc.S OBJS.kernel+= ${UNPAGED_OBJS} diff --git a/minix/kernel/arch/earm/fdt.c b/minix/kernel/arch/earm/fdt.c new file mode 100644 index 000000000..aaeb1b73e --- /dev/null +++ b/minix/kernel/arch/earm/fdt.c @@ -0,0 +1,47 @@ +#include +#include +#include +#include "fdt.h" + +void *dev_tree; + +int fdt_set_machine_type (void *fdt, int offset, void *dst) +{ + struct machine *machine = (struct machine *)dst; + const char *model = fdt_getprop(fdt, offset, "model", NULL); + if (model == NULL) + return -1; + + machine->board_id = get_board_id_by_long_name(model); + + if (machine->board_id == 0) { + /* same thing as above there is no safe escape */ + return -1; + } + return 0; +} + +int fdt_set_memory (void *fdt, int offset, void *dst) +{ + return 0; +} + +int fdt_set_cpu_num (void *fdt, int offset, void *dst) +{ + return 0; +} + +int fdt_step_node (void *fdt, int (*cb)(void *fdt, int offset, void *dst), void *dst) +{ + int offset = -1; + int len = -1; + int retv = 0; + for (offset = fdt_next_node(fdt, -1, &len); + offset >= 0 && len >= 0; + offset = fdt_next_node(fdt, offset, &len)) { + retv = cb(fdt, offset, dst); + if (retv == 0) + return 0; + } + return -1; +} diff --git a/minix/kernel/arch/earm/head.S b/minix/kernel/arch/earm/head.S index bd7d5847b..68169b6c2 100644 --- a/minix/kernel/arch/earm/head.S +++ b/minix/kernel/arch/earm/head.S @@ -130,7 +130,7 @@ check2: orr r3, r3, #ARM_VM_SECTION_USER orr r3, r3, #ARM_VM_SECTION_DOMAIN 1: - ldr r5, =0x3effffff //FIXME + ldr r5, =0x3effffff cmp r7, r5 blo cached ldr r2, =#ARM_VM_SECTION_DEVICE @@ -154,7 +154,7 @@ setup: /* The first free entry in the page table is placed */ /* in freepde. */ /****************************************************/ - ldr r6, =0xf0400000 //FIXME + ldr r6, =_kern_vir_base mov r7, r9 add r5, r4, r6, lsr #18 @@ -228,11 +228,10 @@ setup: mov r2, r10 ldr sp, =k_initial_stktop /* make usable stack */ - mov r3, #0 push {r3} mov fp, #0 - push {r3} + push {r2} bl _C_LABEL(pre_init) ldr r4, =1384 // FIXME @@ -240,15 +239,15 @@ setup: ldr r5, =freepde ldr r5, [r5] str r5, [r3] - + pop {r2} /* Kernel is mapped high now and ready to go, with * the boot info pointer returned by pre_init in r0. * Set the highly mapped stack and initialize it. * * After that call kmain with r0 still pointing to boot info */ - ldr r2, =_C_LABEL(kmain) /* r0 holds kinfo_t ptr */ - bx r2 + ldr r3, =_C_LABEL(kmain) /* r0 holds kinfo_t ptr */ + bx r3 /* not reached */ hang: diff --git a/minix/kernel/arch/earm/include/fdt.h b/minix/kernel/arch/earm/include/fdt.h new file mode 100644 index 000000000..5608d4f74 --- /dev/null +++ b/minix/kernel/arch/earm/include/fdt.h @@ -0,0 +1,9 @@ +#ifndef __FDT_H__ +#define __FDT_H__ + +int fdt_set_machine_type (void *fdt, int offset, void *machine); +int fdt_set_memory (void *fdt, int offset, void *dst); +int fdt_set_cpu_num (void *fdt, int offset, void *dst); +int fdt_step_node (void *fdt, int (*cb)(void *fdt, int offset, void *dst), void *dst); + +#endif \ No newline at end of file diff --git a/minix/kernel/arch/earm/pre_init.c b/minix/kernel/arch/earm/pre_init.c index e807dfbc3..866b57beb 100644 --- a/minix/kernel/arch/earm/pre_init.c +++ b/minix/kernel/arch/earm/pre_init.c @@ -16,9 +16,8 @@ #include "bsp_table.h" #include "glo.h" #include - #include -#include +#include "fdt.h" #if USE_SYSDEBUG #define MULTIBOOT_VERBOSE 1 @@ -40,6 +39,8 @@ int kernel_may_alloc = 1; extern u32_t _edata; extern u32_t _end; +extern void *dev_tree; + #define BSP_TABLE_GENERATE(name) \ do { \ platform_tb.bsp_init = name##_init; \ @@ -416,43 +417,6 @@ void set_bsp_table() bsp_tb = &platform_tb; } -static void test_node(const void *fdt, int parent_offset) -{ - uint32_t subnodes; - const fdt32_t *prop; - int offset; - int count; - int len; - /* This property indicates the number of subnodes to expect */ - prop = fdt_getprop(fdt, parent_offset, "subnodes", &len); - if (!prop || len != sizeof(fdt32_t)) { - printf("Missing/invalid subnodes property at '%s'", - fdt_get_name(fdt, parent_offset, NULL)); - } - subnodes = fdt32_to_cpu(*prop); - count = 0; - fdt_for_each_subnode(offset, fdt, parent_offset) - count++; - if (count != subnodes) { - printf("Node '%s': Expected %d subnodes, got %d\n", - fdt_get_name(fdt, parent_offset, NULL), subnodes, count); - } -} - -void parse_dev_tree(const void *dev_tree) -{ - uint32_t offset; - uint32_t len; - if (!fdt_check_header(dev_tree)) { - printf("BAD HEADER\n"); - return; - } - int node; - fdt_for_each_subnode(node, dev_tree, 0) { - test_node(dev_tree, node); - } -} - void read_tsc_64(u64_t * t) { bsp_tb->read_tsc_64(t); @@ -471,9 +435,7 @@ int intr_init(const int auto_eoi) kinfo_t *pre_init(int argc, char **argv) { char* bootargs; - - void* dev_tree; - asm volatile ("ldr %0, [%%r2]":"=r"(dev_tree)::"r2", "memory"); + asm volatile ("mov %0, r2":"=r"(dev_tree)::"r2", "memory"); /* This is the main "c" entry point into the kernel. It gets called from head.S */ @@ -486,8 +448,11 @@ kinfo_t *pre_init(int argc, char **argv) POORMANS_FAILURE_NOTIFICATION; } - bootargs = argv[1]; - set_machine_id(bootargs); + if (fdt_step_node(dev_tree, fdt_set_machine_type, &machine)) { + bootargs = argv[1]; + set_machine_id(bootargs); + } + set_bsp_table(); /* Get our own copy boot params pointed to by r1.