Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 8 additions & 0 deletions kernel/init/boot/boot.h
Original file line number Diff line number Diff line change
Expand Up @@ -50,4 +50,12 @@
#define SBIT_SIZE 1
#endif

#if !defined(ASM) && !defined(__ASSEMBLER__)
/*
* Boot parameter block in the entry page (see boot.ref.S): r1:0 as
* captured at reset on the boot thread, followed by reserved pad.
*/
extern unsigned int h2_boot_params[];
#endif

#endif
38 changes: 38 additions & 0 deletions kernel/init/boot/boot.ref.S
Original file line number Diff line number Diff line change
Expand Up @@ -70,10 +70,48 @@
#define CORE_DONE 0x1

FUNC_START start .entry .p2align 12
/*
* STANDALONE test links pull this object in solely for
* h2_boot_params (referenced by info.ref.c) and supply their own
* `start' via crt0_standalone.o. Weak lets that definition win
* instead of colliding; real (non-STANDALONE) links still resolve
* to this one, since it's the only definition present there.
*/
.weak start
jump .Lpast_mbox
.space 0x200 // FIXME: needs to be enough for all angel mailboxes but still fit all code in 4K

/*
* Boot parameter block: lives at a fixed offset in the entry page
* so that boot firmware or external tooling can locate and patch
* it. The first two words capture r1:0 as they were at reset on
* the boot thread; bootloaders pass the device tree blob physical
* address there for forwarding to a guest. The remaining pad is
* reserved for future parameters or a patched-in platform-specific
* boot stub.
*/
.p2align 3
.globl h2_boot_params
h2_boot_params:
.word 0 // r0 at entry (e.g. DTB physical address, low)
.word 0 // r1 at entry (e.g. DTB physical address, high)
.space 0x38 // reserved

.Lpast_mbox:
/*
* Capture r1:0 into the boot parameter block before anything
* clobbers them. Only the boot thread's values are meaningful;
* secondary hardware threads also enter here when started later.
*/
r10 = HTID
{
p0 = cmp.eq(r10,#0)
if (!p0.new) jump:nt .Lpast_bootparam_capture
}
r10 = add(PC,##h2_boot_params@PCREL)
memd(r10+#0) = r1:0
dccleana(r10) // reach memory before the cache kill below
.Lpast_bootparam_capture:

#ifdef CRASH_DEBUG
r7 = PC
Expand Down
9 changes: 8 additions & 1 deletion kernel/traps/info/info.ref.c
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
#include <symbols.h>
#include <cfg_table.h>
#include <log.h>
#include <boot.h>

u32_t H2K_trap_info(info_type op, u32_t unit, h2_cfg_unit_entry entry, H2K_thread_context *me) {

Expand Down Expand Up @@ -195,7 +196,13 @@ u32_t H2K_trap_info(info_type op, u32_t unit, h2_cfg_unit_entry entry, H2K_threa

case INFO_NOC_SBASE:
return H2K_gp->noc_sbase;


case INFO_BOOT_R00:
return h2_boot_params[0];

case INFO_BOOT_R01:
return h2_boot_params[1];

default:
return -1;
}
Expand Down
2 changes: 2 additions & 0 deletions libs/h2/common/h2_common_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,8 @@ typedef enum {
INFO_TCM_OFFSET, /**< Multicore TCM base offset */
INFO_NOC_MBASE, /**< Multicore NOC master widget base */
INFO_NOC_SBASE, /**< Multicore NOC slave widget base */
INFO_BOOT_R00, /**< r0 at reset on the boot thread (e.g. DTB address, low) */
INFO_BOOT_R01, /**< r1 at reset on the boot thread (e.g. DTB address, high) */
INFO_MAX
} info_type;

Expand Down
26 changes: 25 additions & 1 deletion linux/loadlinux.c
Original file line number Diff line number Diff line change
Expand Up @@ -145,6 +145,27 @@ void boot_ucos() {
#endif
}

/*
* The platform bootloader may have passed a device tree blob address in
* r1:0 at reset; h2 captures those registers in its entry page. Return
* the DTB physical address if one was passed and looks valid, else 0.
*/
static unsigned long boot_dtb_addr(void) {

unsigned long r0 = h2_info(INFO_BOOT_R00);
unsigned long r1 = h2_info(INFO_BOOT_R01);

if (r1 != 0 || r0 == 0 || (r0 & 3) != 0)
return 0;

if (*(volatile unsigned long *)r0 != 0xedfe0dd0) { /* FDT magic, LE view */
PRINTF("linux: no FDT magic at 0x%08lx\n", r0);
return 0;
}

return r0;
}

unsigned long boot_linux(char fname[]) {

unsigned long linux_vm = 0;
Expand Down Expand Up @@ -198,8 +219,11 @@ unsigned long boot_linux(char fname[]) {
);
#endif

unsigned long dtb = boot_dtb_addr();
PRINTF("linux: dtb at 0x%08lx\n", dtb);

if (h2_vmboot(linux_stext, &linux_vcpu_stacks[0][VCPU_STACK_SIZE - 1],
0, LINUX_VM_PRIO, linux_vm) == -1) FAIL("linux vmboot");
dtb, LINUX_VM_PRIO, linux_vm) == -1) FAIL("linux vmboot");

PRINTF ("linux: booted\n");
#endif
Expand Down
Loading