All of lore.kernel.org
 help / color / mirror / Atom feed
From: Andrew Jones <andrew.jones@linux.dev>
To: kvm-riscv@lists.infradead.org
Subject: [kvm-unit-tests PATCH 18/24] riscv: Add MMU support
Date: Wed, 24 Jan 2024 08:18:34 +0100	[thread overview]
Message-ID: <20240124071815.6898-44-andrew.jones@linux.dev> (raw)
In-Reply-To: <20240124071815.6898-26-andrew.jones@linux.dev>

Add minimal page table defines and functions in order to build page
tables and enable the MMU.

Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
 lib/riscv/asm/csr.h     |   1 +
 lib/riscv/asm/io.h      |   3 +
 lib/riscv/asm/mmu.h     |  28 ++++++++
 lib/riscv/asm/page.h    |  11 ++++
 lib/riscv/asm/pgtable.h |  42 ++++++++++++
 lib/riscv/mmu.c         | 140 ++++++++++++++++++++++++++++++++++++++++
 lib/riscv/setup.c       |   3 +
 riscv/Makefile          |   1 +
 8 files changed, 229 insertions(+)
 create mode 100644 lib/riscv/asm/mmu.h
 create mode 100644 lib/riscv/asm/pgtable.h
 create mode 100644 lib/riscv/mmu.c

diff --git a/lib/riscv/asm/csr.h b/lib/riscv/asm/csr.h
index eeddd1fb448a..88c816c68d09 100644
--- a/lib/riscv/asm/csr.h
+++ b/lib/riscv/asm/csr.h
@@ -9,6 +9,7 @@
 #define CSR_SEPC		0x141
 #define CSR_SCAUSE		0x142
 #define CSR_STVAL		0x143
+#define CSR_SATP		0x180
 
 /* Exception cause high bit - is an interrupt if set */
 #define CAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
diff --git a/lib/riscv/asm/io.h b/lib/riscv/asm/io.h
index d2eb3acc9fda..6fe111289102 100644
--- a/lib/riscv/asm/io.h
+++ b/lib/riscv/asm/io.h
@@ -73,6 +73,9 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 }
 #endif
 
+#define ioremap ioremap
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
+
 #include <asm-generic/io.h>
 
 #endif /* _ASMRISCV_IO_H_ */
diff --git a/lib/riscv/asm/mmu.h b/lib/riscv/asm/mmu.h
new file mode 100644
index 000000000000..02703f607511
--- /dev/null
+++ b/lib/riscv/asm/mmu.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_MMU_H_
+#define _ASMRISCV_MMU_H_
+#include <libcflat.h>
+#include <asm/csr.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+static inline pgd_t *current_pgtable(void)
+{
+	return (pgd_t *)((csr_read(CSR_SATP) & SATP_PPN) << PAGE_SHIFT);
+}
+
+void mmu_set_range_ptes(pgd_t *pgtable, uintptr_t virt_offset,
+			phys_addr_t phys_start, phys_addr_t phys_end,
+			pgprot_t prot, bool flush);
+void __mmu_enable(unsigned long satp);
+void mmu_enable(unsigned long mode, pgd_t *pgtable);
+void mmu_disable(void);
+
+void setup_mmu(void);
+
+static inline void local_flush_tlb_page(unsigned long addr)
+{
+	asm volatile("sfence.vma %0" : : "r" (addr) : "memory");
+}
+
+#endif /* _ASMRISCV_MMU_H_ */
diff --git a/lib/riscv/asm/page.h b/lib/riscv/asm/page.h
index 7d7c9191605a..9801b4d1b9c1 100644
--- a/lib/riscv/asm/page.h
+++ b/lib/riscv/asm/page.h
@@ -2,6 +2,17 @@
 #ifndef _ASMRISCV_PAGE_H_
 #define _ASMRISCV_PAGE_H_
 
+#ifndef __ASSEMBLY__
+
+typedef unsigned long pgd_t;
+typedef unsigned long pte_t;
+typedef unsigned long pgprot_t;
+typedef unsigned long pteval_t;
+
+#define __pgprot(x)		((pgprot_t)(x))
+
+#endif /* !__ASSEMBLY__ */
+
 #include <asm-generic/page.h>
 
 #endif /* _ASMRISCV_PAGE_H_ */
diff --git a/lib/riscv/asm/pgtable.h b/lib/riscv/asm/pgtable.h
new file mode 100644
index 000000000000..98d41ff9f661
--- /dev/null
+++ b/lib/riscv/asm/pgtable.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_PGTABLE_H_
+#define _ASMRISCV_PGTABLE_H_
+#include <linux/const.h>
+
+#if __riscv_xlen == 32
+#define SATP_PPN		_AC(0x003FFFFF, UL)
+#define SATP_MODE_32		_AC(0x80000000, UL)
+#define SATP_MODE_SHIFT		31
+#define NR_LEVELS		2
+#define PGDIR_BITS		10
+#define PGDIR_MASK		_AC(0x3FF, UL)
+#define PTE_PPN			_AC(0xFFFFFC00, UL)
+
+#define SATP_MODE_DEFAULT	SATP_MODE_32
+
+#else
+#define SATP_PPN		_AC(0x00000FFFFFFFFFFF, UL)
+#define SATP_MODE_39		_AC(0x8000000000000000, UL)
+#define SATP_MODE_SHIFT		60
+#define NR_LEVELS		3
+#define PGDIR_BITS		9
+#define PGDIR_MASK		_AC(0x1FF, UL)
+#define PTE_PPN			_AC(0x3FFFFFFFFFFC00, UL)
+
+#define SATP_MODE_DEFAULT	SATP_MODE_39
+
+#endif
+
+#define PPN_SHIFT		10
+
+#define _PAGE_PRESENT		(1 << 0)
+#define _PAGE_READ		(1 << 1)
+#define _PAGE_WRITE		(1 << 2)
+#define _PAGE_EXEC		(1 << 3)
+#define _PAGE_USER		(1 << 4)
+#define _PAGE_GLOBAL		(1 << 5)
+#define _PAGE_ACCESSED		(1 << 6)
+#define _PAGE_DIRTY		(1 << 7)
+#define _PAGE_SOFT		(3 << 8)
+
+#endif /* _ASMRISCV_PGTABLE_H_ */
diff --git a/lib/riscv/mmu.c b/lib/riscv/mmu.c
new file mode 100644
index 000000000000..6b1af518ddd8
--- /dev/null
+++ b/lib/riscv/mmu.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+#include <alloc_page.h>
+#include <memregions.h>
+#include <asm/csr.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+#include <asm/page.h>
+
+static pgd_t *__initial_pgtable;
+
+static int pte_index(uintptr_t vaddr, int level)
+{
+	return (vaddr >> (PGDIR_BITS * level + PAGE_SHIFT)) & PGDIR_MASK;
+}
+
+static pte_t *pte_to_ptep(pte_t pte)
+{
+	return (pte_t *)(((pte & PTE_PPN) >> PPN_SHIFT) << PAGE_SHIFT);
+}
+
+static pte_t ptep_to_pte(pte_t *ptep)
+{
+	return ((pte_t)ptep >> PAGE_SHIFT) << PPN_SHIFT;
+}
+
+static pteval_t *__install_page(pgd_t *pgtable, phys_addr_t paddr,
+				uintptr_t vaddr, pgprot_t prot, bool flush)
+{
+	phys_addr_t ppn = (paddr >> PAGE_SHIFT) << PPN_SHIFT;
+	pte_t pte = (pte_t)ppn;
+	pte_t *ptep = pgtable;
+
+	assert(pgtable && !((uintptr_t)pgtable & ~PAGE_MASK));
+	assert(!(ppn & ~PTE_PPN));
+
+	for (int level = NR_LEVELS - 1; level > 0; --level) {
+		pte_t *next = &ptep[pte_index(vaddr, level)];
+		if (!*next) {
+			void *page = alloc_page();
+			*next = ptep_to_pte(page) | _PAGE_PRESENT;
+		}
+		ptep = pte_to_ptep(*next);
+	}
+	ptep = &ptep[pte_index(vaddr, 0)];
+	*ptep = pte | prot | _PAGE_PRESENT;
+
+	if (flush)
+		local_flush_tlb_page(vaddr);
+
+	return (pteval_t *)ptep;
+}
+
+void mmu_set_range_ptes(pgd_t *pgtable, uintptr_t virt_offset,
+			phys_addr_t phys_start, phys_addr_t phys_end,
+			pgprot_t prot, bool flush)
+{
+	phys_addr_t paddr = phys_start & PAGE_MASK;
+	uintptr_t vaddr = virt_offset & PAGE_MASK;
+	uintptr_t virt_end = phys_end - paddr + vaddr;
+
+	assert(phys_start < phys_end);
+
+	for (; vaddr < virt_end; vaddr += PAGE_SIZE, paddr += PAGE_SIZE)
+		__install_page(pgtable, paddr, vaddr, prot, flush);
+}
+
+void mmu_disable(void)
+{
+	__asm__ __volatile__ (
+	"	csrw	" xstr(CSR_SATP) ", zero\n"
+	"	sfence.vma\n"
+	: : : "memory");
+}
+
+void __mmu_enable(unsigned long satp)
+{
+	__asm__ __volatile__ (
+	"	sfence.vma\n"
+	"	csrw	" xstr(CSR_SATP) ", %0\n"
+	: : "r" (satp) : "memory");
+}
+
+void mmu_enable(unsigned long mode, pgd_t *pgtable)
+{
+	unsigned long ppn = (unsigned long)pgtable >> PAGE_SHIFT;
+	unsigned long satp = mode | ppn;
+
+	assert(!(ppn & ~SATP_PPN));
+	__mmu_enable(satp);
+}
+
+void setup_mmu(void)
+{
+	struct mem_region *r;
+	pgd_t *pgtable;
+
+	if (!__initial_pgtable)
+		__initial_pgtable = alloc_page();
+	pgtable = __initial_pgtable;
+
+	for (r = mem_regions; r->end; ++r) {
+		if (r->flags & (MR_F_IO | MR_F_RESERVED))
+			continue;
+		if (r->flags & MR_F_CODE) {
+			mmu_set_range_ptes(pgtable, r->start, r->start, r->end,
+					   __pgprot(_PAGE_READ | _PAGE_EXEC), false);
+		} else {
+			mmu_set_range_ptes(pgtable, r->start, r->start, r->end,
+					   __pgprot(_PAGE_READ | _PAGE_WRITE), false);
+		}
+	}
+
+	mmu_enable(SATP_MODE_DEFAULT, pgtable);
+}
+
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size)
+{
+	phys_addr_t start = phys_addr & PAGE_MASK;
+	phys_addr_t end = PAGE_ALIGN(phys_addr + size);
+	pgd_t *pgtable = current_pgtable();
+	bool flush = true;
+
+	assert(sizeof(long) == 8 || !(phys_addr >> 32));
+
+	if (!pgtable) {
+		if (!__initial_pgtable)
+			__initial_pgtable = alloc_page();
+		pgtable = __initial_pgtable;
+		flush = false;
+	}
+
+	mmu_set_range_ptes(pgtable, start, start, end,
+			   __pgprot(_PAGE_READ | _PAGE_WRITE), flush);
+
+	return (void __iomem *)(unsigned long)phys_addr;
+}
diff --git a/lib/riscv/setup.c b/lib/riscv/setup.c
index 848ec8e83496..c4c1bd58b337 100644
--- a/lib/riscv/setup.c
+++ b/lib/riscv/setup.c
@@ -14,6 +14,7 @@
 #include <memregions.h>
 #include <on-cpus.h>
 #include <asm/csr.h>
+#include <asm/mmu.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/setup.h>
@@ -171,5 +172,7 @@ void setup(const void *fdt, phys_addr_t freemem_start)
 		setup_env(env, initrd_size);
 	}
 
+	setup_mmu();
+
 	banner();
 }
diff --git a/riscv/Makefile b/riscv/Makefile
index ed1a14025ed2..821891b719e7 100644
--- a/riscv/Makefile
+++ b/riscv/Makefile
@@ -29,6 +29,7 @@ cflatobjs += lib/memregions.o
 cflatobjs += lib/on-cpus.o
 cflatobjs += lib/riscv/bitops.o
 cflatobjs += lib/riscv/io.o
+cflatobjs += lib/riscv/mmu.o
 cflatobjs += lib/riscv/processor.o
 cflatobjs += lib/riscv/sbi.o
 cflatobjs += lib/riscv/setup.o
-- 
2.43.0



WARNING: multiple messages have this Message-ID (diff)
From: Andrew Jones <andrew.jones@linux.dev>
To: kvm@vger.kernel.org, kvm-riscv@lists.infradead.org,
	kvmarm@lists.linux.dev
Cc: ajones@ventanamicro.com, anup@brainfault.org,
	atishp@atishpatra.org, pbonzini@redhat.com, thuth@redhat.com,
	alexandru.elisei@arm.com, eric.auger@redhat.com
Subject: [kvm-unit-tests PATCH 18/24] riscv: Add MMU support
Date: Wed, 24 Jan 2024 08:18:34 +0100	[thread overview]
Message-ID: <20240124071815.6898-44-andrew.jones@linux.dev> (raw)
In-Reply-To: <20240124071815.6898-26-andrew.jones@linux.dev>

Add minimal page table defines and functions in order to build page
tables and enable the MMU.

Signed-off-by: Andrew Jones <andrew.jones@linux.dev>
---
 lib/riscv/asm/csr.h     |   1 +
 lib/riscv/asm/io.h      |   3 +
 lib/riscv/asm/mmu.h     |  28 ++++++++
 lib/riscv/asm/page.h    |  11 ++++
 lib/riscv/asm/pgtable.h |  42 ++++++++++++
 lib/riscv/mmu.c         | 140 ++++++++++++++++++++++++++++++++++++++++
 lib/riscv/setup.c       |   3 +
 riscv/Makefile          |   1 +
 8 files changed, 229 insertions(+)
 create mode 100644 lib/riscv/asm/mmu.h
 create mode 100644 lib/riscv/asm/pgtable.h
 create mode 100644 lib/riscv/mmu.c

diff --git a/lib/riscv/asm/csr.h b/lib/riscv/asm/csr.h
index eeddd1fb448a..88c816c68d09 100644
--- a/lib/riscv/asm/csr.h
+++ b/lib/riscv/asm/csr.h
@@ -9,6 +9,7 @@
 #define CSR_SEPC		0x141
 #define CSR_SCAUSE		0x142
 #define CSR_STVAL		0x143
+#define CSR_SATP		0x180
 
 /* Exception cause high bit - is an interrupt if set */
 #define CAUSE_IRQ_FLAG		(_AC(1, UL) << (__riscv_xlen - 1))
diff --git a/lib/riscv/asm/io.h b/lib/riscv/asm/io.h
index d2eb3acc9fda..6fe111289102 100644
--- a/lib/riscv/asm/io.h
+++ b/lib/riscv/asm/io.h
@@ -73,6 +73,9 @@ static inline u64 __raw_readq(const volatile void __iomem *addr)
 }
 #endif
 
+#define ioremap ioremap
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size);
+
 #include <asm-generic/io.h>
 
 #endif /* _ASMRISCV_IO_H_ */
diff --git a/lib/riscv/asm/mmu.h b/lib/riscv/asm/mmu.h
new file mode 100644
index 000000000000..02703f607511
--- /dev/null
+++ b/lib/riscv/asm/mmu.h
@@ -0,0 +1,28 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_MMU_H_
+#define _ASMRISCV_MMU_H_
+#include <libcflat.h>
+#include <asm/csr.h>
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+static inline pgd_t *current_pgtable(void)
+{
+	return (pgd_t *)((csr_read(CSR_SATP) & SATP_PPN) << PAGE_SHIFT);
+}
+
+void mmu_set_range_ptes(pgd_t *pgtable, uintptr_t virt_offset,
+			phys_addr_t phys_start, phys_addr_t phys_end,
+			pgprot_t prot, bool flush);
+void __mmu_enable(unsigned long satp);
+void mmu_enable(unsigned long mode, pgd_t *pgtable);
+void mmu_disable(void);
+
+void setup_mmu(void);
+
+static inline void local_flush_tlb_page(unsigned long addr)
+{
+	asm volatile("sfence.vma %0" : : "r" (addr) : "memory");
+}
+
+#endif /* _ASMRISCV_MMU_H_ */
diff --git a/lib/riscv/asm/page.h b/lib/riscv/asm/page.h
index 7d7c9191605a..9801b4d1b9c1 100644
--- a/lib/riscv/asm/page.h
+++ b/lib/riscv/asm/page.h
@@ -2,6 +2,17 @@
 #ifndef _ASMRISCV_PAGE_H_
 #define _ASMRISCV_PAGE_H_
 
+#ifndef __ASSEMBLY__
+
+typedef unsigned long pgd_t;
+typedef unsigned long pte_t;
+typedef unsigned long pgprot_t;
+typedef unsigned long pteval_t;
+
+#define __pgprot(x)		((pgprot_t)(x))
+
+#endif /* !__ASSEMBLY__ */
+
 #include <asm-generic/page.h>
 
 #endif /* _ASMRISCV_PAGE_H_ */
diff --git a/lib/riscv/asm/pgtable.h b/lib/riscv/asm/pgtable.h
new file mode 100644
index 000000000000..98d41ff9f661
--- /dev/null
+++ b/lib/riscv/asm/pgtable.h
@@ -0,0 +1,42 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+#ifndef _ASMRISCV_PGTABLE_H_
+#define _ASMRISCV_PGTABLE_H_
+#include <linux/const.h>
+
+#if __riscv_xlen == 32
+#define SATP_PPN		_AC(0x003FFFFF, UL)
+#define SATP_MODE_32		_AC(0x80000000, UL)
+#define SATP_MODE_SHIFT		31
+#define NR_LEVELS		2
+#define PGDIR_BITS		10
+#define PGDIR_MASK		_AC(0x3FF, UL)
+#define PTE_PPN			_AC(0xFFFFFC00, UL)
+
+#define SATP_MODE_DEFAULT	SATP_MODE_32
+
+#else
+#define SATP_PPN		_AC(0x00000FFFFFFFFFFF, UL)
+#define SATP_MODE_39		_AC(0x8000000000000000, UL)
+#define SATP_MODE_SHIFT		60
+#define NR_LEVELS		3
+#define PGDIR_BITS		9
+#define PGDIR_MASK		_AC(0x1FF, UL)
+#define PTE_PPN			_AC(0x3FFFFFFFFFFC00, UL)
+
+#define SATP_MODE_DEFAULT	SATP_MODE_39
+
+#endif
+
+#define PPN_SHIFT		10
+
+#define _PAGE_PRESENT		(1 << 0)
+#define _PAGE_READ		(1 << 1)
+#define _PAGE_WRITE		(1 << 2)
+#define _PAGE_EXEC		(1 << 3)
+#define _PAGE_USER		(1 << 4)
+#define _PAGE_GLOBAL		(1 << 5)
+#define _PAGE_ACCESSED		(1 << 6)
+#define _PAGE_DIRTY		(1 << 7)
+#define _PAGE_SOFT		(3 << 8)
+
+#endif /* _ASMRISCV_PGTABLE_H_ */
diff --git a/lib/riscv/mmu.c b/lib/riscv/mmu.c
new file mode 100644
index 000000000000..6b1af518ddd8
--- /dev/null
+++ b/lib/riscv/mmu.c
@@ -0,0 +1,140 @@
+// SPDX-License-Identifier: GPL-2.0-only
+/*
+ * Copyright (C) 2023, Ventana Micro Systems Inc., Andrew Jones <ajones@ventanamicro.com>
+ */
+#include <libcflat.h>
+#include <alloc_page.h>
+#include <memregions.h>
+#include <asm/csr.h>
+#include <asm/io.h>
+#include <asm/mmu.h>
+#include <asm/page.h>
+
+static pgd_t *__initial_pgtable;
+
+static int pte_index(uintptr_t vaddr, int level)
+{
+	return (vaddr >> (PGDIR_BITS * level + PAGE_SHIFT)) & PGDIR_MASK;
+}
+
+static pte_t *pte_to_ptep(pte_t pte)
+{
+	return (pte_t *)(((pte & PTE_PPN) >> PPN_SHIFT) << PAGE_SHIFT);
+}
+
+static pte_t ptep_to_pte(pte_t *ptep)
+{
+	return ((pte_t)ptep >> PAGE_SHIFT) << PPN_SHIFT;
+}
+
+static pteval_t *__install_page(pgd_t *pgtable, phys_addr_t paddr,
+				uintptr_t vaddr, pgprot_t prot, bool flush)
+{
+	phys_addr_t ppn = (paddr >> PAGE_SHIFT) << PPN_SHIFT;
+	pte_t pte = (pte_t)ppn;
+	pte_t *ptep = pgtable;
+
+	assert(pgtable && !((uintptr_t)pgtable & ~PAGE_MASK));
+	assert(!(ppn & ~PTE_PPN));
+
+	for (int level = NR_LEVELS - 1; level > 0; --level) {
+		pte_t *next = &ptep[pte_index(vaddr, level)];
+		if (!*next) {
+			void *page = alloc_page();
+			*next = ptep_to_pte(page) | _PAGE_PRESENT;
+		}
+		ptep = pte_to_ptep(*next);
+	}
+	ptep = &ptep[pte_index(vaddr, 0)];
+	*ptep = pte | prot | _PAGE_PRESENT;
+
+	if (flush)
+		local_flush_tlb_page(vaddr);
+
+	return (pteval_t *)ptep;
+}
+
+void mmu_set_range_ptes(pgd_t *pgtable, uintptr_t virt_offset,
+			phys_addr_t phys_start, phys_addr_t phys_end,
+			pgprot_t prot, bool flush)
+{
+	phys_addr_t paddr = phys_start & PAGE_MASK;
+	uintptr_t vaddr = virt_offset & PAGE_MASK;
+	uintptr_t virt_end = phys_end - paddr + vaddr;
+
+	assert(phys_start < phys_end);
+
+	for (; vaddr < virt_end; vaddr += PAGE_SIZE, paddr += PAGE_SIZE)
+		__install_page(pgtable, paddr, vaddr, prot, flush);
+}
+
+void mmu_disable(void)
+{
+	__asm__ __volatile__ (
+	"	csrw	" xstr(CSR_SATP) ", zero\n"
+	"	sfence.vma\n"
+	: : : "memory");
+}
+
+void __mmu_enable(unsigned long satp)
+{
+	__asm__ __volatile__ (
+	"	sfence.vma\n"
+	"	csrw	" xstr(CSR_SATP) ", %0\n"
+	: : "r" (satp) : "memory");
+}
+
+void mmu_enable(unsigned long mode, pgd_t *pgtable)
+{
+	unsigned long ppn = (unsigned long)pgtable >> PAGE_SHIFT;
+	unsigned long satp = mode | ppn;
+
+	assert(!(ppn & ~SATP_PPN));
+	__mmu_enable(satp);
+}
+
+void setup_mmu(void)
+{
+	struct mem_region *r;
+	pgd_t *pgtable;
+
+	if (!__initial_pgtable)
+		__initial_pgtable = alloc_page();
+	pgtable = __initial_pgtable;
+
+	for (r = mem_regions; r->end; ++r) {
+		if (r->flags & (MR_F_IO | MR_F_RESERVED))
+			continue;
+		if (r->flags & MR_F_CODE) {
+			mmu_set_range_ptes(pgtable, r->start, r->start, r->end,
+					   __pgprot(_PAGE_READ | _PAGE_EXEC), false);
+		} else {
+			mmu_set_range_ptes(pgtable, r->start, r->start, r->end,
+					   __pgprot(_PAGE_READ | _PAGE_WRITE), false);
+		}
+	}
+
+	mmu_enable(SATP_MODE_DEFAULT, pgtable);
+}
+
+void __iomem *ioremap(phys_addr_t phys_addr, size_t size)
+{
+	phys_addr_t start = phys_addr & PAGE_MASK;
+	phys_addr_t end = PAGE_ALIGN(phys_addr + size);
+	pgd_t *pgtable = current_pgtable();
+	bool flush = true;
+
+	assert(sizeof(long) == 8 || !(phys_addr >> 32));
+
+	if (!pgtable) {
+		if (!__initial_pgtable)
+			__initial_pgtable = alloc_page();
+		pgtable = __initial_pgtable;
+		flush = false;
+	}
+
+	mmu_set_range_ptes(pgtable, start, start, end,
+			   __pgprot(_PAGE_READ | _PAGE_WRITE), flush);
+
+	return (void __iomem *)(unsigned long)phys_addr;
+}
diff --git a/lib/riscv/setup.c b/lib/riscv/setup.c
index 848ec8e83496..c4c1bd58b337 100644
--- a/lib/riscv/setup.c
+++ b/lib/riscv/setup.c
@@ -14,6 +14,7 @@
 #include <memregions.h>
 #include <on-cpus.h>
 #include <asm/csr.h>
+#include <asm/mmu.h>
 #include <asm/page.h>
 #include <asm/processor.h>
 #include <asm/setup.h>
@@ -171,5 +172,7 @@ void setup(const void *fdt, phys_addr_t freemem_start)
 		setup_env(env, initrd_size);
 	}
 
+	setup_mmu();
+
 	banner();
 }
diff --git a/riscv/Makefile b/riscv/Makefile
index ed1a14025ed2..821891b719e7 100644
--- a/riscv/Makefile
+++ b/riscv/Makefile
@@ -29,6 +29,7 @@ cflatobjs += lib/memregions.o
 cflatobjs += lib/on-cpus.o
 cflatobjs += lib/riscv/bitops.o
 cflatobjs += lib/riscv/io.o
+cflatobjs += lib/riscv/mmu.o
 cflatobjs += lib/riscv/processor.o
 cflatobjs += lib/riscv/sbi.o
 cflatobjs += lib/riscv/setup.o
-- 
2.43.0


  parent reply	other threads:[~2024-01-24  7:18 UTC|newest]

Thread overview: 66+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2024-01-24  7:18 [kvm-unit-tests PATCH 00/24] Introduce RISC-V Andrew Jones
2024-01-24  7:18 ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 01/24] configure: Add ARCH_LIBDIR Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:33   ` Thomas Huth
2024-01-24  9:33     ` Thomas Huth
2024-01-24  7:18 ` [kvm-unit-tests PATCH 02/24] riscv: Initial port, hello world Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 03/24] arm/arm64: Move cpumask.h to common lib Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:52   ` Thomas Huth
2024-01-24  9:52     ` Thomas Huth
2024-01-24  7:18 ` [kvm-unit-tests PATCH 04/24] arm/arm64: Share cpu online, present and idle masks Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:53   ` Thomas Huth
2024-01-24  9:53     ` Thomas Huth
2024-01-24  7:18 ` [kvm-unit-tests PATCH 05/24] riscv: Add DT parsing Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 06/24] riscv: Add initial SBI support Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 07/24] riscv: Add run script and unittests.cfg Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 08/24] riscv: Add riscv32 support Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 09/24] riscv: Add exception handling Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 10/24] riscv: Add backtrace support Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 11/24] arm/arm64: Generalize wfe/sev names in smp.c Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 12/24] arm/arm64: Remove spinlocks from on_cpu_async Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 13/24] arm/arm64: Share on_cpus Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 14/24] riscv: Compile with march Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 15/24] riscv: Add SMP support Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 16/24] arm/arm64: Share memregions Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 17/24] riscv: Populate memregions and switch to page allocator Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` Andrew Jones [this message]
2024-01-24  7:18   ` [kvm-unit-tests PATCH 18/24] riscv: Add MMU support Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 19/24] riscv: Enable the MMU in secondaries Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 20/24] riscv: Enable vmalloc Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 21/24] lib: Add strcasecmp and strncasecmp Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:41   ` Thomas Huth
2024-01-24  9:41     ` Thomas Huth
2024-01-24  7:18 ` [kvm-unit-tests PATCH 22/24] riscv: Add isa string parsing Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 23/24] gitlab-ci: Add riscv64 tests Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:45   ` Thomas Huth
2024-01-24  9:45     ` Thomas Huth
2024-01-24 10:21     ` Andrew Jones
2024-01-24 10:21       ` Andrew Jones
2024-01-24  7:18 ` [kvm-unit-tests PATCH 24/24] MAINTAINERS: Add riscv Andrew Jones
2024-01-24  7:18   ` Andrew Jones
2024-01-24  9:46   ` Thomas Huth
2024-01-24  9:46     ` Thomas Huth
2024-01-24  9:58 ` [kvm-unit-tests PATCH 00/24] Introduce RISC-V Thomas Huth
2024-01-24  9:58   ` Thomas Huth

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20240124071815.6898-44-andrew.jones@linux.dev \
    --to=andrew.jones@linux.dev \
    --cc=kvm-riscv@lists.infradead.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.