summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorvisa <visa@openbsd.org>2016-03-21 14:20:57 +0000
committervisa <visa@openbsd.org>2016-03-21 14:20:57 +0000
commitfe08f639e47d7da7b52597c209b7d7d03645aecd (patch)
treedfa9070c0ca1ba0d80d50500a2d768afb8e1f978
parentMore ksh POSIX compliance fixes by Martijn Dekker: (diff)
downloadwireguard-openbsd-fe08f639e47d7da7b52597c209b7d7d03645aecd.tar.xz
wireguard-openbsd-fe08f639e47d7da7b52597c209b7d7d03645aecd.zip
On Octeon systems, U-Boot provides a list of usable memory regions. Use
the list instead of hardcoded regions in memory setup. Works on EdgeRouter Lite, EdgeRouter Pro, Lanner MR326b and Movidis 16x. Tested by jj@ Tested by and ok jmatthew@
-rw-r--r--sys/arch/octeon/include/octeonvar.h20
-rw-r--r--sys/arch/octeon/octeon/machdep.c86
2 files changed, 61 insertions, 45 deletions
diff --git a/sys/arch/octeon/include/octeonvar.h b/sys/arch/octeon/include/octeonvar.h
index 1479d8032aa..9c6ae16fac0 100644
--- a/sys/arch/octeon/include/octeonvar.h
+++ b/sys/arch/octeon/include/octeonvar.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: octeonvar.h,v 1.24 2015/07/20 19:44:32 pirofti Exp $ */
+/* $OpenBSD: octeonvar.h,v 1.25 2016/03/21 14:20:57 visa Exp $ */
/* $NetBSD: maltavar.h,v 1.3 2002/03/18 10:10:16 simonb Exp $ */
/*-
@@ -273,6 +273,24 @@ struct boot_info {
uint32_t config_flags;
};
+struct octeon_bootmem_desc {
+ uint32_t lock;
+ uint32_t flags;
+ uint64_t head_addr;
+ uint32_t major_version;
+ uint32_t minor_version;
+ uint64_t app_data_addr;
+ uint64_t app_data_size;
+ uint32_t named_block_num_blocks;
+ uint32_t named_block_name_len;
+ uint64_t named_block_array_addr;
+};
+
+struct octeon_bootmem_block {
+ uint64_t next;
+ uint64_t size;
+};
+
extern struct boot_desc *octeon_boot_desc;
extern struct boot_info *octeon_boot_info;
diff --git a/sys/arch/octeon/octeon/machdep.c b/sys/arch/octeon/octeon/machdep.c
index 825216bb4e3..5872fe54b51 100644
--- a/sys/arch/octeon/octeon/machdep.c
+++ b/sys/arch/octeon/octeon/machdep.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: machdep.c,v 1.72 2016/03/06 19:42:27 mpi Exp $ */
+/* $OpenBSD: machdep.c,v 1.73 2016/03/21 14:20:57 visa Exp $ */
/*
* Copyright (c) 2009, 2010 Miodrag Vallat.
@@ -154,54 +154,52 @@ struct timecounter ipdclock_timecounter = {
void
octeon_memory_init(struct boot_info *boot_info)
{
- extern char end[];
+ struct octeon_bootmem_block *block;
+ struct octeon_bootmem_desc *memdesc;
+ paddr_t blockaddr;
+ uint64_t fp, lp;
int i;
- uint32_t realmem_bytes;
-
- realmem_bytes = boot_info->dram_size << 20;
- physmem = atop(realmem_bytes);
-
- /*-
- * Octeon Memory looks as follows:
- * PA
- * First 256 MB DR0
- * 0000 0000 0000 0000 to 0000 0000 0FFF FFFF
- * Second 256 MB DR1
- * 0000 0004 1000 0000 to 0000 0004 1FFF FFFF
- * Over 512MB Memory DR2 15.5GB
- * 0000 0000 2000 0000 to 0000 0003 FFFF FFFF
- */
- /* DR0, ignoring everything below the kernel image */
- mem_layout[0].mem_first_page =
- atop(CKSEG0_TO_PHYS(round_page((vaddr_t)&end)));
- if (physmem > atop(256 << 20))
- mem_layout[0].mem_last_page = atop(256 << 20);
- else
- mem_layout[0].mem_last_page = physmem;
-
- /* DR1 */
- i = 1;
- if (physmem > atop(256 << 20)) {
- mem_layout[i].mem_first_page = atop(0x410000000ULL);
- if (physmem > atop(512 << 20))
- mem_layout[i].mem_last_page = atop(0x420000000ULL);
- else
- mem_layout[i].mem_last_page =
- atop(0x410000000ULL) + physmem - atop(256 << 20);
- i++;
- }
+ physmem = atop((uint64_t)boot_info->dram_size << 20);
+
+ if (boot_info->phys_mem_desc_addr == 0)
+ panic("bootmem desc is missing");
+ memdesc = (struct octeon_bootmem_desc *)PHYS_TO_XKPHYS(
+ boot_info->phys_mem_desc_addr, CCA_CACHED);
+ printf("bootmem desc 0x%x version %d.%d\n",
+ boot_info->phys_mem_desc_addr, memdesc->major_version,
+ memdesc->minor_version);
+ if (memdesc->major_version > 3)
+ panic("unhandled bootmem desc version %d.%d",
+ memdesc->major_version, memdesc->minor_version);
+
+ blockaddr = memdesc->head_addr;
+ if (blockaddr == 0)
+ panic("bootmem list is empty");
+ for (i = 0; i < MAXMEMSEGS && blockaddr != 0; blockaddr = block->next) {
+ block = (struct octeon_bootmem_block *)PHYS_TO_XKPHYS(
+ blockaddr, CCA_CACHED);
+ printf("avail phys mem 0x%016lx - 0x%016lx\n", blockaddr,
+ (paddr_t)(blockaddr + block->size));
+
+ fp = atop(round_page(blockaddr));
+ lp = atop(trunc_page(blockaddr + block->size));
+
+ /* Clamp to the range of the pmap. */
+ if (fp > atop(pfn_to_pad(PG_FRAME)))
+ continue;
+ if (lp > atop(pfn_to_pad(PG_FRAME)) + 1)
+ lp = atop(pfn_to_pad(PG_FRAME)) + 1;
+ if (fp >= lp)
+ continue;
- /* DR2 */
- if (physmem > atop(512 << 20)) {
- mem_layout[i].mem_first_page = atop(0x20000000ULL);
- mem_layout[i].mem_last_page =
- atop(0x20000000ULL) + physmem - atop(512 << 20);
- /* i++; */
+ mem_layout[i].mem_first_page = fp;
+ mem_layout[i].mem_last_page = lp;
+ i++;
}
- printf("Total DRAM Size 0x%016X\n",
- (uint32_t)(boot_info->dram_size << 20));
+ printf("Total DRAM Size 0x%016llX\n",
+ (uint64_t)boot_info->dram_size << 20);
for (i = 0; mem_layout[i].mem_last_page; i++) {
printf("mem_layout[%d] page 0x%016llX -> 0x%016llX\n", i,