version 1.58, 2019/01/31 13:26:21 |
version 1.66, 2020/01/21 10:54:11 |
Line 64 __KERNEL_RCSID(0, "$NetBSD$"); |
|
Line 64 __KERNEL_RCSID(0, "$NetBSD$"); |
|
#include <sys/disk.h> |
#include <sys/disk.h> |
#include <sys/md5.h> |
#include <sys/md5.h> |
#include <sys/pserialize.h> |
#include <sys/pserialize.h> |
|
#include <sys/rnd.h> |
|
|
#include <net/if.h> |
#include <net/if.h> |
#include <net/if_dl.h> |
#include <net/if_dl.h> |
Line 117 u_long uboot_args[4] __attribute__((__se |
|
Line 118 u_long uboot_args[4] __attribute__((__se |
|
const uint8_t *fdt_addr_r __attribute__((__section__(".data"))); |
const uint8_t *fdt_addr_r __attribute__((__section__(".data"))); |
|
|
static uint64_t initrd_start, initrd_end; |
static uint64_t initrd_start, initrd_end; |
|
static uint64_t rndseed_start, rndseed_end; |
|
|
#include <libfdt.h> |
#include <libfdt.h> |
#include <dev/fdt/fdtvar.h> |
#include <dev/fdt/fdtvar.h> |
Line 158 static struct consdev earlycons = { |
|
Line 160 static struct consdev earlycons = { |
|
#endif |
#endif |
|
|
/* |
/* |
* ARM: Get the first physically contiguous region of memory. |
* Get all of physical memory, including holes. |
* ARM64: Get all of physical memory, including holes. |
|
*/ |
*/ |
static void |
static void |
fdt_get_memory(uint64_t *pstart, uint64_t *pend) |
fdt_get_memory(uint64_t *pstart, uint64_t *pend) |
Line 184 fdt_get_memory(uint64_t *pstart, uint64_ |
|
Line 185 fdt_get_memory(uint64_t *pstart, uint64_ |
|
VPRINTF("FDT /memory [%d] @ 0x%" PRIx64 " size 0x%" PRIx64 "\n", |
VPRINTF("FDT /memory [%d] @ 0x%" PRIx64 " size 0x%" PRIx64 "\n", |
index, cur_addr, cur_size); |
index, cur_addr, cur_size); |
|
|
#ifdef __aarch64__ |
|
if (cur_addr + cur_size > *pend) |
if (cur_addr + cur_size > *pend) |
*pend = cur_addr + cur_size; |
*pend = cur_addr + cur_size; |
#else |
|
/* If subsequent entries follow the previous, append them. */ |
|
if (*pend == cur_addr) |
|
*pend = cur_addr + cur_size; |
|
#endif |
|
} |
} |
} |
} |
|
|
Line 258 static struct boot_physmem fdt_physmem[M |
|
Line 253 static struct boot_physmem fdt_physmem[M |
|
static void |
static void |
fdt_add_boot_physmem(const struct fdt_memory *m, void *arg) |
fdt_add_boot_physmem(const struct fdt_memory *m, void *arg) |
{ |
{ |
struct boot_physmem *bp = &fdt_physmem[nfdt_physmem++]; |
const paddr_t saddr = round_page(m->start); |
|
const paddr_t eaddr = trunc_page(m->end); |
|
|
VPRINTF(" %" PRIx64 " - %" PRIx64 "\n", m->start, m->end - 1); |
VPRINTF(" %" PRIx64 " - %" PRIx64, m->start, m->end - 1); |
|
if (saddr >= eaddr) { |
|
VPRINTF(" skipped\n"); |
|
return; |
|
} |
|
VPRINTF("\n"); |
|
|
|
struct boot_physmem *bp = &fdt_physmem[nfdt_physmem++]; |
|
|
KASSERT(nfdt_physmem <= MAX_PHYSMEM); |
KASSERT(nfdt_physmem <= MAX_PHYSMEM); |
|
|
bp->bp_start = atop(round_page(m->start)); |
bp->bp_start = atop(saddr); |
bp->bp_pages = atop(trunc_page(m->end)) - bp->bp_start; |
bp->bp_pages = atop(eaddr) - bp->bp_start; |
bp->bp_freelist = VM_FREELIST_DEFAULT; |
bp->bp_freelist = VM_FREELIST_DEFAULT; |
|
|
#ifdef _LP64 |
|
if (m->end > 0x100000000) |
|
bp->bp_freelist = VM_FREELIST_HIGHMEM; |
|
#endif |
|
|
|
#ifdef PMAP_NEED_ALLOC_POOLPAGE |
#ifdef PMAP_NEED_ALLOC_POOLPAGE |
const uint64_t memory_size = *(uint64_t *)arg; |
const uint64_t memory_size = *(uint64_t *)arg; |
if (atop(memory_size) > bp->bp_pages) { |
if (atop(memory_size) > bp->bp_pages) { |
Line 310 fdt_build_bootconfig(uint64_t mem_start, |
|
Line 308 fdt_build_bootconfig(uint64_t mem_start, |
|
if (initrd_size > 0) |
if (initrd_size > 0) |
fdt_memory_remove_range(initrd_start, initrd_size); |
fdt_memory_remove_range(initrd_start, initrd_size); |
|
|
|
const uint64_t rndseed_size = rndseed_end - rndseed_start; |
|
if (rndseed_size > 0) |
|
fdt_memory_remove_range(rndseed_start, rndseed_size); |
|
|
const int framebuffer = OF_finddevice("/chosen/framebuffer"); |
const int framebuffer = OF_finddevice("/chosen/framebuffer"); |
if (framebuffer >= 0) { |
if (framebuffer >= 0) { |
for (index = 0; |
for (index = 0; |
Line 389 fdt_setup_initrd(void) |
|
Line 391 fdt_setup_initrd(void) |
|
#endif |
#endif |
} |
} |
|
|
|
static void |
|
fdt_probe_rndseed(uint64_t *pstart, uint64_t *pend) |
|
{ |
|
int chosen, len; |
|
const void *start_data, *end_data; |
|
|
|
*pstart = *pend = 0; |
|
chosen = OF_finddevice("/chosen"); |
|
if (chosen < 0) |
|
return; |
|
|
|
start_data = fdtbus_get_prop(chosen, "netbsd,rndseed-start", &len); |
|
end_data = fdtbus_get_prop(chosen, "netbsd,rndseed-end", NULL); |
|
if (start_data == NULL || end_data == NULL) |
|
return; |
|
|
|
switch (len) { |
|
case 4: |
|
*pstart = be32dec(start_data); |
|
*pend = be32dec(end_data); |
|
break; |
|
case 8: |
|
*pstart = be64dec(start_data); |
|
*pend = be64dec(end_data); |
|
break; |
|
default: |
|
printf("Unsupported len %d for /chosen/rndseed-start\n", len); |
|
return; |
|
} |
|
} |
|
|
|
static void |
|
fdt_setup_rndseed(void) |
|
{ |
|
const uint64_t rndseed_size = rndseed_end - rndseed_start; |
|
const paddr_t startpa = trunc_page(rndseed_start); |
|
const paddr_t endpa = round_page(rndseed_end); |
|
paddr_t pa; |
|
vaddr_t va; |
|
void *rndseed; |
|
|
|
if (rndseed_size == 0) |
|
return; |
|
|
|
va = uvm_km_alloc(kernel_map, endpa - startpa, 0, |
|
UVM_KMF_VAONLY | UVM_KMF_NOWAIT); |
|
if (va == 0) { |
|
printf("Failed to allocate VA for rndseed\n"); |
|
return; |
|
} |
|
rndseed = (void *)va; |
|
|
|
for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE) |
|
pmap_kenter_pa(va, pa, VM_PROT_READ|VM_PROT_WRITE, 0); |
|
pmap_update(pmap_kernel()); |
|
|
|
rnd_seed(rndseed, rndseed_size); |
|
} |
|
|
#ifdef EFI_RUNTIME |
#ifdef EFI_RUNTIME |
static void |
static void |
fdt_map_efi_runtime(const char *prop, enum arm_efirt_mem_type type) |
fdt_map_efi_runtime(const char *prop, enum arm_efirt_mem_type type) |
Line 415 fdt_map_efi_runtime(const char *prop, en |
|
Line 476 fdt_map_efi_runtime(const char *prop, en |
|
} |
} |
#endif |
#endif |
|
|
u_int initarm(void *arg); |
vaddr_t |
|
|
u_int |
|
initarm(void *arg) |
initarm(void *arg) |
{ |
{ |
const struct arm_platform *plat; |
const struct arm_platform *plat; |
Line 519 initarm(void *arg) |
|
Line 578 initarm(void *arg) |
|
/* Parse ramdisk info */ |
/* Parse ramdisk info */ |
fdt_probe_initrd(&initrd_start, &initrd_end); |
fdt_probe_initrd(&initrd_start, &initrd_end); |
|
|
|
/* Parse rndseed */ |
|
fdt_probe_rndseed(&rndseed_start, &rndseed_end); |
|
|
/* |
/* |
* Populate bootconfig structure for the benefit of |
* Populate bootconfig structure for the benefit of |
* dodumpsys |
* dodumpsys |
Line 542 initarm(void *arg) |
|
Line 604 initarm(void *arg) |
|
VPRINTF("Memory regions:\n"); |
VPRINTF("Memory regions:\n"); |
fdt_memory_foreach(fdt_add_boot_physmem, &memory_size); |
fdt_memory_foreach(fdt_add_boot_physmem, &memory_size); |
|
|
u_int sp = initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, fdt_physmem, |
vaddr_t sp = initarm_common(KERNEL_VM_BASE, KERNEL_VM_SIZE, fdt_physmem, |
nfdt_physmem); |
nfdt_physmem); |
|
|
|
/* |
|
* initarm_common flushes cache if required before AP start |
|
*/ |
error = 0; |
error = 0; |
if ((boothowto & RB_MD1) == 0) { |
if ((boothowto & RB_MD1) == 0) { |
VPRINTF("mpstart\n"); |
VPRINTF("mpstart\n"); |
Line 567 initarm(void *arg) |
|
Line 632 initarm(void *arg) |
|
const paddr_t spg = atop(spa); |
const paddr_t spg = atop(spa); |
const paddr_t epg = atop(epa); |
const paddr_t epg = atop(epa); |
|
|
|
VPRINTF(" start %08lx end %08lx... " |
|
"loading in freelist %d\n", spa, epa, VM_FREELIST_DEFAULT); |
|
|
uvm_page_physload(spg, epg, spg, epg, VM_FREELIST_DEFAULT); |
uvm_page_physload(spg, epg, spg, epg, VM_FREELIST_DEFAULT); |
|
|
VPRINTF(" start %08lx end %08lx", ptoa(spa), ptoa(epa)); |
|
} |
} |
|
|
return sp; |
return sp; |
|
|
} |
} |
|
|
void |
void |
|
cpu_startup_hook(void) |
|
{ |
|
|
|
fdt_setup_rndseed(); |
|
} |
|
|
|
void |
delay(u_int us) |
delay(u_int us) |
{ |
{ |
const struct arm_platform *plat = arm_fdt_platform(); |
const struct arm_platform *plat = arm_fdt_platform(); |