133 lines
2.7 KiB
C
133 lines
2.7 KiB
C
/*
|
|
* Multiboot C Entry
|
|
*/
|
|
|
|
#include <stdbool.h>
|
|
#include <stdint.h>
|
|
|
|
#include <sys/kassert.h>
|
|
#include <sys/cdefs.h>
|
|
|
|
#include "../dev/console.h"
|
|
|
|
#include <machine/mrt.h>
|
|
#include <machine/pmap.h>
|
|
#include <machine/paging.h>
|
|
#include <machine/bootinfo.h>
|
|
|
|
#include <sys/contrib/libfdt/libfdt.h>
|
|
|
|
#define PAGE_ALIGN __attribute__((aligned(PGSIZE)))
|
|
#define DATA_SECTION __attribute__((section(".data")))
|
|
|
|
extern void Machine_EarlyInit();
|
|
extern void Machine_Init();
|
|
extern void PAlloc_AddRegion(uintptr_t start, uintptr_t len);
|
|
|
|
struct bootinfo kbootinfo;
|
|
|
|
//
|
|
// parse the total memory
|
|
//
|
|
static bool
|
|
machineboot_parse_dtb()
|
|
{
|
|
const void * dtb = kbootinfo.dtb_addr;
|
|
|
|
if (fdt_num_mem_rsv(kbootinfo.dtb_addr) > 0) {
|
|
/* XXX: don't support memory reservation for now */
|
|
return false;
|
|
}
|
|
|
|
int offset = -1;
|
|
kbootinfo.mem_region_sz = 0;
|
|
|
|
while(true) {
|
|
offset = fdt_node_offset_by_prop_value(dtb, offset, "device_type",
|
|
"memory", strlen("memory") + 1);
|
|
|
|
if (offset < 0) {
|
|
break;
|
|
}
|
|
|
|
if (kbootinfo.mem_region_sz >= MAX_BOOT_MEM_REGIONS) {
|
|
// max region reached
|
|
return false;
|
|
}
|
|
|
|
int lenp;
|
|
const struct fdt_property * prop = fdt_get_property(dtb, offset, "reg", &lenp);
|
|
|
|
if (prop == NULL || lenp != 4 * sizeof(uint32_t)) {
|
|
// invalid memory block spec
|
|
return false;
|
|
}
|
|
|
|
const uint32_t * ptr = (const uint32_t *)prop->data;
|
|
const uint64_t base = fdt32_to_cpu(ptr[1]) | ((uint64_t)fdt32_to_cpu(ptr[0]) << 32);
|
|
const uint64_t limit = fdt32_to_cpu(ptr[3]) | ((uint64_t)fdt32_to_cpu(ptr[2]) << 32);
|
|
|
|
kbootinfo.mem_region_base[kbootinfo.mem_region_sz] = base;
|
|
kbootinfo.mem_region_len[kbootinfo.mem_region_sz] = limit;
|
|
kbootinfo.mem_region_sz++;
|
|
}
|
|
|
|
return kbootinfo.mem_region_sz > 0;
|
|
}
|
|
|
|
void
|
|
MachineBoot_Entry(unsigned long magic, paddr_t dtb_paddr, unsigned long dtb_len)
|
|
{
|
|
if (magic != 0x10CA5201) {
|
|
Halt();
|
|
}
|
|
|
|
// initialize metal mode
|
|
mtl_init();
|
|
|
|
// early metal paging init
|
|
vm_early_paging_init();
|
|
|
|
// parse dtb files
|
|
if (fdt_check_full((const void *)DMPA2VA(dtb_paddr), dtb_len) != 0) {
|
|
Halt();
|
|
}
|
|
|
|
kbootinfo.dtb_addr = (const void *)DMPA2VA(dtb_paddr);
|
|
kbootinfo.dtb_len = dtb_len;
|
|
|
|
if (!machineboot_parse_dtb()){
|
|
Halt();
|
|
}
|
|
|
|
// Main initialization
|
|
Machine_Init();
|
|
|
|
return;
|
|
}
|
|
|
|
void
|
|
MachineBoot_AddMem()
|
|
{
|
|
unsigned int i;
|
|
uintptr_t initRamEnd = 32*1024*1024;
|
|
|
|
for (i = 0; i < kbootinfo.mem_region_sz; i++)
|
|
{
|
|
uintptr_t start = kbootinfo.mem_region_base[i];
|
|
uintptr_t len = kbootinfo.mem_region_len[i];
|
|
|
|
if (start + len < initRamEnd)
|
|
continue;
|
|
|
|
if (start < initRamEnd) {
|
|
len = initRamEnd - start;
|
|
start = initRamEnd;
|
|
}
|
|
kprintf("Initializing physical memory region: base = 0x%lx, len = 0x%lx ... ", start, len);
|
|
PAlloc_AddRegion(start + MEM_DIRECTMAP_BASE, len);
|
|
kprintf("Done!\n");
|
|
}
|
|
}
|
|
|