[MAJOR] Added a simple device tree parser

This commit is contained in:
Korobov Nikita
2017-05-27 04:54:01 +03:00
parent e70062feb3
commit add751549f
6 changed files with 100 additions and 53 deletions

View File

@@ -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)

View File

@@ -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}

View File

@@ -0,0 +1,47 @@
#include <libfdt.h>
#include <minix/board.h>
#include <minix/type.h>
#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;
}

View File

@@ -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:

View File

@@ -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

View File

@@ -16,9 +16,8 @@
#include "bsp_table.h"
#include "glo.h"
#include <machine/multiboot.h>
#include <libfdt.h>
#include <libfdt_internal.h>
#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.