Changeset View
Changeset View
Standalone View
Standalone View
sys/riscv/riscv/machdep.c
Show First 20 Lines • Show All 116 Lines • ▼ Show 20 Lines | |||||
u_int physmap_idx; | u_int physmap_idx; | ||||
struct kva_md_info kmi; | struct kva_md_info kmi; | ||||
int64_t dcache_line_size; /* The minimum D cache line size */ | int64_t dcache_line_size; /* The minimum D cache line size */ | ||||
int64_t icache_line_size; /* The minimum I cache line size */ | int64_t icache_line_size; /* The minimum I cache line size */ | ||||
int64_t idcache_line_size; /* The minimum 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; | cpuset_t all_harts; | ||||
extern int *end; | extern int *end; | ||||
static void | static void | ||||
cpu_startup(void *dummy) | cpu_startup(void *dummy) | ||||
{ | { | ||||
▲ Show 20 Lines • Show All 584 Lines • ▼ Show 20 Lines | cache_setup(void) | ||||
dcache_line_size = 0; | dcache_line_size = 0; | ||||
icache_line_size = 0; | icache_line_size = 0; | ||||
idcache_line_size = 0; | idcache_line_size = 0; | ||||
} | } | ||||
/* | /* | ||||
* Fake up a boot descriptor table. | * 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) | fake_preload_metadata(struct riscv_bootparams *rvbp) | ||||
{ | { | ||||
static uint32_t fake_preload[35]; | static uint32_t fake_preload[48]; | ||||
vm_offset_t lastaddr; | vm_offset_t lastaddr; | ||||
size_t fake_size, dtb_size; | size_t fake_size, dtb_size; | ||||
#define PRELOAD_PUSH_VALUE(type, value) do { \ | #define PRELOAD_PUSH_VALUE(type, value) do { \ | ||||
*(type *)((char *)fake_preload + fake_size) = (value); \ | *(type *)((char *)fake_preload + fake_size) = (value); \ | ||||
fake_size += sizeof(type); \ | fake_size += sizeof(type); \ | ||||
} while (0) | } while (0) | ||||
Show All 26 Lines | #define PRELOAD_PUSH_STRING(str) do { \ | ||||
lastaddr = roundup(lastaddr, sizeof(int)); | lastaddr = roundup(lastaddr, sizeof(int)); | ||||
PRELOAD_PUSH_VALUE(uint32_t, MODINFO_METADATA | MODINFOMD_DTBP); | PRELOAD_PUSH_VALUE(uint32_t, MODINFO_METADATA | MODINFOMD_DTBP); | ||||
PRELOAD_PUSH_VALUE(uint32_t, sizeof(vm_offset_t)); | PRELOAD_PUSH_VALUE(uint32_t, sizeof(vm_offset_t)); | ||||
PRELOAD_PUSH_VALUE(vm_offset_t, lastaddr); | PRELOAD_PUSH_VALUE(vm_offset_t, lastaddr); | ||||
dtb_size = fdt_totalsize(rvbp->dtbp_virt); | dtb_size = fdt_totalsize(rvbp->dtbp_virt); | ||||
memmove((void *)lastaddr, (const void *)rvbp->dtbp_virt, dtb_size); | memmove((void *)lastaddr, (const void *)rvbp->dtbp_virt, dtb_size); | ||||
lastaddr = roundup(lastaddr + dtb_size, sizeof(int)); | 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 */ | /* End marker */ | ||||
PRELOAD_PUSH_VALUE(uint32_t, 0); | PRELOAD_PUSH_VALUE(uint32_t, 0); | ||||
PRELOAD_PUSH_VALUE(uint32_t, 0); | PRELOAD_PUSH_VALUE(uint32_t, 0); | ||||
preload_metadata = (caddr_t)fake_preload; | preload_metadata = (caddr_t)fake_preload; | ||||
/* Check if bootloader clobbered part of the kernel with the DTB. */ | /* Check if bootloader clobbered part of the kernel with the DTB. */ | ||||
KASSERT(rvbp->dtbp_phys + dtb_size <= rvbp->kern_phys || | KASSERT(rvbp->dtbp_phys + dtb_size <= rvbp->kern_phys || | ||||
rvbp->dtbp_phys >= rvbp->kern_phys + (lastaddr - KERNBASE), | rvbp->dtbp_phys >= rvbp->kern_phys + (lastaddr - KERNBASE), | ||||
("FDT (%lx-%lx) and kernel (%lx-%lx) overlap", rvbp->dtbp_phys, | ("FDT (%lx-%lx) and kernel (%lx-%lx) overlap", rvbp->dtbp_phys, | ||||
rvbp->dtbp_phys + dtb_size, rvbp->kern_phys, | rvbp->dtbp_phys + dtb_size, rvbp->kern_phys, | ||||
rvbp->kern_phys + (lastaddr - KERNBASE))); | rvbp->kern_phys + (lastaddr - KERNBASE))); | ||||
KASSERT(fake_size < sizeof(fake_preload), | KASSERT(fake_size < sizeof(fake_preload), | ||||
("Too many fake_preload items")); | ("Too many fake_preload items")); | ||||
if (boothowto & RB_VERBOSE) | if (boothowto & RB_VERBOSE) | ||||
printf("FDT phys (%lx-%lx), kernel phys (%lx-%lx)\n", | printf("FDT phys (%lx-%lx), kernel phys (%lx-%lx)\n", | ||||
rvbp->dtbp_phys, rvbp->dtbp_phys + dtb_size, | rvbp->dtbp_phys, rvbp->dtbp_phys + dtb_size, | ||||
rvbp->kern_phys, rvbp->kern_phys + (lastaddr - KERNBASE)); | 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); | return (lastaddr); | ||||
} | } | ||||
void | void | ||||
initriscv(struct riscv_bootparams *rvbp) | initriscv(struct riscv_bootparams *rvbp) | ||||
{ | { | ||||
struct mem_region mem_regions[FDT_MEM_REGIONS]; | struct mem_region mem_regions[FDT_MEM_REGIONS]; | ||||
struct pcpu *pcpup; | struct pcpu *pcpup; | ||||
int mem_regions_sz; | int mem_regions_sz; | ||||
vm_offset_t lastaddr; | vm_offset_t lastaddr; | ||||
vm_size_t kernlen; | vm_size_t kernlen; | ||||
caddr_t kmdp; | #ifdef FDT | ||||
phandle_t chosen; | |||||
uint32_t hart; | |||||
#endif | |||||
TSRAW(&thread0, TS_ENTER, __func__, NULL); | TSRAW(&thread0, TS_ENTER, __func__, NULL); | ||||
/* Set the pcpu data, this is needed by pmap_bootstrap */ | /* Set the pcpu data, this is needed by pmap_bootstrap */ | ||||
pcpup = &__pcpu[0]; | pcpup = &__pcpu[0]; | ||||
pcpu_init(pcpup, 0, sizeof(struct pcpu)); | pcpu_init(pcpup, 0, sizeof(struct pcpu)); | ||||
pcpup->pc_hart = boot_hart; | |||||
/* Set the pcpu pointer */ | /* Set the pcpu pointer */ | ||||
__asm __volatile("mv tp, %0" :: "r"(pcpup)); | __asm __volatile("mv tp, %0" :: "r"(pcpup)); | ||||
PCPU_SET(curthread, &thread0); | PCPU_SET(curthread, &thread0); | ||||
/* Initialize SBI interface. */ | /* Initialize SBI interface. */ | ||||
sbi_init(); | sbi_init(); | ||||
/* Set the module data location */ | /* Parse the boot metadata. */ | ||||
lastaddr = fake_preload_metadata(rvbp); | 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 | #ifdef FDT | ||||
try_load_dtb(kmdp); | /* | ||||
* Get 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 = (u_long)hart; | |||||
markj: In this line both `boot_hart` and `hart` are uint32_t, so the cast doesn't really make sense. | |||||
mhorneAuthorUnsubmitted Done Inline ActionsI think it was left from an earlier iteration where I converted boot_hart to a u_long. Thanks for catching this. mhorne: I think it was left from an earlier iteration where I converted boot_hart to a u_long. Thanks… | |||||
} | |||||
#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, | * Exclude reserved memory specified by the device tree. Typically, | ||||
* this contains an entry for memory used by the runtime SBI firmware. | * this contains an entry for memory used by the runtime SBI firmware. | ||||
*/ | */ | ||||
if (fdt_get_reserved_mem(mem_regions, &mem_regions_sz) == 0) { | if (fdt_get_reserved_mem(mem_regions, &mem_regions_sz) == 0) { | ||||
physmem_exclude_regions(mem_regions, mem_regions_sz, | physmem_exclude_regions(mem_regions, mem_regions_sz, | ||||
EXFLAG_NODUMP | EXFLAG_NOALLOC); | EXFLAG_NODUMP | EXFLAG_NOALLOC); | ||||
} | } | ||||
▲ Show 20 Lines • Show All 64 Lines • Show Last 20 Lines |
In this line both boot_hart and hart are uint32_t, so the cast doesn't really make sense.
We seem to consistently use uint32_t for hart IDs (e.g., boot_hart, pc_hart), but per Jessica's initial point there is no apparent requirement that the IDs fit in 32 bits on RV64.