Skip to contentSkip to conversation

mini-os: initial ARM support

PATCH Superseded Thomas Leonard 7 participants 75 messages Jul 16, 2014 – Aug 5, 2014

v6 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v6 cover mini-os: initial ARM support

This series is based on Karim's ARM support commits, further broken up into smaller patches.

The comments from last time should be addressed now, plus a few other things:

- The series is rebased on staging, dropping patches that have already been applied.

- The changes have been further split into smaller patches to ease reviewing. Note that the build system isn't changed to allow building the new code until patch 13.

- Define BUG to cause an undefined instruction fault. This lets us us dump the registers.

- Renamed stack to _boot_stack for clarity.

- Include kernel.h from arm/os.h. This is for consistency with x86/os.h and is needed to compile with lwIP.

- Moved SVC stack to first 16KB of RAM (provides some protection against stack overlow corrupting memory).

- Put translation table in second 16KB (simplifies boot code).

- Moved shared_info_page and irqstack to .bss section (smaller image).

- Moved __bss_start and _edata inside section in linker script. The linker adds non-listed sections, such as .got, just before .bss. This meant that we accidentally zeroed those out too.

- Enable floating point unit.

- Require only minimum FDT property lengths (requested by Ian Campbell).

Addressed Julien Grall's comments:

- Get hypercall numbers from xen.h.
- Avoid duplicating the definition of _start's virtual address.
- Moved definition of physical_address_offset from asm to C.
- Added paddr_t type to represent physical addresses.
- Added comments explaining the lengths when checking FDT properties.
- Fixed (commented) DEBUG macro.
- Drop check for arm,cortex-a9-gic.

There are two assumptions the code makes that may need changing in the future, but which hopefully don't need to hold up this initial support:

- The assumption that the kernel will be loaded at start of RAM + 0x8000.

- The assumption that Xen will mark the GIC address range as device memory. This should probably be fixed when the C code gains the ability to control the translation tables, map 4K pages, etc.

Karim Raslan (3):
mini-os: headers for ARM
mini-os: import libfdt
mini-os: arm: events

Thomas Leonard (11):
mini-os: x86_64: make thread stacks 16-byte aligned
mini-os: don't include lib.h from mm.h
mini-os: added HYPERVISOR_xsm_op
mini-os: use generic local_irq_enable function
mini-os: arm: boot code
mini-os: arm: memory management
mini-os: arm: scheduling
mini-os: arm: time
mini-os: arm: interrupt controller
mini-os: arm: build system
mini-os: arm: show registers, stack and exception vector on fault

 extras/mini-os/ARM-TODO.txt                      |    5 +
 extras/mini-os/COPYING                           |   27 +
 extras/mini-os/Config.mk                         |    2 +
 extras/mini-os/Makefile                          |   22 +
 extras/mini-os/arch/arm/Makefile                 |   32 +
 extras/mini-os/arch/arm/arch.mk                  |    7 +
 extras/mini-os/arch/arm/arm32.S                  |  294 +++++
 extras/mini-os/arch/arm/events.c                 |   31 +
 extras/mini-os/arch/arm/gic.c                    |  232 ++++
 extras/mini-os/arch/arm/hypercalls32.S           |   64 +
 extras/mini-os/arch/arm/minios-arm32.lds         |   79 ++
 extras/mini-os/arch/arm/mm.c                     |  138 ++
 extras/mini-os/arch/arm/panic.c                  |   98 ++
 extras/mini-os/arch/arm/sched.c                  |   38 +
 extras/mini-os/arch/arm/setup.c                  |  119 ++
 extras/mini-os/arch/arm/time.c                   |  202 +++
 extras/mini-os/arch/x86/sched.c                  |    3 +
 extras/mini-os/events.c                          |    4 +-
 extras/mini-os/include/arm/arch_endian.h         |    7 +
 extras/mini-os/include/arm/arch_limits.h         |    9 +
 extras/mini-os/include/arm/arch_mm.h             |   38 +
 extras/mini-os/include/arm/arch_sched.h          |   19 +
 extras/mini-os/include/arm/arch_spinlock.h       |   36 +
 extras/mini-os/include/arm/arm32/arch_wordsize.h |    1 +
 extras/mini-os/include/arm/gic.h                 |    1 +
 extras/mini-os/include/arm/hypercall-arm.h       |   98 ++
 extras/mini-os/include/arm/os.h                  |  216 ++++
 extras/mini-os/include/arm/traps.h               |   20 +
 extras/mini-os/include/fdt.h                     |   60 +
 extras/mini-os/include/hypervisor.h              |    2 +
 extras/mini-os/include/lib.h                     |    4 +-
 extras/mini-os/include/libfdt.h                  | 1478 ++++++++++++++++++++++
 extras/mini-os/include/libfdt_env.h              |   37 +
 extras/mini-os/include/mm.h                      |    5 +-
 extras/mini-os/include/types.h                   |   10 +-
 extras/mini-os/include/x86/os.h                  |    7 +
 extras/mini-os/kernel.c                          |    2 +-
 extras/mini-os/lib/fdt/fdt.c                     |  222 ++++
 extras/mini-os/lib/fdt/fdt_empty_tree.c          |   84 ++
 extras/mini-os/lib/fdt/fdt_ro.c                  |  574 +++++++++
 extras/mini-os/lib/fdt/fdt_rw.c                  |  492 +++++++
 extras/mini-os/lib/fdt/fdt_strerror.c            |   96 ++
 extras/mini-os/lib/fdt/fdt_sw.c                  |  256 ++++
 extras/mini-os/lib/fdt/fdt_wip.c                 |  118 ++
 extras/mini-os/lib/fdt/libfdt_internal.h         |   95 ++
 extras/mini-os/lib/memmove.c                     |   45 +
 extras/mini-os/lib/string.c                      |   12 +
 extras/mini-os/lock.c                            |    1 +
 extras/mini-os/main.c                            |    1 +
 extras/mini-os/tpmfront.c                        |    1 +
 50 files changed, 5433 insertions(+), 11 deletions(-)
 create mode 100644 extras/mini-os/ARM-TODO.txt
 create mode 100755 extras/mini-os/arch/arm/Makefile
 create mode 100644 extras/mini-os/arch/arm/arch.mk
 create mode 100644 extras/mini-os/arch/arm/arm32.S
 create mode 100644 extras/mini-os/arch/arm/events.c
 create mode 100644 extras/mini-os/arch/arm/gic.c
 create mode 100644 extras/mini-os/arch/arm/hypercalls32.S
 create mode 100755 extras/mini-os/arch/arm/minios-arm32.lds
 create mode 100644 extras/mini-os/arch/arm/mm.c
 create mode 100644 extras/mini-os/arch/arm/panic.c
 create mode 100644 extras/mini-os/arch/arm/sched.c
 create mode 100644 extras/mini-os/arch/arm/setup.c
 create mode 100644 extras/mini-os/arch/arm/time.c
 create mode 100644 extras/mini-os/include/arm/arch_endian.h
 create mode 100644 extras/mini-os/include/arm/arch_limits.h
 create mode 100644 extras/mini-os/include/arm/arch_mm.h
 create mode 100644 extras/mini-os/include/arm/arch_sched.h
 create mode 100755 extras/mini-os/include/arm/arch_spinlock.h
 create mode 100644 extras/mini-os/include/arm/arm32/arch_wordsize.h
 create mode 100644 extras/mini-os/include/arm/gic.h
 create mode 100644 extras/mini-os/include/arm/hypercall-arm.h
 create mode 100644 extras/mini-os/include/arm/os.h
 create mode 100644 extras/mini-os/include/arm/traps.h
 create mode 100644 extras/mini-os/include/fdt.h
 create mode 100644 extras/mini-os/include/libfdt.h
 create mode 100644 extras/mini-os/include/libfdt_env.h
 create mode 100644 extras/mini-os/lib/fdt/fdt.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_empty_tree.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_ro.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_rw.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_strerror.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_sw.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_wip.c
 create mode 100644 extras/mini-os/lib/fdt/libfdt_internal.h
 create mode 100644 extras/mini-os/lib/memmove.c
Signature · 1 line
2.0.1
#1 lore raw

PATCH v6 1/14 mini-os: x86_64: make thread stacks 16-byte aligned

Otherwise, passing doubles to varargs functions causes a crash.

---
 extras/mini-os/arch/x86/sched.c | 3 +++
 1 file changed, 3 insertions(+)
extras/mini-os/arch/x86/sched.c +3 -0
index 8a05b58..e4a3dc2 100644
@@ -107,6 +107,9 @@ struct thread* arch_create_thread(char *name, void (*function)(void *),
     thread->sp = (unsigned long)thread->stack + STACK_SIZE;
     /* Save pointer to the thread on the stack, used by current macro */
     *((unsigned long *)thread->stack) = (unsigned long)thread;
+
+    /* Must ensure that (%rsp + 8) is 16-byte aligned at the start of thread_starter. */
+    thread->sp -= sizeof(unsigned long);
     
     stack_push(thread, (unsigned long) function);
     stack_push(thread, (unsigned long) data);
Signature · 1 line
2.0.1
#2 lore raw

Re: [PATCH ARM v6 01/14] mini-os: x86_64: make thread stacks 16-byte aligned

Quoted 5 lines · Thomas Leonard

Otherwise, passing doubles to varargs functions causes a crash.

+ /* Must ensure that (%rsp + 8) is 16-byte aligned at the start of thread_starter. */

Is this really effectively a requirement for the stack to start out misaligned? Or am I misinterpreting it?

Assuming I'm not reading it wrong is this some weird architectural quirk which I've forgotten about or is it something to do with the behaviour of thread_starter?

In either case, but especially the latter, I think it would be good to explain more fully in the comment how this need arises.

...

So, reading the asm code it seems that x86_64 thread_starter will pop 2*quad words and push one, undoing the misalignment you've set up here. A comment there pointing to this setup here would be good at a minimum, but an even better fix would be to add a dummy push at that point keeping both halves of this equation in the same place in that one function making it responsible for maintaining the invariant.

Ian.

Quoted 4 lines
+    thread->sp -= sizeof(unsigned long);
     
     stack_push(thread, (unsigned long) function);
     stack_push(thread, (unsigned long) data);
#3 lore raw

Re: [PATCH ARM v6 01/14] mini-os: x86_64: make thread stacks 16-byte aligned

Quoted 9 lines · Ian Campbell, le Thu 17 Jul 2014 16:50:25 +0100, a écrit :
Quoted 5 lines · Thomas Leonard

Otherwise, passing doubles to varargs functions causes a crash.

+ /* Must ensure that (%rsp + 8) is 16-byte aligned at the start of thread_starter. */

Is this really effectively a requirement for the stack to start out misaligned?

Yes. From the x86_64 ABI pdf I have here:

“
The end of the input argument area shall be aligned on a 16 byte boundary. In other words, the value (%rsp - 8) is always a multiple of 16 when control is transferred to the function entry point.
”

So the proposed comment is exactly the ABI requirement. Maybe it should even say

/* x86_64 ABI requires that (%rsp + 8) is 16-byte aligned at the start of thread_starter. */

Samuel

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#4 lore raw

Re: [PATCH ARM v6 01/14] mini-os: x86_64: make thread stacks 16-byte aligned

Quoted 13 lines · Samuel Thibault
Quoted 9 lines · Ian Campbell, le Thu 17 Jul 2014 16:50:25 +0100, a écrit :
Quoted 5 lines · Thomas Leonard

Otherwise, passing doubles to varargs functions causes a crash.

+ /* Must ensure that (%rsp + 8) is 16-byte aligned at the start of thread_starter. */

Is this really effectively a requirement for the stack to start out misaligned?

Yes. From the x86_64 ABI pdf I have here:

Quoted 7 lines

“
The end of the input argument area shall be aligned on a 16 byte boundary. In other words, the value (%rsp - 8) is always a multiple of 16 when control is transferred to the function entry point.
”

So the proposed comment is exactly the ABI requirement.

I see. How exciting!

I suppose this comes from the stack normally being 16-byte aligned but the actual call to the function adding another 8 by pushing the return address, so on funciton entry you are "misaligned" by 8 bytes. So this offset is accounting for the fact that thread_starter is (in effect) entered with a jmp and not a call.

Quoted 4 lines

Maybe it should
even say

/* x86_64 ABI requires that (%rsp + 8) is 16-byte aligned at the start of thread_starter. */

With your explanation I'm happy with whatever you are happy with ;-)

Ian.

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

#5 lore raw

Re: [PATCH ARM v6 01/14] mini-os: x86_64: make thread stacks 16-byte aligned

Quoted 3 lines · Ian Campbell, le Fri 18 Jul 2014 11:00:45 +0100, a écrit :

I suppose this comes from the stack normally being 16-byte aligned but the actual call to the function adding another 8 by pushing the return address, so on funciton entry you are "misaligned" by 8 bytes.

Yes.

Samuel

Acked-by on v6 1/14
#6 lore raw

Re: [PATCH ARM v6 01/14] mini-os: x86_64: make thread stacks 16-byte aligned

In reply to Thomas Leonard
Quoted 3 lines · Thomas Leonard, le Wed 16 Jul 2014 12:07:41 +0100, a écrit :

Otherwise, passing doubles to varargs functions causes a crash.

Quoted 21 lines
---
 extras/mini-os/arch/x86/sched.c | 3 +++
 1 file changed, 3 insertions(+)
extras/mini-os/arch/x86/sched.c +3 -0
index 8a05b58..e4a3dc2 100644
@@ -107,6 +107,9 @@ struct thread* arch_create_thread(char *name, void (*function)(void *),
     thread->sp = (unsigned long)thread->stack + STACK_SIZE;
     /* Save pointer to the thread on the stack, used by current macro */
     *((unsigned long *)thread->stack) = (unsigned long)thread;
+
+    /* Must ensure that (%rsp + 8) is 16-byte aligned at the start of thread_starter. */
+    thread->sp -= sizeof(unsigned long);
 
     stack_push(thread, (unsigned long) function);
     stack_push(thread, (unsigned long) data);
Signature · 1 line
2.0.1
Signature · 3 lines
Samuel
<m> argh, pi est plus grand que 2. Ca casse tout
 -+- #ens-mim -+-
#7 lore raw

PATCH v6 2/14 mini-os: don't include lib.h from mm.h

In reply to Thomas Leonard

This breaks the include cycle hypervisor.h -> hypercall-x86_32.h -> mm.h -> lib.h -> gntmap.h -> os.h -> hypervisor.h.

---
 extras/mini-os/include/mm.h | 3 +--
 extras/mini-os/lock.c       | 1 +
 extras/mini-os/main.c       | 1 +
 extras/mini-os/tpmfront.c   | 1 +
 4 files changed, 4 insertions(+), 2 deletions(-)
extras/mini-os/include/mm.h +1 -2
index a94cd6d..a177251 100644
@@ -32,8 +32,7 @@
 #else
 #error "Unsupported architecture"
 #endif
-
-#include <mini-os/lib.h>
+#include <xen/xen.h>
 
 #include <mini-os/arch_limits.h>
 #include <mini-os/arch_mm.h>
extras/mini-os/lock.c +1 -0
index 71a4971..61194e5 100644
@@ -9,6 +9,7 @@
 #include <sys/lock.h>
 #include <sched.h>
 #include <wait.h>
+#include <mini-os/lib.h>
 
 int ___lock_init(_LOCK_T *lock)
 {
extras/mini-os/main.c +1 -0
index aec0586..4ec40b5 100644
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <xenbus.h>
 #include <events.h>
+#include <mini-os/lib.h>
 
 extern int main(int argc, char *argv[], char *envp[]);
 extern void __libc_init_array(void);
extras/mini-os/tpmfront.c +1 -0
index ce5b3e1..6049244 100644
@@ -31,6 +31,7 @@
 #include <xen/io/xenbus.h>
 #include <xen/io/tpmif.h>
 #include <mini-os/tpmfront.h>
+#include <mini-os/lib.h>
 #include <fcntl.h>
 
 //#define TPMFRONT_PRINT_DEBUG
Signature · 1 line
2.0.1
#8 lore raw

Re: [PATCH ARM v6 02/14] mini-os: don't include lib.h from mm.h

Quoted 2 lines · Thomas Leonard

This breaks the include cycle hypervisor.h -> hypercall-x86_32.h -> mm.h -> lib.h -> gntmap.h -> os.h -> hypervisor.h.

I've just realised this is missing an include in tpm_tis.c (which isn't built by default). Fixed patch attached.

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

From 98705b128feb2e46272c4d29205f384899108704 Mon Sep 17 00:00:00 2001
From: Thomas Leonard <[email protected]>
Date: Mon, 7 Jul 2014 13:20:43 +0100
Subject: [PATCH] mini-os: don't include lib.h from mm.h

This breaks the include cycle hypervisor.h -> hypercall-x86_32.h -> mm.h -> lib.h -> gntmap.h -> os.h -> hypervisor.h.

---

- Added missing #include <mini-os/lib.h> to tpm_tis.c

---
 extras/mini-os/include/mm.h | 3 +--
 extras/mini-os/lock.c       | 1 +
 extras/mini-os/main.c       | 1 +
 extras/mini-os/tpm_tis.c    | 1 +
 extras/mini-os/tpmfront.c   | 1 +
 5 files changed, 5 insertions(+), 2 deletions(-)
extras/mini-os/include/mm.h +1 -2
index a94cd6d..a177251 100644
@@ -32,8 +32,7 @@
 #else
 #error "Unsupported architecture"
 #endif
-
-#include <mini-os/lib.h>
+#include <xen/xen.h>
 
 #include <mini-os/arch_limits.h>
 #include <mini-os/arch_mm.h>
extras/mini-os/lock.c +1 -0
index 71a4971..61194e5 100644
@@ -9,6 +9,7 @@
 #include <sys/lock.h>
 #include <sched.h>
 #include <wait.h>
+#include <mini-os/lib.h>
 
 int ___lock_init(_LOCK_T *lock)
 {
extras/mini-os/main.c +1 -0
index aec0586..4ec40b5 100644
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <xenbus.h>
 #include <events.h>
+#include <mini-os/lib.h>
 
 extern int main(int argc, char *argv[], char *envp[]);
 extern void __libc_init_array(void);
extras/mini-os/tpm_tis.c +1 -0
index e8ca69f..09234e5 100644
@@ -26,6 +26,7 @@
 #include <mini-os/events.h>
 #include <mini-os/wait.h>
 #include <mini-os/xmalloc.h>
+#include <mini-os/lib.h>
 #include <errno.h>
 #include <stdbool.h>
 
extras/mini-os/tpmfront.c +1 -0
index ce5b3e1..6049244 100644
@@ -31,6 +31,7 @@
 #include <xen/io/xenbus.h>
 #include <xen/io/tpmif.h>
 #include <mini-os/tpmfront.h>
+#include <mini-os/lib.h>
 #include <fcntl.h>
 
 //#define TPMFRONT_PRINT_DEBUG
Signature · 1 line
2.0.1

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

Acked-by
#9 lore raw

Re: [PATCH ARM v6 02/14] mini-os: don't include lib.h from mm.h

Quoted 6 lines · Thomas Leonard
Quoted 2 lines · Thomas Leonard

This breaks the include cycle hypervisor.h -> hypercall-x86_32.h -> mm.h -> lib.h -> gntmap.h -> os.h -> hypervisor.h.

I've just realised this is missing an include in tpm_tis.c (which isn't built by default). Fixed patch attached.

This version looks good to me:

Ian.

#10 lore raw

Re: [PATCH ARM v6 02/14] mini-os: don't include lib.h from mm.h

In reply to Thomas Leonard
Quoted 6 lines · Thomas Leonard, le Wed 16 Jul 2014 14:30:43 +0100, a écrit :
Quoted 2 lines · Thomas Leonard

This breaks the include cycle hypervisor.h -> hypercall-x86_32.h -> mm.h -> lib.h -> gntmap.h -> os.h -> hypervisor.h.

I've just realised this is missing an include in tpm_tis.c (which isn't built by default). Fixed patch attached.

Quoted 92 lines
Signature · 25 lines
-- 
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

From 98705b128feb2e46272c4d29205f384899108704 Mon Sep 17 00:00:00 2001
From: Thomas Leonard <[email protected]>
Date: Mon, 7 Jul 2014 13:20:43 +0100
Subject: [PATCH] mini-os: don't include lib.h from mm.h

This breaks the include cycle hypervisor.h -> hypercall-x86_32.h -> mm.h
-> lib.h -> gntmap.h -> os.h -> hypervisor.h.

Signed-off-by: Thomas Leonard <[email protected]>

---

- Added missing #include <mini-os/lib.h> to tpm_tis.c
---
 extras/mini-os/include/mm.h | 3 +--
 extras/mini-os/lock.c       | 1 +
 extras/mini-os/main.c       | 1 +
 extras/mini-os/tpm_tis.c    | 1 +
 extras/mini-os/tpmfront.c   | 1 +
 5 files changed, 5 insertions(+), 2 deletions(-)
extras/mini-os/include/mm.h +1 -2
index a94cd6d..a177251 100644
@@ -32,8 +32,7 @@
 #else
 #error "Unsupported architecture"
 #endif
-
-#include <mini-os/lib.h>
+#include <xen/xen.h>
 
 #include <mini-os/arch_limits.h>
 #include <mini-os/arch_mm.h>
extras/mini-os/lock.c +1 -0
index 71a4971..61194e5 100644
@@ -9,6 +9,7 @@
 #include <sys/lock.h>
 #include <sched.h>
 #include <wait.h>
+#include <mini-os/lib.h>
 
 int ___lock_init(_LOCK_T *lock)
 {
extras/mini-os/main.c +1 -0
index aec0586..4ec40b5 100644
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <xenbus.h>
 #include <events.h>
+#include <mini-os/lib.h>
 
 extern int main(int argc, char *argv[], char *envp[]);
 extern void __libc_init_array(void);
extras/mini-os/tpm_tis.c +1 -0
index e8ca69f..09234e5 100644
@@ -26,6 +26,7 @@
 #include <mini-os/events.h>
 #include <mini-os/wait.h>
 #include <mini-os/xmalloc.h>
+#include <mini-os/lib.h>
 #include <errno.h>
 #include <stdbool.h>
 
extras/mini-os/tpmfront.c +1 -0
index ce5b3e1..6049244 100644
@@ -31,6 +31,7 @@
 #include <xen/io/xenbus.h>
 #include <xen/io/tpmif.h>
 #include <mini-os/tpmfront.h>
+#include <mini-os/lib.h>
 #include <fcntl.h>
 
 //#define TPMFRONT_PRINT_DEBUG
Signature · 1 line
2.0.1
Signature · 3 lines
Samuel
<d> bah à défaut de ligne TGV, ils ont un GR
 -+- #ens-mim - comment ça, paumé ?! -+-
#11 lore raw

PATCH v6 3/14 mini-os: added HYPERVISOR_xsm_op

In reply to Thomas Leonard

Avoids using _hypercall1 in events.c.

---
 extras/mini-os/events.c         | 4 ++--
 extras/mini-os/include/x86/os.h | 7 +++++++
 2 files changed, 9 insertions(+), 2 deletions(-)
extras/mini-os/events.c +2 -2
index 48742de..2a23042 100644
@@ -245,7 +245,7 @@ int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size)
     op.cmd = FLASK_GET_PEER_SID;
     op.interface_version = XEN_FLASK_INTERFACE_VERSION;
     op.u.peersid.evtchn = local_port;
-    rc = _hypercall1(int, xsm_op, &op);
+    rc = HYPERVISOR_xsm_op(&op);
     if (rc)
         return rc;
     sid = op.u.peersid.sid;
@@ -253,7 +253,7 @@ int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size)
     op.u.sid_context.sid = sid;
     op.u.sid_context.size = size;
     set_xen_guest_handle(op.u.sid_context.context, ctx);
-    rc = _hypercall1(int, xsm_op, &op);
+    rc = HYPERVISOR_xsm_op(&op);
     return rc;
 }
 
extras/mini-os/include/x86/os.h +7 -0
index 192b23cd..7a1bdc5 100644
@@ -15,6 +15,7 @@
 #include <mini-os/types.h>
 #include <mini-os/hypervisor.h>
 #include <mini-os/kernel.h>
+#include <xen/xsm/flask_op.h>
 
 #define USED    __attribute__ ((used))
 
@@ -558,6 +559,12 @@ static __inline__ int synch_var_test_bit(int nr, volatile void * addr)
  synch_const_test_bit((nr),(addr)) : \
  synch_var_test_bit((nr),(addr)))
 
+static inline int
+HYPERVISOR_xsm_op(
+	struct xen_flask_op *op)
+{
+	return _hypercall1(int, xsm_op, op);
+}
 
 #undef ADDR
 
Signature · 1 line
2.0.1
#12 lore raw

PATCH v6 4/14 mini-os: headers for ARM

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

Adds header files for future ARM support.
Based on work by Karim Allah Ahmed.

---

Since v5:

Define BUG to cause an undefined instruction fault. This will let us dump the registers.

Renamed stack to _boot_stack for clarity.

Include kernel.h from arm/os.h. This is for consistency with x86/os.h and is needed to compile with lwIP.

Added paddr_t type to represent physical addresses (requested by Julien Grall).

---
 extras/mini-os/include/arm/arch_endian.h         |   7 +
 extras/mini-os/include/arm/arch_limits.h         |   9 +
 extras/mini-os/include/arm/arch_mm.h             |  38 ++++
 extras/mini-os/include/arm/arch_sched.h          |  19 ++
 extras/mini-os/include/arm/arch_spinlock.h       |  36 ++++
 extras/mini-os/include/arm/arm32/arch_wordsize.h |   1 +
 extras/mini-os/include/arm/gic.h                 |   1 +
 extras/mini-os/include/arm/hypercall-arm.h       |  98 ++++++++++
 extras/mini-os/include/arm/os.h                  | 216 +++++++++++++++++++++++
 extras/mini-os/include/arm/traps.h               |  20 +++
 extras/mini-os/include/hypervisor.h              |   2 +
 extras/mini-os/include/mm.h                      |   2 +
 extras/mini-os/include/types.h                   |  10 +-
 13 files changed, 454 insertions(+), 5 deletions(-)
 create mode 100644 extras/mini-os/include/arm/arch_endian.h
 create mode 100644 extras/mini-os/include/arm/arch_limits.h
 create mode 100644 extras/mini-os/include/arm/arch_mm.h
 create mode 100644 extras/mini-os/include/arm/arch_sched.h
 create mode 100755 extras/mini-os/include/arm/arch_spinlock.h
 create mode 100644 extras/mini-os/include/arm/arm32/arch_wordsize.h
 create mode 100644 extras/mini-os/include/arm/gic.h
 create mode 100644 extras/mini-os/include/arm/hypercall-arm.h
 create mode 100644 extras/mini-os/include/arm/os.h
 create mode 100644 extras/mini-os/include/arm/traps.h
extras/mini-os/include/arm/arch_endian.h new file +7 -0
new file mode 100644
index 0000000..0771683
@@ -0,0 +1,7 @@
+#ifndef	ARCH_ENDIAN_H
+#error "Do not include arch_endian by itself, include endian.h"
+#else
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+#endif
extras/mini-os/include/arm/arch_limits.h new file +9 -0
new file mode 100644
index 0000000..bae99e1
@@ -0,0 +1,9 @@
+#ifndef __ARCH_LIMITS_H__
+#define __ARCH_LIMITS_H__
+
+#include <mm.h>
+
+#define __STACK_SIZE_PAGE_ORDER  2
+#define __STACK_SIZE (4 * PAGE_SIZE)
+
+#endif
extras/mini-os/include/arm/arch_mm.h new file +38 -0
new file mode 100644
index 0000000..8e10e4b
@@ -0,0 +1,38 @@
+#ifndef _ARCH_MM_H_
+#define _ARCH_MM_H_
+
+typedef unsigned long paddr_t;
+
+extern char _text, _etext, _erodata, _edata, _end, __bss_start;
+extern int _boot_stack[];
+extern int _boot_stack_end[];
+extern int physical_address_offset;	/* Add this to a virtual address to get the physical address (wraps) */
+
+#define PAGE_SHIFT        12
+#define PAGE_SIZE        (1 << PAGE_SHIFT)
+#define PAGE_MASK       (~(PAGE_SIZE-1))
+
+#define L1_PAGETABLE_SHIFT      12
+
+#define to_phys(x)                 ((paddr_t)(x)+physical_address_offset)
+#define to_virt(x)                 ((void *)((paddr_t)(x)-physical_address_offset))
+
+#define PFN_UP(x)    (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
+#define PFN_DOWN(x)    ((x) >> L1_PAGETABLE_SHIFT)
+#define PFN_PHYS(x)    ((uint64_t)(x) << L1_PAGETABLE_SHIFT)
+#define PHYS_PFN(x)    ((x) >> L1_PAGETABLE_SHIFT)
+
+#define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
+#define virt_to_mfn(_virt)         (PFN_DOWN(to_phys(_virt)))
+#define mfn_to_virt(_mfn)          (to_virt(PFN_PHYS(_mfn)))
+#define pfn_to_virt(_pfn)          (to_virt(PFN_PHYS(_pfn)))
+
+#define mfn_to_pfn(x) (x)
+#define pfn_to_mfn(x) (x)
+
+#define virtual_to_mfn(_virt)	   virt_to_mfn(_virt)
+
+// FIXME
+#define map_frames(f, n) (NULL)
+
+#endif
extras/mini-os/include/arm/arch_sched.h new file +19 -0
new file mode 100644
index 0000000..de3ac02
@@ -0,0 +1,19 @@
+#ifndef __ARCH_SCHED_H__
+#define __ARCH_SCHED_H__
+
+#include "arch_limits.h"
+
+static inline struct thread* get_current(void)
+{
+    struct thread **current;
+    unsigned long sp;
+    __asm__ __volatile__ ("mov %0, sp":"=r"(sp));
+    current = (void *)(unsigned long)(sp & ~(__STACK_SIZE-1));
+    return *current;
+}
+
+void __arch_switch_threads(unsigned long *prevctx, unsigned long *nextctx);
+
+#define arch_switch_threads(prev,next) __arch_switch_threads(&(prev)->sp, &(next)->sp)
+
+#endif /* __ARCH_SCHED_H__ */
extras/mini-os/include/arm/arch_spinlock.h new file +36 -0
new file mode 100755
index 0000000..dccb9fc
@@ -0,0 +1,36 @@
+#ifndef __ARCH_ASM_SPINLOCK_H
+#define __ARCH_ASM_SPINLOCK_H
+
+#include "os.h"
+
+#define ARCH_SPIN_LOCK_UNLOCKED { 1 }
+
+/*
+ * Simple spin lock operations.  There are two variants, one clears IRQ's
+ * on the local processor, one does not.
+ *
+ * We make no fairness assumptions. They have a cost.
+ */
+
+#define arch_spin_is_locked(x)    (*(volatile signed char *)(&(x)->slock) <= 0)
+#define arch_spin_unlock_wait(x) do { barrier(); } while(spin_is_locked(x))
+
+static inline void _raw_spin_unlock(spinlock_t *lock)
+{
+    xchg(&lock->slock, 1);
+}
+
+static inline int _raw_spin_trylock(spinlock_t *lock)
+{
+    return xchg(&lock->slock, 0) != 0 ? 1 : 0;
+}
+
+static inline void _raw_spin_lock(spinlock_t *lock)
+{
+    volatile int was_locked;
+    do {
+        was_locked = xchg(&lock->slock, 0) == 0 ? 1 : 0;
+    } while(was_locked);
+}
+
+#endif
extras/mini-os/include/arm/arm32/arch_wordsize.h new file +1 -0
new file mode 100644
index 0000000..b47eee9
@@ -0,0 +1 @@
+#define __WORDSIZE 32
extras/mini-os/include/arm/gic.h new file +1 -0
new file mode 100644
index 0000000..cead2e5
@@ -0,0 +1 @@
+void gic_init(void);
extras/mini-os/include/arm/hypercall-arm.h new file +98 -0

98 lines not on this page · raw message

extras/mini-os/include/arm/os.h new file +216 -0

216 lines not on this page · raw message

extras/mini-os/include/arm/traps.h new file +20 -0
new file mode 100644
index 0000000..704df22
@@ -0,0 +1,20 @@
+#ifndef _TRAPS_H_
+#define _TRAPS_H_
+
+struct pt_regs {
+    unsigned long r0;
+    unsigned long r1;
+    unsigned long r2;
+    unsigned long r3;
+    unsigned long r4;
+    unsigned long r5;
+    unsigned long r6;
+    unsigned long r7;
+    unsigned long r8;
+    unsigned long r9;
+    unsigned long r10;
+    unsigned long r11;
+    unsigned long r12;
+};
+
+#endif
extras/mini-os/include/hypervisor.h +2 -0
index a62cb78..21b3566 100644
@@ -18,6 +18,8 @@
 #include <hypercall-x86_32.h>
 #elif defined(__x86_64__)
 #include <hypercall-x86_64.h>
+#elif defined(__arm__) || defined(__aarch64__)
+#include <hypercall-arm.h>
 #else
 #error "Unsupported architecture"
 #endif
extras/mini-os/include/mm.h +2 -0
index a177251..f57d8ab 100644
@@ -29,6 +29,8 @@
 #include <xen/arch-x86_32.h>
 #elif defined(__x86_64__)
 #include <xen/arch-x86_64.h>
+#elif defined(__arm__) || defined(__aarch64__)
+#include <xen/arch-arm.h>
 #else
 #error "Unsupported architecture"
 #endif
extras/mini-os/include/types.h +5 -5
index 93356fe..be9f1d3 100644
@@ -27,7 +27,7 @@ typedef unsigned char       u_char;
 typedef unsigned int        u_int;
 typedef unsigned long       u_long;
 #endif
-#ifdef __i386__
+#if defined(__i386__) || defined(__arm__)
 typedef long long           quad_t;
 typedef unsigned long long  u_quad_t;
 #elif defined(__x86_64__)
@@ -39,10 +39,10 @@ typedef unsigned long       u_quad_t;
 #include <limits.h>
 #include <stdint.h>
 #else
-#ifdef __i386__
+#if defined(__i386__) || defined(__arm__)
 typedef unsigned int        uintptr_t;
 typedef int                 intptr_t;
-#elif defined(__x86_64__)
+#elif defined(__x86_64__) || defined(__aarch64__)
 typedef unsigned long       uintptr_t;
 typedef long                intptr_t;
 #endif /* __i386__ || __x86_64__ */
@@ -52,10 +52,10 @@ typedef unsigned short uint16_t;
 typedef   signed short int16_t;
 typedef unsigned int uint32_t;
 typedef   signed int int32_t;
-#ifdef __i386__
+#if defined(__i386__) || defined(__arm__)
 typedef   signed long long int64_t;
 typedef unsigned long long uint64_t;
-#elif defined(__x86_64__)
+#elif defined(__x86_64__) || defined(__aarch64__)
 typedef   signed long int64_t;
 typedef unsigned long uint64_t;
 #endif
Signature · 1 line
2.0.1
#13 lore raw

Re: [PATCH ARM v6 04/14] mini-os: headers for ARM

Hi Thomas,

Quoted 13 lines · Thomas Leonard
extras/mini-os/include/arm/os.h new file +7 -0
new file mode 100644
index 0000000..6a1cc37
@@ -0,0 +1,216 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+#ifndef __ASSEMBLY__
+
+#include <mini-os/hypervisor.h>
+#include <mini-os/types.h>

extras/mini-os/include/arm/os.h line 17

Quoted 10 lines
extras/mini-os/include/arm/os.h new file +10 -0
+#include <mini-os/compiler.h>
+#include <mini-os/kernel.h>
+#include <xen/xen.h>
+
+void arch_fini(void);
+void timer_handler(evtchn_port_t port, struct pt_regs *regs, void *ign);
+
+extern void *device_tree;
+
+#define BUG() while(1){asm volatile (".word 0xe7f000f0\n");} /* Undefined instruction; will call our fault handler. */

NIT: I would explain that ARM doesn't provide any undefined instruction so we use an encoding that is invalid on ARMv7.

The other part of this patch looks good to me.

FWIW: Acked-by: Julien Grall <[email protected]>

Regards,

Signature · 1 line
Julien Grall
#14 lore raw

Re: [PATCH ARM v6 04/14] mini-os: headers for ARM

Quoted 26 lines · Julien Grall

Hi Thomas,

Quoted 22 lines · Thomas Leonard
extras/mini-os/include/arm/os.h new file +14 -0
new file mode 100644
index 0000000..6a1cc37
@@ -0,0 +1,216 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+#ifndef __ASSEMBLY__
+
+#include <mini-os/hypervisor.h>
+#include <mini-os/types.h>
+#include <mini-os/compiler.h>
+#include <mini-os/kernel.h>
+#include <xen/xen.h>
+
+void arch_fini(void);
+void timer_handler(evtchn_port_t port, struct pt_regs *regs, void *ign);
+
Quoted 8 lines
Quoted 4 lines
extras/mini-os/include/arm/os.h new file +3 -0
+extern void *device_tree;
+
+#define BUG() while(1){asm volatile (".word 0xe7f000f0\n");} /* Undefined

instruction; will call our fault handler. */

NIT: I would explain that ARM doesn't provide any undefined instruction so we use an encoding that is invalid on ARMv7.

I think it does, although I can't find it in the ARMv7 reference at the moment. But from
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHJIJCA.html
:

"UND pseudo-instruction

Generate an architecturally undefined instruction. An attempt to execute an undefined instruction causes the Undefined instruction exception. Architecturally undefined instructions are expected to remain undefined.

ARM : 0xV7FYYYFY"

(V is the 4 bits that encode for the condition code, Y allows passing extra data)

Quoted 8 lines

The other part of this patch looks good to me.

FWIW: Acked-by: Julien Grall <[email protected]>

Regards,

--
Julien Grall

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#15 lore raw

Re: [PATCH ARM v6 04/14] mini-os: headers for ARM

Quoted 36 lines · Thomas Leonard
Quoted 26 lines · Julien Grall

Hi Thomas,

Quoted 22 lines · Thomas Leonard
extras/mini-os/include/arm/os.h new file +14 -0
new file mode 100644
index 0000000..6a1cc37
@@ -0,0 +1,216 @@
+#ifndef _OS_H_
+#define _OS_H_
+
+#ifndef __ASSEMBLY__
+
+#include <mini-os/hypervisor.h>
+#include <mini-os/types.h>
+#include <mini-os/compiler.h>
+#include <mini-os/kernel.h>
+#include <xen/xen.h>
+
+void arch_fini(void);
+void timer_handler(evtchn_port_t port, struct pt_regs *regs, void *ign);
+
Quoted 8 lines
Quoted 4 lines
extras/mini-os/include/arm/os.h new file +3 -0
+extern void *device_tree;
+
+#define BUG() while(1){asm volatile (".word 0xe7f000f0\n");} /* Undefined

instruction; will call our fault handler. */

NIT: I would explain that ARM doesn't provide any undefined instruction so we use an encoding that is invalid on ARMv7.

Quoted 2 lines

I think it does, although I can't find it in the ARMv7 reference at the moment.

In the past I've looked pretty hard for this and been completely unable to find it. It's interesting that they document it in the assembler reference.

Prompted by this I took another look and there it is, A8.8.247 defines "UDF" as a permanently undefined encoding.

Quoted 5 lines

But from
http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0489c/CIHJIJCA.html
:

"UND pseudo-instruction

Thanks for the tip, this is the same encoding as the ARM ARM calls UDF, helpfully with a different name, but it did lead mean to find UDF in the ARM.

ARMv8 Aarch64 doesn't seem to have the same. It looks like C5.2.2 together with C5.2.7 is defining a set of undefined encodings, but I'm not 100% clear that they are "permanently undefined", nor does there appear to be a mnemonic for these encodings. Not sure we can rely on that.

Ian.

Acked-by on v6 4/14
#17 lore raw

Re: [PATCH ARM v6 04/14] mini-os: headers for ARM

In reply to Thomas Leonard
Quoted 7 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Adds header files for future ARM support.
Based on work by Karim Allah Ahmed.

Quoted 1 line

+/********************* common arm32 and arm64 ****************************/

[...]

Quoted 2 lines
extras/mini-os/include/hypervisor.h +2 -0
+#elif defined(__arm__) || defined(__aarch64__)
+#include <hypercall-arm.h>

[...]

extras/mini-os/include/mm.h line 33

Quoted 2 lines
extras/mini-os/include/mm.h +2 -0
+#elif defined(__arm__) || defined(__aarch64__)
+#include <xen/arch-arm.h>

This series isn't adding aarch64 as well, is it?

I don't object to these being here, I would just be pleasantly surprised to find arm64 being supported too ;-)

Ian.

#18 lore raw

Re: [PATCH ARM v6 04/14] mini-os: headers for ARM

Quoted 16 lines · Ian Campbell
Quoted 7 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Adds header files for future ARM support.
Based on work by Karim Allah Ahmed.

Quoted 1 line

+/********************* common arm32 and arm64 ****************************/

[...]

Quoted 2 lines
extras/mini-os/include/hypervisor.h +2 -0
+#elif defined(__arm__) || defined(__aarch64__)
+#include <hypercall-arm.h>

[...]

Quoted 7 lines

extras/mini-os/include/mm.h line 33

Quoted 2 lines
extras/mini-os/include/mm.h +2 -0
+#elif defined(__arm__) || defined(__aarch64__)
+#include <xen/arch-arm.h>

This series isn't adding aarch64 as well, is it?

I don't object to these being here, I would just be pleasantly surprised to find arm64 being supported too ;-)

I’ve made an initial (very early stage) repo for arm64 on https://github.com/baozich/minios-arm64
Haven’t got time to complement the rest codes yet...

Cheers,

Baozi

#19 lore raw

Re: [PATCH ARM v6 04/14] mini-os: headers for ARM

In reply to Ian Campbell
Quoted 16 lines · Ian Campbell
Quoted 7 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Adds header files for future ARM support.
Based on work by Karim Allah Ahmed.

Quoted 1 line

+/********************* common arm32 and arm64 ****************************/

[...]

Quoted 2 lines
extras/mini-os/include/hypervisor.h +2 -0
+#elif defined(__arm__) || defined(__aarch64__)
+#include <hypercall-arm.h>

[...]

Quoted 7 lines

extras/mini-os/include/mm.h line 33

Quoted 2 lines
extras/mini-os/include/mm.h +2 -0
+#elif defined(__arm__) || defined(__aarch64__)
+#include <xen/arch-arm.h>

This series isn't adding aarch64 as well, is it?

I don't object to these being here, I would just be pleasantly surprised to find arm64 being supported too ;-)

These changes are from Karim's original patches. Unfortunately, I don't have any arm64 hardware myself.

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#21 lore raw

Re: [PATCH ARM v6 04/14] mini-os: headers for ARM

Quoted 4 lines · Samuel Thibault
Quoted 1 line · Thomas Leonard, le Wed 16 Jul 2014 12:07:44 +0100, a écrit :

+extern int physical_address_offset; /* Add this to a virtual address to get the physical address (wraps) */

int only?

I'll make it "unsigned long" (long and int are the same on ARM, but paddr_t is defined that way too).

Signature · 8 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#22 lore raw

PATCH v6 5/14 mini-os: import libfdt

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git

The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.c (r246827).

[[email protected]: split out FDT support into a separate patch]
[[email protected]: fixed "make clean" for FDT]
[[email protected]: replaced GPL memmove with BSD one]
---
 extras/mini-os/COPYING                   |   27 +
 extras/mini-os/Makefile                  |   13 +
 extras/mini-os/include/fdt.h             |   60 ++
 extras/mini-os/include/lib.h             |    4 +-
 extras/mini-os/include/libfdt.h          | 1478 ++++++++++++++++++++++++++++++
 extras/mini-os/include/libfdt_env.h      |   37 +
 extras/mini-os/lib/fdt/fdt.c             |  222 +++++
 extras/mini-os/lib/fdt/fdt_empty_tree.c  |   84 ++
 extras/mini-os/lib/fdt/fdt_ro.c          |  574 ++++++++++++
 extras/mini-os/lib/fdt/fdt_rw.c          |  492 ++++++++++
 extras/mini-os/lib/fdt/fdt_strerror.c    |   96 ++
 extras/mini-os/lib/fdt/fdt_sw.c          |  256 ++++++
 extras/mini-os/lib/fdt/fdt_wip.c         |  118 +++
 extras/mini-os/lib/fdt/libfdt_internal.h |   95 ++
 extras/mini-os/lib/memmove.c             |   45 +
 extras/mini-os/lib/string.c              |   12 +
 16 files changed, 3612 insertions(+), 1 deletion(-)
 create mode 100644 extras/mini-os/include/fdt.h
 create mode 100644 extras/mini-os/include/libfdt.h
 create mode 100644 extras/mini-os/include/libfdt_env.h
 create mode 100644 extras/mini-os/lib/fdt/fdt.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_empty_tree.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_ro.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_rw.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_strerror.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_sw.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_wip.c
 create mode 100644 extras/mini-os/lib/fdt/libfdt_internal.h
 create mode 100644 extras/mini-os/lib/memmove.c
extras/mini-os/COPYING +27 -0
index 1d9df6c..b676bb6 100644
@@ -34,3 +34,30 @@ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
 OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
 SUCH DAMAGE.
 
+
+Copyright (c) 2005,2006, NLnetLabs
+All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+    * Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+    * Neither the name of NLnetLabs nor the names of its
+      contributors may be used to endorse or promote products derived from this
+      software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
extras/mini-os/Makefile +13 -0
index 6d6537e..931cd05 100644
@@ -77,6 +77,18 @@ TARGET := mini-os
 # Subdirectories common to mini-os
 SUBDIRS := lib xenbus console
 
+ifeq ($(XEN_TARGET_ARCH),arm32)
+# Device tree support
+SUBDIRS += lib/fdt
+src-y += lib/fdt/fdt.c
+src-y += lib/fdt/fdt_empty_tree.c
+src-y += lib/fdt/fdt_ro.c
+src-y += lib/fdt/fdt_rw.c
+src-y += lib/fdt/fdt_strerror.c
+src-y += lib/fdt/fdt_sw.c
+src-y += lib/fdt/fdt_wip.c
+endif
+
 src-$(CONFIG_BLKFRONT) += blkfront.c
 src-$(CONFIG_TPMFRONT) += tpmfront.c
 src-$(CONFIG_TPM_TIS) += tpm_tis.c
@@ -101,6 +113,7 @@ src-y += lib/math.c
 src-y += lib/printf.c
 src-y += lib/stack_chk_fail.c
 src-y += lib/string.c
+src-y += lib/memmove.c
 src-y += lib/sys.c
 src-y += lib/xmalloc.c
 src-$(CONFIG_XENBUS) += lib/xs.c
extras/mini-os/include/fdt.h new file +60 -0

60 lines not on this page · raw message

extras/mini-os/include/lib.h +3 -1
index 62836c7..cc7dc7f 100644
@@ -95,6 +95,7 @@ char	*strncpy(char * __restrict, const char * __restrict, size_t);
 
 char	*strstr(const char *, const char *);
 
+void *memmove(void * dest,const void *src,size_t count);
 void *memset(void *, int, size_t);
 
 char *strchr(const char *p, int ch);
@@ -104,7 +105,8 @@ char *strrchr(const char *p, int ch);
  *	@(#)systm.h	8.7 (Berkeley) 3/29/95
  * $FreeBSD$
  */
-void	*memcpy(void *to, const void *from, size_t len);
+void *memcpy(void *to, const void *from, size_t len);
+void *memchr(const void *s, int c, size_t n);
 
 size_t strnlen(const char *, size_t);
 #endif
extras/mini-os/include/libfdt.h new file +1478 -0

1,478 lines not on this page · raw message

extras/mini-os/include/libfdt_env.h new file +37 -0
new file mode 100644
index 0000000..f91f137
@@ -0,0 +1,37 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#ifdef _KERNEL
+#include <sys/cdefs.h>
+#include <sys/param.h>
+#include <sys/types.h>
+#include <sys/systm.h>
+#include <sys/stdint.h>
+#else
+#include <stddef.h>
+#include <stdint.h>
+#include <string.h>
+#endif
+
+#define EXTRACT_BYTE(n)	((unsigned long long)((uint8_t *)&x)[n])
+static inline uint16_t fdt16_to_cpu(uint16_t x)
+{
+	return (EXTRACT_BYTE(0) << 8) | EXTRACT_BYTE(1);
+}
+#define cpu_to_fdt16(x) fdt16_to_cpu(x)
+
+static inline uint32_t fdt32_to_cpu(uint32_t x)
+{
+	return (EXTRACT_BYTE(0) << 24) | (EXTRACT_BYTE(1) << 16) | (EXTRACT_BYTE(2) << 8) | EXTRACT_BYTE(3);
+}
+#define cpu_to_fdt32(x) fdt32_to_cpu(x)
+
+static inline uint64_t fdt64_to_cpu(uint64_t x)
+{
+	return (EXTRACT_BYTE(0) << 56) | (EXTRACT_BYTE(1) << 48) | (EXTRACT_BYTE(2) << 40) | (EXTRACT_BYTE(3) << 32)
+		| (EXTRACT_BYTE(4) << 24) | (EXTRACT_BYTE(5) << 16) | (EXTRACT_BYTE(6) << 8) | EXTRACT_BYTE(7);
+}
+#define cpu_to_fdt64(x) fdt64_to_cpu(x)
+#undef EXTRACT_BYTE
+
+#endif /* _LIBFDT_ENV_H */
extras/mini-os/lib/fdt/fdt.c new file +222 -0

222 lines not on this page · raw message

extras/mini-os/lib/fdt/fdt_empty_tree.c new file +84 -0

84 lines not on this page · raw message

extras/mini-os/lib/fdt/fdt_ro.c new file +574 -0

574 lines not on this page · raw message

extras/mini-os/lib/fdt/fdt_rw.c new file +492 -0

474 lines not on this page · raw message

extras/mini-os/lib/fdt/fdt_strerror.c new file +96 -0

96 lines not on this page · raw message

extras/mini-os/lib/fdt/fdt_sw.c new file +256 -0

256 lines not on this page · raw message

extras/mini-os/lib/fdt/fdt_wip.c new file +118 -0

118 lines not on this page · raw message

extras/mini-os/lib/fdt/libfdt_internal.h new file +95 -0

95 lines not on this page · raw message

extras/mini-os/lib/memmove.c new file +45 -0

45 lines not on this page · raw message

extras/mini-os/lib/string.c +12 -0
index 8b24146..c96ca41 100644

Lines of this file are not shown. View the raw message.

The rest of this diff is not shown. View the raw message.

Signature · 1 line
2.0.1

Part of the diff is not shown here. View the raw message.

#23 lore raw

Re: [PATCH ARM v6 05/14] mini-os: import libfdt

Quoted 5 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git

Quoted 8 lines

The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.c (r246827).

[[email protected]: split out FDT support into a separate patch]
[[email protected]: fixed "make clean" for FDT]
[[email protected]: replaced GPL memmove with BSD one]

Xen already has a copy of libfdt in xen/common/libfdt.

I think it sets a poor precedent to have multiple different copies of the same library in the source tree.

Libraries like this should live in their own part of the Xen source tree (libs/ or perhaps common/) and each component wanting to use them (Xen, libxc, mini-os) can VPATH themselves access to the headers/source.

This would have the added advantage of making it obvious which shared libraries are used by multiple components in the tree (libelf is another example), and avoids duplication and stagnation.

~Andrew

#24 lore raw

Re: [PATCH ARM v6 05/14] mini-os: import libfdt

Quoted 9 lines · Andrew Cooper
Quoted 8 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git

The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.c (r246827).

Quoted 7 lines
Quoted 5 lines
[[email protected]: split out FDT support into a separate patch]
[[email protected]: fixed "make clean" for FDT]
[[email protected]: replaced GPL memmove with BSD one]

Xen already has a copy of libfdt in xen/common/libfdt.

Please review the thread on this from the previous postings.

Ian.

#25 lore raw

Re: [PATCH ARM v6 05/14] mini-os: import libfdt

Quoted 15 lines · Ian Campbell
Quoted 14 lines · Andrew Cooper
Quoted 13 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git

The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.c (r246827).

[[email protected]: split out FDT support into a separate patch]
[[email protected]: fixed "make clean" for FDT]
[[email protected]: replaced GPL memmove with BSD one]
Quoted 5 lines
Quoted 1 line

Xen already has a copy of libfdt in xen/common/libfdt.

Please review the thread on this from the previous postings.

Ian.

Which appears to be unconcluded.

libfdt is a 3rd party library which, from what I can tell in the history, is unmodified. Therefore, my suggestion of moving it outside of the xen/ tree and having both minios and Xen VPATH themselves access to it helps with the end goal of preventing minios becoming dependent on Xen code. It further prevents both Xen and minios from accidentally gaining localisation hacks in the library itself, which makes it easier to updates to the base libdft if/when necessary.

~Andrew

#26 lore raw

Re: [PATCH ARM v6 05/14] mini-os: import libfdt

Quoted 16 lines · Andrew Cooper
Quoted 15 lines · Ian Campbell
Quoted 14 lines · Andrew Cooper
Quoted 13 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git

The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.c (r246827).

[[email protected]: split out FDT support into a separate patch]
[[email protected]: fixed "make clean" for FDT]
[[email protected]: replaced GPL memmove with BSD one]
Quoted 7 lines
Quoted 5 lines
Quoted 1 line

Xen already has a copy of libfdt in xen/common/libfdt.

Please review the thread on this from the previous postings.

Ian.

Which appears to be unconcluded.

http://article.gmane.org/gmane.comp.emulators.xen.devel/205280 looked conclusive to me.

Quoted 7 lines

libfdt is a 3rd party library which, from what I can tell in the history, is unmodified. Therefore, my suggestion of moving it outside of the xen/ tree and having both minios and Xen VPATH themselves access to it helps with the end goal of preventing minios becoming dependent on Xen code. It further prevents both Xen and minios from accidentally gaining localisation hacks in the library itself, which makes it easier to updates to the base libdft if/when necessary.

This would mean that splitting extras/mini-os off wouldn't be just a case of doing that, you'd also need arrange for the VPATH to be satisfied, I don't know if Anil et al will be happy with that.

Ultimately this is up to Samuel if he is happy with the current approach or not.

Ian.

#27 lore raw

Re: [PATCH ARM v6 05/14] mini-os: import libfdt

Quoted 36 lines · Ian Campbell
Quoted 16 lines · Andrew Cooper
Quoted 15 lines · Ian Campbell
Quoted 14 lines · Andrew Cooper
Quoted 13 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git

The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.c (r246827).

[[email protected]: split out FDT support into a separate patch]
[[email protected]: fixed "make clean" for FDT]
[[email protected]: replaced GPL memmove with BSD one]
Quoted 7 lines
Quoted 5 lines
Quoted 1 line

Xen already has a copy of libfdt in xen/common/libfdt.

Please review the thread on this from the previous postings.

Ian.

Which appears to be unconcluded.

http://article.gmane.org/gmane.comp.emulators.xen.devel/205280 looked conclusive to me.

Quoted 7 lines

libfdt is a 3rd party library which, from what I can tell in the history, is unmodified. Therefore, my suggestion of moving it outside of the xen/ tree and having both minios and Xen VPATH themselves access to it helps with the end goal of preventing minios becoming dependent on Xen code. It further prevents both Xen and minios from accidentally gaining localisation hacks in the library itself, which makes it easier to updates to the base libdft if/when necessary.

Quoted 3 lines

This would mean that splitting extras/mini-os off wouldn't be just a case of doing that, you'd also need arrange for the VPATH to be satisfied, I don't know if Anil et al will be happy with that.

As long as we can resist the urge to locally modify libfdt, that shouldn't be too onerous. However, if libfdt isn't being modified at all, then why import it into the tree at all? We could just clone the right revision in the build system as happens for some other upstream tools.

-anil

#28 lore raw

Re: [PATCH ARM v6 05/14] mini-os: import libfdt

Quoted 38 lines · Anil Madhavapeddy
Quoted 36 lines · Ian Campbell
Quoted 16 lines · Andrew Cooper
Quoted 15 lines · Ian Campbell
Quoted 14 lines · Andrew Cooper
Quoted 13 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git

The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.c (r246827).

[[email protected]: split out FDT support into a separate patch]
[[email protected]: fixed "make clean" for FDT]
[[email protected]: replaced GPL memmove with BSD one]
Quoted 7 lines
Quoted 5 lines
Quoted 1 line

Xen already has a copy of libfdt in xen/common/libfdt.

Please review the thread on this from the previous postings.

Ian.

Which appears to be unconcluded.

http://article.gmane.org/gmane.comp.emulators.xen.devel/205280 looked conclusive to me.

Quoted 7 lines

libfdt is a 3rd party library which, from what I can tell in the history, is unmodified. Therefore, my suggestion of moving it outside of the xen/ tree and having both minios and Xen VPATH themselves access to it helps with the end goal of preventing minios becoming dependent on Xen code. It further prevents both Xen and minios from accidentally gaining localisation hacks in the library itself, which makes it easier to updates to the base libdft if/when necessary.

Quoted 8 lines
Quoted 3 lines

This would mean that splitting extras/mini-os off wouldn't be just a case of doing that, you'd also need arrange for the VPATH to be satisfied, I don't know if Anil et al will be happy with that.

As long as we can resist the urge to locally modify libfdt, that shouldn't be too onerous. However, if libfdt isn't being modified at all, then why import it into the tree at all? We could just clone the right revision in the build system as happens for some other upstream tools.

That's generally a sucky approach though, I'd like to see less not more of it.

libfdt is somewhat designed to be embedded in this way.

Ian.

#29 lore raw

Re: [PATCH ARM v6 05/14] mini-os: import libfdt

In reply to Ian Campbell
Quoted 36 lines · Ian Campbell, le Wed 16 Jul 2014 14:34:42 +0100, a écrit :
Quoted 16 lines · Andrew Cooper
Quoted 15 lines · Ian Campbell
Quoted 14 lines · Andrew Cooper
Quoted 13 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git

The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.c (r246827).

[[email protected]: split out FDT support into a separate patch]
[[email protected]: fixed "make clean" for FDT]
[[email protected]: replaced GPL memmove with BSD one]
Quoted 7 lines
Quoted 5 lines
Quoted 1 line

Xen already has a copy of libfdt in xen/common/libfdt.

Please review the thread on this from the previous postings.

Ian.

Which appears to be unconcluded.

http://article.gmane.org/gmane.comp.emulators.xen.devel/205280 looked conclusive to me.

Quoted 7 lines

libfdt is a 3rd party library which, from what I can tell in the history, is unmodified. Therefore, my suggestion of moving it outside of the xen/ tree and having both minios and Xen VPATH themselves access to it helps with the end goal of preventing minios becoming dependent on Xen code. It further prevents both Xen and minios from accidentally gaining localisation hacks in the library itself, which makes it easier to updates to the base libdft if/when necessary.

Quoted 6 lines

This would mean that splitting extras/mini-os off wouldn't be just a case of doing that, you'd also need arrange for the VPATH to be satisfied, I don't know if Anil et al will be happy with that.

Ultimately this is up to Samuel if he is happy with the current approach or not.

I'd say it should be fine to make mini-os use a shared copy of libfdt if it's made easy to make it use a copy from another place: people who want to build mini-os out of a xen tree can then just stuff a copy of libfdt wherever they feel like, and point mini-os to it.

Samuel

#30 lore raw

PATCH v6 6/14 mini-os: use generic local_irq_enable function

In reply to Thomas Leonard

__sti is x86 specific.

---
 extras/mini-os/kernel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
extras/mini-os/kernel.c +1 -1
index 9a30550..437e5b4 100644
@@ -121,7 +121,7 @@ void start_kernel(void)
     init_events();
 
     /* ENABLE EVENT DELIVERY. This is disabled at start of day. */
-    __sti();
+    local_irq_enable();
 
     setup_xen_features();
 
Signature · 1 line
2.0.1
Acked-by on v6 6/14
#32 lore raw

Re: [PATCH ARM v6 06/14] mini-os: use generic local_irq_enable function

In reply to Thomas Leonard
Quoted 3 lines · Thomas Leonard, le Wed 16 Jul 2014 12:07:46 +0100, a écrit :

__sti is x86 specific.

Quoted 20 lines
---
 extras/mini-os/kernel.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
extras/mini-os/kernel.c +1 -1
index 9a30550..437e5b4 100644
@@ -121,7 +121,7 @@ void start_kernel(void)
     init_events();
 
     /* ENABLE EVENT DELIVERY. This is disabled at start of day. */
-    __sti();
+    local_irq_enable();
 
     setup_xen_features();
 
Signature · 1 line
2.0.1
Signature · 3 lines
Samuel
Accroche-toi au terminal, j'enlève le shell...
 -+- nojhan -+-
#33 lore raw

PATCH v6 7/14 mini-os: arm: boot code

In reply to Thomas Leonard

Based on an initial patch by Karim Raslan.

---

Changes since v5:

- Moved SVC stack to first 16KB of RAM (provides some protection against stack overlow corrupting memory).
- Put translation table in second 16KB (simplifies boot code).
- Moved definition of physical_address_offset out of asm.
- Moved shared_info_page and irqstack to .bss section (smaller image).
- Moved __bss_start and _edata inside section in linker script. The linker adds non-listed sections, such as .got, just before .bss. This meant that we accidentally zeroed those out too.
- Enable floating point unit during boot.

Addressed Julien Grall's comments:
- Get hypercall numbers from xen.h.
- Avoid duplicating the definition of _start's virtual address.

---
 extras/mini-os/arch/arm/arm32.S          | 211 +++++++++++++++++++++++++++++++
 extras/mini-os/arch/arm/hypercalls32.S   |  64 ++++++++++
 extras/mini-os/arch/arm/minios-arm32.lds |  79 ++++++++++++
 extras/mini-os/arch/arm/setup.c          | 119 +++++++++++++++++
 4 files changed, 473 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/arm32.S
 create mode 100644 extras/mini-os/arch/arm/hypercalls32.S
 create mode 100755 extras/mini-os/arch/arm/minios-arm32.lds
 create mode 100644 extras/mini-os/arch/arm/setup.c
extras/mini-os/arch/arm/arm32.S new file +211 -0
new file mode 100644
index 0000000..88efe24
@@ -0,0 +1,211 @@
+@ Offset of the kernel within the RAM. This is a Linux/zImage convention which we
+@ rely on for now.
+#define ZIMAGE_KERNEL_OFFSET 0x8000
+
+.section .text
+
+.globl _start
+_start:
+	@ zImage header
+.rept   8
+        mov     r0, r0
+.endr
+        b       reset
+        .word   0x016f2818      @ Magic numbers to help the loader
+        .word   0		@ zImage start address (0 = relocatable)
+        .word   _edata - _start @ zImage end address (excludes bss section)
+	@ end of zImage header
+
+@ Called at boot time. Sets up MMU, exception vectors and stack, and then calls C arch_init() function.
+@ => r2 -> DTB
+@ <= never returns
+@ Note: this boot code needs to be within the first (1MB - ZIMAGE_KERNEL_OFFSET) of _start.
+reset:
+	@ Problem: the C code wants to be at a known address (_start), but Xen might
+	@ load us anywhere. We initialise the MMU (mapping virtual to physical @ addresses)
+	@ so everything ends up where the code expects it to be.
+	@
+	@ We calculate the offet between where the linker thought _start would be and where
+	@ it actually is and initialise the page tables to have that offset for every page.
+	@
+	@ When we turn on the MMU, we're still executing at the old address. We don't want
+	@ the code to disappear from under us. So we have to do the mapping in stages:
+	@
+	@ 1. set up a mapping to our current page from both its current and desired addresses
+	@ 2. enable the MMU
+	@ 3. jump to the new address
+	@ 4. remap all the other pages with the calculated offset
+
+	adr	r1, _start		@ r1 = physical address of _start
+	ldr	r3, =_start		@ r3 = (desired) virtual address of _start
+	sub 	r9, r1, r3		@ r9 = (physical - virtual) offset
+
+	ldr	r7, =_page_dir		@ r7 = (desired) virtual addr of translation table
+	add	r1, r7, r9		@ r1 = physical addr of translation table
+
+	@ Tell the system where our page table is located.
+	@ This is the 16 KB top-level translation table, in which
+	@ each word maps one 1MB virtual section to a physical section.
+	mcr	p15, 0, r1, c2, c0, 0	@ set ttbr0 = r1
+
+	@ Set access permission for domains.
+	@ Domains are deprecated, but we have to configure them anyway.
+	@ We mark every page as being domain 0 and set domain 0 to "client mode"
+	@ (client mode = use access flags in page table).
+	mov	r0, #1			@ 1 = client
+	mcr	p15, 0, r0, c3, c0, 0	@ DACR
+
+	@ Template (flags) for a 1 MB page-table entry.
+	@ TEX[2:0] C B = 001 1 1 (outer and inner write-back, write-allocate)
+	ldr	r8, =(0x2 +  		/* Section entry */ \
+		      0xc +  		/* C B */ \
+		      (3 << 10) + 	/* Read/write */ \
+		      (1 << 12) +	/* TEX */ \
+		      (1 << 16) +	/* Sharable */ \
+		      (1<<19))		/* Non-secure */
+	@ r8 = template page table entry
+
+	@ Add an entry for the current physical section, at the old and new
+	@ addresses. It's OK if they're the same.
+	mov	r0, pc, lsr#20
+	mov	r0, r0, lsl#20		@ r0 = physical address of this code's section start
+	orr	r3, r0, r8		@ r3 = table entry for this section
+	ldr	r4, =_start		@ r4 = desired virtual address of this section
+	str	r3, [r1, r4, lsr#18] 	@ map desired virtual section to this code
+	str	r3, [r1, r0, lsr#18]	@ map current section to this code too
+
+	@ Invalidate TLB
+	mcr	p15, 0, r1, c8, c7, 0	@ TLBIALL
+
+	@ Enable MMU / SCTLR
+	@ We leave caches off for now because we're going to be changing the
+	@ TLB a lot and this avoids having to flush the caches each time.
+	mrc	p15, 0, r1, c1, c0, 0	@ SCTLR
+	orr	r1, r1, #0x1		@ Enable MMU
+	mcr	p15, 0, r1, c1, c0, 0	@ SCTLR
+	isb
+
+	adr	r1, stage2		@ Physical address of stage2
+	sub	r1, r1, r9		@ Virtual address of stage2
+	bx	r1
+
+@ Called once the MMU is enabled. The boot code and the page table are mapped,
+@ but nothing else is yet.
+@
+@ => r2 -> dtb (physical)
+@    r7 = virtual address of page table
+@    r8 = section entry template (flags)
+@    r9 = desired physical - virtual offset
+@    pc -> somewhere in newly-mapped virtual code section
+stage2:
+	@ Invalidate TLB
+	mcr	p15, 0, r1, c8, c7, 0	@ TLBIALL
+	isb
+
+	@ The new mapping has now taken effect:
+	@ r7 -> page_dir
+
+	@ Fill in the whole top-level translation table (at page_dir).
+	@ Populate the whole pagedir with 1MB section descriptors.
+
+	mov	r1, r7			@ r1 -> first section entry
+	add	r3, r1, #4*4*1024	@ limit (4 GB address space, 4 byte entries)
+	orr	r0, r8, r9		@ r0 = entry mapping section zero to start of physical RAM
+1:
+	str	r0, [r1],#4		@ write the section entry
+	add	r0, r0, #1 << 20 	@ next physical page (wraps)
+	cmp	r1, r3
+	bne	1b
+
+	@ Invalidate TLB
+	mcr	p15, 0, r1, c8, c7, 0	@ TLBIALL
+	isb
+
+	@ At this point, everything is mapped to its final location.
+	@ It's now safe to turn on caching.
+	ldr	r0, =(3 << 11) + 4	@ icache, branch prediction, dcache
+	mrc	p15, 0, r1, c1, c0, 0	@ SCTLR
+	orr	r1, r1, r0
+	mcr	p15, 0, r1, c1, c0, 0	@ SCTLR
+
+	@ Set VBAR -> exception_vector_table
+	@ SCTLR.V = 0
+	adr	r0, exception_vector_table
+	mcr	p15, 0, r0, c12, c0, 0
+
+	@ Enable hardware floating point:
+	@ 1. Access to CP10 and CP11 must be enabled in the Coprocessor Access
+	@    Control Register (CP15.CACR):
+	mrc	p15, 0, r1, c1, c0, 2		@ CACR
+	orr	r1, r1, #(3 << 20) + (3 << 22)	@ full access for CP10 & CP11
+	mcr	p15, 0, r1, c1, c0, 2
+	@ 2. The EN bit in the FPEXC register must be set:
+	vmrs	r0, FPEXC
+	orr	r0, r0, #1<<30		@ EN (enable)
+	vmsr	FPEXC, r0
+
+	@ Initialise 16 KB stack
+	ldr	sp, =_boot_stack_end
+
+	sub	r0, r2, r9		@ r0 -> device tree (virtual address)
+	mov	r1, r9			@ r1 = physical_address_offset
+
+	b	arch_init
+
+.pushsection .bss
+@ Note: calling arch_init zeroes out this region.
+.align 12
+.globl shared_info_page
+shared_info_page:
+	.fill (1024), 4, 0x0
+
+.align 3
+.globl irqstack
+.globl irqstack_end
+irqstack:
+	.fill (1024), 4, 0x0
+irqstack_end:
+
+.popsection
+
+@ exception base address
+.align 5
+.globl exception_vector_table
+@ Note: remember to call CLREX if returning from an exception:
+@ "The architecture enables the local monitor to treat any exclusive store as
+@  matching a previous LDREX address. For this reason, use of the CLREX
+@  instruction to clear an existing tag is required on context switches."
+@ -- ARM Cortex-A Series Programmer’s Guide (Version: 4.0)
+exception_vector_table:
+	b	. @ reset
+	b	. @ undefined instruction
+	b	. @ supervisor call
+	b	. @ prefetch call
+	b	. @ prefetch abort
+	b	. @ data abort
+	b	irq_handler @ irq
+	.word 0xe7f000f0    @ abort on FIQ
+
+irq_handler:
+	ldr	sp, =irqstack_end
+	push	{r0 - r12, r14}
+
+	ldr	r0, IRQ_handler
+	cmp	r0, #0
+	.word	0x07f000f0    	@ undeq - panic if no handler
+	blx	r0		@ call handler
+
+	@ Return from IRQ
+	pop	{r0 - r12, r14}
+	clrex
+	subs	pc, lr, #4
+
+.globl IRQ_handler
+IRQ_handler:
+	.long	0x0
+
+@ This is called if you try to divide by zero. For now, we make a supervisor call,
+@ which will make us halt.
+.globl raise
+raise:
+	svc	0
extras/mini-os/arch/arm/hypercalls32.S new file +64 -0

64 lines not on this page · raw message

extras/mini-os/arch/arm/minios-arm32.lds new file +79 -0

79 lines not on this page · raw message

extras/mini-os/arch/arm/setup.c new file +119 -0

119 lines not on this page · raw message

Signature · 7 lines
2.0.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#34 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Hi Thomas,

extras/mini-os/arch/arm/arm32.S line 49

Quoted 5 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S new file +5 -0
+
+	@ Tell the system where our page table is located.
+	@ This is the 16 KB top-level translation table, in which
+	@ each word maps one 1MB virtual section to a physical section.
+	mcr	p15, 0, r1, c2, c0, 0	@ set ttbr0 = r1

I don't see any modification of TTBCR (so the initial value is 0). I guess you are using short-descriptor translation table format, right? If so, I would write somewhere.

Quoted 22 lines
extras/mini-os/arch/arm/arm32.S new file +22 -0
+	@ Set access permission for domains.
+	@ Domains are deprecated, but we have to configure them anyway.
+	@ We mark every page as being domain 0 and set domain 0 to "client mode"
+	@ (client mode = use access flags in page table).
+	mov	r0, #1			@ 1 = client
+	mcr	p15, 0, r0, c3, c0, 0	@ DACR
+
+	@ Template (flags) for a 1 MB page-table entry.
+	@ TEX[2:0] C B = 001 1 1 (outer and inner write-back, write-allocate)
+	ldr	r8, =(0x2 +  		/* Section entry */ \
+		      0xc +  		/* C B */ \
+		      (3 << 10) + 	/* Read/write */ \
+		      (1 << 12) +	/* TEX */ \
+		      (1 << 16) +	/* Sharable */ \
+		      (1<<19))		/* Non-secure */
+	@ r8 = template page table entry
+
+	@ Add an entry for the current physical section, at the old and new
+	@ addresses. It's OK if they're the same.
+	mov	r0, pc, lsr#20
+	mov	r0, r0, lsl#20		@ r0 = physical address of this code's section start
+	orr	r3, r0, r8		@ r3 = table entry for this section

extras/mini-os/arch/arm/arm32.S line 82

Quoted 10 lines
extras/mini-os/arch/arm/arm32.S new file +10 -0
+	ldr	r4, =_start		@ r4 = desired virtual address of this section
+	str	r3, [r1, r4, lsr#18] 	@ map desired virtual section to this code
+	str	r3, [r1, r0, lsr#18]	@ map current section to this code too
+
+	@ Invalidate TLB
+	mcr	p15, 0, r1, c8, c7, 0	@ TLBIALL
+
+	@ Enable MMU / SCTLR
+	@ We leave caches off for now because we're going to be changing the
+	@ TLB a lot and this avoids having to flush the caches each time.

Did you intend to mean page table rather than TLB?

[..]

extras/mini-os/arch/arm/arm32.S line 195

Quoted 7 lines
extras/mini-os/arch/arm/arm32.S new file +7 -0
+irq_handler:
+	ldr	sp, =irqstack_end
+	push	{r0 - r12, r14}
+
+	ldr	r0, IRQ_handler
+	cmp	r0, #0
+	.word	0x07f000f0    	@ undeq - panic if no handler

Hrmmm, I didn't spot this earlier. How can this work? You unconditionally called an undefined encoding.

[..]

extras/mini-os/arch/arm/minios-arm32.lds line 7

Quoted 13 lines
extras/mini-os/arch/arm/minios-arm32.lds new file +7 -0
new file mode 100755
index 0000000..21c3893
@@ -0,0 +1,79 @@
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+  _boot_stack 	 = 0x400000;	/* 16 KB boot stack */
+  _boot_stack_end = 0x404000;
+  _page_dir      = 0x404000;	/* 16 KB translation table */

It might be worse to explain that you are relying on there is a hole before the kernel address.

Regards,

Signature · 1 line
Julien Grall
#35 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 12 lines · Julien Grall

Hi Thomas,

extras/mini-os/arch/arm/arm32.S line 49

Quoted 6 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S new file +5 -0
+
+       @ Tell the system where our page table is located.
+       @ This is the 16 KB top-level translation table, in which
+       @ each word maps one 1MB virtual section to a physical section.
+       mcr     p15, 0, r1, c2, c0, 0   @ set ttbr0 = r1
Quoted 3 lines

I don't see any modification of TTBCR (so the initial value is 0). I guess you are using short-descriptor translation table format, right? If so, I would write somewhere.

Yes, good idea.

Quoted 36 lines
Quoted 36 lines
extras/mini-os/arch/arm/arm32.S new file +3 -0
+       @ Set access permission for domains.
+       @ Domains are deprecated, but we have to configure them anyway.
+       @ We mark every page as being domain 0 and set domain 0 to "client

mode"

extras/mini-os/arch/arm/arm32.S new file +6 -0
+       @ (client mode = use access flags in page table).
+       mov     r0, #1                  @ 1 = client
+       mcr     p15, 0, r0, c3, c0, 0   @ DACR
+
+       @ Template (flags) for a 1 MB page-table entry.
+       @ TEX[2:0] C B = 001 1 1 (outer and inner write-back,

write-allocate)

extras/mini-os/arch/arm/arm32.S new file +9 -0
+       ldr     r8, =(0x2 +             /* Section entry */ \
+                     0xc +             /* C B */ \
+                     (3 << 10) +       /* Read/write */ \
+                     (1 << 12) +       /* TEX */ \
+                     (1 << 16) +       /* Sharable */ \
+                     (1<<19))          /* Non-secure */
+       @ r8 = template page table entry
+
+       @ Add an entry for the current physical section, at the old and

new

extras/mini-os/arch/arm/arm32.S new file +3 -0
+       @ addresses. It's OK if they're the same.
+       mov     r0, pc, lsr#20
+       mov     r0, r0, lsl#20          @ r0 = physical address of this

code's section start
+ orr r3, r0, r8 @ r3 = table entry for this
section
+ ldr r4, =_start @ r4 = desired virtual address of
this section
+ str r3, [r1, r4, lsr#18] @ map desired virtual section to
this code
+ str r3, [r1, r0, lsr#18] @ map current section to this code
too

extras/mini-os/arch/arm/arm32.S new file +3 -0
+
+       @ Invalidate TLB
+       mcr     p15, 0, r1, c8, c7, 0   @ TLBIALL
Quoted 8 lines
Quoted 5 lines
extras/mini-os/arch/arm/arm32.S new file +3 -0
+
+       @ Enable MMU / SCTLR
+       @ We leave caches off for now because we're going to be changing

the
+ @ TLB a lot and this avoids having to flush the caches each time.

Did you intend to mean page table rather than TLB?

Yes. Fixed.

Quoted 14 lines

[..]

extras/mini-os/arch/arm/arm32.S line 195

Quoted 7 lines
extras/mini-os/arch/arm/arm32.S new file +7 -0
+irq_handler:
+       ldr     sp, =irqstack_end
+       push    {r0 - r12, r14}
+
+       ldr     r0, IRQ_handler
+       cmp     r0, #0
+       .word   0x07f000f0      @ undeq - panic if no handler

Hrmmm, I didn't spot this earlier. How can this work? You unconditionally called an undefined encoding.

Here, the leading "0" is EQ, so it's only executed if IRQ_handler is unset ("undEQ").

Quoted 13 lines

[..]

Quoted 10 lines
extras/mini-os/arch/arm/minios-arm32.lds new file +3 -0
new file mode 100755
index 0000000..21c3893
@@ -0,0 +1,79 @@
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
Quoted 8 lines

extras/mini-os/arch/arm/minios-arm32.lds line 7

Quoted 4 lines
extras/mini-os/arch/arm/minios-arm32.lds new file +4 -0
+{
+  _boot_stack   = 0x400000;    /* 16 KB boot stack */
+  _boot_stack_end = 0x404000;
+  _page_dir      = 0x404000;   /* 16 KB translation table */

It might be worse to explain that you are relying on there is a hole before the kernel address.

OK, will add a note here.

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#36 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 12 lines · Thomas Leonard
Quoted 11 lines

extras/mini-os/arch/arm/arm32.S line 195

Quoted 7 lines
extras/mini-os/arch/arm/arm32.S new file +7 -0
+irq_handler:
+       ldr     sp, =irqstack_end
+       push    {r0 - r12, r14}
+
+       ldr     r0, IRQ_handler
+       cmp     r0, #0
+       .word   0x07f000f0      @ undeq - panic if no handler

Hrmmm, I didn't spot this earlier. How can this work? You unconditionally called an undefined encoding.

Quoted 2 lines

Here, the leading "0" is EQ, so it's only executed if IRQ_handler is unset ("undEQ").

ARMv7 ARM A8.8.247 says that UDF isn't conditional,so you probably odn't want to rely on that.

Ian.

#37 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 14 lines · Ian Campbell
Quoted 12 lines · Thomas Leonard
Quoted 11 lines

extras/mini-os/arch/arm/arm32.S line 195

Quoted 7 lines
extras/mini-os/arch/arm/arm32.S new file +7 -0
+irq_handler:
+       ldr     sp, =irqstack_end
+       push    {r0 - r12, r14}
+
+       ldr     r0, IRQ_handler
+       cmp     r0, #0
+       .word   0x07f000f0      @ undeq - panic if no handler

Hrmmm, I didn't spot this earlier. How can this work? You unconditionally called an undefined encoding.

Quoted 5 lines
Quoted 2 lines

Here, the leading "0" is EQ, so it's only executed if IRQ_handler is unset ("undEQ").

ARMv7 ARM A8.8.247 says that UDF isn't conditional,so you probably odn't want to rely on that.

Yes, just noticed that myself. Will replace it with a branch.

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#38 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

In reply to Thomas Leonard

extras/mini-os/arch/arm/arm32.S line 82

Quoted 3 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S new file +3 -0
+	@ Enable MMU / SCTLR
+	@ We leave caches off for now because we're going to be changing the
+	@ TLB a lot and this avoids having to flush the caches each time.

ARMv7 (or perhaps it was the virt extensions, either way you can rely on it here) makes the MMU cache coherent, so you don't need to flush the caches when doing a PTE write any more.

extras/mini-os/arch/arm/arm32.S line 84

Quoted 5 lines
extras/mini-os/arch/arm/arm32.S new file +5 -0
+       @ Enable MMU / SCTLR
+       @ We leave caches off for now because we're going to be changing the
+       @ TLB a lot and this avoids having to flush the caches each time.
+       mrc     p15, 0, r1, c1, c0, 0   @ SCTLR
+       orr     r1, r1, #0x1            @ Enable MMU

I think you want a dsb here to ensure that any previous PTE write you did when setting up the PTs have actually occurred.

extras/mini-os/arch/arm/arm32.S line 89

Quoted 6 lines
extras/mini-os/arch/arm/arm32.S new file +5 -0
+       mcr     p15, 0, r1, c1, c0, 0   @ SCTLR
+       isb
+
 
+	adr	r1, stage2		@ Physical address of stage2
+	sub	r1, r1, r9		@ Virtual address of stage2

ldr r1, =stage2

would do this in one, I think.

extras/mini-os/arch/arm/arm32.S line 100

Quoted 11 lines
extras/mini-os/arch/arm/arm32.S new file +11 -0
+	bx	r1
+
+@ Called once the MMU is enabled. The boot code and the page table are mapped,
+@ but nothing else is yet.
+@
+@ => r2 -> dtb (physical)
+@    r7 = virtual address of page table
+@    r8 = section entry template (flags)
+@    r9 = desired physical - virtual offset
+@    pc -> somewhere in newly-mapped virtual code section
+stage2:

I think you want another dsb around here somewhere to ensure that none of the PT updates you do in a moment float up and interfere with the mapping of the code between the write to SCTLR until the bx r1.

Quoted 8 lines
extras/mini-os/arch/arm/arm32.S new file +8 -0
+	@ Invalidate TLB
+	mcr	p15, 0, r1, c8, c7, 0	@ TLBIALL
+	isb
+
+	@ The new mapping has now taken effect:
+	@ r7 -> page_dir
+
+	@ Fill in the whole top-level translation table (at page_dir).

extras/mini-os/arch/arm/arm32.S line 118

Quoted 10 lines
extras/mini-os/arch/arm/arm32.S new file +10 -0
+	@ Populate the whole pagedir with 1MB section descriptors.
+
+	mov	r1, r7			@ r1 -> first section entry
+	add	r3, r1, #4*4*1024	@ limit (4 GB address space, 4 byte entries)
+	orr	r0, r8, r9		@ r0 = entry mapping section zero to start of physical RAM
+1:
+	str	r0, [r1],#4		@ write the section entry
+	add	r0, r0, #1 << 20 	@ next physical page (wraps)
+	cmp	r1, r3
+	bne	1b

dsb here to make sure those writes have actually occurred before you come to rely on them.

If there is any chance of any of those writes going through a mapping which you are then changing at the same time then I worry that you might also need a dsb before each write. I'm not 100% sure what would happen in this case, I think you'd be better off creating a whole new set of PTs rather than pulling the rug out from under yourself. It's either that or cold towel on head time ;-)

Ian.

#39 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 8 lines · Ian Campbell

extras/mini-os/arch/arm/arm32.S line 82

Quoted 3 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S new file +3 -0
+     @ Enable MMU / SCTLR
+     @ We leave caches off for now because we're going to be changing the
+     @ TLB a lot and this avoids having to flush the caches each time.

ARMv7 (or perhaps it was the virt extensions, either way you can rely on it here) makes the MMU cache coherent, so you don't need to flush the caches when doing a PTE write any more.

I tried enabling the D-cache here, but then it frequently (but not always) fails to boot, even with various dsb and isb instructions scattered around.

If I enable the D-cache immediately before the loop that writes the translation table entries, it fails. Adding a dsb after the loop doesn't help. But if I enable it after the loop then it's fine.

I don't know what's going on there - any suggestions? Here's my (failing) test-case (tested using Xen/stable-4.4 - 4.4.1-rc1-28-gee81dda):

https://github.com/talex5/xen/commit/adadfa7e483aa3f3a351c0aeca6a560614fcdead

Quoted 8 lines

extras/mini-os/arch/arm/arm32.S line 84

Quoted 5 lines
extras/mini-os/arch/arm/arm32.S new file +5 -0
+       @ Enable MMU / SCTLR
+       @ We leave caches off for now because we're going to be changing the
+       @ TLB a lot and this avoids having to flush the caches each time.
+       mrc     p15, 0, r1, c1, c0, 0   @ SCTLR
+       orr     r1, r1, #0x1            @ Enable MMU

I think you want a dsb here to ensure that any previous PTE write you did when setting up the PTs have actually occurred.

Presumably this isn't needed in the current code, since the caches are off?

Quoted 10 lines

extras/mini-os/arch/arm/arm32.S line 89

Quoted 6 lines
extras/mini-os/arch/arm/arm32.S new file +5 -0
+       mcr     p15, 0, r1, c1, c0, 0   @ SCTLR
+       isb
+
 
+     adr     r1, stage2              @ Physical address of stage2
+     sub     r1, r1, r9              @ Virtual address of stage2

ldr r1, =stage2

would do this in one, I think.

Yes, OK.

Quoted 7 lines
Quoted 7 lines
extras/mini-os/arch/arm/arm32.S new file +7 -0
+     bx      r1
+
+@ Called once the MMU is enabled. The boot code and the page table are mapped,
+@ but nothing else is yet.
+@
+@ => r2 -> dtb (physical)
+@    r7 = virtual address of page table
Quoted 8 lines
Quoted 4 lines
+@    r8 = section entry template (flags)
+@    r9 = desired physical - virtual offset
+@    pc -> somewhere in newly-mapped virtual code section

+stage2:

I think you want another dsb around here somewhere to ensure that none of the PT updates you do in a moment float up and interfere with the mapping of the code between the write to SCTLR until the bx r1.

How does that happen? Presumably the isb below will block that.

Quoted 22 lines
Quoted 8 lines
extras/mini-os/arch/arm/arm32.S new file +8 -0
+     @ Invalidate TLB
+     mcr     p15, 0, r1, c8, c7, 0   @ TLBIALL
+     isb
+
+     @ The new mapping has now taken effect:
+     @ r7 -> page_dir
+
+     @ Fill in the whole top-level translation table (at page_dir).

extras/mini-os/arch/arm/arm32.S line 118

Quoted 10 lines
extras/mini-os/arch/arm/arm32.S new file +10 -0
+     @ Populate the whole pagedir with 1MB section descriptors.
+
+     mov     r1, r7                  @ r1 -> first section entry
+     add     r3, r1, #4*4*1024       @ limit (4 GB address space, 4 byte entries)
+     orr     r0, r8, r9              @ r0 = entry mapping section zero to start of physical RAM
+1:
+     str     r0, [r1],#4             @ write the section entry
+     add     r0, r0, #1 << 20        @ next physical page (wraps)
+     cmp     r1, r3
+     bne     1b

dsb here to make sure those writes have actually occurred before you come to rely on them.

Quoted 3 lines

If there is any chance of any of those writes going through a mapping which you are then changing at the same time then I worry that you might also need a dsb before each write.

The mapping for the translation table itself doesn't change (its entry will be written with the same value as previously).

Quoted 6 lines

I'm not 100% sure what would happen
in this case, I think you'd be better off creating a whole new set of PTs rather than pulling the rug out from under yourself. It's either that or cold towel on head time ;-)

Ian.

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#40 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 18 lines · Thomas Leonard
Quoted 8 lines · Ian Campbell

extras/mini-os/arch/arm/arm32.S line 82

Quoted 3 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S new file +3 -0
+     @ Enable MMU / SCTLR
+     @ We leave caches off for now because we're going to be changing the
+     @ TLB a lot and this avoids having to flush the caches each time.

ARMv7 (or perhaps it was the virt extensions, either way you can rely on it here) makes the MMU cache coherent, so you don't need to flush the caches when doing a PTE write any more.

I tried enabling the D-cache here, but then it frequently (but not always) fails to boot, even with various dsb and isb instructions scattered around.

If I enable the D-cache immediately before the loop that writes the translation table entries, it fails. Adding a dsb after the loop doesn't help. But if I enable it after the loop then it's fine.

Quoted 5 lines

I don't know what's going on there - any suggestions? Here's my (failing) test-case (tested using Xen/stable-4.4 - 4.4.1-rc1-28-gee81dda):

https://github.com/talex5/xen/commit/adadfa7e483aa3f3a351c0aeca6a560614fcdead

My guess would be that it is related to the lack of dsb before the initial write to SCTLR which turns on M. Try:

        mrc	p15, 0, r1, c1, c0, 0	@ SCTLR
        orr	r1, r1, #0x1 @ Enable MMU
        dsb
        mcr	p15, 0, r1, c1, c0, 0	@ SCTLR
        isb

Otherwise I worry that the dsb() involved when you turn on caching are causing differences it what you are seeing at this point depending on where you place it. Xen enables caches at the same time and MMU BTW.

Quoted 10 lines
Quoted 8 lines

extras/mini-os/arch/arm/arm32.S line 84

Quoted 5 lines
extras/mini-os/arch/arm/arm32.S new file +5 -0
+       @ Enable MMU / SCTLR
+       @ We leave caches off for now because we're going to be changing the
+       @ TLB a lot and this avoids having to flush the caches each time.
+       mrc     p15, 0, r1, c1, c0, 0   @ SCTLR
+       orr     r1, r1, #0x1            @ Enable MMU

I think you want a dsb here to ensure that any previous PTE write you did when setting up the PTs have actually occurred.

Presumably this isn't needed in the current code, since the caches are off?

The processor can still reorder writes and things like that, so I think it is still needed.

Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
extras/mini-os/arch/arm/arm32.S new file +7 -0
+     bx      r1
+
+@ Called once the MMU is enabled. The boot code and the page table are mapped,
+@ but nothing else is yet.
+@
+@ => r2 -> dtb (physical)
+@    r7 = virtual address of page table
Quoted 8 lines
Quoted 4 lines
+@    r8 = section entry template (flags)
+@    r9 = desired physical - virtual offset
+@    pc -> somewhere in newly-mapped virtual code section

+stage2:

I think you want another dsb around here somewhere to ensure that none of the PT updates you do in a moment float up and interfere with the mapping of the code between the write to SCTLR until the bx r1.

Quoted 1 line

How does that happen? Presumably the isb below will block that.

I don't think it will, it's effectively just a pipeline flush but that doesn't necessarily mean there isn't a write from below already in that pipeline.

(I think, I haven't actually gone back to the spec on this one...)

In Xen we do dsb+isb before and after the TLB flush.

Quoted 22 lines
Quoted 22 lines
Quoted 8 lines
extras/mini-os/arch/arm/arm32.S new file +8 -0
+     @ Invalidate TLB
+     mcr     p15, 0, r1, c8, c7, 0   @ TLBIALL
+     isb
+
+     @ The new mapping has now taken effect:
+     @ r7 -> page_dir
+
+     @ Fill in the whole top-level translation table (at page_dir).

extras/mini-os/arch/arm/arm32.S line 118

Quoted 10 lines
extras/mini-os/arch/arm/arm32.S new file +10 -0
+     @ Populate the whole pagedir with 1MB section descriptors.
+
+     mov     r1, r7                  @ r1 -> first section entry
+     add     r3, r1, #4*4*1024       @ limit (4 GB address space, 4 byte entries)
+     orr     r0, r8, r9              @ r0 = entry mapping section zero to start of physical RAM
+1:
+     str     r0, [r1],#4             @ write the section entry
+     add     r0, r0, #1 << 20        @ next physical page (wraps)
+     cmp     r1, r3
+     bne     1b

dsb here to make sure those writes have actually occurred before you come to rely on them.

Quoted 6 lines
Quoted 3 lines

If there is any chance of any of those writes going through a mapping which you are then changing at the same time then I worry that you might also need a dsb before each write.

The mapping for the translation table itself doesn't change (its entry will be written with the same value as previously).

Phew!

#41 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 33 lines · Ian Campbell
Quoted 18 lines · Thomas Leonard
Quoted 8 lines · Ian Campbell

extras/mini-os/arch/arm/arm32.S line 82

Quoted 3 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S new file +3 -0
+     @ Enable MMU / SCTLR
+     @ We leave caches off for now because we're going to be changing the
+     @ TLB a lot and this avoids having to flush the caches each time.

ARMv7 (or perhaps it was the virt extensions, either way you can rely on it here) makes the MMU cache coherent, so you don't need to flush the caches when doing a PTE write any more.

I tried enabling the D-cache here, but then it frequently (but not always) fails to boot, even with various dsb and isb instructions scattered around.

If I enable the D-cache immediately before the loop that writes the translation table entries, it fails. Adding a dsb after the loop doesn't help. But if I enable it after the loop then it's fine.

Quoted 5 lines

I don't know what's going on there - any suggestions? Here's my (failing) test-case (tested using Xen/stable-4.4 - 4.4.1-rc1-28-gee81dda):

https://github.com/talex5/xen/commit/adadfa7e483aa3f3a351c0aeca6a560614fcdead

My guess would be that it is related to the lack of dsb before the initial write to SCTLR which turns on M. Try:

        mrc     p15, 0, r1, c1, c0, 0   @ SCTLR
        orr     r1, r1, #0x1 @ Enable MMU
        dsb
        mcr     p15, 0, r1, c1, c0, 0   @ SCTLR
        isb
Quoted 3 lines

Otherwise I worry that the dsb() involved when you turn on caching are causing differences it what you are seeing at this point depending on where you place it.

Doesn't help.

Quoted 1 line

Xen enables caches at the same time and MMU BTW.

Also doesn't help (actualy, I only split it out to narrow down the problem a bit).

Quoted 6 lines
Quoted 6 lines
Quoted 6 lines
Quoted 5 lines
extras/mini-os/arch/arm/arm32.S new file +5 -0
+       @ Enable MMU / SCTLR
+       @ We leave caches off for now because we're going to be changing the
+       @ TLB a lot and this avoids having to flush the caches each time.
+       mrc     p15, 0, r1, c1, c0, 0   @ SCTLR
+       orr     r1, r1, #0x1            @ Enable MMU
Quoted 7 lines
Quoted 4 lines
Quoted 2 lines

I think you want a dsb here to ensure that any previous PTE write you did when setting up the PTs have actually occurred.

Presumably this isn't needed in the current code, since the caches are off?

The processor can still reorder writes and things like that, so I think it is still needed.

Ah, I'd assumed it would default everything to Strongly Ordered with the MMU off, but I see it depends on how Xen sets the "Default cacheable" bit.

Quoted 18 lines
Quoted 16 lines
Quoted 7 lines
Quoted 7 lines
extras/mini-os/arch/arm/arm32.S new file +7 -0
+     bx      r1
+
+@ Called once the MMU is enabled. The boot code and the page table are mapped,
+@ but nothing else is yet.
+@
+@ => r2 -> dtb (physical)
+@    r7 = virtual address of page table
Quoted 8 lines
Quoted 4 lines
+@    r8 = section entry template (flags)
+@    r9 = desired physical - virtual offset
+@    pc -> somewhere in newly-mapped virtual code section

+stage2:

I think you want another dsb around here somewhere to ensure that none of the PT updates you do in a moment float up and interfere with the mapping of the code between the write to SCTLR until the bx r1.

Quoted 1 line

How does that happen? Presumably the isb below will block that.

Quoted 7 lines

I don't think it will, it's effectively just a pipeline flush but that doesn't necessarily mean there isn't a write from below already in that pipeline.

(I think, I haven't actually gone back to the spec on this one...)

In Xen we do dsb+isb before and after the TLB flush.

I've added these in various places, but no improvement:

https://github.com/talex5/xen/commit/39199da8493ad6e235849d7ecd51a1415d7d60a7

Quoted 32 lines
Quoted 22 lines
Quoted 22 lines
Quoted 8 lines
extras/mini-os/arch/arm/arm32.S new file +8 -0
+     @ Invalidate TLB
+     mcr     p15, 0, r1, c8, c7, 0   @ TLBIALL
+     isb
+
+     @ The new mapping has now taken effect:
+     @ r7 -> page_dir
+
+     @ Fill in the whole top-level translation table (at page_dir).

extras/mini-os/arch/arm/arm32.S line 118

Quoted 10 lines
extras/mini-os/arch/arm/arm32.S new file +10 -0
+     @ Populate the whole pagedir with 1MB section descriptors.
+
+     mov     r1, r7                  @ r1 -> first section entry
+     add     r3, r1, #4*4*1024       @ limit (4 GB address space, 4 byte entries)
+     orr     r0, r8, r9              @ r0 = entry mapping section zero to start of physical RAM
+1:
+     str     r0, [r1],#4             @ write the section entry
+     add     r0, r0, #1 << 20        @ next physical page (wraps)
+     cmp     r1, r3
+     bne     1b

dsb here to make sure those writes have actually occurred before you come to rely on them.

Quoted 6 lines
Quoted 3 lines

If there is any chance of any of those writes going through a mapping which you are then changing at the same time then I worry that you might also need a dsb before each write.

The mapping for the translation table itself doesn't change (its entry will be written with the same value as previously).

Phew!

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#42 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 6 lines · Thomas Leonard
Quoted 2 lines

The processor can still reorder writes and things like that, so I think it is still needed.

Ah, I'd assumed it would default everything to Strongly Ordered with the MMU off, but I see it depends on how Xen sets the "Default cacheable" bit.

Even if memory accesses are strongly ordered that doesn't include co processor register accesses so they can still be reordered wrt loads/stores.

Quoted 6 lines
Quoted 6 lines
Quoted 1 line

How does that happen? Presumably the isb below will block that.

I don't think it will, it's effectively just a pipeline flush but that doesn't necessarily mean there isn't a write from below already in that pipeline.

Quoted 7 lines
Quoted 3 lines

(I think, I haven't actually gone back to the spec on this one...)

In Xen we do dsb+isb before and after the TLB flush.

I've added these in various places, but no improvement:

https://github.com/talex5/xen/commit/39199da8493ad6e235849d7ecd51a1415d7d60a7

Ah, you aren't setting the cacheability of the PT walks, I bet that's it. If you don't do that then you do need cache maintenance when writing PTEs (or to have caches disabled).

Xen uses LPAE mode and therefore the extended format of TTBCR (called HTCR for Xen), which is where the bits controlling the cacheability of page table walks are held for LPAE.

In non-LPAE mode it looks like the cacheability bits are in TTBR[01] in bits 0..6.

Ian.

#43 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 31 lines · Ian Campbell
Quoted 6 lines · Thomas Leonard
Quoted 2 lines

The processor can still reorder writes and things like that, so I think it is still needed.

Ah, I'd assumed it would default everything to Strongly Ordered with the MMU off, but I see it depends on how Xen sets the "Default cacheable" bit.

Even if memory accesses are strongly ordered that doesn't include co processor register accesses so they can still be reordered wrt loads/stores.

Quoted 6 lines
Quoted 6 lines
Quoted 1 line

How does that happen? Presumably the isb below will block that.

I don't think it will, it's effectively just a pipeline flush but that doesn't necessarily mean there isn't a write from below already in that pipeline.

Quoted 7 lines
Quoted 3 lines

(I think, I haven't actually gone back to the spec on this one...)

In Xen we do dsb+isb before and after the TLB flush.

I've added these in various places, but no improvement:

https://github.com/talex5/xen/commit/39199da8493ad6e235849d7ecd51a1415d7d60a7

Ah, you aren't setting the cacheability of the PT walks, I bet that's it. If you don't do that then you do need cache maintenance when writing PTEs (or to have caches disabled).

Quoted 6 lines

Xen uses LPAE mode and therefore the extended format of TTBCR (called HTCR for Xen), which is where the bits controlling the cacheability of page table walks are held for LPAE.

In non-LPAE mode it looks like the cacheability bits are in TTBR[01] in bits 0..6.

You're right - that was it - thanks!

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#44 lore raw

Re: [PATCH ARM v6 07/14] mini-os: arm: boot code

Quoted 32 lines · Thomas Leonard
Quoted 31 lines · Ian Campbell
Quoted 6 lines · Thomas Leonard
Quoted 2 lines

The processor can still reorder writes and things like that, so I think it is still needed.

Ah, I'd assumed it would default everything to Strongly Ordered with the MMU off, but I see it depends on how Xen sets the "Default cacheable" bit.

Even if memory accesses are strongly ordered that doesn't include co processor register accesses so they can still be reordered wrt loads/stores.

Quoted 6 lines
Quoted 6 lines
Quoted 1 line

How does that happen? Presumably the isb below will block that.

I don't think it will, it's effectively just a pipeline flush but that doesn't necessarily mean there isn't a write from below already in that pipeline.

Quoted 7 lines
Quoted 3 lines

(I think, I haven't actually gone back to the spec on this one...)

In Xen we do dsb+isb before and after the TLB flush.

I've added these in various places, but no improvement:

https://github.com/talex5/xen/commit/39199da8493ad6e235849d7ecd51a1415d7d60a7

Ah, you aren't setting the cacheability of the PT walks, I bet that's it. If you don't do that then you do need cache maintenance when writing PTEs (or to have caches disabled).

Quoted 8 lines
Quoted 6 lines

Xen uses LPAE mode and therefore the extended format of TTBCR (called HTCR for Xen), which is where the bits controlling the cacheability of page table walks are held for LPAE.

In non-LPAE mode it looks like the cacheability bits are in TTBR[01] in bits 0..6.

You're right - that was it - thanks!

My pleasure. You had me scratching my head for a while though ;-)

Ian.

#45 lore raw

PATCH v6 8/14 mini-os: arm: memory management

In reply to Thomas Leonard

Based on an initial patch by Karim Raslan.

---

Changes since v5:

- Require only minimum property lengths (requested by Ian Campbell).

Addressed Julien Grall's comments:
- Added comments explaining the lengths when checking FDT properties.
- Use paddr_t type to represent physical addresses.

---
 extras/mini-os/arch/arm/mm.c | 138 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/mm.c
extras/mini-os/arch/arm/mm.c new file +138 -0
new file mode 100644
index 0000000..ec1f821
@@ -0,0 +1,138 @@
+#include <mini-os/console.h>
+#include <xen/memory.h>
+#include <arch_mm.h>
+#include <mini-os/hypervisor.h>
+#include <libfdt.h>
+#include <lib.h>
+
+int physical_address_offset;
+
+unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
+{
+    // FIXME
+    BUG();
+}
+
+void arch_init_mm(unsigned long *start_pfn_p, unsigned long *max_pfn_p)
+{
+    int memory;
+    int prop_len = 0;
+    const uint64_t *regs;
+
+    printk("    _text: %p(VA)\n", &_text);
+    printk("    _etext: %p(VA)\n", &_etext);
+    printk("    _erodata: %p(VA)\n", &_erodata);
+    printk("    _edata: %p(VA)\n", &_edata);
+    printk("    stack start: %p(VA)\n", _boot_stack);
+    printk("    _end: %p(VA)\n", &_end);
+
+    if (fdt_num_mem_rsv(device_tree) != 0)
+        printk("WARNING: reserved memory not supported!\n");
+
+    memory = fdt_node_offset_by_prop_value(device_tree, -1, "device_type", "memory", sizeof("memory"));
+    if (memory < 0) {
+        printk("No memory found in FDT!\n");
+        BUG();
+    }
+
+    /* Xen will always provide us at least one bank of memory.
+     * Mini-OS will use the first bank for the time-being. */
+    regs = fdt_getprop(device_tree, memory, "reg", &prop_len);
+
+    /* The property must contain at least the start address
+     * and size, each of which is 8-bytes. */
+    if (regs == NULL || prop_len < 16) {
+        printk("Bad 'reg' property: %p %d\n", regs, prop_len);
+        BUG();
+    }
+
+    unsigned int end = (unsigned int) &_end;
+    paddr_t mem_base = fdt64_to_cpu(regs[0]);
+    unsigned int mem_size = fdt64_to_cpu(regs[1]);
+    printk("Found memory at %p (len 0x%x)\n", mem_base, mem_size);
+
+    BUG_ON(to_virt(mem_base) > (void *) &_text);          /* Our image isn't in our RAM! */
+    *start_pfn_p = PFN_UP(to_phys(end));
+    int heap_len = mem_size - (PFN_PHYS(*start_pfn_p) - mem_base);
+    *max_pfn_p = *start_pfn_p + PFN_DOWN(heap_len);
+
+    printk("Using pages %d to %d as free space for heap.\n", *start_pfn_p, *max_pfn_p);
+
+    /* The device tree is probably in memory that we're about to hand over to the page
+     * allocator, so move it to the end and reserve that space.
+     */
+    int fdt_size = fdt_totalsize(device_tree);
+    void *new_device_tree = to_virt(((*max_pfn_p << PAGE_SHIFT) - fdt_size) & PAGE_MASK);
+    if (new_device_tree != device_tree) {
+        memmove(new_device_tree, device_tree, fdt_size);
+    }
+    device_tree = new_device_tree;
+    *max_pfn_p = to_phys(new_device_tree) >> PAGE_SHIFT;
+}
+
+void arch_init_p2m(unsigned long max_pfn)
+{
+}
+
+void arch_init_demand_mapping_area(unsigned long cur_pfn)
+{
+}
+
+/* Get Xen's suggested physical page assignments for the grant table. */
+static paddr_t get_gnttab_base(void)
+{
+    int hypervisor;
+    int len = 0;
+    const uint64_t *regs;
+    paddr_t gnttab_base;
+
+    hypervisor = fdt_node_offset_by_compatible(device_tree, -1, "xen,xen");
+    BUG_ON(hypervisor < 0);
+
+    regs = fdt_getprop(device_tree, hypervisor, "reg", &len);
+    /* The property contains the address and size, 8-bytes each. */
+    if (regs == NULL || len < 16) {
+        printk("Bad 'reg' property: %p %d\n", regs, len);
+        BUG();
+    }
+
+    gnttab_base = fdt64_to_cpu(regs[0]);
+
+    printk("FDT suggests grant table base %lx\n", gnttab_base);
+
+    return gnttab_base;
+}
+
+grant_entry_t *arch_init_gnttab(int nr_grant_frames)
+{
+    struct xen_add_to_physmap xatp;
+    struct gnttab_setup_table setup;
+    xen_pfn_t frames[nr_grant_frames];
+    paddr_t gnttab_table;
+    int i, rc;
+
+    gnttab_table = get_gnttab_base();
+
+    for (i = 0; i < nr_grant_frames; i++)
+    {
+        xatp.domid = DOMID_SELF;
+        xatp.size = 0;      /* Seems to be unused */
+        xatp.space = XENMAPSPACE_grant_table;
+        xatp.idx = i;
+        xatp.gpfn = (gnttab_table >> PAGE_SHIFT) + i;
+        rc = HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp);
+        BUG_ON(rc != 0);
+    }
+
+    setup.dom = DOMID_SELF;
+    setup.nr_frames = nr_grant_frames;
+    set_xen_guest_handle(setup.frame_list, frames);
+    HYPERVISOR_grant_table_op(GNTTABOP_setup_table, &setup, 1);
+    if (setup.status != 0)
+    {
+        printk("GNTTABOP_setup_table failed; status = %d\n", setup.status);
+        BUG();
+    }
+
+    return to_virt(gnttab_table);
+}
Signature · 1 line
2.0.1
#46 lore raw

Re: [PATCH ARM v6 08/14] mini-os: arm: memory management

Hi Thomas,

Quoted 25 lines · Thomas Leonard

Based on an initial patch by Karim Raslan.

---

Changes since v5:

- Require only minimum property lengths (requested by Ian Campbell).

Addressed Julien Grall's comments:
- Added comments explaining the lengths when checking FDT properties.
- Use paddr_t type to represent physical addresses.

---
 extras/mini-os/arch/arm/mm.c | 138 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/mm.c
extras/mini-os/arch/arm/mm.c new file +0 -0
new file mode 100644
index 0000000..ec1f821

extras/mini-os/arch/arm/mm.c line 8

Quoted 8 lines
extras/mini-os/arch/arm/mm.c new file +8 -0
@@ -0,0 +1,138 @@
+#include <mini-os/console.h>
+#include <xen/memory.h>
+#include <arch_mm.h>
+#include <mini-os/hypervisor.h>
+#include <libfdt.h>
+#include <lib.h>
+
+int physical_address_offset;

int64_t maybe?

Quoted 9 lines
extras/mini-os/arch/arm/mm.c new file +9 -0
+
+unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
+{
+    // FIXME
+    BUG();
+}
+
+void arch_init_mm(unsigned long *start_pfn_p, unsigned long *max_pfn_p)
+{

[..]

extras/mini-os/arch/arm/mm.c line 51

Quoted 3 lines
extras/mini-os/arch/arm/mm.c new file +3 -0
+    unsigned int end = (unsigned int) &_end;
+    paddr_t mem_base = fdt64_to_cpu(regs[0]);
+    unsigned int mem_size = fdt64_to_cpu(regs[1]);

mem_size should be a paddr_t. Even though, the first bank will always have the size fit in 32 bits.

extras/mini-os/arch/arm/mm.c line 56

Quoted 5 lines
extras/mini-os/arch/arm/mm.c new file +5 -0
+    printk("Found memory at %p (len 0x%x)\n", mem_base, mem_size);
+
+    BUG_ON(to_virt(mem_base) > (void *) &_text);          /* Our image isn't in our RAM! */
+    *start_pfn_p = PFN_UP(to_phys(end));
+    int heap_len = mem_size - (PFN_PHYS(*start_pfn_p) - mem_base);

You need to use at least an unsigned int here. And it will be better if you use paddr_t.

extras/mini-os/arch/arm/mm.c line 64

Quoted 8 lines
extras/mini-os/arch/arm/mm.c new file +8 -0
+    *max_pfn_p = *start_pfn_p + PFN_DOWN(heap_len);
+
+    printk("Using pages %d to %d as free space for heap.\n", *start_pfn_p, *max_pfn_p);
+
+    /* The device tree is probably in memory that we're about to hand over to the page
+     * allocator, so move it to the end and reserve that space.
+     */
+    int fdt_size = fdt_totalsize(device_tree);

uint32_t has the definition of the field totalsize in the fdt structure.

Regards,

Signature · 1 line
Julien Grall
#47 lore raw

Re: [PATCH ARM v6 08/14] mini-os: arm: memory management

Quoted 22 lines · Julien Grall

Hi Thomas,

Quoted 19 lines · Thomas Leonard

Based on an initial patch by Karim Raslan.

---

Changes since v5:

- Require only minimum property lengths (requested by Ian Campbell).

Addressed Julien Grall's comments:
- Added comments explaining the lengths when checking FDT properties.
- Use paddr_t type to represent physical addresses.

---
 extras/mini-os/arch/arm/mm.c | 138 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 138 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/mm.c
Quoted 16 lines
Quoted 6 lines
extras/mini-os/arch/arm/mm.c new file +0 -0
new file mode 100644
index 0000000..ec1f821

extras/mini-os/arch/arm/mm.c line 8

Quoted 8 lines
extras/mini-os/arch/arm/mm.c new file +8 -0
@@ -0,0 +1,138 @@
+#include <mini-os/console.h>
+#include <xen/memory.h>
+#include <arch_mm.h>
+#include <mini-os/hypervisor.h>
+#include <libfdt.h>
+#include <lib.h>
+
+int physical_address_offset;

int64_t maybe?

Currently we're using the short descriptor format, so we do assume physical addresses are 32-bit. But it probably does make sense to treat them as 64-bit and BUG_ON any we can't handle for now, so I will change this as you suggest.

Quoted 27 lines
Quoted 8 lines
extras/mini-os/arch/arm/mm.c new file +8 -0
+unsigned long allocate_ondemand(unsigned long n, unsigned long alignment)
+{
+    // FIXME
+    BUG();
+}
+
+void arch_init_mm(unsigned long *start_pfn_p, unsigned long *max_pfn_p)
+{

[..]

extras/mini-os/arch/arm/mm.c line 51

Quoted 3 lines
extras/mini-os/arch/arm/mm.c new file +3 -0
+    unsigned int end = (unsigned int) &_end;
+    paddr_t mem_base = fdt64_to_cpu(regs[0]);
+    unsigned int mem_size = fdt64_to_cpu(regs[1]);

mem_size should be a paddr_t. Even though, the first bank will always have the size fit in 32 bits.

extras/mini-os/arch/arm/mm.c line 56

Quoted 5 lines
extras/mini-os/arch/arm/mm.c new file +5 -0
+    printk("Found memory at %p (len 0x%x)\n", mem_base, mem_size);
+
+    BUG_ON(to_virt(mem_base) > (void *) &_text);          /* Our image isn't in our RAM! */
+    *start_pfn_p = PFN_UP(to_phys(end));
+    int heap_len = mem_size - (PFN_PHYS(*start_pfn_p) - mem_base);

You need to use at least an unsigned int here. And it will be better if you use paddr_t.

Quoted 10 lines

extras/mini-os/arch/arm/mm.c line 64

Quoted 8 lines
extras/mini-os/arch/arm/mm.c new file +8 -0
+    *max_pfn_p = *start_pfn_p + PFN_DOWN(heap_len);
+
+    printk("Using pages %d to %d as free space for heap.\n", *start_pfn_p, *max_pfn_p);
+
+    /* The device tree is probably in memory that we're about to hand over to the page
+     * allocator, so move it to the end and reserve that space.
+     */
+    int fdt_size = fdt_totalsize(device_tree);

uint32_t has the definition of the field totalsize in the fdt structure.

OK.

Quoted 4 lines

Regards,

--
Julien Grall

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#48 lore raw

PATCH v6 9/14 mini-os: arm: scheduling

In reply to Thomas Leonard

Based on an initial patch by Karim Raslan.

---
 extras/mini-os/arch/arm/arm32.S | 22 ++++++++++++++++++++++
 extras/mini-os/arch/arm/sched.c | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/sched.c
extras/mini-os/arch/arm/arm32.S +22 -0
index 88efe24..56429b1 100644
@@ -204,8 +204,30 @@ irq_handler:
 IRQ_handler:
 	.long	0x0
 
+
+.globl __arch_switch_threads
+@ => r0 = &prev->sp
+@    r1 = &next->sp
+@ <= returns to next thread's saved return address
+__arch_switch_threads:
+	stmia	r0, {sp, lr}	@ Store current sp and ip to prev's struct thread
+	str	fp, [sp, #-4]	@ Store fp on the old stack
+
+	ldmia	r1, {sp, lr}	@ Load new sp, ip from next's struct thread
+	ldr	fp, [sp, #-4]	@ Restore fp from the stack
+
+	mov	pc, lr
+
 @ This is called if you try to divide by zero. For now, we make a supervisor call,
 @ which will make us halt.
 .globl raise
 raise:
 	svc	0
+
+.globl arm_start_thread
+arm_start_thread:
+	pop	{r0, r1}
+	@ r0 = user data
+	@ r1 -> thread's main function
+	ldr	lr, =exit_thread
+	bx	r1
extras/mini-os/arch/arm/sched.c new file +38 -0
new file mode 100644
index 0000000..9fb884e
@@ -0,0 +1,38 @@
+#include <mini-os/sched.h>
+#include <mini-os/xmalloc.h>
+#include <mini-os/console.h>
+
+void arm_start_thread(void);
+
+/* Architecture specific setup of thread creation */
+struct thread* arch_create_thread(char *name, void (*function)(void *),
+                                  void *data)
+{
+    struct thread *thread;
+
+    thread = xmalloc(struct thread);
+    /* We can't use lazy allocation here since the trap handler runs on the stack */
+    thread->stack = (char *)alloc_pages(STACK_SIZE_PAGE_ORDER);
+    thread->name = name;
+    printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread,
+            thread->stack);
+
+    /* Save pointer to the thread on the stack, used by current macro */
+    *((unsigned long *)thread->stack) = (unsigned long)thread;
+
+    /* Push the details to pass to arm_start_thread onto the stack */
+    int *sp = (int *) (thread->stack + STACK_SIZE);
+    *(--sp) = (int) function;
+    *(--sp) = (int) data;
+    thread->sp = (unsigned long) sp;
+
+    thread->ip = (unsigned long) arm_start_thread;
+
+    return thread;
+}
+
+void run_idle_thread(void)
+{
+    __asm__ __volatile__ ("mov sp, %0; mov pc, %1"::"r"(idle_thread->sp), "r"(idle_thread->ip));
+    /* Never arrive here! */
+}
Signature · 1 line
2.0.1
#49 lore raw

Re: [PATCH ARM v6 09/14] mini-os: arm: scheduling

Quoted 21 lines · Thomas Leonard

Based on an initial patch by Karim Raslan.

---
 extras/mini-os/arch/arm/arm32.S | 22 ++++++++++++++++++++++
 extras/mini-os/arch/arm/sched.c | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/sched.c
extras/mini-os/arch/arm/arm32.S +3 -0
index 88efe24..56429b1 100644
@@ -204,8 +204,30 @@ irq_handler:
 IRQ_handler:
 	.long	0x0
 
+
+.globl __arch_switch_threads
+@ => r0 = &prev->sp

extras/mini-os/arch/arm/arm32.S irq_handler: · line 219

Quoted 10 lines
extras/mini-os/arch/arm/arm32.S +10 -0
+@    r1 = &next->sp
+@ <= returns to next thread's saved return address
+__arch_switch_threads:
+	stmia	r0, {sp, lr}	@ Store current sp and ip to prev's struct thread
+	str	fp, [sp, #-4]	@ Store fp on the old stack
+
+	ldmia	r1, {sp, lr}	@ Load new sp, ip from next's struct thread
+	ldr	fp, [sp, #-4]	@ Restore fp from the stack
+
+	mov	pc, lr

I'm a bit confused by the lack of saving of the GPRs here. Shouldn't at least the caller saved registers (r4..r11) be saved/restored here?

extras/mini-os/arch/arm/arm32.S irq_handler: · line 222

Quoted 3 lines
extras/mini-os/arch/arm/arm32.S +3 -0
+void run_idle_thread(void)
+{
+    __asm__ __volatile__ ("mov sp, %0; mov pc, %1"::"r"(idle_thread->sp), "r"(idle_thread->ip));

Is bx preferred to mov pc these days? I don't know if it matters in this case...

Quoted 2 lines
extras/mini-os/arch/arm/arm32.S +2 -0
+    /* Never arrive here! */
+}
#50 lore raw

Re: [PATCH ARM v6 09/14] mini-os: arm: scheduling

Quoted 19 lines · Ian Campbell
Quoted 18 lines · Thomas Leonard

Based on an initial patch by Karim Raslan.

---
 extras/mini-os/arch/arm/arm32.S | 22 ++++++++++++++++++++++
 extras/mini-os/arch/arm/sched.c | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/sched.c
extras/mini-os/arch/arm/arm32.S +0 -0
index 88efe24..56429b1 100644
@@ -204,8 +204,30 @@ irq_handler:
 IRQ_handler:
      .long   0x0
 
Quoted 16 lines

extras/mini-os/arch/arm/arm32.S irq_handler: · line 219

Quoted 13 lines
extras/mini-os/arch/arm/arm32.S +13 -0
+
+.globl __arch_switch_threads
+@ => r0 = &prev->sp
+@    r1 = &next->sp
+@ <= returns to next thread's saved return address
+__arch_switch_threads:
+     stmia   r0, {sp, lr}    @ Store current sp and ip to prev's struct thread
+     str     fp, [sp, #-4]   @ Store fp on the old stack
+
+     ldmia   r1, {sp, lr}    @ Load new sp, ip from next's struct thread
+     ldr     fp, [sp, #-4]   @ Restore fp from the stack
+
+     mov     pc, lr

I'm a bit confused by the lack of saving of the GPRs here. Shouldn't at least the caller saved registers (r4..r11) be saved/restored here?

If they were caller saved then sched.c would save them itself before calling switch_threads. But the AAPCS says:

"A subroutine must preserve the contents of the registers r4-r8, r10, r11 and SP (and r9 in PCS variants that designate r9 as v6)."

So I think these are callee-saved and we should save them here.

Quoted 6 lines

extras/mini-os/arch/arm/arm32.S irq_handler: · line 222

Quoted 3 lines
extras/mini-os/arch/arm/arm32.S +3 -0
+void run_idle_thread(void)
+{
+    __asm__ __volatile__ ("mov sp, %0; mov pc, %1"::"r"(idle_thread->sp), "r"(idle_thread->ip));

Is bx preferred to mov pc these days? I don't know if it matters in this case...

Yes, that would probably be better (in both places).

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#51 lore raw

Re: [PATCH ARM v6 09/14] mini-os: arm: scheduling

Quoted 37 lines · Thomas Leonard
Quoted 19 lines · Ian Campbell
Quoted 18 lines · Thomas Leonard

Based on an initial patch by Karim Raslan.

---
 extras/mini-os/arch/arm/arm32.S | 22 ++++++++++++++++++++++
 extras/mini-os/arch/arm/sched.c | 38 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 60 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/sched.c
extras/mini-os/arch/arm/arm32.S +0 -0
index 88efe24..56429b1 100644
@@ -204,8 +204,30 @@ irq_handler:
 IRQ_handler:
      .long   0x0
 
Quoted 16 lines

extras/mini-os/arch/arm/arm32.S irq_handler: · line 219

Quoted 13 lines
extras/mini-os/arch/arm/arm32.S +13 -0
+
+.globl __arch_switch_threads
+@ => r0 = &prev->sp
+@    r1 = &next->sp
+@ <= returns to next thread's saved return address
+__arch_switch_threads:
+     stmia   r0, {sp, lr}    @ Store current sp and ip to prev's struct thread
+     str     fp, [sp, #-4]   @ Store fp on the old stack
+
+     ldmia   r1, {sp, lr}    @ Load new sp, ip from next's struct thread
+     ldr     fp, [sp, #-4]   @ Restore fp from the stack
+
+     mov     pc, lr

I'm a bit confused by the lack of saving of the GPRs here. Shouldn't at least the caller saved registers (r4..r11) be saved/restored here?

Quoted 7 lines

If they were caller saved then sched.c would save them itself before calling switch_threads. But the AAPCS says:

"A subroutine must preserve the contents of the registers r4-r8, r10, r11 and SP (and r9 in PCS variants that designate r9 as v6)."

So I think these are callee-saved and we should save them here.

I had a typo in my register/AAPCS cheatsheet but not in my head, so I was kind of right for the wrong reason ;-). r4..r11 are indeed *callee* saved.

Normally on ctxt switch you would save and restore everything to prevent information leaks but since mini-os processes^Wthreads are mutually trusting it doesn't seem entirely necessary here (but it does save remembering which registers are which ;-)).

Ian.

#52 lore raw

PATCH v6 10/14 mini-os: arm: events

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

---
 extras/mini-os/arch/arm/events.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/events.c
extras/mini-os/arch/arm/events.c new file +31 -0
new file mode 100644
index 0000000..441010d
@@ -0,0 +1,31 @@
+#include <mini-os/os.h>
+#include <mini-os/events.h>
+#include <mini-os/hypervisor.h>
+#include <mini-os/console.h>
+
+static void virq_debug(evtchn_port_t port, struct pt_regs *regs, void *params)
+{
+    printk("Received a virq_debug event\n");
+}
+
+evtchn_port_t debug_port = -1;
+void arch_init_events(void)
+{
+    debug_port = bind_virq(VIRQ_DEBUG, (evtchn_handler_t)virq_debug, 0);
+    if(debug_port == -1)
+        BUG();
+    unmask_evtchn(debug_port);
+}
+
+void arch_unbind_ports(void)
+{
+    if(debug_port != -1)
+    {
+        mask_evtchn(debug_port);
+        unbind_evtchn(debug_port);
+    }
+}
+
+void arch_fini_events(void)
+{
+}
Signature · 1 line
2.0.1
Acked-by on v6 10/14
#53 lore raw

Re: [PATCH ARM v6 10/14] mini-os: arm: events

Quoted 15 lines · Thomas Leonard

From: Karim Raslan <[email protected]>

---
 extras/mini-os/arch/arm/events.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/events.c
extras/mini-os/arch/arm/events.c new file +0 -0
new file mode 100644
index 0000000..441010d

extras/mini-os/arch/arm/events.c line 8

Quoted 8 lines
extras/mini-os/arch/arm/events.c new file +8 -0
@@ -0,0 +1,31 @@
+#include <mini-os/os.h>
+#include <mini-os/events.h>
+#include <mini-os/hypervisor.h>
+#include <mini-os/console.h>
+
+static void virq_debug(evtchn_port_t port, struct pt_regs *regs, void *params)
+{
+    printk("Received a virq_debug event\n");

It hardly seems worth the effort of receiving this ;-)

#54 lore raw

PATCH v6 11/14 mini-os: arm: time

In reply to Thomas Leonard

Based on an initial patch by Karim Raslan.

---
 extras/mini-os/arch/arm/time.c | 202 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 202 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/time.c
extras/mini-os/arch/arm/time.c new file +202 -0
new file mode 100644
index 0000000..a522aa9
@@ -0,0 +1,202 @@
+#include <mini-os/os.h>
+#include <mini-os/hypervisor.h>
+#include <mini-os/events.h>
+#include <mini-os/traps.h>
+#include <mini-os/types.h>
+#include <mini-os/time.h>
+#include <mini-os/lib.h>
+
+//#define VTIMER_DEBUG
+#ifdef VTIMER_DEBUG
+#define DEBUG(_f, _a...) \
+    printk("MINI_OS(file=vtimer.c, line=%d) " _f , __LINE__, ## _a)
+#else
+#define DEBUG(_f, _a...)    ((void)0)
+#endif
+
+/************************************************************************
+ * Time functions
+ *************************************************************************/
+
+static uint64_t cntvct_at_init;
+static uint32_t counter_freq;
+
+/* Compute with 96 bit intermediate result: (a*b)/c */
+uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
+{
+    union {
+        uint64_t ll;
+        struct {
+            uint32_t low, high;
+        } l;
+    } u, res;
+    uint64_t rl, rh;
+
+    u.ll = a;
+    rl = (uint64_t)u.l.low * (uint64_t)b;
+    rh = (uint64_t)u.l.high * (uint64_t)b;
+    rh += (rl >> 32);
+    res.l.high = rh / c;
+    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
+    return res.ll;
+}
+
+static inline s_time_t ticks_to_ns(uint64_t ticks)
+{
+    return muldiv64(ticks, SECONDS(1), counter_freq);
+}
+
+static inline uint64_t ns_to_ticks(s_time_t ns)
+{
+    return muldiv64(ns, counter_freq, SECONDS(1));
+}
+
+/* These are peridically updated in shared_info, and then copied here. */
+struct shadow_time_info {
+    uint64_t tsc_timestamp;     /* TSC at last update of time vals.  */
+    uint64_t system_timestamp;  /* Time, in nanosecs, since boot.    */
+    uint32_t tsc_to_nsec_mul;
+    uint32_t tsc_to_usec_mul;
+    int tsc_shift;
+    uint32_t version;
+};
+static struct timespec shadow_ts;
+static uint32_t shadow_ts_version;
+
+static struct shadow_time_info shadow;
+
+static void get_time_values_from_xen(void)
+{
+    struct vcpu_time_info    *src = &HYPERVISOR_shared_info->vcpu_info[0].time;
+
+     do {
+        shadow.version = src->version;
+        rmb();
+        shadow.tsc_timestamp     = src->tsc_timestamp;
+        shadow.system_timestamp  = src->system_time;
+        shadow.tsc_to_nsec_mul   = src->tsc_to_system_mul;
+        shadow.tsc_shift         = src->tsc_shift;
+        rmb();
+    }
+    while ((src->version & 1) | (shadow.version ^ src->version));
+
+    shadow.tsc_to_usec_mul = shadow.tsc_to_nsec_mul / 1000;
+}
+
+static inline uint64_t read_virtual_count(void)
+{
+    uint32_t c_lo, c_hi;
+    __asm__ __volatile__("isb;mrrc p15, 1, %0, %1, c14":"=r"(c_lo), "=r"(c_hi));
+    return (((uint64_t) c_hi) << 32) + c_lo;
+}
+
+/* monotonic_clock(): returns # of nanoseconds passed since time_init()
+ *        Note: This function is required to return accurate
+ *        time even in the absence of multiple timer ticks.
+ */
+uint64_t monotonic_clock(void)
+{
+    s_time_t time = ticks_to_ns(read_virtual_count() - cntvct_at_init);
+    //printk("monotonic_clock: %llu (%llu)\n", time, NSEC_TO_SEC(time));
+    return time;
+}
+
+static void update_wallclock(void)
+{
+    shared_info_t *s = HYPERVISOR_shared_info;
+
+    do {
+        shadow_ts_version = s->wc_version;
+        rmb();
+        shadow_ts.tv_sec  = s->wc_sec;
+        shadow_ts.tv_nsec = s->wc_nsec;
+        rmb();
+    }
+    while ((s->wc_version & 1) | (shadow_ts_version ^ s->wc_version));
+}
+
+
+int gettimeofday(struct timeval *tv, void *tz)
+{
+    uint64_t nsec = monotonic_clock();
+    nsec += shadow_ts.tv_nsec;
+
+    tv->tv_sec = shadow_ts.tv_sec;
+    tv->tv_sec += NSEC_TO_SEC(nsec);
+    tv->tv_usec = NSEC_TO_USEC(nsec % 1000000000UL);
+
+    return 0;
+}
+
+void set_vtimer_compare(uint64_t value) {
+    uint32_t x, y;
+
+    DEBUG("New CompareValue : %llx\n", value);
+    x = 0xFFFFFFFFULL & value;
+    y = (value >> 32) & 0xFFFFFFFF;
+
+    __asm__ __volatile__("mcrr p15, 3, %0, %1, c14"
+            ::"r"(x), "r"(y));
+
+    __asm__ __volatile__("mov %0, #0x1\n"
+            "mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */
+            "isb":"=r"(x));
+}
+
+void unset_vtimer_compare(void) {
+    uint32_t x;
+
+    __asm__ __volatile__("mov %0, #0x2\n"
+            "mcr p15, 0, %0, c14, c3, 1\n" /* Disable timer and mask the output signal */
+            "isb":"=r"(x));
+}
+
+void block_domain(s_time_t until)
+{
+    uint64_t until_count = ns_to_ticks(until) + cntvct_at_init;
+    ASSERT(irqs_disabled());
+    if (read_virtual_count() < until_count)
+    {
+        set_vtimer_compare(until_count);
+        //char buf[] = "sleep\n"; (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
+        __asm__ __volatile__("wfi");
+        //char wake[] = "wake\n"; (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(wake), wake);
+        unset_vtimer_compare();
+
+        /* Give the IRQ handler a chance to handle whatever woke us up. */
+        local_irq_enable();
+        local_irq_disable();
+    }
+}
+
+void timer_handler(evtchn_port_t port, struct pt_regs *regs, void *ign)
+{
+    DEBUG("Timer kick\n");
+    get_time_values_from_xen();
+    update_wallclock();
+}
+
+evtchn_port_t timer_port = -1;
+
+void init_time(void)
+{
+    printk("Initialising timer interface\n");
+
+    __asm__ __volatile__("mrc p15, 0, %0, c14, c0, 0":"=r"(counter_freq));
+    cntvct_at_init = read_virtual_count();
+    printk("Virtual Count register is %llx, freq = %d Hz\n", cntvct_at_init, counter_freq);
+
+    timer_port = bind_virq(VIRQ_TIMER, (evtchn_handler_t)timer_handler, 0);
+    if (timer_port == -1)
+        BUG();
+    unmask_evtchn(timer_port);
+}
+
+void fini_time(void)
+{
+    if (timer_port != -1)
+    {
+        mask_evtchn(timer_port);
+        unbind_evtchn(timer_port);
+    }
+}
Signature · 1 line
2.0.1
#55 lore raw

Re: [PATCH ARM v6 11/14] mini-os: arm: time

Hi Thomas,

Quoted 21 lines · Thomas Leonard
extras/mini-os/arch/arm/time.c new file +21 -0
+/* These are peridically updated in shared_info, and then copied here. */
+struct shadow_time_info {
+    uint64_t tsc_timestamp;     /* TSC at last update of time vals.  */
+    uint64_t system_timestamp;  /* Time, in nanosecs, since boot.    */
+    uint32_t tsc_to_nsec_mul;
+    uint32_t tsc_to_usec_mul;
+    int tsc_shift;
+    uint32_t version;
+};
+static struct timespec shadow_ts;
+static uint32_t shadow_ts_version;
+
+static struct shadow_time_info shadow;
+
+static void get_time_values_from_xen(void)
+{
+    struct vcpu_time_info    *src = &HYPERVISOR_shared_info->vcpu_info[0].time;
+
+     do {
+        shadow.version = src->version;
+        rmb();

extras/mini-os/arch/arm/time.c line 84

Quoted 10 lines
extras/mini-os/arch/arm/time.c new file +10 -0
+        shadow.tsc_timestamp     = src->tsc_timestamp;
+        shadow.system_timestamp  = src->system_time;
+        shadow.tsc_to_nsec_mul   = src->tsc_to_system_mul;
+        shadow.tsc_shift         = src->tsc_shift;
+        rmb();
+    }
+    while ((src->version & 1) | (shadow.version ^ src->version));
+
+    shadow.tsc_to_usec_mul = shadow.tsc_to_nsec_mul / 1000;
+}

It looks the code above is the same as x86. Did you think about sharing the code which used Xen time?

Looking closer to this patch, nothing is using the field of this shared structure, which is CPU time consuming and adding line for no improvement. So I think you can drop all the code related the PV timer for now.

Regards,

Signature · 1 line
Julien Grall
#56 lore raw

Re: [PATCH ARM v6 11/14] mini-os: arm: time

Quoted 38 lines · Julien Grall

Hi Thomas,

Quoted 21 lines · Thomas Leonard
extras/mini-os/arch/arm/time.c new file +21 -0
+/* These are peridically updated in shared_info, and then copied here. */
+struct shadow_time_info {
+    uint64_t tsc_timestamp;     /* TSC at last update of time vals.  */
+    uint64_t system_timestamp;  /* Time, in nanosecs, since boot.    */
+    uint32_t tsc_to_nsec_mul;
+    uint32_t tsc_to_usec_mul;
+    int tsc_shift;
+    uint32_t version;
+};
+static struct timespec shadow_ts;
+static uint32_t shadow_ts_version;
+
+static struct shadow_time_info shadow;
+
+static void get_time_values_from_xen(void)
+{
+    struct vcpu_time_info    *src = &HYPERVISOR_shared_info->vcpu_info[0].time;
+
+     do {
+        shadow.version = src->version;
+        rmb();

extras/mini-os/arch/arm/time.c line 84

Quoted 10 lines
extras/mini-os/arch/arm/time.c new file +10 -0
+        shadow.tsc_timestamp     = src->tsc_timestamp;
+        shadow.system_timestamp  = src->system_time;
+        shadow.tsc_to_nsec_mul   = src->tsc_to_system_mul;
+        shadow.tsc_shift         = src->tsc_shift;
+        rmb();
+    }
+    while ((src->version & 1) | (shadow.version ^ src->version));
+
+    shadow.tsc_to_usec_mul = shadow.tsc_to_nsec_mul / 1000;
+}

It looks the code above is the same as x86. Did you think about sharing the code which used Xen time?

Quoted 4 lines

Looking closer to this patch, nothing is using the field of this shared structure, which is CPU time consuming and adding line for no improvement. So I think you can drop all the code related the PV timer for now.

Does Xen even populate this struct on ARM? I'm not sure...

Ian.

#57 lore raw

PATCH v6 12/14 mini-os: arm: interrupt controller

In reply to Thomas Leonard

Based on an initial patch by Karim Raslan.

---

Changes since v5:

Addressed Julien Grall's comments:
- Added comments explaining the lengths when checking FDT properties.
- Fixed (commented) DEBUG macro.
- Drop check for arm,cortex-a9-gic.

- Require only minimum property lengths (requested by Ian Campbell).

---
 extras/mini-os/arch/arm/gic.c | 232 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 232 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/gic.c
extras/mini-os/arch/arm/gic.c new file +232 -0
new file mode 100644
index 0000000..1afa099
@@ -0,0 +1,232 @@
+// ARM GIC implementation
+
+#include <mini-os/os.h>
+#include <mini-os/hypervisor.h>
+#include <mini-os/console.h>
+#include <libfdt.h>
+
+//#define VGIC_DEBUG
+#ifdef VGIC_DEBUG
+#define DEBUG(_f, _a...) \
+    printk("MINI_OS(file=vgic.c, line=%d) " _f , __LINE__, ## _a)
+#else
+#define DEBUG(_f, _a...)    ((void)0)
+#endif
+
+extern void (*IRQ_handler)(void);
+
+struct gic {
+    volatile char *gicd_base;
+    volatile char *gicc_base;
+};
+
+static struct gic gic;
+
+// Distributor Interface
+#define GICD_CTLR        0x0
+#define GICD_ISENABLER    0x100
+#define GICD_IPRIORITYR   0x400
+#define GICD_ITARGETSR    0x800
+#define GICD_ICFGR        0xC00
+
+// CPU Interface
+#define GICC_CTLR    0x0
+#define GICC_PMR    0x4
+#define GICC_IAR    0xc
+#define GICC_EOIR    0x10
+#define GICC_HPPIR    0x18
+
+#define gicd(gic, offset) ((gic)->gicd_base + (offset))
+#define gicc(gic, offset) ((gic)->gicc_base + (offset))
+
+#define REG(addr) ((uint32_t *)(addr))
+
+static inline uint32_t REG_READ32(volatile uint32_t *addr)
+{
+    uint32_t value;
+    __asm__ __volatile__("ldr %0, [%1]":"=&r"(value):"r"(addr));
+    rmb();
+    return value;
+}
+
+static inline void REG_WRITE32(volatile uint32_t *addr, unsigned int value)
+{
+    __asm__ __volatile__("str %0, [%1]"::"r"(value), "r"(addr));
+    wmb();
+}
+
+static void gic_set_priority(struct gic *gic, int irq_number, unsigned char priority)
+{
+    uint32_t value;
+    uint32_t *addr = REG(gicd(gic, GICD_IPRIORITYR)) + (irq_number >> 2);
+    value = REG_READ32(addr);
+    value &= ~(0xff << (8 * (irq_number & 0x3))); // clear old priority
+    value |= priority << (8 * (irq_number & 0x3)); // set new priority
+    REG_WRITE32(addr, value);
+}
+
+static void gic_route_interrupt(struct gic *gic, int irq_number, unsigned char cpu_set)
+{
+    uint32_t value;
+    uint32_t *addr = REG(gicd(gic, GICD_ITARGETSR)) + (irq_number >> 2);
+    value = REG_READ32(addr);
+    value &= ~(0xff << (8 * (irq_number & 0x3))); // clear old target
+    value |= cpu_set << (8 * (irq_number & 0x3)); // set new target
+    REG_WRITE32(addr, value);
+}
+
+/* When accessing the GIC registers, we can't use LDREX/STREX because it's not regular memory. */
+static __inline__ void clear_bit_non_atomic(int nr, volatile void *base)
+{
+    volatile uint32_t *tmp = base;
+    tmp[nr >> 5] &= (unsigned long)~(1 << (nr & 0x1f));
+}
+
+static __inline__ void set_bit_non_atomic(int nr, volatile void *base)
+{
+    volatile uint32_t *tmp = base;
+    tmp[nr >> 5] |= (1 << (nr & 0x1f));
+}
+
+/* Note: not thread safe (but we only support one CPU for now anyway) */
+static void gic_enable_interrupt(struct gic *gic, int irq_number,
+        unsigned char cpu_set, unsigned char level_sensitive, unsigned char ppi)
+{
+    void *set_enable_reg;
+    void *cfg_reg;
+
+    // set priority
+    gic_set_priority(gic, irq_number, 0x0);
+
+    // set target cpus for this interrupt
+    gic_route_interrupt(gic, irq_number, cpu_set);
+
+    // set level/edge triggered
+    cfg_reg = (void *)gicd(gic, GICD_ICFGR);
+    level_sensitive ? clear_bit_non_atomic((irq_number * 2) + 1, cfg_reg) : set_bit_non_atomic((irq_number * 2) + 1, cfg_reg);
+    if(ppi)
+        clear_bit_non_atomic((irq_number * 2), cfg_reg);
+
+    wmb();
+
+    // enable forwarding interrupt from distributor to cpu interface
+    set_enable_reg = (void *)gicd(gic, GICD_ISENABLER);
+    set_bit_non_atomic(irq_number, set_enable_reg);
+    wmb();
+}
+
+static void gic_enable_interrupts(struct gic *gic)
+{
+    // Global enable forwarding interrupts from distributor to cpu interface
+    REG_WRITE32(REG(gicd(gic, GICD_CTLR)), 0x00000001);
+
+    // Global enable signalling of interrupt from the cpu interface
+    REG_WRITE32(REG(gicc(gic, GICC_CTLR)), 0x00000001);
+}
+
+static void gic_disable_interrupts(struct gic *gic)
+{
+    // Global disable signalling of interrupt from the cpu interface
+    REG_WRITE32(REG(gicc(gic, GICC_CTLR)), 0x00000000);
+
+    // Global disable forwarding interrupts from distributor to cpu interface
+    REG_WRITE32(REG(gicd(gic, GICD_CTLR)), 0x00000000);
+}
+
+static void gic_cpu_set_priority(struct gic *gic, char priority)
+{
+    REG_WRITE32(REG(gicc(gic, GICC_PMR)), priority & 0x000000FF);
+}
+
+static unsigned long gic_readiar(struct gic *gic) {
+    return REG_READ32(REG(gicc(gic, GICC_IAR))) & 0x000003FF; // Interrupt ID
+}
+
+static void gic_eoir(struct gic *gic, uint32_t irq) {
+    REG_WRITE32(REG(gicc(gic, GICC_EOIR)), irq & 0x000003FF);
+}
+
+//FIXME Get event_irq from dt
+#define EVENTS_IRQ 31
+#define VIRTUALTIMER_IRQ 27
+
+static void gic_handler(void) {
+    unsigned int irq = gic_readiar(&gic);
+
+    DEBUG("IRQ received : %i\n", irq);
+    switch(irq) {
+    case EVENTS_IRQ:
+        do_hypervisor_callback(NULL);
+        break;
+    case VIRTUALTIMER_IRQ:
+        timer_handler(0, NULL, 0);
+        break;
+    default:
+        DEBUG("Unhandled irq\n");
+        break;
+    }
+
+    DEBUG("EIRQ\n");
+
+    gic_eoir(&gic, irq);
+}
+
+void gic_init(void) {
+    gic.gicd_base = NULL;
+    int node = 0;
+    int depth = 0;
+    for (;;)
+    {
+        node = fdt_next_node(device_tree, node, &depth);
+        if (node <= 0 || depth < 0)
+            break;
+
+        if (fdt_getprop(device_tree, node, "interrupt-controller", NULL)) {
+            int len = 0;
+
+            if (fdt_node_check_compatible(device_tree, node, "arm,cortex-a15-gic") &&
+                fdt_node_check_compatible(device_tree, node, "arm,cortex-a7-gic")) {
+                printk("Skipping incompatible interrupt-controller node\n");
+                continue;
+            }
+
+            const uint64_t *reg = fdt_getprop(device_tree, node, "reg", &len);
+
+            /* We have two registers (GICC and GICD), each of which contains
+             * two parts (an address and a size), each of which is a 64-bit
+             * value (8 bytes), so we expect a length of 2 * 2 * 8 = 32.
+             * If any extra values are passed in future, we ignore them. */
+            if (reg == NULL || len < 32) {
+                printk("Bad 'reg' property: %p %d\n", reg, len);
+                continue;
+            }
+
+            gic.gicd_base = to_virt((long) fdt64_to_cpu(reg[0]));
+            gic.gicc_base = to_virt((long) fdt64_to_cpu(reg[2]));
+            printk("Found GIC: gicd_base = %p, gicc_base = %p\n", gic.gicd_base, gic.gicc_base);
+            break;
+        }
+    }
+    if (!gic.gicd_base) {
+        printk("GIC not found!\n");
+        BUG();
+    }
+    wmb();
+
+    /* Note: we could mark this as "device" memory here, but Xen will have already
+     * set it that way in the second stage translation table, so it's not necessary.
+     * See "Overlaying the memory type attribute" in the Architecture Reference Manual.
+     */
+
+    IRQ_handler = gic_handler;
+
+    gic_disable_interrupts(&gic);
+    gic_cpu_set_priority(&gic, 0xff);
+
+    /* Must call gic_enable_interrupts before enabling individual interrupts, otherwise our IRQ handler
+     * gets called endlessly with spurious interrupts. */
+    gic_enable_interrupts(&gic);
+
+    gic_enable_interrupt(&gic, EVENTS_IRQ /* interrupt number */, 0x1 /*cpu_set*/, 1 /*level_sensitive*/, 0 /* ppi */);
+    gic_enable_interrupt(&gic, VIRTUALTIMER_IRQ /* interrupt number */, 0x1 /*cpu_set*/, 1 /*level_sensitive*/, 1 /* ppi */);
+}
Signature · 1 line
2.0.1
#58 lore raw

Re: [PATCH ARM v6 12/14] mini-os: arm: interrupt controller

Hi Thomas,

Quoted 6 lines · Thomas Leonard
extras/mini-os/arch/arm/gic.c new file +6 -0
+/* Note: not thread safe (but we only support one CPU for now anyway) */
+static void gic_enable_interrupt(struct gic *gic, int irq_number,
+        unsigned char cpu_set, unsigned char level_sensitive, unsigned char ppi)
+{
+    void *set_enable_reg;
+    void *cfg_reg;

extras/mini-os/arch/arm/gic.c line 106

Quoted 10 lines
extras/mini-os/arch/arm/gic.c new file +10 -0
+
+    // set priority
+    gic_set_priority(gic, irq_number, 0x0);
+
+    // set target cpus for this interrupt
+    gic_route_interrupt(gic, irq_number, cpu_set);
+
+    // set level/edge triggered
+    cfg_reg = (void *)gicd(gic, GICD_ICFGR);
+    level_sensitive ? clear_bit_non_atomic((irq_number * 2) + 1, cfg_reg) : set_bit_non_atomic((irq_number * 2) + 1, cfg_reg);

I didn't spot this before. Why didn't you use if (level_sensitive)...?

I found this line very hard to read.

[..]

extras/mini-os/arch/arm/gic.c line 151

Quoted 3 lines
extras/mini-os/arch/arm/gic.c new file +3 -0
+//FIXME Get event_irq from dt
+#define EVENTS_IRQ 31
+#define VIRTUALTIMER_IRQ 27

Any plan to get this from the DT soon?

The rest of the patch looks good to me.

Regards,

Signature · 1 line
Julien Grall
#59 lore raw

PATCH v6 13/14 mini-os: arm: build system

In reply to Thomas Leonard

Based on an initial patch by Karim Raslan.

This activates the ARM code added in the previous patches. On ARM, Mini-OS will boot and display some output on the console. Tested with:

make XEN_TARGET_ARCH=arm32 CROSS_COMPILE=arm-linux-gnueabihf- \
	CONFIG_TEST=y CONFIG_START_NETWORK=n CONFIG_BLKFRONT=n \
	CONFIG_NETFRONT=n CONFIG_FBFRONT=n CONFIG_KBDFRONT=n \
	CONFIG_CONSFRONT=n CONFIG_XC=n -j4
---
 extras/mini-os/ARM-TODO.txt      |  6 ++++++
 extras/mini-os/Config.mk         |  2 ++
 extras/mini-os/Makefile          |  9 +++++++++
 extras/mini-os/arch/arm/Makefile | 32 ++++++++++++++++++++++++++++++++
 extras/mini-os/arch/arm/arch.mk  |  7 +++++++
 5 files changed, 56 insertions(+)
 create mode 100644 extras/mini-os/ARM-TODO.txt
 create mode 100755 extras/mini-os/arch/arm/Makefile
 create mode 100644 extras/mini-os/arch/arm/arch.mk
extras/mini-os/ARM-TODO.txt new file +6 -0
new file mode 100644
index 0000000..c85ee5b
@@ -0,0 +1,6 @@
+* support abort exception handling ( and others )
+* gic request_irq implementation, currently all IRQs all hardcoded in gic irq handler.
+* bind_*
+* add multiple cpu support (?)
+* map_frames
+* make sure that wallclock is functioning properly
extras/mini-os/Config.mk +2 -0
index d61877b..4ecde54 100644
@@ -12,6 +12,8 @@ export XEN_INTERFACE_VERSION
 # If not x86 then use $(XEN_TARGET_ARCH)
 ifeq ($(findstring x86_,$(XEN_TARGET_ARCH)),x86_)
 TARGET_ARCH_FAM = x86
+else ifeq ($(findstring arm,$(XEN_TARGET_ARCH)),arm)
+TARGET_ARCH_FAM = arm
 else
 TARGET_ARCH_FAM = $(XEN_TARGET_ARCH)
 endif
extras/mini-os/Makefile +9 -0
index 931cd05..01d8af0 100644
@@ -78,6 +78,9 @@ TARGET := mini-os
 SUBDIRS := lib xenbus console
 
 ifeq ($(XEN_TARGET_ARCH),arm32)
+# Need libgcc.a for division helpers
+LDLIBS += `$(CC) -print-libgcc-file-name`
+
 # Device tree support
 SUBDIRS += lib/fdt
 src-y += lib/fdt/fdt.c
@@ -109,7 +112,9 @@ src-y += sched.c
 src-$(CONFIG_TEST) += test.c
 
 src-y += lib/ctype.c
+ifneq ($(XEN_TARGET_ARCH),arm32)
 src-y += lib/math.c
+endif
 src-y += lib/printf.c
 src-y += lib/stack_chk_fail.c
 src-y += lib/string.c
@@ -203,7 +208,11 @@ $(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib
 	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected]
 	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected]
 	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@
+ifeq ($(XEN_TARGET_ARCH),arm32)
+	$(OBJCOPY) -O binary $@ [email protected]
+else
 	gzip -f -9 -c $@ >[email protected]
+endif
 
 .PHONY: clean arch_clean
 
extras/mini-os/arch/arm/Makefile new file +32 -0
new file mode 100755
index 0000000..8b78651
@@ -0,0 +1,32 @@
+#
+# ARM architecture specific makefiles.
+#
+
+XEN_ROOT = $(CURDIR)/../../../..
+include $(XEN_ROOT)/Config.mk
+include ../../Config.mk
+
+# include arch.mk has to be before minios.mk!
+
+include arch.mk
+include ../../minios.mk
+
+# Sources here are all *.c (without $(XEN_TARGET_ARCH).S)
+# This is handled in $(HEAD_ARCH_OBJ)
+ARCH_SRCS := $(wildcard *.c)
+
+# The objects built from the sources.
+ARCH_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ARCH_SRCS))
+
+ARCH_OBJS += hypercalls32.o
+
+all: $(OBJ_DIR)/$(ARCH_LIB)
+
+# $(HEAD_ARCH_OBJ) is only built here, needed on linking
+# in ../../Makefile.
+$(OBJ_DIR)/$(ARCH_LIB): $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
+	$(AR) rv $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS)
+
+clean:
+	rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
+
extras/mini-os/arch/arm/arch.mk new file +7 -0
new file mode 100644
index 0000000..ad6e05f
@@ -0,0 +1,7 @@
+ifeq ($(XEN_TARGET_ARCH),arm32)
+DEF_ASFLAGS += -march=armv7-a -mfpu=vfpv3
+ARCH_CFLAGS  := -march=armv7-a -marm -fms-extensions -D__arm__ -DXEN_HAVE_PV_GUEST_ENTRY #-DCPU_EXCLUSIVE_LDST
+EXTRA_INC += $(TARGET_ARCH_FAM)/$(XEN_TARGET_ARCH)
+EXTRA_SRC += arch/$(EXTRA_INC)
+endif
+
Signature · 1 line
2.0.1
#60 lore raw

Re: [PATCH ARM v6 13/14] mini-os: arm: build system

Hi Thomas,

Quoted 9 lines · Thomas Leonard

Based on an initial patch by Karim Raslan.

This activates the ARM code added in the previous patches. On ARM, Mini-OS will boot and display some output on the console. Tested with:

make XEN_TARGET_ARCH=arm32 CROSS_COMPILE=arm-linux-gnueabihf- \
	CONFIG_TEST=y CONFIG_START_NETWORK=n CONFIG_BLKFRONT=n \
	CONFIG_NETFRONT=n CONFIG_FBFRONT=n CONFIG_KBDFRONT=n \
	CONFIG_CONSFRONT=n CONFIG_XC=n -j4

Can you provide instructions to build (git tag/branch...) and test mini-os? Also, is there any particular to not build blkfront, netfront, consfront?

It would be nice if they are working from the initial support.

Regards,

Signature · 1 line
Julien Grall
#61 lore raw

Re: [PATCH ARM v6 13/14] mini-os: arm: build system

Quoted 10 lines · Julien Grall

Hi Thomas,

Quoted 6 lines · Thomas Leonard

Based on an initial patch by Karim Raslan.

This activates the ARM code added in the previous patches. On ARM, Mini-OS will boot and display some output on the console. Tested with:

Quoted 7 lines
Quoted 4 lines
make XEN_TARGET_ARCH=arm32 CROSS_COMPILE=arm-linux-gnueabihf- \
        CONFIG_TEST=y CONFIG_START_NETWORK=n CONFIG_BLKFRONT=n \
        CONFIG_NETFRONT=n CONFIG_FBFRONT=n CONFIG_KBDFRONT=n \
        CONFIG_CONSFRONT=n CONFIG_XC=n -j4

Can you provide instructions to build (git tag/branch...) and test mini-os?

$ git clone -b next https://github.com/talex5/xen.git
$ cd xen/extras/mini-os
$ make CONFIG_TEST=y

(if cross-compiling, add XEN_TARGET_ARCH=arm32
CROSS_COMPILE=arm-linux-gnueabihf- )

This is my mini-os.cfg file:

name = 'mini-os'
kernel = 'mini-os.img'
builder = 'linux'
memory = 16
on_crash = 'preserve'
disk = ['/dev/vg0/test,,xvda' ]
vif = ['mac=c0:ff:ee:c0:ff:ee,bridge=br0' ]

Quoted 3 lines

Also, is there any particular to not build blkfront, netfront, consfront?

It would be nice if they are working from the initial support.

It turned out it didn't build because it wanted rand() from math.c (which ARM doesn't use).

As rand probably isn't something that should be exposed for general use (it just calls gettimeofday), I've moved it into test.c (on the next branch mentioned above).

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#63 lore raw

PATCH v6 14/14 mini-os: arm: show registers, stack and exception vector on fault

In reply to Thomas Leonard

---

Exit with SHUTDOWN_crash on BUG or fault (suggested by Ian Campbell).

---
 extras/mini-os/ARM-TODO.txt     |  1 -
 extras/mini-os/arch/arm/arm32.S | 75 ++++++++++++++++++++++++++++---
 extras/mini-os/arch/arm/panic.c | 98 +++++++++++++++++++++++++++++++++++++++++
 3 files changed, 166 insertions(+), 8 deletions(-)
 create mode 100644 extras/mini-os/arch/arm/panic.c
extras/mini-os/ARM-TODO.txt +0 -1
index c85ee5b..27507cd 100644
@@ -1,4 +1,3 @@
-* support abort exception handling ( and others )
 * gic request_irq implementation, currently all IRQs all hardcoded in gic irq handler.
 * bind_*
 * add multiple cpu support (?)
extras/mini-os/arch/arm/arm32.S +68 -7

89 lines not on this page · raw message

extras/mini-os/arch/arm/panic.c new file +98 -0

98 lines not on this page · raw message

Signature · 7 lines
2.0.1


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#64 lore raw

Re: [PATCH ARM v6 14/14] mini-os: arm: show registers, stack and exception vector on fault

Quoted 4 lines · Thomas Leonard

+@ We want to store a unique value to identify this handler, without corrupting +@ any of the registers. So, we store r15 (which will point just after the branch). +@ Later, we subtract 12 so the user gets pointed at the start of the exception +@ handler.

You do corrupt r13 though.

The way many OSes handle this is to make at least the initial saving (i.e. that which you have at fault:) into a macro and inlining a copy at each entry point. They also arrange for each SP_$mode to always point to something useful (in your case fault_dump, I guess) to avoid using a register as the save target.

BTW you can infer the same information as you do all this -12 stuff for from the saved CPSR.

Ian.

#65 lore raw

Re: [PATCH ARM v6 14/14] mini-os: arm: show registers, stack and exception vector on fault

Quoted 7 lines · Ian Campbell
Quoted 4 lines · Thomas Leonard

+@ We want to store a unique value to identify this handler, without corrupting +@ any of the registers. So, we store r15 (which will point just after the branch). +@ Later, we subtract 12 so the user gets pointed at the start of the exception +@ handler.

You do corrupt r13 though.

r13 is banked for all faults except SVC. Possibly for SVC we should do something different (though you'll always lose r14 anyway if SVC code makes an SVC call for some reason).

Quoted 5 lines

The way many OSes handle this is to make at least the initial saving (i.e. that which you have at fault:) into a macro and inlining a copy at each entry point. They also arrange for each SP_$mode to always point to something useful (in your case fault_dump, I guess) to avoid using a register as the save target.

You mean dumping the registers to the SVC stack in the SVC fault handler? That might cause another fault if the stack is full, but I may be misunderstanding you.

Quoted 2 lines

BTW you can infer the same information as you do all this -12 stuff for from the saved CPSR.

You mean by looking at the processor mode? There are two exceptions that both go to Abort mode though. I haven't checked to see whether the information could be recovered some other way; substracting 12 seemed pretty easy.

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#66 lore raw

Re: [PATCH ARM v6 14/14] mini-os: arm: show registers, stack and exception vector on fault

Quoted 10 lines · Thomas Leonard
Quoted 7 lines · Ian Campbell
Quoted 4 lines · Thomas Leonard

+@ We want to store a unique value to identify this handler, without corrupting +@ any of the registers. So, we store r15 (which will point just after the branch). +@ Later, we subtract 12 so the user gets pointed at the start of the exception +@ handler.

You do corrupt r13 though.

r13 is banked for all faults except SVC.

Oh yes, I'd a) spent too much time with the hyp exception model (which differs here) and b) momentarily forgotten that r13 is sp.

Quoted 10 lines

Possibly for SVC we should do
something different (though you'll always lose r14 anyway if SVC code makes an SVC call for some reason).

Quoted 5 lines

The way many OSes handle this is to make at least the initial saving (i.e. that which you have at fault:) into a macro and inlining a copy at each entry point. They also arrange for each SP_$mode to always point to something useful (in your case fault_dump, I guess) to avoid using a register as the save target.

Quoted 3 lines

You mean dumping the registers to the SVC stack in the SVC fault handler? That might cause another fault if the stack is full, but I may be misunderstanding you.

It was what I meant but now that you've reminded me about r13 its a bit moot.

Quoted 5 lines
Quoted 2 lines

BTW you can infer the same information as you do all this -12 stuff for from the saved CPSR.

You mean by looking at the processor mode? There are two exceptions that both go to Abort mode though.

Once again I've been spending too much time with the hyp exception model ;-)

Quoted 3 lines

I haven't checked to see whether
the information could be recovered some other way; substracting 12 seemed pretty easy.

OK.

Ian.

#67 lore raw
In reply to Thomas Leonard

Hi Thomas,

Quoted 45 lines · Thomas Leonard

This series is based on Karim's ARM support commits, further broken up into smaller patches.

The comments from last time should be addressed now, plus a few other things:

- The series is rebased on staging, dropping patches that have already been applied.

- The changes have been further split into smaller patches to ease reviewing. Note that the build system isn't changed to allow building the new code until patch 13.

- Define BUG to cause an undefined instruction fault. This lets us us dump the registers.

- Renamed stack to _boot_stack for clarity.

- Include kernel.h from arm/os.h. This is for consistency with x86/os.h and is needed to compile with lwIP.

- Moved SVC stack to first 16KB of RAM (provides some protection against stack overlow corrupting memory).

- Put translation table in second 16KB (simplifies boot code).

- Moved shared_info_page and irqstack to .bss section (smaller image).

- Moved __bss_start and _edata inside section in linker script. The linker adds non-listed sections, such as .got, just before .bss. This meant that we accidentally zeroed those out too.

- Enable floating point unit.

- Require only minimum FDT property lengths (requested by Ian Campbell).

Addressed Julien Grall's comments:

- Get hypercall numbers from xen.h.
- Avoid duplicating the definition of _start's virtual address.
- Moved definition of physical_address_offset from asm to C.
- Added paddr_t type to represent physical addresses.
- Added comments explaining the lengths when checking FDT properties.
- Fixed (commented) DEBUG macro.
- Drop check for arm,cortex-a9-gic.

Quoted 8 lines

There are two assumptions the code makes that may need changing in the future, but which hopefully don't need to hold up this initial support:

- The assumption that the kernel will be loaded at start of RAM + 0x8000.

- The assumption that Xen will mark the GIC address range as device memory. This should probably be fixed when the C code gains the ability to control the translation tables, map 4K pages, etc.

I'm fine with the assumptions for an initial support. Did you write-down somewhere those restrictions? So if an issue happen in the future, we will be able to find quickly the issue.

Regards,

Signature · 1 line
Julien Grall
#68 lore raw
Quoted 5 lines · Julien Grall
Quoted 5 lines

There are two assumptions the code makes that may need changing in the future, but which hopefully don't need to hold up this initial support:

- The assumption that the kernel will be loaded at start of RAM + 0x8000.

Quoted 7 lines
Quoted 3 lines

- The assumption that Xen will mark the GIC address range as device memory. This should probably be fixed when the C code gains the ability to control the translation tables, map 4K pages, etc.

I'm fine with the assumptions for an initial support. Did you write-down somewhere those restrictions? So if an issue happen in the future, we will be able to find quickly the issue.

Yeah. we can live with them for now, I think. It should be documented though.

What sort of time line are you foreseeing for fixing them, in terms of before or after 4.5?

We should probably consider sticking a "tech preview" or similar label on mini-os/ARM in 4.5 if these issues remain (the load address one in particular).

Ian.

#69 lore raw
Quoted 1 line · Ian Campbell
Quoted 1 line
Quoted 1 line

- The assumption that the kernel will be loaded at start of RAM + 0x8000.

Reading the comments in 07/14 -- is this limitation still present? It looks like you are at least partially handling it?

Ian.

#70 lore raw
Quoted 6 lines · Ian Campbell
Quoted 1 line · Ian Campbell
Quoted 1 line
Quoted 1 line

- The assumption that the kernel will be loaded at start of RAM + 0x8000.

Reading the comments in 07/14 -- is this limitation still present? It looks like you are at least partially handling it?

It's still present.

Before (in v5), the translation table was in the .data section and therefore could end up in a different memory section to the boot code. By moving it to 0x4000, I simplified all that logic because we now know that the translation table and the boot code are both in the same 1MB memory section, which avoids any problem with the old and new mappings overlapping.

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#71 lore raw
In reply to Ian Campbell
Quoted 11 lines · Ian Campbell
Quoted 9 lines · Julien Grall
Quoted 8 lines

There are two assumptions the code makes that may need changing in the future, but which hopefully don't need to hold up this initial support:

- The assumption that the kernel will be loaded at start of RAM + 0x8000.

- The assumption that Xen will mark the GIC address range as device memory. This should probably be fixed when the C code gains the ability to control the translation tables, map 4K pages, etc.

Quoted 6 lines
Quoted 3 lines

I'm fine with the assumptions for an initial support. Did you write-down somewhere those restrictions? So if an issue happen in the future, we will be able to find quickly the issue.

Yeah. we can live with them for now, I think. It should be documented though.

I've noted the offset requirement in the linker script and the GIC memory type assumption in a comment in gic.c.

Quoted 2 lines

What sort of time line are you foreseeing for fixing them, in terms of before or after 4.5?

If the GIC will always occupy a distinct set of 1MB sections then flagging those is easy enough. Otherwise, we'd have to add support for the second-level page tables, which would complicate things a little.

Making the boot code work from arbitrary offsets looks very difficult. I guess we'd need to compile libfdt as PIC, set up a temporary C stack after the kernel (we can assume there's some RAM following it I think), parse the FDT to find the base address, copy the kernel forwards or backwards word by word (first copying the copying code to a safe location somewhere).

It all seems very inefficient. From my point of view, it would seem better to have some way to specify the desired load offset.

Quoted 3 lines

We should probably consider sticking a "tech preview" or similar label on mini-os/ARM in 4.5 if these issues remain (the load address one in particular).

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA
#72 lore raw
Quoted 19 lines · Thomas Leonard
Quoted 11 lines · Ian Campbell
Quoted 9 lines · Julien Grall
Quoted 8 lines

There are two assumptions the code makes that may need changing in the future, but which hopefully don't need to hold up this initial support:

- The assumption that the kernel will be loaded at start of RAM + 0x8000.

- The assumption that Xen will mark the GIC address range as device memory. This should probably be fixed when the C code gains the ability to control the translation tables, map 4K pages, etc.

Quoted 6 lines
Quoted 3 lines

I'm fine with the assumptions for an initial support. Did you write-down somewhere those restrictions? So if an issue happen in the future, we will be able to find quickly the issue.

Yeah. we can live with them for now, I think. It should be documented though.

Quoted 8 lines

I've noted the offset requirement in the linker script and the GIC memory type assumption in a comment in gic.c.

Quoted 2 lines

What sort of time line are you foreseeing for fixing them, in terms of before or after 4.5?

If the GIC will always occupy a distinct set of 1MB sections then flagging those is easy enough.

I don't think that is guaranteed, but I've not dug deeply into the GIC spec, I don't think it says anything about the relative placement of the various sub functions though.

Quoted 4 lines

Otherwise, we'd have to add support for
the second-level page tables, which would complicate things a little.

Making the boot code work from arbitrary offsets looks very difficult.

Xen itself manages it (not quite arbitrary, it assumes 4K alignment), so does Linux (completely arbitrary I think), it's not that hard, you just need to switch to a virtual mapping before you hit C or any non-PIE code. Once you have a virtual mapping you don't actually care about the load address any more.

Quoted 7 lines

I guess we'd need to compile libfdt as PIC, set up a temporary C stack after the kernel (we can assume there's some RAM following it I think), parse the FDT to find the base address, copy the kernel forwards or backwards word by word (first copying the copying code to a safe location somewhere).

It all seems very inefficient.

The mechanism which you propose certainly is, yes. But I don't think any of what you describe is necessary.

Quoted 2 lines

From my point of view, it would seem
better to have some way to specify the desired load offset.

Sadly the zImage header is what it is and doesn't include this.

Ian.

Quoted 5 lines
Quoted 3 lines

We should probably consider sticking a "tech preview" or similar label on mini-os/ARM in 4.5 if these issues remain (the load address one in particular).

#73 lore raw
In reply to Thomas Leonard

On Wed, 2014-07-16 at 12:07 +0100, Thomas Leonard wrote:

I tried to apply:
mini-os: x86_64: make thread stacks 16-byte aligned
mini-os: don't include lib.h from mm.h (the second, attached, version)
mini-os: added HYPERVISOR_xsm_op
mini-os: use generic local_irq_enable function

but got:
vtpm_cmd_handler.c: In function ‘tm_dhkx_gen’:
vtpm_cmd_handler.c:486:3: error: implicit declaration of function ‘ARRAY_SIZE’ [-Werror=implicit-function-declaration]
cc1: all warnings being treated as errors
make[2]: *** [vtpm_cmd_handler.o] Error 1
make[2]: *** Waiting for unfinished jobs....
disk_tpm.c: In function ‘TPM_disk_seal’:
disk_tpm.c:84:2: error: implicit declaration of function ‘printk’ [-Werror=implicit-function-declaration]
cc1: all warnings being treated as errors
make[2]: *** [disk_tpm.o] Error 1
make[2]: Entering directory `/local/scratch/ianc/devel/committer-amd64.git/stubdom/libxc-x86_64' make libs

Which I think was the mm.h one.

Then I got:
In file included from /local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/mini-os/gntmap.h:4:0,
from /local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/mini-os/lib.h:55, from /local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/mini-os/mm.h:36, from /local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/x86/x86_64/hypercall-x86_64.h:39, from /local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/hypervisor.h:20, from mini-os.c:13:
/local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/x86/os.h: In function ‘HYPERVISOR_xsm_op’:
/local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/x86/os.h:566:21: error: expected expression before ‘int’ mini-os.c: In function ‘main’:
mini-os.c:756:35: warning: cast from pointer to integer of different size [-Wpointer-to-int-cast]
make[2]: *** [/local/scratch/ianc/devel/committer-amd64.git/stubdom/grub-x86_64/mini-os.o] Error 1
make[2]: *** Waiting for unfinished jobs....

Which I assume was the XSM one.

So I only ended up applying:
mini-os: x86_64: make thread stacks 16-byte aligned
mini-os: use generic local_irq_enable function

Cheers,
Ian

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel

author Acked-by Ian Campbell Acked-by Samuel Thibault
#74 lore raw
Quoted 22 lines · Ian Campbell

On Wed, 2014-07-16 at 12:07 +0100, Thomas Leonard wrote:

I tried to apply:
mini-os: x86_64: make thread stacks 16-byte aligned
mini-os: don't include lib.h from mm.h (the second, attached, version)
mini-os: added HYPERVISOR_xsm_op
mini-os: use generic local_irq_enable function

but got:
vtpm_cmd_handler.c: In function ‘tm_dhkx_gen’:
vtpm_cmd_handler.c:486:3: error: implicit declaration of function ‘ARRAY_SIZE’ [-Werror=implicit-function-declaration]
cc1: all warnings being treated as errors
make[2]: *** [vtpm_cmd_handler.o] Error 1
make[2]: *** Waiting for unfinished jobs....
disk_tpm.c: In function ‘TPM_disk_seal’:
disk_tpm.c:84:2: error: implicit declaration of function ‘printk’ [-Werror=implicit-function-declaration]
cc1: all warnings being treated as errors
make[2]: *** [disk_tpm.o] Error 1
make[2]: Entering directory `/local/scratch/ianc/devel/committer-amd64.git/stubdom/libxc-x86_64' make libs

Quoted 1 line

Which I think was the mm.h one.

Oops. The attached updated patch fixes compiling the stubdoms for me.

Quoted 4 lines

Then I got:
In file included from /local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/mini-os/gntmap.h:4:0,
from /local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/mini-os/lib.h:55, from /local/scratch/ianc/devel/committer-amd64.git/stubdom/../extras/mini-os/include/mini-os/mm.h:36,

I guess this is just due to skipping the previous patch, since after that mm.h will no longer inlcude lib.h.

Signature · 3 lines
Dr Thomas Leonard        http://0install.net/
GPG: 9242 9807 C985 3C07 44A6  8B9A AE07 8280 59A5 3CC1
GPG: DA98 25AE CAD0 8975 7CDA  BD8E 0713 3F96 CA74 D8BA

From b102c8ad50db789e850e482770c3809e60167375 Mon Sep 17 00:00:00 2001
From: Thomas Leonard <[email protected]>
Date: Mon, 7 Jul 2014 13:20:43 +0100
Subject: [PATCH] mini-os: don't include lib.h from mm.h

This breaks the include cycle hypervisor.h -> hypercall-x86_32.h -> mm.h -> lib.h -> gntmap.h -> os.h -> hypervisor.h.

---

Added missing includes in stubdom code.

---
 extras/mini-os/include/mm.h        | 3 +--
 extras/mini-os/lock.c              | 1 +
 extras/mini-os/main.c              | 1 +
 extras/mini-os/tpm_tis.c           | 1 +
 extras/mini-os/tpmfront.c          | 1 +
 stubdom/vtpmmgr/disk_tpm.c         | 1 +
 stubdom/vtpmmgr/vtpm_cmd_handler.c | 1 +
 7 files changed, 7 insertions(+), 2 deletions(-)
extras/mini-os/include/mm.h +1 -2
index a94cd6d..a177251 100644
@@ -32,8 +32,7 @@
 #else
 #error "Unsupported architecture"
 #endif
-
-#include <mini-os/lib.h>
+#include <xen/xen.h>
 
 #include <mini-os/arch_limits.h>
 #include <mini-os/arch_mm.h>
extras/mini-os/lock.c +1 -0
index 71a4971..61194e5 100644
@@ -9,6 +9,7 @@
 #include <sys/lock.h>
 #include <sched.h>
 #include <wait.h>
+#include <mini-os/lib.h>
 
 int ___lock_init(_LOCK_T *lock)
 {
extras/mini-os/main.c +1 -0
index aec0586..4ec40b5 100644
@@ -15,6 +15,7 @@
 #include <unistd.h>
 #include <xenbus.h>
 #include <events.h>
+#include <mini-os/lib.h>
 
 extern int main(int argc, char *argv[], char *envp[]);
 extern void __libc_init_array(void);
extras/mini-os/tpm_tis.c +1 -0
index dc4134a..b067cb7 100644
@@ -26,6 +26,7 @@
 #include <mini-os/events.h>
 #include <mini-os/wait.h>
 #include <mini-os/xmalloc.h>
+#include <mini-os/lib.h>
 #include <errno.h>
 #include <stdbool.h>
 
extras/mini-os/tpmfront.c +1 -0
index ce5b3e1..6049244 100644
@@ -31,6 +31,7 @@
 #include <xen/io/xenbus.h>
 #include <xen/io/tpmif.h>
 #include <mini-os/tpmfront.h>
+#include <mini-os/lib.h>
 #include <fcntl.h>
 
 //#define TPMFRONT_PRINT_DEBUG
stubdom/vtpmmgr/disk_tpm.c +1 -0
index a9f4552..d650fbc 100644
@@ -7,6 +7,7 @@
 #include <stdlib.h>
 #include <stdbool.h>
 #include <mini-os/byteorder.h>
+#include <mini-os/lib.h>
 #include <polarssl/aes.h>
 #include <polarssl/sha1.h>
 
stubdom/vtpmmgr/vtpm_cmd_handler.c +1 -0
index 8a42790..13ead93 100644
@@ -38,6 +38,7 @@
 #include <string.h>
 #include <stdlib.h>
 #include <mini-os/console.h>
+#include <mini-os/lib.h>
 #include <polarssl/sha1.h>
 #include <polarssl/sha2.h>
 
Signature · 1 line
2.0.3

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel