[MAJOR] Added a simple device tree parser
This commit is contained in:
@@ -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)
|
||||
|
||||
@@ -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}
|
||||
|
||||
|
||||
47
minix/kernel/arch/earm/fdt.c
Normal file
47
minix/kernel/arch/earm/fdt.c
Normal 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;
|
||||
}
|
||||
@@ -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:
|
||||
|
||||
9
minix/kernel/arch/earm/include/fdt.h
Normal file
9
minix/kernel/arch/earm/include/fdt.h
Normal 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
|
||||
@@ -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.
|
||||
|
||||
Reference in New Issue
Block a user