RISCV: Remove hartid and DTB parsing from the boot code.

This commit is contained in:
Siwei Zhuang
2019-03-19 11:40:45 +11:00
parent fa017b6d45
commit 3914931b32
8 changed files with 20 additions and 317 deletions

View File

@@ -11,7 +11,5 @@ manual/figs/*
*parsetab.py
manual/*
CHANGES
src/plat/spike/machine/fdt.c
include/plat/spike/plat/machine/fdt.h
include/arch/riscv/arch/sbi.h
include/arch/riscv/arch/encoding.h

View File

@@ -28,9 +28,7 @@ void init_kernel(
paddr_t ui_p_reg_start,
paddr_t ui_p_reg_end,
sword_t pv_offset,
vptr_t v_entry,
word_t hartid,
paddr_t dtb_output
vptr_t v_entry
);
#endif

View File

@@ -1,35 +0,0 @@
/* Copyright (c) 2010-2017, The Regents of the University of California
* (Regents). All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Regents nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
* OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
* HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/* This file is copied from RISC-V tools. It's modified to work with seL4 */
#ifndef FDT_H
#define FDT_H
void parseFDT(void *fdt);
uint32_t fdt_size(void *fdt);
#endif

View File

@@ -34,15 +34,10 @@ _start:
addi gp, gp, %pcrel_lo(1b)
.option pop
/* hartid is in a4 */
li sp, BIT(CONFIG_KERNEL_STACK_BITS)
mul sp, sp, a4
la x1, (kernel_stack_alloc + (BIT(CONFIG_KERNEL_STACK_BITS)))
add sp, sp, x1
la sp, (kernel_stack_alloc + BIT(CONFIG_KERNEL_STACK_BITS))
csrrw x0, sscratch, a4 /* zero sscratch for the init task */
csrw sscratch, x0 /* zero sscratch for the init task */
/* la sp, (kernel_stack_alloc + BIT(CONFIG_KERNEL_STACK_BITS)) */
jal init_kernel
la ra, restore_user_context

View File

@@ -27,7 +27,6 @@
#include <arch/benchmark.h>
#include <linker.h>
#include <plat/machine/hardware.h>
#include <plat/machine/fdt.h>
#include <machine.h>
/* pointer to the end of boot code/data in kernel image */
@@ -120,22 +119,12 @@ insert_region_excluded(region_t mem_reg, region_t reserved_reg)
}
BOOT_CODE static void
init_freemem(region_t ui_reg, region_t dtb_reg)
init_freemem(region_t ui_reg)
{
unsigned int i;
bool_t result UNUSED;
region_t cur_reg;
region_t res_reg[] = {
{
// We ignore all physical memory before the dtb as the current riscv-pk (proxy kernel)
// that we use for loading is broken and provides an incorrect memory map where
// it claims that the memory that is used to provide the m-mode services are
// free physical memory. As there is no interface to determine what the memory
// reserved for this is we simply hope it placed the dtb after itself and exclude
// all memory up until then.
.start = 0,
.end = dtb_reg.end
},
{
// This looks a bit awkward as our symbols are a reference in the kernel image window, but
// we want to do all allocations in terms of the main kernel window, so we do some translation
@@ -155,10 +144,8 @@ init_freemem(region_t ui_reg, region_t dtb_reg)
/* Force ordering and exclusivity of reserved regions. */
assert(res_reg[0].start < res_reg[0].end);
assert(res_reg[1].start < res_reg[1].end);
assert(res_reg[2].start < res_reg[2].end);
assert(res_reg[0].end <= res_reg[1].start);
assert(res_reg[1].end <= res_reg[2].start);
for (i = 0; i < get_num_avail_p_regs(); i++) {
cur_reg = paddr_to_pptr_reg(get_avail_p_reg(i));
@@ -174,7 +161,6 @@ init_freemem(region_t ui_reg, region_t dtb_reg)
cur_reg = insert_region_excluded(cur_reg, res_reg[0]);
cur_reg = insert_region_excluded(cur_reg, res_reg[1]);
cur_reg = insert_region_excluded(cur_reg, res_reg[2]);
if (cur_reg.start != cur_reg.end) {
result = insert_region(cur_reg);
@@ -213,9 +199,8 @@ init_cpu(void)
/* This and only this function initialises the platform. It does NOT initialise any kernel state. */
BOOT_CODE static void
init_plat(region_t dtb)
init_plat(void)
{
parseFDT((void*)dtb.start);
initIRQController();
initTimer();
}
@@ -226,8 +211,6 @@ static BOOT_CODE bool_t
try_init_kernel(
paddr_t ui_p_reg_start,
paddr_t ui_p_reg_end,
paddr_t dtb_p_reg_start,
paddr_t dtb_p_reg_end,
uint32_t pv_offset,
vptr_t v_entry
)
@@ -243,9 +226,6 @@ try_init_kernel(
region_t ui_reg = paddr_to_pptr_reg((p_region_t) {
ui_p_reg_start, ui_p_reg_end
});
region_t dtb_reg = paddr_to_pptr_reg((p_region_t) {
dtb_p_reg_start, dtb_p_reg_end
});
pptr_t bi_frame_pptr;
vptr_t bi_frame_vptr;
vptr_t ipcbuf_vptr;
@@ -270,10 +250,10 @@ try_init_kernel(
init_cpu();
/* initialize the platform */
init_plat(dtb_reg);
init_plat();
/* make the free memory available to alloc_region() */
init_freemem(ui_reg, dtb_reg);
init_freemem(ui_reg);
/* create the root cnode */
root_cnode_cap = create_root_cnode();
@@ -386,20 +366,13 @@ init_kernel(
paddr_t ui_p_reg_start,
paddr_t ui_p_reg_end,
sword_t pv_offset,
vptr_t v_entry,
word_t hartid,
paddr_t dtb_output_p
vptr_t v_entry
)
{
pptr_t dtb_output = (pptr_t)paddr_to_pptr(dtb_output_p);
bool_t result = try_init_kernel(ui_p_reg_start,
ui_p_reg_end,
dtb_output_p,
dtb_output_p + fdt_size((void*)dtb_output),
pv_offset,
v_entry
);
v_entry);
if (!result) {
fail ("Kernel init failed for some reason :(");

View File

@@ -38,6 +38,5 @@ include(src/plat/spike/instance/freedom/config.cmake)
add_sources(
DEP "KernelPlatformSpike"
CFILES
src/plat/spike/machine/fdt.c
src/plat/spike/machine/hardware.c
)

View File

@@ -1,223 +0,0 @@
/* Copyright (c) 2010-2017, The Regents of the University of California
* (Regents). All Rights Reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. Neither the name of the Regents nor the
* names of its contributors may be used to endorse or promote products
* derived from this software without specific prior written permission.
*
* IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT,
* SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING
* OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS
* BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*
* REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
* PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED
* HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE
* MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*/
/* This file is copied from RISC-V tools. It's modified to work with seL4 */
#include <stdint.h>
#include <string.h>
#include <stdint.h>
#include <string.h>
#include <plat/machine/fdt.h>
#include <config.h>
#include <util.h>
#define FDT_MAGIC 0xd00dfeed
#define FDT_VERSION 17
#define FDT_BEGIN_NODE 1
#define FDT_END_NODE 2
#define FDT_PROP 3
#define FDT_NOP 4
#define FDT_END 9
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; /* <= 17 */
uint32_t boot_cpuid_phys;
uint32_t size_dt_strings;
uint32_t size_dt_struct;
};
struct fdt_scan_node {
const struct fdt_scan_node *parent;
const char *name;
int address_cells;
int size_cells;
};
struct fdt_scan_prop {
const struct fdt_scan_node *node;
const char *name;
uint32_t *value;
int len; // in bytes of value
};
/* workaround because string literals are not supported by the C parser */
const char fdt_address_cells[] = {'#', 'a', 'd', 'd', 'r', 'e', 's', 's', '-', 'c', 'e', 'l', 'l', 's', 0};
const char fdt_size_cells[] = {'#', 's', 'i', 'z', 'e', '-', 'c', 'e', 'l', 'l', 's', 0};
const char fdt_reg[] = {'r', 'e', 'g', 0};
const char fdt_device_type[] = {'d', 'e', 'v', 'i', 'c', 'e', '_', 't', 'y', 'p', 'e', 0};
const char fdt_memory[] = {'m', 'e', 'm', 'o', 'r', 'y', 0};
static inline uint32_t bswap(uint32_t x)
{
uint32_t y = (x & 0x00FF00FF) << 8 | (x & 0xFF00FF00) >> 8;
uint32_t z = (y & 0x0000FFFF) << 16 | (y & 0xFFFF0000) >> 16;
return z;
}
struct scan_state {
int found_memory;
const uint32_t *reg_value;
int reg_len;
};
static const uint32_t *fdt_get_address(const struct fdt_scan_node *node, const uint32_t *value, uint64_t *result)
{
*result = 0;
for (int cells = node->address_cells; cells > 0; cells--) {
*result = (*result << 32) + bswap(*value);
value++;
}
return value;
}
static const uint32_t *fdt_get_size(const struct fdt_scan_node *node, const uint32_t *value, uint64_t *result)
{
*result = 0;
for (int cells = node->size_cells; cells > 0; cells--) {
*result = (*result << 32) + bswap(*value);
value++;
}
return value;
}
static uint32_t *fdt_scan_helper(
uint32_t *lex,
const char *strings,
struct fdt_scan_node *node,
struct scan_state *state)
{
struct fdt_scan_node child;
struct fdt_scan_prop prop;
int UNUSED last = 0;
child.parent = node;
// these are the default cell counts, as per the FDT spec
child.address_cells = 2;
child.size_cells = 1;
prop.node = node;
while (1) {
switch (bswap(lex[0])) {
case FDT_NOP: {
lex += 1;
break;
}
case FDT_PROP: {
assert (!last);
prop.name = strings + bswap(lex[2]);
prop.len = bswap(lex[1]);
prop.value = lex + 3;
if (node && !strncmp(prop.name, fdt_address_cells, 14)) {
node->address_cells = bswap(lex[3]);
}
if (node && !strncmp(prop.name, fdt_size_cells, 11)) {
node->size_cells = bswap(lex[3]);
}
lex += 3 + (prop.len + 3) / 4;
if (state->found_memory && strncmp(prop.name, fdt_reg, 3) == 0) {
state->reg_value = prop.value;
state->reg_len = prop.len;
}
if (strncmp(prop.name, fdt_device_type, 11) == 0 && strncmp((const char*)prop.value, fdt_memory, 6) == 0) {
state->found_memory = 1;
}
break;
}
case FDT_BEGIN_NODE: {
uint32_t *lex_next;
last = 1;
child.name = (const char *)(lex + 1);
lex_next = fdt_scan_helper(
lex + 2 + strnlen(child.name, 1024) / 4,
strings, &child, state);
lex = lex_next;
break;
}
case FDT_END_NODE: {
if (state->found_memory) {
const uint32_t *value = state->reg_value;
const uint32_t *end = value + state->reg_len / 4;
assert (state->reg_value && state->reg_len % 4 == 0);
while (end - value > 0) {
uint64_t base, size;
value = fdt_get_address(node->parent, value, &base);
value = fdt_get_size (node->parent, value, &size);
if (!add_avail_p_reg((p_region_t) {
base, base + size
})) {
printf("Failed to add physical memory region %llu-%llu\n", (unsigned long long)base, (unsigned long long)(base + size));
}
}
state->found_memory = 0;
}
return lex + 1;
}
default: { // FDT_END
return lex;
}
}
}
}
void parseFDT(void *fdt)
{
struct fdt_header *header = (struct fdt_header *)fdt;
// Only process FDT that we understand
if (bswap(header->magic) != FDT_MAGIC ||
bswap(header->last_comp_version) > FDT_VERSION) {
return;
}
const char *strings = (const char *)((word_t)fdt + bswap(header->off_dt_strings));
uint32_t *lex = (uint32_t *)((word_t)fdt + bswap(header->off_dt_struct));
struct scan_state state;
state.found_memory = 0;
fdt_scan_helper(lex, strings, 0, &state);
}
uint32_t fdt_size(void *fdt)
{
struct fdt_header *header = (struct fdt_header *)fdt;
// Only process FDT that we understand
if (bswap(header->magic) != FDT_MAGIC ||
bswap(header->last_comp_version) > FDT_VERSION) {
return 0;
}
return bswap(header->totalsize);
}

View File

@@ -35,12 +35,20 @@
/* Available physical memory regions on platform (RAM minus kernel image). */
/* NOTE: Regions are not allowed to be adjacent! */
static word_t BOOT_DATA num_avail_p_regs = 0;
static p_region_t BOOT_DATA avail_p_regs[MAX_AVAIL_P_REGS];
static p_region_t BOOT_DATA avail_p_regs[] = {
/* The first 2MB are reserved for the SBI in the BBL */
#if defined(CONFIG_BUILD_ROCKET_CHIP_ZEDBOARD)
{ /*.start = */ 0x0, /* .end = */ 0x10000000}
#elif defined(CONFIG_ARCH_RISCV64)
{ /*.start = */ 0x80200000, /* .end = */ 0x17FF00000}
#elif defined(CONFIG_ARCH_RISCV32)
{ /*.start = */ 0x80200000, /* .end = */ 0xFD000000}
#endif
};
BOOT_CODE int get_num_avail_p_regs(void)
{
return num_avail_p_regs;
return sizeof(avail_p_regs) / sizeof(p_region_t);
}
BOOT_CODE p_region_t get_avail_p_reg(unsigned int i)
@@ -48,16 +56,6 @@ BOOT_CODE p_region_t get_avail_p_reg(unsigned int i)
return avail_p_regs[i];
}
BOOT_CODE bool_t add_avail_p_reg(p_region_t reg)
{
if (num_avail_p_regs == MAX_AVAIL_P_REGS) {
return false;
}
avail_p_regs[num_avail_p_regs] = reg;
num_avail_p_regs++;
return true;
}
/**
DONT_TRANSLATE
*/