Add support for radix MMU, 4kB and 64kB pages.
This also adds MMU interrupt test cases, and runs the interrupts
test entirely with MMU enabled if it is available (aside from
machine check tests).
Signed-off-by: Nicholas Piggin
---
configure | 39 +++--
lib/powerpc/asm/hcall.h | 6 +
lib/powerpc/asm/processor.h | 1 +
lib/powerpc/asm/reg.h | 3 +
lib/powerpc/asm/smp.h | 2 +
lib/powerpc/processor.c | 9 ++
lib/powerpc/setup.c | 4 +
lib/ppc64/asm/mmu.h | 11 ++
lib/ppc64/asm/page.h | 67 -
lib/ppc64/asm/pgtable-hwdef.h | 67 +
lib/ppc64/asm/pgtable.h | 126
lib/ppc64/mmu.c | 273 ++
lib/ppc64/opal-calls.S| 4 +-
powerpc/Makefile.common | 2 +
powerpc/Makefile.ppc64| 1 +
powerpc/interrupts.c | 96 ++--
16 files changed, 684 insertions(+), 27 deletions(-)
create mode 100644 lib/ppc64/asm/mmu.h
create mode 100644 lib/ppc64/asm/pgtable-hwdef.h
create mode 100644 lib/ppc64/asm/pgtable.h
create mode 100644 lib/ppc64/mmu.c
diff --git a/configure b/configure
index 05e6702ea..6907ccbbb 100755
--- a/configure
+++ b/configure
@@ -222,29 +222,35 @@ fi
if [ -z "$page_size" ]; then
if [ "$efi" = 'y' ] && [ "$arch" = "arm64" ]; then
page_size="4096"
-elif [ "$arch" = "arm64" ]; then
+elif [ "$arch" = "arm64" ] || [ "$arch" = "ppc64" ]; then
page_size="65536"
elif [ "$arch" = "arm" ]; then
page_size="4096"
fi
else
-if [ "$arch" != "arm64" ]; then
-echo "--page-size is not supported for $arch"
-usage
-fi
-
if [ "${page_size: -1}" = "K" ] || [ "${page_size: -1}" = "k" ]; then
page_size=$(( ${page_size%?} * 1024 ))
fi
-if [ "$page_size" != "4096" ] && [ "$page_size" != "16384" ] &&
- [ "$page_size" != "65536" ]; then
-echo "arm64 doesn't support page size of $page_size"
+
+if [ "$arch" = "arm64" ]; then
+if [ "$page_size" != "4096" ] && [ "$page_size" != "16384" ] &&
+ [ "$page_size" != "65536" ]; then
+echo "arm64 doesn't support page size of $page_size"
+usage
+fi
+if [ "$efi" = 'y' ] && [ "$page_size" != "4096" ]; then
+echo "efi must use 4K pages"
+exit 1
+fi
+elif [ "$arch" = "ppc64" ]; then
+if [ "$page_size" != "4096" ] && [ "$page_size" != "65536" ]; then
+echo "ppc64 doesn't support page size of $page_size"
+usage
+fi
+else
+echo "--page-size is not supported for $arch"
usage
fi
-if [ "$efi" = 'y' ] && [ "$page_size" != "4096" ]; then
-echo "efi must use 4K pages"
-exit 1
-fi
fi
[ -z "$processor" ] && processor="$arch"
@@ -444,6 +450,13 @@ cat <> lib/config.h
#define CONFIG_UART_EARLY_BASE ${arm_uart_early_addr}
#define CONFIG_ERRATA_FORCE ${errata_force}
+
+EOF
+fi
+
+if [ "$arch" = "arm" ] || [ "$arch" = "arm64" ] || [ "$arch" = "ppc64" ]; then
+cat <> lib/config.h
+
#define CONFIG_PAGE_SIZE _AC(${page_size}, UL)
EOF
diff --git a/lib/powerpc/asm/hcall.h b/lib/powerpc/asm/hcall.h
index e0f5009e3..3b44dd204 100644
--- a/lib/powerpc/asm/hcall.h
+++ b/lib/powerpc/asm/hcall.h
@@ -24,6 +24,12 @@
#define H_PUT_TERM_CHAR0x58
#define H_RANDOM 0x300
#define H_SET_MODE 0x31C
+#define H_REGISTER_PROCESS_TABLE 0x37C
+
+#define PTBL_NEW 0x18
+#define PTBL_UNREGISTER0x10
+#define PTBL_RADIX 0x04
+#define PTBL_GTSE 0x01
#define KVMPPC_HCALL_BASE 0xf000
#define KVMPPC_H_RTAS (KVMPPC_HCALL_BASE + 0x0)
diff --git a/lib/powerpc/asm/processor.h b/lib/powerpc/asm/processor.h
index a3859b5d4..d348239c5 100644
--- a/lib/powerpc/asm/processor.h
+++ b/lib/powerpc/asm/processor.h
@@ -14,6 +14,7 @@ extern bool cpu_has_hv;
extern bool cpu_has_power_mce;
extern bool cpu_has_siar;
extern bool cpu_has_heai;
+extern bool cpu_has_radix;
extern bool cpu_has_prefix;
extern bool cpu_has_sc_lev;
extern bool cpu_has_pause_short;
diff --git a/lib/powerpc/asm/reg.h b/lib/powerpc/asm/reg.h
index 12f9e8ac6..b2fab4313 100644
--- a/lib/powerpc/asm/reg.h
+++ b/lib/powerpc/asm/reg.h
@@ -11,6 +11,7 @@
#define SPR_SRR0 0x01a
#define SPR_SRR1 0x01b
#define SRR1_PREFIX UL(0x2000)
+#define SPR_PIDR 0x030
#define SPR_FSCR 0x099
#define FSCR_PREFIX UL(0x2000)
#define SPR_HFSCR 0x0be
@@ -36,7 +37,9 @@
#define SPR_LPCR 0x13e
#define LPCR_HDICE UL(0x1)
#define LPCR_LD UL(0x2)
+#define SPR_LPIDR 0x13f
#define SPR_HEIR 0x153
+#define SPR_PTCR 0x1d0
#define SPR_MMCR0 0x31b
#define MMCR0_FC UL(0x8000)
#define MMCR0_PMAE UL(0x0400)
diff --git