public inbox for kvm@vger.kernel.org
 help / color / mirror / Atom feed
* [kvm-unit-tests PATCH 0/6] arm: enable MMU
@ 2014-10-30 15:56 Andrew Jones
  2014-10-30 15:57 ` [PATCH 1/6] arm: fix crash on cubietruck Andrew Jones
                   ` (7 more replies)
  0 siblings, 8 replies; 9+ messages in thread
From: Andrew Jones @ 2014-10-30 15:56 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

This first patch of this series fixes a bug caused by attempting
to use spinlocks without enabling the MMU. The next three do some
prep for the fifth, and also fix arm's PAGE_ALIGN. The fifth is
prep for the sixth, which finally turns the MMU on for arm unit
tests.

Andrew Jones (6):
  arm: fix crash on cubietruck
  lib: add ALIGN() macro
  lib: steal const.h from kernel
  arm: apply ALIGN() and const.h to arm files
  arm: import some Linux page table API
  arm: turn on the MMU

 arm/cstart.S                | 33 +++++++++++++++++++++++
 config/config-arm.mak       |  3 ++-
 lib/alloc.c                 |  4 +--
 lib/arm/asm/mmu.h           | 43 ++++++++++++++++++++++++++++++
 lib/arm/asm/page.h          | 43 +++++++++++++++++++++++-------
 lib/arm/asm/pgtable-hwdef.h | 65 +++++++++++++++++++++++++++++++++++++++++++++
 lib/arm/mmu.c               | 53 ++++++++++++++++++++++++++++++++++++
 lib/arm/processor.c         | 11 ++++++++
 lib/arm/setup.c             |  3 +++
 lib/arm/spinlock.c          |  7 +++++
 lib/asm-generic/page.h      | 17 ++++++------
 lib/const.h                 | 11 ++++++++
 lib/libcflat.h              |  4 +++
 13 files changed, 275 insertions(+), 22 deletions(-)
 create mode 100644 lib/arm/asm/mmu.h
 create mode 100644 lib/arm/asm/pgtable-hwdef.h
 create mode 100644 lib/arm/mmu.c
 create mode 100644 lib/const.h

-- 
1.9.3


^ permalink raw reply	[flat|nested] 9+ messages in thread

* [PATCH 1/6] arm: fix crash on cubietruck
  2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
@ 2014-10-30 15:57 ` Andrew Jones
  2014-10-30 15:57 ` [PATCH 2/6] lib: add ALIGN() macro Andrew Jones
                   ` (6 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrew Jones @ 2014-10-30 15:57 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Cubietruck seems to be more sensitive than my Midway when
attempting to use [ldr|str]ex instructions without caches
enabled (mmu disabled). Fix this by making the spinlock
implementation (currently the only user of *ex instructions)
conditional on the mmu being enabled.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/arm/asm/mmu.h  | 11 +++++++++++
 lib/arm/spinlock.c |  7 +++++++
 2 files changed, 18 insertions(+)
 create mode 100644 lib/arm/asm/mmu.h

diff --git a/lib/arm/asm/mmu.h b/lib/arm/asm/mmu.h
new file mode 100644
index 0000000000000..987928b2c432c
--- /dev/null
+++ b/lib/arm/asm/mmu.h
@@ -0,0 +1,11 @@
+#ifndef __ASMARM_MMU_H_
+#define __ASMARM_MMU_H_
+/*
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+
+#define mmu_enabled() (0)
+
+#endif /* __ASMARM_MMU_H_ */
diff --git a/lib/arm/spinlock.c b/lib/arm/spinlock.c
index d8a6d4c3383d6..e2bb1ace43c4e 100644
--- a/lib/arm/spinlock.c
+++ b/lib/arm/spinlock.c
@@ -1,12 +1,19 @@
 #include "libcflat.h"
 #include "asm/spinlock.h"
 #include "asm/barrier.h"
+#include "asm/mmu.h"
 
 void spin_lock(struct spinlock *lock)
 {
 	u32 val, fail;
 
 	dmb();
+
+	if (!mmu_enabled()) {
+		lock->v = 1;
+		return;
+	}
+
 	do {
 		asm volatile(
 		"1:	ldrex	%0, [%2]\n"
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 2/6] lib: add ALIGN() macro
  2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
  2014-10-30 15:57 ` [PATCH 1/6] arm: fix crash on cubietruck Andrew Jones
@ 2014-10-30 15:57 ` Andrew Jones
  2014-10-30 15:57 ` [PATCH 3/6] lib: steal const.h from kernel Andrew Jones
                   ` (5 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrew Jones @ 2014-10-30 15:57 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Add a type-considerate ALIGN[_UP] macro to libcflat, and apply
it to /lib code that can make use of it. This will be used to
fix PAGE_ALIGN on arm, which can be used on phys_addr_t
addresses, which may exceed 32 bits.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/alloc.c            | 4 +---
 lib/asm-generic/page.h | 9 ++++++---
 lib/libcflat.h         | 4 ++++
 3 files changed, 11 insertions(+), 6 deletions(-)

diff --git a/lib/alloc.c b/lib/alloc.c
index 5d55e285dcd1d..1abe4961ae9dd 100644
--- a/lib/alloc.c
+++ b/lib/alloc.c
@@ -7,8 +7,6 @@
 #include "asm/spinlock.h"
 #include "asm/io.h"
 
-#define ALIGN_UP_MASK(x, mask)	(((x) + (mask)) & ~(mask))
-#define ALIGN_UP(x, a)		ALIGN_UP_MASK(x, (typeof(x))(a) - 1)
 #define MIN(a, b)		((a) < (b) ? (a) : (b))
 #define MAX(a, b)		((a) > (b) ? (a) : (b))
 
@@ -70,7 +68,7 @@ static phys_addr_t phys_alloc_aligned_safe(phys_addr_t size,
 
 	spin_lock(&lock);
 
-	addr = ALIGN_UP(base, align);
+	addr = ALIGN(base, align);
 	size += addr - base;
 
 	if ((top_safe - base) < size) {
diff --git a/lib/asm-generic/page.h b/lib/asm-generic/page.h
index 559938fcf0b3f..8602752002f71 100644
--- a/lib/asm-generic/page.h
+++ b/lib/asm-generic/page.h
@@ -16,13 +16,16 @@
 #define PAGE_SIZE		(1 << PAGE_SHIFT)
 #endif
 #define PAGE_MASK		(~(PAGE_SIZE-1))
-#define PAGE_ALIGN(addr)	(((addr) + (PAGE_SIZE-1)) & PAGE_MASK)
 
 #ifndef __ASSEMBLY__
+
+#define PAGE_ALIGN(addr)	ALIGN(addr, PAGE_SIZE)
+
 #define __va(x)			((void *)((unsigned long) (x)))
 #define __pa(x)			((unsigned long) (x))
 #define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
 #define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
-#endif
 
-#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASM_GENERIC_PAGE_H_ */
diff --git a/lib/libcflat.h b/lib/libcflat.h
index a43eba0329f8e..7db29a4f4f3cb 100644
--- a/lib/libcflat.h
+++ b/lib/libcflat.h
@@ -30,6 +30,10 @@
 #define xstr(s) xxstr(s)
 #define xxstr(s) #s
 
+#define __ALIGN_MASK(x, mask)	(((x) + (mask)) & ~(mask))
+#define __ALIGN(x, a)		__ALIGN_MASK(x, (typeof(x))(a) - 1)
+#define ALIGN(x, a)		__ALIGN((x), (a))
+
 typedef uint8_t		u8;
 typedef int8_t		s8;
 typedef uint16_t	u16;
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 3/6] lib: steal const.h from kernel
  2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
  2014-10-30 15:57 ` [PATCH 1/6] arm: fix crash on cubietruck Andrew Jones
  2014-10-30 15:57 ` [PATCH 2/6] lib: add ALIGN() macro Andrew Jones
@ 2014-10-30 15:57 ` Andrew Jones
  2014-10-30 15:57 ` [PATCH 4/6] arm: apply ALIGN() and const.h to arm files Andrew Jones
                   ` (4 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrew Jones @ 2014-10-30 15:57 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

And apply it to /lib files. This prepares for the import of
kernel headers that make use of the const.h macros.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/asm-generic/page.h |  8 +++-----
 lib/const.h            | 11 +++++++++++
 2 files changed, 14 insertions(+), 5 deletions(-)
 create mode 100644 lib/const.h

diff --git a/lib/asm-generic/page.h b/lib/asm-generic/page.h
index 8602752002f71..66c72a62bb0f7 100644
--- a/lib/asm-generic/page.h
+++ b/lib/asm-generic/page.h
@@ -9,12 +9,10 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 
+#include "const.h"
+
 #define PAGE_SHIFT		12
-#ifndef __ASSEMBLY__
-#define PAGE_SIZE		(1UL << PAGE_SHIFT)
-#else
-#define PAGE_SIZE		(1 << PAGE_SHIFT)
-#endif
+#define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK		(~(PAGE_SIZE-1))
 
 #ifndef __ASSEMBLY__
diff --git a/lib/const.h b/lib/const.h
new file mode 100644
index 0000000000000..5cd94d7067541
--- /dev/null
+++ b/lib/const.h
@@ -0,0 +1,11 @@
+#ifndef _CONST_H_
+#define _CONST_H_
+#ifdef __ASSEMBLY__
+#define _AC(X,Y)	X
+#define _AT(T,X)	X
+#else
+#define __AC(X,Y)	(X##Y)
+#define _AC(X,Y)	__AC(X,Y)
+#define _AT(T,X)	((T)(X))
+#endif
+#endif
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 4/6] arm: apply ALIGN() and const.h to arm files
  2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
                   ` (2 preceding siblings ...)
  2014-10-30 15:57 ` [PATCH 3/6] lib: steal const.h from kernel Andrew Jones
@ 2014-10-30 15:57 ` Andrew Jones
  2014-10-30 15:57 ` [PATCH 5/6] arm: import some Linux page table API Andrew Jones
                   ` (3 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrew Jones @ 2014-10-30 15:57 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

This fixes PAGE_ALIGN for greater than 32-bit addresses.
Also fix up some whitespace in lib/arm/asm/page.h

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/arm/asm/page.h | 21 +++++++++++----------
 1 file changed, 11 insertions(+), 10 deletions(-)

diff --git a/lib/arm/asm/page.h b/lib/arm/asm/page.h
index 606d76f5775cf..4602d735b7886 100644
--- a/lib/arm/asm/page.h
+++ b/lib/arm/asm/page.h
@@ -6,16 +6,16 @@
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
 
+#include "const.h"
+
 #define PAGE_SHIFT		12
-#ifndef __ASSEMBLY__
-#define PAGE_SIZE		(1UL << PAGE_SHIFT)
-#else
-#define PAGE_SIZE		(1 << PAGE_SHIFT)
-#endif
+#define PAGE_SIZE		(_AC(1,UL) << PAGE_SHIFT)
 #define PAGE_MASK		(~(PAGE_SIZE-1))
-#define PAGE_ALIGN(addr)	(((addr) + (PAGE_SIZE-1)) & PAGE_MASK)
 
 #ifndef __ASSEMBLY__
+
+#define PAGE_ALIGN(addr)	ALIGN(addr, PAGE_SIZE)
+
 #include <asm/setup.h>
 
 #ifndef __virt_to_phys
@@ -26,8 +26,9 @@
 #define __va(x)			((void *)__phys_to_virt((phys_addr_t)(x)))
 #define __pa(x)			__virt_to_phys((unsigned long)(x))
 
-#define virt_to_pfn(kaddr)      (__pa(kaddr) >> PAGE_SHIFT)
-#define pfn_to_virt(pfn)        __va((pfn) << PAGE_SHIFT)
-#endif
+#define virt_to_pfn(kaddr)	(__pa(kaddr) >> PAGE_SHIFT)
+#define pfn_to_virt(pfn)	__va((pfn) << PAGE_SHIFT)
 
-#endif
+#endif /* __ASSEMBLY__ */
+
+#endif /* _ASMARM_PAGE_H_ */
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 5/6] arm: import some Linux page table API
  2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
                   ` (3 preceding siblings ...)
  2014-10-30 15:57 ` [PATCH 4/6] arm: apply ALIGN() and const.h to arm files Andrew Jones
@ 2014-10-30 15:57 ` Andrew Jones
  2014-10-30 15:57 ` [PATCH 6/6] arm: turn on the MMU Andrew Jones
                   ` (2 subsequent siblings)
  7 siblings, 0 replies; 9+ messages in thread
From: Andrew Jones @ 2014-10-30 15:57 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 lib/arm/asm/page.h          | 22 +++++++++++++++
 lib/arm/asm/pgtable-hwdef.h | 65 +++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 87 insertions(+)
 create mode 100644 lib/arm/asm/pgtable-hwdef.h

diff --git a/lib/arm/asm/page.h b/lib/arm/asm/page.h
index 4602d735b7886..6ff849a0c0e3b 100644
--- a/lib/arm/asm/page.h
+++ b/lib/arm/asm/page.h
@@ -18,6 +18,28 @@
 
 #include <asm/setup.h>
 
+typedef u64 pteval_t;
+typedef u64 pmdval_t;
+typedef u64 pgdval_t;
+typedef struct { pteval_t pte; } pte_t;
+typedef struct { pmdval_t pmd; } pmd_t;
+typedef struct { pgdval_t pgd; } pgd_t;
+typedef struct { pteval_t pgprot; } pgprot_t;
+
+#define pte_val(x)		((x).pte)
+#define pmd_val(x)		((x).pmd)
+#define pgd_val(x)		((x).pgd)
+#define pgprot_val(x)		((x).pgprot)
+
+#define __pte(x)		((pte_t) { (x) } )
+#define __pmd(x)		((pmd_t) { (x) } )
+#define __pgd(x)		((pgd_t) { (x) } )
+#define __pgprot(x)		((pgprot_t) { (x) } )
+
+typedef struct { pgd_t pgd; } pud_t;
+#define pud_val(x)		(pgd_val((x).pgd))
+#define __pud(x)		((pud_t) { __pgd(x) } )
+
 #ifndef __virt_to_phys
 #define __phys_to_virt(x)	((unsigned long) (x))
 #define __virt_to_phys(x)	(x)
diff --git a/lib/arm/asm/pgtable-hwdef.h b/lib/arm/asm/pgtable-hwdef.h
new file mode 100644
index 0000000000000..a2564aaca05a3
--- /dev/null
+++ b/lib/arm/asm/pgtable-hwdef.h
@@ -0,0 +1,65 @@
+#ifndef _ASMARM_PGTABLE_HWDEF_H_
+#define _ASMARM_PGTABLE_HWDEF_H_
+/*
+ * From arch/arm/include/asm/pgtable-3level-hwdef.h
+ */
+
+/*
+ * Hardware page table definitions.
+ *
+ * + Level 1/2 descriptor
+ *   - common
+ */
+#define PMD_TYPE_MASK		(_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_FAULT		(_AT(pmdval_t, 0) << 0)
+#define PMD_TYPE_TABLE		(_AT(pmdval_t, 3) << 0)
+#define PMD_TYPE_SECT		(_AT(pmdval_t, 1) << 0)
+#define PMD_TABLE_BIT		(_AT(pmdval_t, 1) << 1)
+#define PMD_BIT4		(_AT(pmdval_t, 0))
+#define PMD_DOMAIN(x)		(_AT(pmdval_t, 0))
+#define PMD_APTABLE_SHIFT	(61)
+#define PMD_APTABLE		(_AT(pgdval_t, 3) << PGD_APTABLE_SHIFT)
+#define PMD_PXNTABLE		(_AT(pgdval_t, 1) << 59)
+
+/*
+ *   - section
+ */
+#define PMD_SECT_BUFFERABLE	(_AT(pmdval_t, 1) << 2)
+#define PMD_SECT_CACHEABLE	(_AT(pmdval_t, 1) << 3)
+#define PMD_SECT_USER		(_AT(pmdval_t, 1) << 6)		/* AP[1] */
+#define PMD_SECT_AP2		(_AT(pmdval_t, 1) << 7)		/* read only */
+#define PMD_SECT_S		(_AT(pmdval_t, 3) << 8)
+#define PMD_SECT_AF		(_AT(pmdval_t, 1) << 10)
+#define PMD_SECT_nG		(_AT(pmdval_t, 1) << 11)
+#define PMD_SECT_PXN		(_AT(pmdval_t, 1) << 53)
+#define PMD_SECT_XN		(_AT(pmdval_t, 1) << 54)
+#define PMD_SECT_AP_WRITE	(_AT(pmdval_t, 0))
+#define PMD_SECT_AP_READ	(_AT(pmdval_t, 0))
+#define PMD_SECT_AP1		(_AT(pmdval_t, 1) << 6)
+#define PMD_SECT_TEX(x)		(_AT(pmdval_t, 0))
+
+/*
+ * AttrIndx[2:0] encoding (mapping attributes defined in the MAIR* registers).
+ */
+#define PMD_SECT_UNCACHED	(_AT(pmdval_t, 0) << 2)	/* strongly ordered */
+#define PMD_SECT_BUFFERED	(_AT(pmdval_t, 1) << 2)	/* normal non-cacheable */
+#define PMD_SECT_WT		(_AT(pmdval_t, 2) << 2)	/* normal inner write-through */
+#define PMD_SECT_WB		(_AT(pmdval_t, 3) << 2)	/* normal inner write-back */
+#define PMD_SECT_WBWA		(_AT(pmdval_t, 7) << 2)	/* normal inner write-alloc */
+
+/*
+ * + Level 3 descriptor (PTE)
+ */
+#define PTE_TYPE_MASK		(_AT(pteval_t, 3) << 0)
+#define PTE_TYPE_FAULT		(_AT(pteval_t, 0) << 0)
+#define PTE_TYPE_PAGE		(_AT(pteval_t, 3) << 0)
+#define PTE_TABLE_BIT		(_AT(pteval_t, 1) << 1)
+#define PTE_BUFFERABLE		(_AT(pteval_t, 1) << 2)		/* AttrIndx[0] */
+#define PTE_CACHEABLE		(_AT(pteval_t, 1) << 3)		/* AttrIndx[1] */
+#define PTE_AP2			(_AT(pteval_t, 1) << 7)		/* AP[2] */
+#define PTE_EXT_SHARED		(_AT(pteval_t, 3) << 8)		/* SH[1:0], inner shareable */
+#define PTE_EXT_AF		(_AT(pteval_t, 1) << 10)	/* Access Flag */
+#define PTE_EXT_NG		(_AT(pteval_t, 1) << 11)	/* nG */
+#define PTE_EXT_XN		(_AT(pteval_t, 1) << 54)	/* XN */
+
+#endif /* _ASMARM_PGTABLE_HWDEF_H_ */
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* [PATCH 6/6] arm: turn on the MMU
  2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
                   ` (4 preceding siblings ...)
  2014-10-30 15:57 ` [PATCH 5/6] arm: import some Linux page table API Andrew Jones
@ 2014-10-30 15:57 ` Andrew Jones
  2014-10-31 11:43 ` [kvm-unit-tests PATCH 0/6] arm: enable MMU Paolo Bonzini
  2014-11-17 12:26 ` Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Andrew Jones @ 2014-10-30 15:57 UTC (permalink / raw)
  To: kvmarm, kvm; +Cc: christoffer.dall, pbonzini

We should probably always run with the mmu on, so let's
enable it from setup with an identity map.

Signed-off-by: Andrew Jones <drjones@redhat.com>
---
 arm/cstart.S          | 33 ++++++++++++++++++++++++++++++++
 config/config-arm.mak |  3 ++-
 lib/arm/asm/mmu.h     | 34 ++++++++++++++++++++++++++++++++-
 lib/arm/mmu.c         | 53 +++++++++++++++++++++++++++++++++++++++++++++++++++
 lib/arm/processor.c   | 11 +++++++++++
 lib/arm/setup.c       |  3 +++
 6 files changed, 135 insertions(+), 2 deletions(-)
 create mode 100644 lib/arm/mmu.c

diff --git a/arm/cstart.S b/arm/cstart.S
index cc87ece4b6b40..a1ccfb24bb4e0 100644
--- a/arm/cstart.S
+++ b/arm/cstart.S
@@ -72,6 +72,39 @@ halt:
 	b	1b
 
 /*
+ * asm_mmu_enable
+ *   Inputs:
+ *     (r0 - lo, r1 - hi) is the base address of the translation table
+ *   Outputs: none
+ */
+.equ	PRRR,	0xeeaa4400		@ MAIR0 (from Linux kernel)
+.equ	NMRR,	0xff000004		@ MAIR1 (from Linux kernel)
+.globl asm_mmu_enable
+asm_mmu_enable:
+	/* TTBCR */
+	mrc	p15, 0, r2, c2, c0, 2
+	orr	r2, #(1 << 31)		@ TTB_EAE
+	mcr	p15, 0, r2, c2, c0, 2
+
+	/* MAIR */
+	ldr	r2, =PRRR
+	mrc	p15, 0, r2, c10, c2, 0
+	ldr	r2, =NMRR
+	mrc	p15, 0, r2, c10, c2, 1
+
+	/* TTBR0 */
+	mcrr	p15, 0, r0, r1, c2
+
+	/* SCTLR */
+	mrc	p15, 0, r2, c1, c0, 0
+	orr	r2, #CR_C
+	orr	r2, #CR_I
+	orr	r2, #CR_M
+	mcr	p15, 0, r2, c1, c0, 0
+
+	mov     pc, lr
+
+/*
  * Vector stubs
  * Simplified version of the Linux kernel implementation
  *   arch/arm/kernel/entry-armv.S
diff --git a/config/config-arm.mak b/config/config-arm.mak
index 8a274c50332b0..86e1d75169b59 100644
--- a/config/config-arm.mak
+++ b/config/config-arm.mak
@@ -42,7 +42,8 @@ cflatobjs += \
 	lib/arm/io.o \
 	lib/arm/setup.o \
 	lib/arm/spinlock.o \
-	lib/arm/processor.o
+	lib/arm/processor.o \
+	lib/arm/mmu.o
 
 libeabi = lib/arm/libeabi.a
 eabiobjs = lib/arm/eabi_compat.o
diff --git a/lib/arm/asm/mmu.h b/lib/arm/asm/mmu.h
index 987928b2c432c..451c7493c2aba 100644
--- a/lib/arm/asm/mmu.h
+++ b/lib/arm/asm/mmu.h
@@ -5,7 +5,39 @@
  *
  * This work is licensed under the terms of the GNU LGPL, version 2.
  */
+#include "asm/page.h"
+#include "asm/barrier.h"
+#include "alloc.h"
 
-#define mmu_enabled() (0)
+#define PTRS_PER_PGD	4
+#define PGDIR_SHIFT	30
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~((1 << PGDIR_SHIFT) - 1))
+
+#define pgd_free(pgd) free(pgd)
+static inline pgd_t *pgd_alloc(void)
+{
+	pgd_t *pgd = memalign(L1_CACHE_BYTES, PTRS_PER_PGD * sizeof(pgd_t));
+	memset(pgd, 0, PTRS_PER_PGD * sizeof(pgd_t));
+	return pgd;
+}
+
+static inline void local_flush_tlb_all(void)
+{
+	asm volatile("mcr p15, 0, %0, c8, c7, 0" :: "r" (0));
+	dsb();
+	isb();
+}
+
+static inline void flush_tlb_all(void)
+{
+	//TODO
+	local_flush_tlb_all();
+}
+
+extern bool mmu_enabled(void);
+extern void mmu_enable(pgd_t *pgtable);
+extern void mmu_enable_idmap(void);
+extern void mmu_init_io_sect(pgd_t *pgtable);
 
 #endif /* __ASMARM_MMU_H_ */
diff --git a/lib/arm/mmu.c b/lib/arm/mmu.c
new file mode 100644
index 0000000000000..c9d39bf6464b8
--- /dev/null
+++ b/lib/arm/mmu.c
@@ -0,0 +1,53 @@
+/*
+ * MMU enable and page table manipulation functions
+ *
+ * Copyright (C) 2014, Red Hat Inc, Andrew Jones <drjones@redhat.com>
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.
+ */
+#include "asm/setup.h"
+#include "asm/mmu.h"
+#include "asm/pgtable-hwdef.h"
+
+static bool mmu_on;
+static pgd_t idmap[PTRS_PER_PGD] __attribute__((aligned(L1_CACHE_BYTES)));
+
+bool mmu_enabled(void)
+{
+	return mmu_on;
+}
+
+extern void asm_mmu_enable(phys_addr_t pgtable);
+void mmu_enable(pgd_t *pgtable)
+{
+	asm_mmu_enable(__pa(pgtable));
+	flush_tlb_all();
+	mmu_on = true;
+}
+
+void mmu_init_io_sect(pgd_t *pgtable)
+{
+	/*
+	 * mach-virt reserves the first 1G section for I/O
+	 */
+	pgd_val(pgtable[0]) = PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_USER;
+	pgd_val(pgtable[0]) |= PMD_SECT_UNCACHED;
+}
+
+void mmu_enable_idmap(void)
+{
+	unsigned long sect, end;
+
+	mmu_init_io_sect(idmap);
+
+	end = sizeof(long) == 8 || !(PHYS_END >> 32) ? PHYS_END : 0xfffff000;
+
+	for (sect = PHYS_OFFSET & PGDIR_MASK; sect < end; sect += PGDIR_SIZE) {
+		int i = sect >> PGDIR_SHIFT;
+		pgd_val(idmap[i]) = sect;
+		pgd_val(idmap[i]) |= PMD_TYPE_SECT | PMD_SECT_AF | PMD_SECT_USER;
+		pgd_val(idmap[i]) |= PMD_SECT_S | PMD_SECT_WBWA;
+	}
+
+	mmu_enable(idmap);
+}
diff --git a/lib/arm/processor.c b/lib/arm/processor.c
index 382a128edd415..866d11975b23b 100644
--- a/lib/arm/processor.c
+++ b/lib/arm/processor.c
@@ -92,6 +92,17 @@ void do_handle_exception(enum vector v, struct pt_regs *regs)
 
 	printf("Exception frame registers:\n");
 	show_regs(regs);
+	if (v == EXCPTN_DABT) {
+		unsigned long far, fsr;
+		asm volatile("mrc p15, 0, %0, c6, c0, 0": "=r" (far));
+		asm volatile("mrc p15, 0, %0, c5, c0, 0": "=r" (fsr));
+		printf("DFAR: %08lx    DFSR: %08lx\n", far, fsr);
+	} else if (v == EXCPTN_PABT) {
+		unsigned long far, fsr;
+		asm volatile("mrc p15, 0, %0, c6, c0, 2": "=r" (far));
+		asm volatile("mrc p15, 0, %0, c5, c0, 1": "=r" (fsr));
+		printf("IFAR: %08lx    IFSR: %08lx\n", far, fsr);
+	}
 	abort();
 }
 
diff --git a/lib/arm/setup.c b/lib/arm/setup.c
index 3941c9757dcb2..5fa37ca35f383 100644
--- a/lib/arm/setup.c
+++ b/lib/arm/setup.c
@@ -16,6 +16,7 @@
 #include "alloc.h"
 #include "asm/setup.h"
 #include "asm/page.h"
+#include "asm/mmu.h"
 
 extern unsigned long stacktop;
 extern void io_init(void);
@@ -57,6 +58,8 @@ static void mem_init(phys_addr_t freemem_start)
 
 	phys_alloc_init(freemem_start, mem_end - freemem_start);
 	phys_alloc_set_minimum_alignment(SMP_CACHE_BYTES);
+
+	mmu_enable_idmap();
 }
 
 void setup(unsigned long arg __unused, unsigned long id __unused,
-- 
1.9.3


^ permalink raw reply related	[flat|nested] 9+ messages in thread

* Re: [kvm-unit-tests PATCH 0/6] arm: enable MMU
  2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
                   ` (5 preceding siblings ...)
  2014-10-30 15:57 ` [PATCH 6/6] arm: turn on the MMU Andrew Jones
@ 2014-10-31 11:43 ` Paolo Bonzini
  2014-11-17 12:26 ` Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2014-10-31 11:43 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall



On 30/10/2014 16:56, Andrew Jones wrote:
> This first patch of this series fixes a bug caused by attempting
> to use spinlocks without enabling the MMU. The next three do some
> prep for the fifth, and also fix arm's PAGE_ALIGN. The fifth is
> prep for the sixth, which finally turns the MMU on for arm unit
> tests.

Thanks, I'll test this and apply.

Paolo

^ permalink raw reply	[flat|nested] 9+ messages in thread

* Re: [kvm-unit-tests PATCH 0/6] arm: enable MMU
  2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
                   ` (6 preceding siblings ...)
  2014-10-31 11:43 ` [kvm-unit-tests PATCH 0/6] arm: enable MMU Paolo Bonzini
@ 2014-11-17 12:26 ` Paolo Bonzini
  7 siblings, 0 replies; 9+ messages in thread
From: Paolo Bonzini @ 2014-11-17 12:26 UTC (permalink / raw)
  To: Andrew Jones, kvmarm, kvm; +Cc: christoffer.dall

On 30/10/2014 16:56, Andrew Jones wrote:
> This first patch of this series fixes a bug caused by attempting
> to use spinlocks without enabling the MMU. The next three do some
> prep for the fifth, and also fix arm's PAGE_ALIGN. The fifth is
> prep for the sixth, which finally turns the MMU on for arm unit
> tests.
> 
> Andrew Jones (6):
>   arm: fix crash on cubietruck
>   lib: add ALIGN() macro
>   lib: steal const.h from kernel
>   arm: apply ALIGN() and const.h to arm files
>   arm: import some Linux page table API
>   arm: turn on the MMU
> 
>  arm/cstart.S                | 33 +++++++++++++++++++++++
>  config/config-arm.mak       |  3 ++-
>  lib/alloc.c                 |  4 +--
>  lib/arm/asm/mmu.h           | 43 ++++++++++++++++++++++++++++++
>  lib/arm/asm/page.h          | 43 +++++++++++++++++++++++-------
>  lib/arm/asm/pgtable-hwdef.h | 65 +++++++++++++++++++++++++++++++++++++++++++++
>  lib/arm/mmu.c               | 53 ++++++++++++++++++++++++++++++++++++
>  lib/arm/processor.c         | 11 ++++++++
>  lib/arm/setup.c             |  3 +++
>  lib/arm/spinlock.c          |  7 +++++
>  lib/asm-generic/page.h      | 17 ++++++------
>  lib/const.h                 | 11 ++++++++
>  lib/libcflat.h              |  4 +++
>  13 files changed, 275 insertions(+), 22 deletions(-)
>  create mode 100644 lib/arm/asm/mmu.h
>  create mode 100644 lib/arm/asm/pgtable-hwdef.h
>  create mode 100644 lib/arm/mmu.c
>  create mode 100644 lib/const.h
> 

Tested on CubieTruck and applied, thanks.

Paolo

^ permalink raw reply	[flat|nested] 9+ messages in thread

end of thread, other threads:[~2014-11-17 12:27 UTC | newest]

Thread overview: 9+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2014-10-30 15:56 [kvm-unit-tests PATCH 0/6] arm: enable MMU Andrew Jones
2014-10-30 15:57 ` [PATCH 1/6] arm: fix crash on cubietruck Andrew Jones
2014-10-30 15:57 ` [PATCH 2/6] lib: add ALIGN() macro Andrew Jones
2014-10-30 15:57 ` [PATCH 3/6] lib: steal const.h from kernel Andrew Jones
2014-10-30 15:57 ` [PATCH 4/6] arm: apply ALIGN() and const.h to arm files Andrew Jones
2014-10-30 15:57 ` [PATCH 5/6] arm: import some Linux page table API Andrew Jones
2014-10-30 15:57 ` [PATCH 6/6] arm: turn on the MMU Andrew Jones
2014-10-31 11:43 ` [kvm-unit-tests PATCH 0/6] arm: enable MMU Paolo Bonzini
2014-11-17 12:26 ` Paolo Bonzini

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox