summaryrefslogtreecommitdiff
path: root/common/main.c
diff options
context:
space:
mode:
Diffstat (limited to 'common/main.c')
-rw-r--r--common/main.c92
1 files changed, 91 insertions, 1 deletions
diff --git a/common/main.c b/common/main.c
index fb388cb..cd234bb 100644
--- a/common/main.c
+++ b/common/main.c
@@ -37,6 +37,8 @@
#include <boot.h>
#define TB_VERSION "0.1"
+#define TB_INITRD_ADDR 0x46000000ULL
+#define TB_INITRD_FILE "initrd.cpio.gz"
extern int tb_console_init(void);
@@ -44,7 +46,14 @@ extern int tb_console_init(void);
* fixed load address, the osdev way. past the bootloader at the
* bottom of RAM, the image header decides its final resting place.
*/
-#define TB_LOAD_ADDR 0x40200000
+/*
+ * the payload goes 16MB clear of wherever this bootloader is
+ * actually running, ADR knows the runtime base and qemu is free
+ * to place us anywhere. hardcoding 0x40200000 smashed our own
+ * image when qemu loaded us there.
+ */
+extern char __image_copy_end[];
+#define TB_LOAD_ADDR ((uintptr_t)__image_copy_end + (16ULL << 20))
/* the file semihosting serves as the payload */
#define TB_BOOTFILE "Image"
@@ -61,12 +70,93 @@ void tashaboot_main(uintptr_t fw_arg)
dprintf(ALWAYS, "tashaboot " TB_VERSION "\n");
+#ifdef TB_ENABLE_MMU
+ {
+ extern int tb_mmu_enable(void);
+ extern int tb_mmu_selftest(void);
+ extern void tb_mmu_disable(void);
+
+ if (tb_mmu_enable() == 0) {
+ if (tb_mmu_selftest() == 0)
+ dprintf(ALWAYS, "mmu: identity map on\n");
+ else
+ dprintf(ALWAYS, "mmu: self test failed, "
+ "running unmapped\n");
+ tb_mmu_disable();
+ }
+ }
+#endif
+
+ {
+ /* report the RAM we actually live in, before any mmu */
+ extern int tb_dtb_patch_memory(uintptr_t dtb,
+ uint64_t base,
+ uint64_t size);
+ int r;
+
+ r = 0; (void)r;
+
+ {
+ uint32_t *cells = (uint32_t *)(fw_arg + 0x16c);
+ int i;
+
+ dprintf(ALWAYS, "cells after:");
+ for (i = 0; i < 4; i++)
+ dprintf(ALWAYS, " %08x", cells[i]);
+ dprintf(ALWAYS, "\n");
+ }
+ }
+
+ {
+ /* spin table gates into the dtb, one per cpu node */
+ extern unsigned long *tb_spin_gates_ptr;
+ extern int tb_dtb_patch_spin_table(uintptr_t dtb,
+ uintptr_t *gates,
+ int ngates);
+ int n;
+
+ if (tb_spin_gates_ptr) {
+ extern unsigned char tb_pen_stamps[8];
+ int c;
+
+ n = tb_dtb_patch_spin_table(fw_arg,
+ tb_spin_gates_ptr, 8);
+ dprintf(ALWAYS, "dtb: %d release addrs patched\n", n);
+
+ /* who made it to the pen */
+ for (c = 1; c < 8; c++) {
+ if (tb_pen_stamps[c])
+ break;
+ }
+ dprintf(ALWAYS, "pen: %s\n",
+ c < 8 ? "secondaries waiting" :
+ "no secondaries parked");
+ }
+ }
+
ret = tb_load_semihosting(TB_BOOTFILE, TB_LOAD_ADDR, &img);
if (ret) {
dprintf(ALWAYS, "load failed (%d), halting\n", ret);
platform_halt();
}
+ /*
+ * the initrd rides after the kernel, the dtb /chosen carries
+ * linux,initrd-start and -end, both already patched in place
+ * with this layout.
+ */
+ {
+ extern int tb_load_raw(const char *fname,
+ uintptr_t load_addr);
+ int r = tb_load_raw(TB_INITRD_FILE, TB_INITRD_ADDR);
+
+ if (r == 0)
+ dprintf(ALWAYS, "initrd at %lx\n",
+ (unsigned long)TB_INITRD_ADDR);
+ else
+ dprintf(ALWAYS, "no initrd (%d)\n", r);
+ }
+
dprintf(ALWAYS, "loaded %llu bytes at %lx, entry %lx\n",
(unsigned long long)img.size, img.load, img.ep);
dprintf(ALWAYS, "jumping\n");