mirror of
https://github.com/openbsd/src.git
synced 2024-12-22 16:42:56 -08:00
T-Head implemented a page attribute extension that violates the RISC-V
specification. The default attributes result in memory being uncached which makes the system perform like a slug. So implement a workaround that is designed to make implementation of the Svpbmt extension that is part of the latest published RISC-V specification. This gets us a bit further booting OpenBSD on an Allwinner D1 SoC. ok mlarkin@, jca@
This commit is contained in:
parent
aa95fb555a
commit
84aa31c6dc
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pmap.h,v 1.10 2023/12/13 18:26:41 jca Exp $ */
|
||||
/* $OpenBSD: pmap.h,v 1.11 2024/01/23 19:51:10 kettenis Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019-2020 Brian Bamsch <bbamsch@google.com>
|
||||
@ -44,8 +44,7 @@
|
||||
/* cache flags */
|
||||
// XXX These are duplicated from arm64 and may need some reworking
|
||||
#define PMAP_CACHE_CI (PMAP_MD0) /* cache inhibit */
|
||||
#define PMAP_CACHE_WT (PMAP_MD1) /* writethru */
|
||||
#define PMAP_CACHE_WB (PMAP_MD1|PMAP_MD0) /* writeback */
|
||||
#define PMAP_CACHE_WB (PMAP_MD1) /* writeback */
|
||||
#define PMAP_CACHE_DEV (PMAP_MD2) /* device mapping */
|
||||
#define PMAP_CACHE_BITS (PMAP_MD0|PMAP_MD1|PMAP_MD2)
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pte.h,v 1.2 2021/05/12 01:20:52 jsg Exp $ */
|
||||
/* $OpenBSD: pte.h,v 1.3 2024/01/23 19:51:10 kettenis Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019 Brian Bamsch <bbamsch@google.com>
|
||||
@ -39,8 +39,12 @@
|
||||
#define PTE_RWX (PTE_R | PTE_W | PTE_X)
|
||||
#define PTE_RX (PTE_R | PTE_X)
|
||||
#define PTE_KERN (PTE_V | PTE_R | PTE_W | PTE_A | PTE_D)
|
||||
#define PTE_PROMOTE (PTE_V | PTE_RWX | PTE_D | PTE_A | PTE_G | PTE_U | \
|
||||
PTE_SW_MANAGED | PTE_SW_WIRED
|
||||
|
||||
/* T-Head extended page attributes */
|
||||
#define PTE_THEAD_SO (1ULL << 63)
|
||||
#define PTE_THEAD_C (1ULL << 62)
|
||||
#define PTE_THEAD_B (1ULL << 61)
|
||||
#define PTE_THEAD_SH (1ULL << 60)
|
||||
|
||||
/* Level 0 table, 512GiB per entry */
|
||||
#define L0_SHIFT 39
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: cpu.c,v 1.16 2023/10/24 13:20:10 claudio Exp $ */
|
||||
/* $OpenBSD: cpu.c,v 1.17 2024/01/23 19:51:10 kettenis Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2016 Dale Rahn <drahn@dalerahn.com>
|
||||
@ -37,9 +37,10 @@
|
||||
#include <dev/ofw/fdt.h>
|
||||
|
||||
/* CPU Identification */
|
||||
|
||||
#define CPU_VENDOR_SIFIVE 0x489
|
||||
#define CPU_VENDOR_THEAD 0x5b7
|
||||
|
||||
/* SiFive */
|
||||
#define CPU_ARCH_U5 0x0000000000000001
|
||||
#define CPU_ARCH_U7 0x8000000000000007
|
||||
|
||||
@ -66,6 +67,7 @@ const struct vendor {
|
||||
struct arch *archlist;
|
||||
} cpu_vendors[] = {
|
||||
{ CPU_VENDOR_SIFIVE, "SiFive", cpu_arch_sifive },
|
||||
{ CPU_VENDOR_THEAD, "T-Head", cpu_arch_none },
|
||||
{ 0, NULL }
|
||||
};
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: machdep.c,v 1.33 2023/12/04 15:00:09 claudio Exp $ */
|
||||
/* $OpenBSD: machdep.c,v 1.34 2024/01/23 19:51:10 kettenis Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2014 Patrick Wildt <patrick@blueri.se>
|
||||
@ -912,7 +912,8 @@ pmap_bootstrap_bs_map(bus_space_tag_t t, bus_addr_t bpa, bus_size_t size,
|
||||
*bshp = (bus_space_handle_t)(va + (bpa - startpa));
|
||||
|
||||
for (pa = startpa; pa < endpa; pa += PAGE_SIZE, va += PAGE_SIZE)
|
||||
pmap_kenter_pa(va, pa, PROT_READ | PROT_WRITE);
|
||||
pmap_kenter_cache(va, pa, PROT_READ | PROT_WRITE,
|
||||
PMAP_CACHE_DEV);
|
||||
|
||||
virtual_avail = va;
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
/* $OpenBSD: pmap.c,v 1.37 2023/12/13 18:26:41 jca Exp $ */
|
||||
/* $OpenBSD: pmap.c,v 1.38 2024/01/23 19:51:10 kettenis Exp $ */
|
||||
|
||||
/*
|
||||
* Copyright (c) 2019-2020 Brian Bamsch <bbamsch@google.com>
|
||||
@ -216,6 +216,8 @@ vaddr_t zero_page;
|
||||
vaddr_t copy_src_page;
|
||||
vaddr_t copy_dst_page;
|
||||
|
||||
#define CPU_VENDOR_THEAD 0x5b7
|
||||
|
||||
struct pool pmap_pmap_pool;
|
||||
struct pool pmap_pted_pool;
|
||||
struct pool pmap_vp_pool;
|
||||
@ -299,6 +301,11 @@ const pt_entry_t ap_bits_kern[8] = {
|
||||
[PROT_EXEC|PROT_WRITE|PROT_READ] = PTE_A|PTE_X|PTE_R|PTE_D|PTE_W,
|
||||
};
|
||||
|
||||
/* PBMT encodings for the Svpmbt modes. */
|
||||
uint64_t pmap_pma;
|
||||
uint64_t pmap_nc;
|
||||
uint64_t pmap_io;
|
||||
|
||||
/*
|
||||
* This is used for pmap_kernel() mappings, they are not to be removed
|
||||
* from the vp table because they were statically initialized at the
|
||||
@ -769,8 +776,6 @@ pmap_fill_pte(pmap_t pm, vaddr_t va, paddr_t pa, struct pte_desc *pted,
|
||||
switch (cache) {
|
||||
case PMAP_CACHE_WB:
|
||||
break;
|
||||
case PMAP_CACHE_WT:
|
||||
break;
|
||||
case PMAP_CACHE_CI:
|
||||
if (pa >= pmap_cached_start && pa <= pmap_cached_end)
|
||||
pa += (pmap_uncached_start - pmap_cached_start);
|
||||
@ -778,7 +783,7 @@ pmap_fill_pte(pmap_t pm, vaddr_t va, paddr_t pa, struct pte_desc *pted,
|
||||
case PMAP_CACHE_DEV:
|
||||
break;
|
||||
default:
|
||||
panic("pmap_fill_pte:invalid cache mode");
|
||||
panic("%s: invalid cache mode", __func__);
|
||||
}
|
||||
pted->pted_va |= cache;
|
||||
|
||||
@ -1177,9 +1182,9 @@ pmap_bootstrap_dmap(vaddr_t kern_l1, paddr_t min_pa, paddr_t max_pa)
|
||||
|
||||
/* gigapages */
|
||||
pn = (pa / PAGE_SIZE);
|
||||
entry = PTE_KERN;
|
||||
entry = PTE_KERN | pmap_pma;
|
||||
entry |= (pn << PTE_PPN0_S);
|
||||
atomic_store_64(&l1[l1_slot], entry);
|
||||
l1[l1_slot] = entry;
|
||||
}
|
||||
|
||||
sfence_vma();
|
||||
@ -1198,8 +1203,27 @@ pmap_bootstrap(long kvo, vaddr_t l1pt, vaddr_t kernelstart, vaddr_t kernelend,
|
||||
vaddr_t vstart;
|
||||
int i, j, k;
|
||||
int lb_idx2, ub_idx2;
|
||||
uint64_t marchid, mimpid;
|
||||
uint32_t mvendorid;
|
||||
void *node;
|
||||
|
||||
mvendorid = sbi_get_mvendorid();
|
||||
marchid = sbi_get_marchid();
|
||||
mimpid = sbi_get_mimpid();
|
||||
|
||||
/*
|
||||
* The T-Head cores implement a page attributes extension that
|
||||
* violates the RISC-V privileged architecture specification.
|
||||
* Work around this as best as we can by adding the
|
||||
* appropriate page attributes in a way that is mostly
|
||||
* compatible with the Svpbmt extension.
|
||||
*/
|
||||
if (mvendorid == CPU_VENDOR_THEAD && marchid == 0 && mimpid == 0) {
|
||||
pmap_pma = PTE_THEAD_C | PTE_THEAD_B | PTE_THEAD_SH;
|
||||
pmap_nc = PTE_THEAD_B | PTE_THEAD_SH;
|
||||
pmap_io = PTE_THEAD_SO | PTE_THEAD_SH;
|
||||
}
|
||||
|
||||
node = fdt_find_node("/");
|
||||
if (fdt_is_compatible(node, "starfive,jh7100")) {
|
||||
pmap_cached_start = 0x0080000000ULL;
|
||||
@ -1604,15 +1628,30 @@ pmap_pte_insert(struct pte_desc *pted)
|
||||
void
|
||||
pmap_pte_update(struct pte_desc *pted, uint64_t *pl3)
|
||||
{
|
||||
pt_entry_t pte, access_bits;
|
||||
uint64_t pte, access_bits;
|
||||
pmap_t pm = pted->pted_pmap;
|
||||
uint64_t attr = 0;
|
||||
|
||||
switch (pted->pted_va & PMAP_CACHE_BITS) {
|
||||
case PMAP_CACHE_WB:
|
||||
attr |= pmap_pma;
|
||||
break;
|
||||
case PMAP_CACHE_CI:
|
||||
attr |= pmap_nc;
|
||||
break;
|
||||
case PMAP_CACHE_DEV:
|
||||
attr |= pmap_io;
|
||||
break;
|
||||
default:
|
||||
panic("%s: invalid cache mode", __func__);
|
||||
}
|
||||
|
||||
if (pm->pm_privileged)
|
||||
access_bits = ap_bits_kern[pted->pted_pte & PROT_MASK];
|
||||
else
|
||||
access_bits = ap_bits_user[pted->pted_pte & PROT_MASK];
|
||||
|
||||
pte = VP_Lx(pted->pted_pte) | access_bits | PTE_V;
|
||||
pte = VP_Lx(pted->pted_pte) | attr | access_bits | PTE_V;
|
||||
*pl3 = access_bits ? pte : 0;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user