diff options
author | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-05-28 20:32:31 +0000 |
---|---|---|
committer | Patrick Wildt <patrick@cvs.openbsd.org> | 2019-05-28 20:32:31 +0000 |
commit | e38afe5713823427a93a4d345980264b1596ebf4 (patch) | |
tree | 52bc7f76968243aac8851ff711b1e0c0a535d549 /sys/arch | |
parent | 5837f76c6c1e13d30d267690afbde081a914afd4 (diff) |
On bigger arm64 machines with plenty of memory it is possible that
the kernel, which is allocated in low memory by efiboot, is not in
the same 512 GiB L0 address space as the EFI/FDT/ACPI tables. Since
we only identity-map a single L0 entry for bootstrapping purposes we
can't reach those tables. Keep a set of spare L1 tables, currently
one, which we can dynamically enter into the identity map so that we
are able to reach those tables. While there, do the FDT mapping a
bit later in C code by calling pmap_map_early(). This allows us to
boot further on Packet's Ampere eMAGs.
Discussed with drahn@
ok kettenis@
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/arm64/arm64/locore.S | 14 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/locore0.S | 35 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/machdep.c | 4 | ||||
-rw-r--r-- | sys/arch/arm64/arm64/pmap.c | 24 |
4 files changed, 62 insertions, 15 deletions
diff --git a/sys/arch/arm64/arm64/locore.S b/sys/arch/arm64/arm64/locore.S index 3bdbdc6d122..a8f92a57826 100644 --- a/sys/arch/arm64/arm64/locore.S +++ b/sys/arch/arm64/arm64/locore.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore.S,v 1.24 2018/09/09 16:41:43 mortimer Exp $ */ +/* $OpenBSD: locore.S,v 1.25 2019/05/28 20:32:30 patrick Exp $ */ /*- * Copyright (c) 2012-2014 Andrew Turner * All rights reserved. @@ -35,6 +35,7 @@ #include <machine/param.h> #define VIRT_BITS 39 +#define NUM_L1_TTBR0 2 /* * If we are started in EL2, configure the required hypervisor @@ -270,12 +271,21 @@ pagetable_l1_ttbr1: .space PAGE_SIZE * 2 // allocate 2 pages for pmapvp1 .globl pagetable_l1_ttbr0 pagetable_l1_ttbr0: - .space PAGE_SIZE * 2 // allocate 2 pages, reused later in pmap + .space PAGE_SIZE * NUM_L1_TTBR0 .globl pagetable_l0_ttbr0 pagetable_l0_ttbr0: .space PAGE_SIZE .globl pagetable_end pagetable_end: + .globl pagetable_l1_ttbr0_pa +pagetable_l1_ttbr0_pa: + .xword 0 + .globl pagetable_l1_ttbr0_num +pagetable_l1_ttbr0_num: + .xword NUM_L1_TTBR0 + .globl pagetable_l1_ttbr0_idx +pagetable_l1_ttbr0_idx: /* uint64_t[NUM_L1_TTBR0] */ + .fill NUM_L1_TTBR0 * 8, 1, 0xff .bss .align 4 .globl initstack diff --git a/sys/arch/arm64/arm64/locore0.S b/sys/arch/arm64/arm64/locore0.S index daa352dcad2..8b7184824c6 100644 --- a/sys/arch/arm64/arm64/locore0.S +++ b/sys/arch/arm64/arm64/locore0.S @@ -1,4 +1,4 @@ -/* $OpenBSD: locore0.S,v 1.4 2018/01/21 22:30:41 kettenis Exp $ */ +/* $OpenBSD: locore0.S,v 1.5 2019/05/28 20:32:30 patrick Exp $ */ /*- * Copyright (c) 2012-2014 Andrew Turner * All rights reserved. @@ -193,6 +193,12 @@ virtdone: .xword pagetable .Lpagetable_end: .xword pagetable_end +.Lpagetable_l1_ttbr0_idx: + .xword pagetable_l1_ttbr0_idx +.Lpagetable_l1_ttbr0_num: + .xword pagetable_l1_ttbr0_num +.Lpagetable_l1_ttbr0_pa: + .xword pagetable_l1_ttbr0_pa .Lesym: .xword esym @@ -277,15 +283,28 @@ create_pagetables: mov x10, #1 bl build_l1_block_pagetable - /* Create a mapping for the FDT */ - mov x7, #NORMAL_MEM // #NORMAL - mov x9, x23 - mov x8, x9 /* VA start (== PA start) */ - mov x10, #1 - bl build_l1_block_pagetable + /* Store pa of l1 table space start */ + adr x7, .Lpagetable_l1_ttbr0_pa + ldr x7, [x7] + sub x7, x7, x29 // VA -> PA + str x27, [x7] + + /* Store idx of created l1 table */ + adr x7, .Lpagetable_l1_ttbr0_idx + ldr x7, [x7] + sub x7, x7, x29 // VA -> PA + lsr x9, x27, #L0_SHIFT + and x9, x9, #Ln_ADDR_MASK + str x9, [x7] + + adr x7, .Lpagetable_l1_ttbr0_num + ldr x7, [x7] + sub x7, x7, x29 // VA -> PA + ldr x7, [x7] /* Move to the l0 table */ - add x27, x27, #PAGE_SIZE * 2 // pagetable_l0_ttbr0: + lsl x7, x7, PAGE_SHIFT + add x27, x27, x7 // pagetable_l0_ttbr0: /* Link the l0 -> l1 table */ mov x9, x6 diff --git a/sys/arch/arm64/arm64/machdep.c b/sys/arch/arm64/arm64/machdep.c index 80ad0271875..f8e1a990700 100644 --- a/sys/arch/arm64/arm64/machdep.c +++ b/sys/arch/arm64/arm64/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.39 2019/04/30 20:04:31 patrick Exp $ */ +/* $OpenBSD: machdep.c,v 1.40 2019/05/28 20:32:30 patrick Exp $ */ /* * Copyright (c) 2014 Patrick Wildt <patrick@blueri.se> * @@ -812,8 +812,10 @@ initarm(struct arm64_bootparams *abp) // NOTE that 1GB of ram is mapped in by default in // the bootstrap memory config, so nothing is necessary // until pmap_bootstrap_finalize is called?? + pmap_map_early((paddr_t)config, PAGE_SIZE); if (!fdt_init(config) || fdt_get_size(config) == 0) panic("initarm: no FDT"); + pmap_map_early((paddr_t)config, round_page(fdt_get_size(config))); struct fdt_reg reg; void *node; diff --git a/sys/arch/arm64/arm64/pmap.c b/sys/arch/arm64/arm64/pmap.c index 59b018eaddc..d55d733b57a 100644 --- a/sys/arch/arm64/arm64/pmap.c +++ b/sys/arch/arm64/arm64/pmap.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pmap.c,v 1.61 2019/04/16 14:32:44 patrick Exp $ */ +/* $OpenBSD: pmap.c,v 1.62 2019/05/28 20:32:30 patrick Exp $ */ /* * Copyright (c) 2008-2009,2014-2016 Dale Rahn <drahn@dalerahn.com> * @@ -2187,13 +2187,29 @@ pmap_map_early(paddr_t spa, psize_t len) { extern pd_entry_t pagetable_l0_ttbr0[]; extern pd_entry_t pagetable_l1_ttbr0[]; + extern uint64_t pagetable_l1_ttbr0_idx[]; + extern uint64_t pagetable_l1_ttbr0_num; + extern uint64_t pagetable_l1_ttbr0_pa; paddr_t pa, epa = spa + len; + uint64_t i, idx = ~0; for (pa = spa & ~(L1_SIZE - 1); pa < epa; pa += L1_SIZE) { - if (pagetable_l0_ttbr0[VP_IDX0(pa)] == 0) - panic("%s: outside existing L0 entry", __func__); + for (i = 0; i < pagetable_l1_ttbr0_num; i++) { + if (pagetable_l1_ttbr0_idx[i] == ~0) + break; + if (pagetable_l1_ttbr0_idx[i] == VP_IDX0(pa)) + break; + } + if (i == pagetable_l1_ttbr0_num) + panic("%s: outside existing L0 entries", __func__); + if (pagetable_l1_ttbr0_idx[i] == ~0) { + pagetable_l0_ttbr0[VP_IDX0(pa)] = + (pagetable_l1_ttbr0_pa + i * PAGE_SIZE) | L0_TABLE; + pagetable_l1_ttbr0_idx[i] = VP_IDX0(pa); + } - pagetable_l1_ttbr0[VP_IDX1(pa)] = pa | L1_BLOCK | + idx = i * (PAGE_SIZE / sizeof(uint64_t)) + VP_IDX1(pa); + pagetable_l1_ttbr0[idx] = pa | L1_BLOCK | ATTR_IDX(PTE_ATTR_WB) | ATTR_SH(SH_INNER) | ATTR_nG | ATTR_UXN | ATTR_AF | ATTR_AP(0); } |