Page MenuHomeFreeBSD

D24912.id73574.diff
No OneTemporary

D24912.id73574.diff

Index: head/sys/riscv/include/machdep.h
===================================================================
--- head/sys/riscv/include/machdep.h
+++ head/sys/riscv/include/machdep.h
@@ -43,12 +43,12 @@
vm_offset_t kern_stack;
vm_offset_t dtbp_virt; /* Device tree blob virtual addr */
vm_offset_t dtbp_phys; /* Device tree blob physical addr */
+ vm_offset_t modulep; /* loader(8) metadata */
};
extern vm_paddr_t physmap[PHYS_AVAIL_ENTRIES];
extern u_int physmap_idx;
-vm_offset_t fake_preload_metadata(struct riscv_bootparams *rbp);
void initriscv(struct riscv_bootparams *);
#endif /* _MACHINE_MACHDEP_H_ */
Index: head/sys/riscv/riscv/genassym.c
===================================================================
--- head/sys/riscv/riscv/genassym.c
+++ head/sys/riscv/riscv/genassym.c
@@ -107,3 +107,4 @@
kern_stack));
ASSYM(RISCV_BOOTPARAMS_DTBP_VIRT, offsetof(struct riscv_bootparams, dtbp_virt));
ASSYM(RISCV_BOOTPARAMS_DTBP_PHYS, offsetof(struct riscv_bootparams, dtbp_phys));
+ASSYM(RISCV_BOOTPARAMS_MODULEP, offsetof(struct riscv_bootparams, modulep));
Index: head/sys/riscv/riscv/locore.S
===================================================================
--- head/sys/riscv/riscv/locore.S
+++ head/sys/riscv/riscv/locore.S
@@ -46,24 +46,24 @@
.globl kernbase
.set kernbase, KERNBASE
- /* Trap entries */
.text
-
- /* Reset vector */
- .text
- .globl _start
-_start:
+/*
+ * Alternate entry point. Used when booting via SBI firmware. It must be placed
+ * at the beginning of the .text section. Arguments are as follows:
+ * - a0 = hart ID
+ * - a1 = dtbp
+ *
+ * Multiple CPUs might enter from this point, so we perform a hart lottery and
+ * send the losers to mpentry.
+ */
+ .globl _alt_start
+_alt_start:
/* Set the global pointer */
.option push
.option norelax
lla gp, __global_pointer$
.option pop
- /*
- * a0 = hart id
- * a1 = dtbp
- */
-
/* Pick a hart to run the boot process. */
lla t0, hart_lottery
li t1, 1
@@ -75,11 +75,43 @@
*/
beqz t0, 1f
j mpentry
+1:
+ /* Store the boot hart */
+ lla t0, boot_hart
+ sw a0, 0(t0)
+ /* Load zero as modulep */
+ mv a0, zero
+ j pagetables
+
+/*
+ * Main entry point. This routine is marked as the ELF entry, and is where
+ * loader(8) will enter the kernel. Arguments are as follows:
+ * - a0 = modulep
+ * - a1 = ???
+ *
+ * It is expected that only a single CPU will enter here.
+ */
+ .globl _start
+_start:
+ /* Set the global pointer */
+.option push
+.option norelax
+ lla gp, __global_pointer$
+.option pop
+
/*
- * Page tables
+ * Zero a1 to indicate that we have no DTB pointer. It is already
+ * included in the loader(8) metadata.
*/
-1:
+ mv a1, zero
+
+ /*
+ * Page tables setup
+ * a0 - modulep or zero
+ * a1 - zero or dtbp
+ */
+pagetables:
/* Get the kernel's load address */
jal get_physmem
@@ -107,7 +139,7 @@
li t2, 512 /* Build 512 entries */
add t3, t4, t2
li t5, 0
-2:
+1:
li t0, (PTE_KERN | PTE_X)
slli t2, t4, PTE_PPN1_S /* << PTE_PPN1_S */
or t5, t0, t2
@@ -115,7 +147,7 @@
addi s1, s1, PTE_SIZE
addi t4, t4, 1
- bltu t4, t3, 2b
+ bltu t4, t3, 1b
/* Create an L1 page for early devmap */
lla s1, pagetable_l1
@@ -135,6 +167,9 @@
add t0, s1, a5
sd t6, (t0)
+ /* Check if we have a DTB that needs to be mapped */
+ beqz a1, 2f
+
/* Create an L2 page superpage for DTB */
lla s1, pagetable_l2_devmap
mv s2, a1
@@ -156,6 +191,7 @@
/* Page tables END */
/* Setup supervisor trap vector */
+2:
lla t0, va
sub t0, t0, s9
li t1, KERNBASE
@@ -201,12 +237,6 @@
addi s0, s0, 8
bltu s0, s1, 1b
-#ifdef SMP
- /* Store boot hart id. */
- la t0, boot_hart
- sw a0, 0(t0)
-#endif
-
/* Fill riscv_bootparams */
la t0, pagetable_l1
sd t0, RISCV_BOOTPARAMS_KERN_L1PT(sp)
@@ -222,6 +252,8 @@
add t0, t0, t1
sd t0, RISCV_BOOTPARAMS_DTBP_VIRT(sp)
sd a1, RISCV_BOOTPARAMS_DTBP_PHYS(sp)
+
+ sd a0, RISCV_BOOTPARAMS_MODULEP(sp)
mv a0, sp
call _C_LABEL(initriscv) /* Off we go */
Index: head/sys/riscv/riscv/machdep.c
===================================================================
--- head/sys/riscv/riscv/machdep.c
+++ head/sys/riscv/riscv/machdep.c
@@ -122,7 +122,9 @@
int64_t icache_line_size; /* The minimum I cache line size */
int64_t idcache_line_size; /* The minimum cache line size */
-uint32_t boot_hart; /* The hart we booted on. */
+#define BOOT_HART_INVALID 0xffffffff
+uint32_t boot_hart = BOOT_HART_INVALID; /* The hart we booted on. */
+
cpuset_t all_harts;
extern int *end;
@@ -723,12 +725,11 @@
/*
* Fake up a boot descriptor table.
- * RISCVTODO: This needs to be done via loader (when it's available).
*/
-vm_offset_t
+static void
fake_preload_metadata(struct riscv_bootparams *rvbp)
{
- static uint32_t fake_preload[35];
+ static uint32_t fake_preload[48];
vm_offset_t lastaddr;
size_t fake_size, dtb_size;
@@ -771,6 +772,14 @@
memmove((void *)lastaddr, (const void *)rvbp->dtbp_virt, dtb_size);
lastaddr = roundup(lastaddr + dtb_size, sizeof(int));
+ PRELOAD_PUSH_VALUE(uint32_t, MODINFO_METADATA | MODINFOMD_KERNEND);
+ PRELOAD_PUSH_VALUE(uint32_t, sizeof(vm_offset_t));
+ PRELOAD_PUSH_VALUE(vm_offset_t, lastaddr);
+
+ PRELOAD_PUSH_VALUE(uint32_t, MODINFO_METADATA | MODINFOMD_HOWTO);
+ PRELOAD_PUSH_VALUE(uint32_t, sizeof(int));
+ PRELOAD_PUSH_VALUE(int, RB_VERBOSE);
+
/* End marker */
PRELOAD_PUSH_VALUE(uint32_t, 0);
PRELOAD_PUSH_VALUE(uint32_t, 0);
@@ -789,7 +798,38 @@
printf("FDT phys (%lx-%lx), kernel phys (%lx-%lx)\n",
rvbp->dtbp_phys, rvbp->dtbp_phys + dtb_size,
rvbp->kern_phys, rvbp->kern_phys + (lastaddr - KERNBASE));
+}
+static vm_offset_t
+parse_metadata(void)
+{
+ caddr_t kmdp;
+ vm_offset_t lastaddr;
+#ifdef DDB
+ vm_offset_t ksym_start, ksym_end;
+#endif
+ char *kern_envp;
+
+ /* Find the kernel address */
+ kmdp = preload_search_by_type("elf kernel");
+ if (kmdp == NULL)
+ kmdp = preload_search_by_type("elf64 kernel");
+ KASSERT(kmdp != NULL, ("No preload metadata found!"));
+
+ /* Read the boot metadata */
+ boothowto = MD_FETCH(kmdp, MODINFOMD_HOWTO, int);
+ lastaddr = MD_FETCH(kmdp, MODINFOMD_KERNEND, vm_offset_t);
+ kern_envp = MD_FETCH(kmdp, MODINFOMD_ENVP, char *);
+ if (kern_envp != NULL)
+ init_static_kenv(kern_envp, 0);
+#ifdef DDB
+ ksym_start = MD_FETCH(kmdp, MODINFOMD_SSYM, uintptr_t);
+ ksym_end = MD_FETCH(kmdp, MODINFOMD_ESYM, uintptr_t);
+ db_fetch_ksymtab(ksym_start, ksym_end);
+#endif
+#ifdef FDT
+ try_load_dtb(kmdp);
+#endif
return (lastaddr);
}
@@ -801,14 +841,16 @@
int mem_regions_sz;
vm_offset_t lastaddr;
vm_size_t kernlen;
- caddr_t kmdp;
+#ifdef FDT
+ phandle_t chosen;
+ uint32_t hart;
+#endif
TSRAW(&thread0, TS_ENTER, __func__, NULL);
/* Set the pcpu data, this is needed by pmap_bootstrap */
pcpup = &__pcpu[0];
pcpu_init(pcpup, 0, sizeof(struct pcpu));
- pcpup->pc_hart = boot_hart;
/* Set the pcpu pointer */
__asm __volatile("mv tp, %0" :: "r"(pcpup));
@@ -818,22 +860,31 @@
/* Initialize SBI interface. */
sbi_init();
- /* Set the module data location */
- lastaddr = fake_preload_metadata(rvbp);
+ /* Parse the boot metadata. */
+ if (rvbp->modulep != 0) {
+ preload_metadata = (caddr_t)rvbp->modulep;
+ } else {
+ fake_preload_metadata(rvbp);
+ }
+ lastaddr = parse_metadata();
- /* Find the kernel address */
- kmdp = preload_search_by_type("elf kernel");
- if (kmdp == NULL)
- kmdp = preload_search_by_type("elf64 kernel");
-
- boothowto = RB_VERBOSE | RB_SINGLE;
- boothowto = RB_VERBOSE;
-
- kern_envp = NULL;
-
#ifdef FDT
- try_load_dtb(kmdp);
+ /*
+ * Look for the boot hart ID. This was either passed in directly from
+ * the SBI firmware and handled by locore, or was stored in the device
+ * tree by an earlier boot stage.
+ */
+ chosen = OF_finddevice("/chosen");
+ if (OF_getencprop(chosen, "boot-hartid", &hart, sizeof(hart)) != -1) {
+ boot_hart = hart;
+ }
+#endif
+ if (boot_hart == BOOT_HART_INVALID) {
+ panic("Boot hart ID was not properly set");
+ }
+ pcpup->pc_hart = boot_hart;
+#ifdef FDT
/*
* Exclude reserved memory specified by the device tree. Typically,
* this contains an entry for memory used by the runtime SBI firmware.

File Metadata

Mime Type
text/plain
Expires
Mon, Apr 6, 4:52 AM (4 h, 45 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30938835
Default Alt Text
D24912.id73574.diff (7 KB)

Event Timeline