All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH ARM v7 00/13] mini-os: initial ARM support
@ 2014-08-08 15:47 Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 01/13] mini-os: don't include lib.h from mm.h Thomas Leonard
                   ` (12 more replies)
  0 siblings, 13 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

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

Changes since v6:

- Added missing includes in stubdom code.
- Move poor rand function to test.c.
- Fixed printk format types.
- Only build libfdt with read support, since that's all we need.
- Compiling with debug=n now works.

Addressed Andrew Cooper's comment:
- Use Xen's existing copy of libfdt instead of including our own copy.

Addressed Ian Campbell's comments:
- ARMv7 A8.8.247 says udf should not be used conditionally, so use
  a branch instead.
- Enable caching earlier (required setting the cacheability for the
  translation table walks).
- Added some extra dsb instructions to protect against reordering.
- Replace "mov pc" with "bx".
- Preserve all callee-saved registers on thread switch.

Addressed Julien Grall's comments:
- Note that TTBCR is zero (using short-descriptors, TTBR0 only).
- Note about relying on 0x8000 load offset.
- Remove wall-clock time support (doesn't work on ARM anyway).
- Converted an ?: to an if.
- paddr_t is now uint64_t.


Karim Raslan (2):
  mini-os: arm: add header files
  mini-os: arm: events

Thomas Leonard (11):
  mini-os: don't include lib.h from mm.h
  mini-os: added HYPERVISOR_xsm_op
  mini-os: move poor rand function to test.c
  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
  mini-os: fixed compiling with debug=n

 .gitignore                                       |   3 +
 extras/mini-os/ARM-TODO.txt                      |   4 +
 extras/mini-os/COPYING                           |  27 +++
 extras/mini-os/Config.mk                         |   2 +
 extras/mini-os/Makefile                          |  38 ++-
 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                    | 237 ++++++++++++++++++
 extras/mini-os/arch/arm/hypercalls32.S           |  64 +++++
 extras/mini-os/arch/arm/minios-arm32.lds         |  83 +++++++
 extras/mini-os/arch/arm/mm.c                     | 139 +++++++++++
 extras/mini-os/arch/arm/panic.c                  |  98 ++++++++
 extras/mini-os/arch/arm/sched.c                  |  47 ++++
 extras/mini-os/arch/arm/setup.c                  | 119 +++++++++
 extras/mini-os/arch/arm/time.c                   | 141 +++++++++++
 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/hypervisor.h              |   2 +
 extras/mini-os/include/lib.h                     |   4 +-
 extras/mini-os/include/libfdt_env.h              |  29 +++
 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/lib/math.c                        |  13 -
 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/minios.mk                         |   2 +-
 extras/mini-os/test.c                            |  13 +
 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 +
 xen/common/libfdt/fdt_ro.c                       |   2 +-
 46 files changed, 1938 insertions(+), 27 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/libfdt_env.h
 create mode 100644 extras/mini-os/lib/memmove.c

-- 
2.0.3

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

* [PATCH ARM v7 01/13] mini-os: don't include lib.h from mm.h
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 02/13] mini-os: added HYPERVISOR_xsm_op Thomas Leonard
                   ` (11 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

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 <talex5@gmail.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

---

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(-)

diff --git a/extras/mini-os/include/mm.h b/extras/mini-os/include/mm.h
index a94cd6d..a177251 100644
--- a/extras/mini-os/include/mm.h
+++ b/extras/mini-os/include/mm.h
@@ -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>
diff --git a/extras/mini-os/lock.c b/extras/mini-os/lock.c
index 71a4971..61194e5 100644
--- a/extras/mini-os/lock.c
+++ b/extras/mini-os/lock.c
@@ -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)
 {
diff --git a/extras/mini-os/main.c b/extras/mini-os/main.c
index aec0586..4ec40b5 100644
--- a/extras/mini-os/main.c
+++ b/extras/mini-os/main.c
@@ -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);
diff --git a/extras/mini-os/tpm_tis.c b/extras/mini-os/tpm_tis.c
index 936e854..d40b391 100644
--- a/extras/mini-os/tpm_tis.c
+++ b/extras/mini-os/tpm_tis.c
@@ -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>
 
diff --git a/extras/mini-os/tpmfront.c b/extras/mini-os/tpmfront.c
index ce5b3e1..6049244 100644
--- a/extras/mini-os/tpmfront.c
+++ b/extras/mini-os/tpmfront.c
@@ -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
diff --git a/stubdom/vtpmmgr/disk_tpm.c b/stubdom/vtpmmgr/disk_tpm.c
index a9f4552..d650fbc 100644
--- a/stubdom/vtpmmgr/disk_tpm.c
+++ b/stubdom/vtpmmgr/disk_tpm.c
@@ -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>
 
diff --git a/stubdom/vtpmmgr/vtpm_cmd_handler.c b/stubdom/vtpmmgr/vtpm_cmd_handler.c
index 8a42790..13ead93 100644
--- a/stubdom/vtpmmgr/vtpm_cmd_handler.c
+++ b/stubdom/vtpmmgr/vtpm_cmd_handler.c
@@ -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>
 
-- 
2.0.3

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

* [PATCH ARM v7 02/13] mini-os: added HYPERVISOR_xsm_op
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 01/13] mini-os: don't include lib.h from mm.h Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c Thomas Leonard
                   ` (10 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

Avoids using _hypercall1 in events.c.

Signed-off-by: Thomas Leonard <talex5@gmail.com>
Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
---
 extras/mini-os/events.c         | 4 ++--
 extras/mini-os/include/x86/os.h | 7 +++++++
 2 files changed, 9 insertions(+), 2 deletions(-)

diff --git a/extras/mini-os/events.c b/extras/mini-os/events.c
index 48742de..2a23042 100644
--- a/extras/mini-os/events.c
+++ b/extras/mini-os/events.c
@@ -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;
 }
 
diff --git a/extras/mini-os/include/x86/os.h b/extras/mini-os/include/x86/os.h
index 192b23cd..ee9050b 100644
--- a/extras/mini-os/include/x86/os.h
+++ b/extras/mini-os/include/x86/os.h
@@ -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
 
-- 
2.0.3

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

* [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 01/13] mini-os: don't include lib.h from mm.h Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 02/13] mini-os: added HYPERVISOR_xsm_op Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-08-08 16:37   ` Samuel Thibault
  2014-08-08 15:47 ` [PATCH ARM v7 04/13] mini-os: arm: add header files Thomas Leonard
                   ` (9 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

It's only used by test.c and probably isn't something that should be
exposed for general use (it just calls gettimeofday).

This is also useful for ARM, which doesn't use math.c, where this used
to live.

Signed-off-by: Thomas Leonard <talex5@gmail.com>
---
 extras/mini-os/lib/math.c | 13 -------------
 extras/mini-os/test.c     | 13 +++++++++++++
 2 files changed, 13 insertions(+), 13 deletions(-)

diff --git a/extras/mini-os/lib/math.c b/extras/mini-os/lib/math.c
index c941b4c..561393e 100644
--- a/extras/mini-os/lib/math.c
+++ b/extras/mini-os/lib/math.c
@@ -424,16 +424,3 @@ __moddi3(quad_t a, quad_t b)
 	(void)__qdivrem(ua, ub, &ur);
 	return (neg ? -ur : ur);
 }
-
-#ifndef HAVE_LIBC
-/* Should be random enough for our uses */
-int rand(void)
-{
-    static unsigned int previous;
-    struct timeval tv;
-    gettimeofday(&tv, NULL);
-    previous += tv.tv_sec + tv.tv_usec;
-    previous *= RAND_MIX;
-    return previous;
-}
-#endif
diff --git a/extras/mini-os/test.c b/extras/mini-os/test.c
index 64a4057..154af49 100644
--- a/extras/mini-os/test.c
+++ b/extras/mini-os/test.c
@@ -60,6 +60,19 @@ static void xenbus_tester(void *p)
 }
 #endif
 
+#ifndef HAVE_LIBC
+/* Should be random enough for our uses */
+int rand(void)
+{
+    static unsigned int previous;
+    struct timeval tv;
+    gettimeofday(&tv, NULL);
+    previous += tv.tv_sec + tv.tv_usec;
+    previous *= RAND_MIX;
+    return previous;
+}
+#endif
+
 static void periodic_thread(void *p)
 {
     struct timeval tv;
-- 
2.0.3

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

* [PATCH ARM v7 04/13] mini-os: arm: add header files
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (2 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 05/13] mini-os: arm: boot code Thomas Leonard
                   ` (8 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

From: Karim Raslan <karim.allah.ahmed@gmail.com>

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

Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>
Acked-by: Julien Grall <julien.grall@linaro.org>
Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

---
Changes since v6:

- paddr_t is now uint64_t (even though we only use 32-bits)
- physical_address_offset is now uint32_t (wraps at 4 GB)
---
 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

diff --git a/extras/mini-os/include/arm/arch_endian.h b/extras/mini-os/include/arm/arch_endian.h
new file mode 100644
index 0000000..0771683
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_endian.h
@@ -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
diff --git a/extras/mini-os/include/arm/arch_limits.h b/extras/mini-os/include/arm/arch_limits.h
new file mode 100644
index 0000000..bae99e1
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_limits.h
@@ -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
diff --git a/extras/mini-os/include/arm/arch_mm.h b/extras/mini-os/include/arm/arch_mm.h
new file mode 100644
index 0000000..085d4e5
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_mm.h
@@ -0,0 +1,38 @@
+#ifndef _ARCH_MM_H_
+#define _ARCH_MM_H_
+
+typedef uint64_t paddr_t;
+
+extern char _text, _etext, _erodata, _edata, _end, __bss_start;
+extern int _boot_stack[];
+extern int _boot_stack_end[];
+extern uint32_t physical_address_offset;	/* Add this to a virtual address to get the physical address (wraps at 4GB) */
+
+#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) & 0xffffffff)
+#define to_virt(x)                 ((void *)(((x)-physical_address_offset) & 0xffffffff))
+
+#define PFN_UP(x)    (unsigned long)(((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
+#define PFN_DOWN(x)    (unsigned long)((x) >> L1_PAGETABLE_SHIFT)
+#define PFN_PHYS(x)    ((uint64_t)(x) << L1_PAGETABLE_SHIFT)
+#define PHYS_PFN(x)    (unsigned long)((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
diff --git a/extras/mini-os/include/arm/arch_sched.h b/extras/mini-os/include/arm/arch_sched.h
new file mode 100644
index 0000000..de3ac02
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_sched.h
@@ -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__ */
diff --git a/extras/mini-os/include/arm/arch_spinlock.h b/extras/mini-os/include/arm/arch_spinlock.h
new file mode 100755
index 0000000..dccb9fc
--- /dev/null
+++ b/extras/mini-os/include/arm/arch_spinlock.h
@@ -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
diff --git a/extras/mini-os/include/arm/arm32/arch_wordsize.h b/extras/mini-os/include/arm/arm32/arch_wordsize.h
new file mode 100644
index 0000000..b47eee9
--- /dev/null
+++ b/extras/mini-os/include/arm/arm32/arch_wordsize.h
@@ -0,0 +1 @@
+#define __WORDSIZE 32
diff --git a/extras/mini-os/include/arm/gic.h b/extras/mini-os/include/arm/gic.h
new file mode 100644
index 0000000..cead2e5
--- /dev/null
+++ b/extras/mini-os/include/arm/gic.h
@@ -0,0 +1 @@
+void gic_init(void);
diff --git a/extras/mini-os/include/arm/hypercall-arm.h b/extras/mini-os/include/arm/hypercall-arm.h
new file mode 100644
index 0000000..6d862ff
--- /dev/null
+++ b/extras/mini-os/include/arm/hypercall-arm.h
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * hypercall-arm.h
+ * 
+ * Copied from XenLinux.
+ * 
+ * Copyright (c) 2002-2004, K A Fraser
+ * 
+ * 64-bit updates:
+ *   Benjamin Liu <benjamin.liu@intel.com>
+ *   Jun Nakajima <jun.nakajima@intel.com>
+ * 
+ * This file may be distributed separately from the Linux kernel, or
+ * incorporated into other software packages, subject to the following license:
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#ifndef __HYPERCALL_ARM_H__
+#define __HYPERCALL_ARM_H__
+
+#include <xen/xen.h>
+#include <xen/sched.h>
+#include <xen/xsm/flask_op.h>
+#include <mini-os/mm.h>
+
+int
+HYPERVISOR_sched_op(
+    int cmd, void *arg);
+
+static inline int
+HYPERVISOR_shutdown(
+    unsigned int reason)
+{
+    struct sched_shutdown shutdown = { .reason = reason };
+    HYPERVISOR_sched_op(SCHEDOP_shutdown, &shutdown);
+}
+
+int
+HYPERVISOR_memory_op(
+    unsigned int cmd, void *arg);
+
+int
+HYPERVISOR_event_channel_op(
+    int cmd, void *op);
+
+int
+HYPERVISOR_xen_version(
+    int cmd, void *arg);
+
+int
+HYPERVISOR_console_io(
+    int cmd, int count, char *str);
+
+int
+HYPERVISOR_physdev_op(
+    void *physdev_op);
+
+int
+HYPERVISOR_grant_table_op(
+    unsigned int cmd, void *uop, unsigned int count);
+
+int
+HYPERVISOR_vcpu_op(
+    int cmd, int vcpuid, void *extra_args);
+
+int
+HYPERVISOR_sysctl(
+    unsigned long op);
+
+int
+HYPERVISOR_domctl(
+    unsigned long op);
+
+int
+HYPERVISOR_hvm_op(
+    unsigned long op, void *arg);
+
+int
+HYPERVISOR_xsm_op(
+    struct xen_flask_op *);
+
+#endif  /* __HYPERCALL_ARM_H__ */
diff --git a/extras/mini-os/include/arm/os.h b/extras/mini-os/include/arm/os.h
new file mode 100644
index 0000000..6a1cc37
--- /dev/null
+++ b/extras/mini-os/include/arm/os.h
@@ -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);
+
+extern void *device_tree;
+
+#define BUG() while(1){asm volatile (".word 0xe7f000f0\n");} /* Undefined instruction; will call our fault handler. */
+
+#define smp_processor_id() 0
+
+#define barrier() __asm__ __volatile__("": : :"memory")
+
+extern shared_info_t *HYPERVISOR_shared_info;
+
+// disable interrupts
+static inline void local_irq_disable(void) {
+    __asm__ __volatile__("cpsid i":::"memory");
+}
+
+// enable interrupts
+static inline void local_irq_enable(void) {
+    __asm__ __volatile__("cpsie i":::"memory");
+}
+
+#define local_irq_save(x) { \
+    __asm__ __volatile__("mrs %0, cpsr;cpsid i":"=r"(x)::"memory");    \
+}
+
+#define local_irq_restore(x) {    \
+    __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory");    \
+}
+
+#define local_save_flags(x)    { \
+    __asm__ __volatile__("mrs %0, cpsr":"=r"(x)::"memory");    \
+}
+
+static inline int irqs_disabled(void) {
+    int x;
+    local_save_flags(x);
+    return x & 0x80;
+}
+
+/* We probably only need "dmb" here, but we'll start by being paranoid. */
+#define mb() __asm__("dsb":::"memory");
+#define rmb() __asm__("dsb":::"memory");
+#define wmb() __asm__("dsb":::"memory");
+
+/************************** arm *******************************/
+#ifdef __INSIDE_MINIOS__
+#if defined (__arm__)
+#define xchg(ptr,v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST)
+
+/**
+ * test_and_clear_bit - Clear a bit and return its old value
+ * @nr: Bit to clear
+ * @addr: Address to count from
+ *
+ * Note that @nr may be almost arbitrarily large; this function is not
+ * restricted to acting on a single-word quantity.
+ *
+ * This operation is atomic.
+ * If you need a memory barrier, use synch_test_and_clear_bit instead.
+ */
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+    uint8_t *byte = ((uint8_t *)addr) + (nr >> 3);
+    uint8_t bit = 1 << (nr & 7);
+    uint8_t orig;
+
+    orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_RELAXED);
+
+    return (orig & bit) != 0;
+}
+
+/**
+ * Atomically set a bit and return the old value.
+ * Similar to test_and_clear_bit.
+ */
+static __inline__ int test_and_set_bit(int nr, volatile void *base)
+{
+    uint8_t *byte = ((uint8_t *)base) + (nr >> 3);
+    uint8_t bit = 1 << (nr & 7);
+    uint8_t orig;
+
+    orig = __atomic_fetch_or(byte, bit, __ATOMIC_RELAXED);
+
+    return (orig & bit) != 0;
+}
+
+/**
+ * Test whether a bit is set. */
+static __inline__ int test_bit(int nr, const volatile unsigned long *addr)
+{
+    const uint8_t *ptr = (const uint8_t *) addr;
+    return ((1 << (nr & 7)) & (ptr[nr >> 3])) != 0;
+}
+
+/**
+ * Atomically set a bit in memory (like test_and_set_bit but discards result).
+ */
+static __inline__ void set_bit(int nr, volatile unsigned long *addr)
+{
+    test_and_set_bit(nr, addr);
+}
+
+/**
+ * Atomically clear a bit in memory (like test_and_clear_bit but discards result).
+ */
+static __inline__ void clear_bit(int nr, volatile unsigned long *addr)
+{
+    test_and_clear_bit(nr, addr);
+}
+
+/**
+ * __ffs - find first (lowest) set bit in word.
+ * @word: The word to search
+ *
+ * Undefined if no bit exists, so code should check against 0 first.
+ */
+static __inline__ unsigned long __ffs(unsigned long word)
+{
+    int clz;
+
+    /* xxxxx10000 = word
+     * xxxxx01111 = word - 1
+     * 0000011111 = word ^ (word - 1)
+     *      4     = 31 - clz(word ^ (word - 1))
+     */
+
+    __asm__ (
+        "sub r0, %[word], #1\n"
+        "eor r0, r0, %[word]\n"
+        "clz %[clz], r0\n":
+        /* Outputs: */
+        [clz] "=r"(clz):
+        /* Inputs: */
+        [word] "r"(word):
+        /* Clobbers: */
+        "r0");
+
+    return 31 - clz;
+}
+
+#else /* ifdef __arm__ */
+#error "Unsupported architecture"
+#endif
+#endif /* ifdef __INSIDE_MINIOS */
+
+/********************* common arm32 and arm64  ****************************/
+
+/* If *ptr == old, then store new there (and return new).
+ * Otherwise, return the old value.
+ * Atomic. */
+#define synch_cmpxchg(ptr, old, new) \
+({ __typeof__(*ptr) stored = old; \
+   __atomic_compare_exchange_n(ptr, &stored, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? new : old; \
+})
+
+/* As test_and_clear_bit, but using __ATOMIC_SEQ_CST */
+static __inline__ int synch_test_and_clear_bit(int nr, volatile void *addr)
+{
+    uint8_t *byte = ((uint8_t *)addr) + (nr >> 3);
+    uint8_t bit = 1 << (nr & 7);
+    uint8_t orig;
+
+    orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST);
+
+    return (orig & bit) != 0;
+}
+
+/* As test_and_set_bit, but using __ATOMIC_SEQ_CST */
+static __inline__ int synch_test_and_set_bit(int nr, volatile void *base)
+{
+    uint8_t *byte = ((uint8_t *)base) + (nr >> 3);
+    uint8_t bit = 1 << (nr & 7);
+    uint8_t orig;
+
+    orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST);
+
+    return (orig & bit) != 0;
+}
+
+/* As set_bit, but using __ATOMIC_SEQ_CST */
+static __inline__ void synch_set_bit(int nr, volatile void *addr)
+{
+    synch_test_and_set_bit(nr, addr);
+}
+
+/* As clear_bit, but using __ATOMIC_SEQ_CST */
+static __inline__ void synch_clear_bit(int nr, volatile void *addr)
+{
+    synch_test_and_clear_bit(nr, addr);
+}
+
+/* As test_bit, but with a following memory barrier. */
+static __inline__ int synch_test_bit(int nr, volatile void *addr)
+{
+    int result;
+    result = test_bit(nr, addr);
+    barrier();
+    return result;
+}
+
+#endif /* not assembly */
+
+#endif
diff --git a/extras/mini-os/include/arm/traps.h b/extras/mini-os/include/arm/traps.h
new file mode 100644
index 0000000..704df22
--- /dev/null
+++ b/extras/mini-os/include/arm/traps.h
@@ -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
diff --git a/extras/mini-os/include/hypervisor.h b/extras/mini-os/include/hypervisor.h
index a62cb78..21b3566 100644
--- a/extras/mini-os/include/hypervisor.h
+++ b/extras/mini-os/include/hypervisor.h
@@ -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
diff --git a/extras/mini-os/include/mm.h b/extras/mini-os/include/mm.h
index a177251..f57d8ab 100644
--- a/extras/mini-os/include/mm.h
+++ b/extras/mini-os/include/mm.h
@@ -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
diff --git a/extras/mini-os/include/types.h b/extras/mini-os/include/types.h
index 93356fe..be9f1d3 100644
--- a/extras/mini-os/include/types.h
+++ b/extras/mini-os/include/types.h
@@ -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
-- 
2.0.3

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

* [PATCH ARM v7 05/13] mini-os: arm: boot code
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (3 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 04/13] mini-os: arm: add header files Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 06/13] mini-os: arm: memory management Thomas Leonard
                   ` (7 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

Based on an initial patch by Karim Raslan.

Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>

---

Changes since v6:

- Fixed printk format types.

Addressed Ian Campbell's comments:
- ARMv7 A8.8.247 says udf should not be used conditionally, so use
  a branch instead.
- Enable caching earlier (required setting the cacheability for the
  translation table walks).
- Added some extra dsb instructions to protect against reordering.

Addressed Julien Grall's comments:
- Note that TTBCR is zero (using short-descriptors, TTBR0 only).
- Note about relying on 0x8000 load offset.
---
 extras/mini-os/arch/arm/arm32.S          | 211 +++++++++++++++++++++++++++++++
 extras/mini-os/arch/arm/hypercalls32.S   |  64 ++++++++++
 extras/mini-os/arch/arm/minios-arm32.lds |  83 ++++++++++++
 extras/mini-os/arch/arm/setup.c          | 119 +++++++++++++++++
 4 files changed, 477 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

diff --git a/extras/mini-os/arch/arm/arm32.S b/extras/mini-os/arch/arm/arm32.S
new file mode 100644
index 0000000..d2e6932
--- /dev/null
+++ b/extras/mini-os/arch/arm/arm32.S
@@ -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.
+	@ Note: We leave TTBCR as 0, meaning that only TTBR0 is used and
+	@ we use the short-descriptor format (32-bit physical addresses).
+	orr	r0, r1, #0b0001011	@ Sharable, Inner/Outer Write-Back Write-Allocate Cacheable
+	mcr	p15, 0, r0, c2, c0, 0	@ set TTBR0
+
+	@ 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
+	dsb				@ Caching is off, but must still prevent reordering
+	mcr	p15, 0, r1, c8, c7, 0	@ TLBIALL
+
+	@ Enable MMU / SCTLR
+	mrc	p15, 0, r1, c1, c0, 0	@ SCTLR
+	orr	r1, r1, #3 << 11	@ enable icache, branch prediction
+	orr	r1, r1, #4 + 1		@ enable dcache, MMU
+	mcr	p15, 0, r1, c1, c0, 0	@ SCTLR
+	isb
+
+	ldr	r1, =stage2		@ 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
+	dsb
+	mcr	p15, 0, r1, c8, c7, 0	@ TLBIALL
+	isb
+
+	@ 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
+
+@ Call fault_undefined_instruction in "Undefined mode"
+bug:
+	.word	0xe7f000f0    	@ und/udf - a "Permanently Undefined" instruction
+
+irq_handler:
+	ldr	sp, =irqstack_end
+	push	{r0 - r12, r14}
+
+	ldr	r0, IRQ_handler
+	cmp	r0, #0
+	beq	bug
+	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
diff --git a/extras/mini-os/arch/arm/hypercalls32.S b/extras/mini-os/arch/arm/hypercalls32.S
new file mode 100644
index 0000000..af8e175
--- /dev/null
+++ b/extras/mini-os/arch/arm/hypercalls32.S
@@ -0,0 +1,64 @@
+/******************************************************************************
+ * hypercall.S
+ *
+ * Xen hypercall wrappers
+ *
+ * Stefano Stabellini <stefano.stabellini@eu.citrix.com>, Citrix, 2012
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation; or, when distributed
+ * separately from the Linux kernel or incorporated into other
+ * software packages, subject to the following license:
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this source file (the "Software"), to deal in the Software without
+ * restriction, including without limitation the rights to use, copy, modify,
+ * merge, publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
+ * IN THE SOFTWARE.
+ */
+
+#include <xen/xen.h>
+
+#define __HVC(imm16) .long ((0xE1400070 | (((imm16) & 0xFFF0) << 4) | ((imm16) & 0x000F)) & 0xFFFFFFFF)
+
+#define XEN_IMM 0xEA1
+
+#define HYPERCALL_SIMPLE(hypercall)		\
+.globl HYPERVISOR_##hypercall;			\
+.align 4,0x90;					\
+HYPERVISOR_##hypercall:				\
+        mov r12, #__HYPERVISOR_##hypercall;	\
+        __HVC(XEN_IMM);				\
+        mov pc, lr;
+
+#define _hypercall0 HYPERCALL_SIMPLE
+#define _hypercall1 HYPERCALL_SIMPLE
+#define _hypercall2 HYPERCALL_SIMPLE
+#define _hypercall3 HYPERCALL_SIMPLE
+#define _hypercall4 HYPERCALL_SIMPLE
+
+_hypercall2(sched_op);
+_hypercall2(memory_op);
+_hypercall2(event_channel_op);
+_hypercall2(xen_version);
+_hypercall3(console_io);
+_hypercall1(physdev_op);
+_hypercall3(grant_table_op);
+_hypercall3(vcpu_op);
+_hypercall1(sysctl);
+_hypercall1(domctl);
+_hypercall2(hvm_op);
+_hypercall1(xsm_op);
diff --git a/extras/mini-os/arch/arm/minios-arm32.lds b/extras/mini-os/arch/arm/minios-arm32.lds
new file mode 100755
index 0000000..9627162
--- /dev/null
+++ b/extras/mini-os/arch/arm/minios-arm32.lds
@@ -0,0 +1,83 @@
+OUTPUT_ARCH(arm)
+ENTRY(_start)
+SECTIONS
+{
+  /* Note: we currently assume that Xen will load the kernel image
+   * at start-of-RAM + 0x8000. We use this initial 32 KB for the stack
+   * and translation tables.
+   */
+  _boot_stack 	 = 0x400000;	/* 16 KB boot stack */
+  _boot_stack_end = 0x404000;
+  _page_dir      = 0x404000;	/* 16 KB translation table */
+  .		 = 0x408000;
+  _text = .;			/* Text and read-only data */
+  .text : {
+	*(.text)
+	*(.gnu.warning)
+	} = 0x9090
+
+  _etext = .;			/* End of text section */
+
+  .rodata : { *(.rodata) *(.rodata.*) }
+  . = ALIGN(4096);
+  _erodata = .;
+
+  /* newlib initialization functions */
+  . = ALIGN(32 / 8);
+  PROVIDE (__preinit_array_start = .);
+  .preinit_array     : { *(.preinit_array) }
+  PROVIDE (__preinit_array_end = .);
+  PROVIDE (__init_array_start = .);
+  .init_array     : { *(.init_array) }
+  PROVIDE (__init_array_end = .);
+  PROVIDE (__fini_array_start = .);
+  .fini_array     : { *(.fini_array) }
+  PROVIDE (__fini_array_end = .);
+
+  .ctors : {
+        __CTOR_LIST__ = .;
+        *(.ctors)
+	CONSTRUCTORS
+        LONG(0)
+        __CTOR_END__ = .;
+        }
+
+  .dtors : {
+        __DTOR_LIST__ = .;
+        *(.dtors)
+        LONG(0)
+        __DTOR_END__ = .;
+        }
+
+  .data : {			/* Data */
+	*(.data)
+	}
+
+  /* Note: linker will insert any extra sections here, just before .bss */
+
+  .bss : {
+	_edata = .;			/* End of data included in image */
+	/* Nothing after here is included in the zImage's size */
+
+	__bss_start = .;
+	*(.bss)
+        *(.app.bss)
+	}
+  _end = . ;
+
+  /* Sections to be discarded */
+  /DISCARD/ : {
+	*(.text.exit)
+	*(.data.exit)
+	*(.exitcall.exit)
+	}
+
+  /* Stabs debugging sections.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  .stab.excl 0 : { *(.stab.excl) }
+  .stab.exclstr 0 : { *(.stab.exclstr) }
+  .stab.index 0 : { *(.stab.index) }
+  .stab.indexstr 0 : { *(.stab.indexstr) }
+  .comment 0 : { *(.comment) }
+}
diff --git a/extras/mini-os/arch/arm/setup.c b/extras/mini-os/arch/arm/setup.c
new file mode 100644
index 0000000..06afe46
--- /dev/null
+++ b/extras/mini-os/arch/arm/setup.c
@@ -0,0 +1,119 @@
+#include <mini-os/os.h>
+#include <mini-os/kernel.h>
+#include <mini-os/gic.h>
+#include <mini-os/console.h>
+#include <xen/xen.h>
+#include <xen/memory.h>
+#include <xen/hvm/params.h>
+#include <arch_mm.h>
+#include <libfdt.h>
+
+/*
+ * This structure contains start-of-day info, such as pagetable base pointer,
+ * address of the shared_info structure, and things like that.
+ * On x86, the hypervisor passes it to us. On ARM, we fill it in ourselves.
+ */
+union start_info_union start_info_union;
+
+/*
+ * Shared page for communicating with the hypervisor.
+ * Events flags go here, for example.
+ */
+shared_info_t *HYPERVISOR_shared_info;
+
+extern char shared_info_page[PAGE_SIZE];
+
+void *device_tree;
+
+static int hvm_get_parameter(int idx, uint64_t *value)
+{
+    struct xen_hvm_param xhv;
+    int ret;
+
+    xhv.domid = DOMID_SELF;
+    xhv.index = idx;
+    ret = HYPERVISOR_hvm_op(HVMOP_get_param, &xhv);
+    if (ret < 0) {
+        BUG();
+    }
+    *value = xhv.value;
+    return ret;
+}
+
+static void get_console(void)
+{
+    uint64_t v = -1;
+
+    hvm_get_parameter(HVM_PARAM_CONSOLE_EVTCHN, &v);
+    start_info.console.domU.evtchn = v;
+
+    hvm_get_parameter(HVM_PARAM_CONSOLE_PFN, &v);
+    start_info.console.domU.mfn = v;
+
+    printk("Console is on port %d\n", start_info.console.domU.evtchn);
+    printk("Console ring is at mfn %lx\n", (unsigned long) start_info.console.domU.mfn);
+}
+
+void get_xenbus(void)
+{
+    uint64_t value;
+
+    if (hvm_get_parameter(HVM_PARAM_STORE_EVTCHN, &value))
+        BUG();
+
+    start_info.store_evtchn = (int)value;
+
+    if(hvm_get_parameter(HVM_PARAM_STORE_PFN, &value))
+        BUG();
+    start_info.store_mfn = (unsigned long)value;
+}
+
+/*
+ * INITIAL C ENTRY POINT.
+ */
+void arch_init(void *dtb_pointer, uint32_t physical_offset)
+{
+    struct xen_add_to_physmap xatp;
+    int r;
+
+    memset(&__bss_start, 0, &_end - &__bss_start);
+
+    physical_address_offset = physical_offset;
+
+    xprintk("Virtual -> physical offset = %x\n", physical_address_offset);
+
+    xprintk("Checking DTB at %p...\n", dtb_pointer);
+
+    if ((r = fdt_check_header(dtb_pointer))) {
+        xprintk("Invalid DTB from Xen: %s\n", fdt_strerror(r));
+        BUG();
+    }
+    device_tree = dtb_pointer;
+
+    /* Map shared_info page */
+    xatp.domid = DOMID_SELF;
+    xatp.idx = 0;
+    xatp.space = XENMAPSPACE_shared_info;
+    xatp.gpfn = virt_to_pfn(shared_info_page);
+    if (HYPERVISOR_memory_op(XENMEM_add_to_physmap, &xatp) != 0)
+        BUG();
+    HYPERVISOR_shared_info = (struct shared_info *)shared_info_page;
+
+    /* Fill in start_info */
+    get_console();
+    get_xenbus();
+
+    gic_init();
+
+    start_kernel();
+}
+
+void
+arch_fini(void)
+{
+}
+
+void
+arch_do_exit(void)
+{
+}
-- 
2.0.3


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* [PATCH ARM v7 06/13] mini-os: arm: memory management
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (4 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 05/13] mini-os: arm: boot code Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 07/13] mini-os: arm: scheduling Thomas Leonard
                   ` (6 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

Based on an initial patch by Karim Raslan.

Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>

---

Changes since v6:

- fixed printk format types
- physical_address_offset is now uint32_t
---
 extras/mini-os/arch/arm/mm.c | 139 +++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 139 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/mm.c

diff --git a/extras/mini-os/arch/arm/mm.c b/extras/mini-os/arch/arm/mm.c
new file mode 100644
index 0000000..efecc51
--- /dev/null
+++ b/extras/mini-os/arch/arm/mm.c
@@ -0,0 +1,139 @@
+#include <mini-os/console.h>
+#include <xen/memory.h>
+#include <arch_mm.h>
+#include <mini-os/hypervisor.h>
+#include <libfdt.h>
+#include <lib.h>
+
+uint32_t 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]);
+    uint64_t mem_size = fdt64_to_cpu(regs[1]);
+    printk("Found memory at 0x%llx (len 0x%llx)\n",
+            (unsigned long long) mem_base, (unsigned long long) 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));
+    uint64_t heap_len = mem_size - (PFN_PHYS(*start_pfn_p) - mem_base);
+    *max_pfn_p = *start_pfn_p + PFN_DOWN(heap_len);
+
+    printk("Using pages %lu to %lu 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.
+     */
+    uint32_t 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 %llx\n", (unsigned long long) 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);
+}
-- 
2.0.3

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

* [PATCH ARM v7 07/13] mini-os: arm: scheduling
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (5 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 06/13] mini-os: arm: memory management Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 08/13] mini-os: arm: events Thomas Leonard
                   ` (5 subsequent siblings)
  12 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

Based on an initial patch by Karim Raslan.

Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>

---
Changes since v6:

- fixed printk format types

Addressed Ian Campbell's points:
- replace "mov pc" with "bx"
- preserve all callee-saved registers on context switch
---
 extras/mini-os/arch/arm/arm32.S | 22 +++++++++++++++++++
 extras/mini-os/arch/arm/sched.c | 47 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 69 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/sched.c

diff --git a/extras/mini-os/arch/arm/arm32.S b/extras/mini-os/arch/arm/arm32.S
index d2e6932..73223c8 100644
--- a/extras/mini-os/arch/arm/arm32.S
+++ b/extras/mini-os/arch/arm/arm32.S
@@ -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:
+	push	{r4-r11}	@ Store callee-saved registers to old thread's stack
+	stmia	r0, {sp, lr}	@ Store current sp and ip to prev's struct thread
+
+	ldmia	r1, {sp, lr}	@ Load new sp, ip from next's struct thread
+	pop	{r4-r11}	@ Load callee-saved registers from new thread's stack
+
+	bx	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
diff --git a/extras/mini-os/arch/arm/sched.c b/extras/mini-os/arch/arm/sched.c
new file mode 100644
index 0000000..8091566
--- /dev/null
+++ b/extras/mini-os/arch/arm/sched.c
@@ -0,0 +1,47 @@
+#include <mini-os/sched.h>
+#include <mini-os/xmalloc.h>
+#include <mini-os/console.h>
+
+void arm_start_thread(void);
+
+/* The AAPCS requires the callee (e.g. __arch_switch_threads) to preserve r4-r11. */
+#define CALLEE_SAVED_REGISTERS 8
+
+/* 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%p, stack: 0x%p\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;
+
+    /* We leave room for the 8 callee-saved registers which we will
+     * try to restore on thread switch, even though they're not needed
+     * for the initial switch. */
+    thread->sp = (unsigned long) sp - 4 * CALLEE_SAVED_REGISTERS;
+
+    thread->ip = (unsigned long) arm_start_thread;
+
+    return thread;
+}
+
+void run_idle_thread(void)
+{
+    __asm__ __volatile__ ("mov sp, %0; bx %1"::
+            "r"(idle_thread->sp + 4 * CALLEE_SAVED_REGISTERS),
+            "r"(idle_thread->ip));
+    /* Never arrive here! */
+}
-- 
2.0.3

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

* [PATCH ARM v7 08/13] mini-os: arm: events
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (6 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 07/13] mini-os: arm: scheduling Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-09-08 11:52   ` Ian Campbell
  2014-08-08 15:47 ` [PATCH ARM v7 09/13] mini-os: arm: time Thomas Leonard
                   ` (4 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

From: Karim Raslan <karim.allah.ahmed@gmail.com>

Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>
Acked-by: Ian Campbell <ian.campbell@citrix.com>
---
 extras/mini-os/arch/arm/events.c | 31 +++++++++++++++++++++++++++++++
 1 file changed, 31 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/events.c

diff --git a/extras/mini-os/arch/arm/events.c b/extras/mini-os/arch/arm/events.c
new file mode 100644
index 0000000..441010d
--- /dev/null
+++ b/extras/mini-os/arch/arm/events.c
@@ -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)
+{
+}
-- 
2.0.3

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

* [PATCH ARM v7 09/13] mini-os: arm: time
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (7 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 08/13] mini-os: arm: events Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-09-08 10:59   ` Ian Campbell
  2014-08-08 15:47 ` [PATCH ARM v7 10/13] mini-os: arm: interrupt controller Thomas Leonard
                   ` (3 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

Based on an initial patch by Karim Raslan.

Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>

---

Addressed Julien Grall's comments:
- Remove wall-clock time support (doesn't work on ARM anyway)
---
 extras/mini-os/arch/arm/time.c | 141 +++++++++++++++++++++++++++++++++++++++++
 1 file changed, 141 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/time.c

diff --git a/extras/mini-os/arch/arm/time.c b/extras/mini-os/arch/arm/time.c
new file mode 100644
index 0000000..98e931f
--- /dev/null
+++ b/extras/mini-os/arch/arm/time.c
@@ -0,0 +1,141 @@
+#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));
+}
+
+/* Wall-clock time is not currently available on ARM, so this is always zero for now:
+ * http://wiki.xenproject.org/wiki/Xen_ARM_TODO#Expose_Wallclock_time_to_guests
+ */
+static struct timespec shadow_ts;
+
+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;
+}
+
+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 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);
+}
+
+void fini_time(void)
+{
+}
-- 
2.0.3

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

* [PATCH ARM v7 10/13] mini-os: arm: interrupt controller
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (8 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 09/13] mini-os: arm: time Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-09-08 11:01   ` Ian Campbell
  2014-08-08 15:47 ` [PATCH ARM v7 11/13] mini-os: arm: build system Thomas Leonard
                   ` (2 subsequent siblings)
  12 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

Based on an initial patch by Karim Raslan.

Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>

---

Changes since v6:

Addressed Julien Grall's comments:
- converted ?: to if
---
 extras/mini-os/arch/arm/gic.c | 237 ++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 237 insertions(+)
 create mode 100644 extras/mini-os/arch/arm/gic.c

diff --git a/extras/mini-os/arch/arm/gic.c b/extras/mini-os/arch/arm/gic.c
new file mode 100644
index 0000000..6283ed5
--- /dev/null
+++ b/extras/mini-os/arch/arm/gic.c
@@ -0,0 +1,237 @@
+// 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);
+    if (level_sensitive) {
+        clear_bit_non_atomic((irq_number * 2) + 1, cfg_reg);
+    } else {
+        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:
+        /* We need to get this event to wake us up from block_domain,
+         * but we don't need to do anything special with it. */
+        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 */);
+}
-- 
2.0.3

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

* [PATCH ARM v7 11/13] mini-os: arm: build system
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (9 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 10/13] mini-os: arm: interrupt controller Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-09-08 11:05   ` Ian Campbell
  2014-08-08 15:47 ` [PATCH ARM v7 12/13] mini-os: arm: show registers, stack and exception vector on fault Thomas Leonard
  2014-08-08 15:47 ` [PATCH ARM v7 13/13] mini-os: fixed compiling with debug=n Thomas Leonard
  12 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

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

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

The change to fdt_ro.c is to avoid a compiler warning.

Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
Signed-off-by: Thomas Leonard <talex5@gmail.com>

---

Changes since v6:

- Use Xen's existing copy of libfdt instead of including our own copy.
- Only build libfdt with read support, since that's all we need.
---
 .gitignore                          |  3 +++
 extras/mini-os/ARM-TODO.txt         |  5 +++++
 extras/mini-os/COPYING              | 27 ++++++++++++++++++++++
 extras/mini-os/Config.mk            |  2 ++
 extras/mini-os/Makefile             | 38 +++++++++++++++++++++++++++++--
 extras/mini-os/arch/arm/Makefile    | 32 ++++++++++++++++++++++++++
 extras/mini-os/arch/arm/arch.mk     |  7 ++++++
 extras/mini-os/include/lib.h        |  4 +++-
 extras/mini-os/include/libfdt_env.h | 29 ++++++++++++++++++++++++
 extras/mini-os/lib/memmove.c        | 45 +++++++++++++++++++++++++++++++++++++
 extras/mini-os/lib/string.c         | 12 ++++++++++
 11 files changed, 201 insertions(+), 3 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/include/libfdt_env.h
 create mode 100644 extras/mini-os/lib/memmove.c

diff --git a/.gitignore b/.gitignore
index f1d1b9c..a67d2d9 100644
--- a/.gitignore
+++ b/.gitignore
@@ -50,6 +50,9 @@ extras/mini-os/include/mini-os
 extras/mini-os/include/x86/mini-os
 extras/mini-os/include/xen
 extras/mini-os/include/list.h
+extras/mini-os/include/fdt.h
+extras/mini-os/include/libfdt.h
+extras/mini-os/libfdt
 extras/mini-os/mini-os*
 install/*
 linux-[^/]*-paravirt/*
diff --git a/extras/mini-os/ARM-TODO.txt b/extras/mini-os/ARM-TODO.txt
new file mode 100644
index 0000000..3226d39
--- /dev/null
+++ b/extras/mini-os/ARM-TODO.txt
@@ -0,0 +1,5 @@
+* 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
diff --git a/extras/mini-os/COPYING b/extras/mini-os/COPYING
index 1d9df6c..b676bb6 100644
--- a/extras/mini-os/COPYING
+++ b/extras/mini-os/COPYING
@@ -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.
diff --git a/extras/mini-os/Config.mk b/extras/mini-os/Config.mk
index d61877b..4ecde54 100644
--- a/extras/mini-os/Config.mk
+++ b/extras/mini-os/Config.mk
@@ -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
diff --git a/extras/mini-os/Makefile b/extras/mini-os/Makefile
index 6d6537e..77dc9aa 100644
--- a/extras/mini-os/Makefile
+++ b/extras/mini-os/Makefile
@@ -51,7 +51,7 @@ flags-$(CONFIG_XENBUS) += -DCONFIG_XENBUS
 DEF_CFLAGS += $(flags-y)
 
 # Symlinks and headers that must be created before building the C files
-GENERATED_HEADERS := include/list.h $(ARCH_LINKS) include/mini-os include/xen include/$(TARGET_ARCH_FAM)/mini-os
+GENERATED_HEADERS := include/list.h $(ARCH_LINKS) include/mini-os include/xen include/$(TARGET_ARCH_FAM)/mini-os include/fdt.h include/libfdt.h
 
 EXTRA_DEPS += $(GENERATED_HEADERS)
 
@@ -75,7 +75,18 @@ EXTRA_OBJS =
 TARGET := mini-os
 
 # Subdirectories common to mini-os
-SUBDIRS := lib xenbus console
+SUBDIRS := lib xenbus console libfdt
+
+FDT_SRC :=
+ifeq ($(XEN_TARGET_ARCH),arm32)
+# Need libgcc.a for division helpers
+LDLIBS += `$(CC) -print-libgcc-file-name`
+
+# Device tree support
+FDT_SRC := libfdt/fdt.c libfdt/fdt_ro.c libfdt/fdt_strerror.c
+
+src-y += ${FDT_SRC}
+endif
 
 src-$(CONFIG_BLKFRONT) += blkfront.c
 src-$(CONFIG_TPMFRONT) += tpmfront.c
@@ -97,10 +108,13 @@ 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
+src-y += lib/memmove.c
 src-y += lib/sys.c
 src-y += lib/xmalloc.c
 src-$(CONFIG_XENBUS) += lib/xs.c
@@ -125,6 +139,21 @@ $(ARCH_LINKS):
 	$(arch_links)
 endif
 
+include/fdt.h:
+	cp $(XEN_ROOT)/xen/include/xen/libfdt/fdt.h $@
+
+include/libfdt.h:
+	sed 's!xen/libfdt/!!' $(XEN_ROOT)/xen/include/xen/libfdt/libfdt.h > $@
+
+libfdt:
+	mkdir $@
+
+libfdt/libfdt_internal.h: libfdt
+	cp $(XEN_ROOT)/xen/common/libfdt/libfdt_internal.h $@
+
+libfdt/%.c: libfdt libfdt/libfdt_internal.h
+	cp $(XEN_ROOT)/xen/common/libfdt/$*.c $@
+
 include/list.h: $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue-h-seddery $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue.h
 	perl $^ --prefix=minios  >$@.new
 	$(call move-if-changed,$@.new,$@)
@@ -190,7 +219,11 @@ $(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib
 	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o $@.o
 	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start $@.o $@.o
 	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) $@.o $(EXTRA_OBJS) -o $@
+ifeq ($(XEN_TARGET_ARCH),arm32)
+	$(OBJCOPY) -O binary $@ $@.img
+else
 	gzip -f -9 -c $@ >$@.gz
+endif
 
 .PHONY: clean arch_clean
 
@@ -202,6 +235,7 @@ clean:	arch_clean
 		rm -f $$dir/*.o; \
 	done
 	rm -f include/list.h
+	rm -f ${FDT_SRC} libfdt/libfdt_internal.h
 	rm -f $(OBJ_DIR)/*.o *~ $(OBJ_DIR)/core $(OBJ_DIR)/$(TARGET).elf $(OBJ_DIR)/$(TARGET).raw $(OBJ_DIR)/$(TARGET) $(OBJ_DIR)/$(TARGET).gz
 	find . $(OBJ_DIR) -type l | xargs rm -f
 	$(RM) $(OBJ_DIR)/lwip.a $(LWO)
diff --git a/extras/mini-os/arch/arm/Makefile b/extras/mini-os/arch/arm/Makefile
new file mode 100755
index 0000000..8b78651
--- /dev/null
+++ b/extras/mini-os/arch/arm/Makefile
@@ -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)
+
diff --git a/extras/mini-os/arch/arm/arch.mk b/extras/mini-os/arch/arm/arch.mk
new file mode 100644
index 0000000..ad6e05f
--- /dev/null
+++ b/extras/mini-os/arch/arm/arch.mk
@@ -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
+
diff --git a/extras/mini-os/include/lib.h b/extras/mini-os/include/lib.h
index 62836c7..326e39f 100644
--- a/extras/mini-os/include/lib.h
+++ b/extras/mini-os/include/lib.h
@@ -95,6 +95,7 @@ char	*strncpy(char * __restrict, const char * __restrict, size_t);
 
 char	*strstr(const char *, const char *);
 
+void *memmove(void *, const void *, size_t);
 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
diff --git a/extras/mini-os/include/libfdt_env.h b/extras/mini-os/include/libfdt_env.h
new file mode 100644
index 0000000..9c5076e
--- /dev/null
+++ b/extras/mini-os/include/libfdt_env.h
@@ -0,0 +1,29 @@
+#ifndef _LIBFDT_ENV_H
+#define _LIBFDT_ENV_H
+
+#include <stddef.h>
+#include <stdint.h>
+#include <lib.h>
+
+#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 */
diff --git a/extras/mini-os/lib/memmove.c b/extras/mini-os/lib/memmove.c
new file mode 100644
index 0000000..0298b7c
--- /dev/null
+++ b/extras/mini-os/lib/memmove.c
@@ -0,0 +1,45 @@
+/*
+ *	memmove.c: memmove compat implementation.
+ *
+ *	Copyright (c) 2001-2008, NLnet Labs. All rights reserved.
+ *
+ * See COPYING for the license.
+*/
+
+#include <os.h>
+#include <mini-os/lib.h>
+
+#ifndef HAVE_LIBC
+
+void *memmove(void *dest, const void *src, size_t n)
+{
+	uint8_t* from = (uint8_t*) src;
+	uint8_t* to = (uint8_t*) dest;
+
+	if (from == to || n == 0)
+		return dest;
+	if (to > from && to-from < (int)n) {
+		/* to overlaps with from */
+		/*  <from......>         */
+		/*         <to........>  */
+		/* copy in reverse, to avoid overwriting from */
+		int i;
+		for(i=n-1; i>=0; i--)
+			to[i] = from[i];
+		return dest;
+	}
+	if (from > to  && from-to < (int)n) {
+		/* to overlaps with from */
+		/*        <from......>   */
+		/*  <to........>         */
+		/* copy forwards, to avoid overwriting from */
+		size_t i;
+		for(i=0; i<n; i++)
+			to[i] = from[i];
+		return dest;
+	}
+	memcpy(dest, src, n);
+	return dest;
+}
+
+#endif
diff --git a/extras/mini-os/lib/string.c b/extras/mini-os/lib/string.c
index 8b24146..c96ca41 100644
--- a/extras/mini-os/lib/string.c
+++ b/extras/mini-os/lib/string.c
@@ -225,4 +225,16 @@ int ffs(int i)
    return 0;
 }
 
+void *memchr(const void *s, int c, size_t n)
+{
+    if (n != 0) {
+        const unsigned char *p = s;
+
+        do {
+            if (*p++ == (unsigned char)c)
+                return ((void *)(uintptr_t)(p - 1));
+        } while (--n != 0);
+    }
+    return (NULL);
+}
 #endif
-- 
2.0.3

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

* [PATCH ARM v7 12/13] mini-os: arm: show registers, stack and exception vector on fault
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (10 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 11/13] mini-os: arm: build system Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-09-08 11:06   ` Ian Campbell
  2014-08-08 15:47 ` [PATCH ARM v7 13/13] mini-os: fixed compiling with debug=n Thomas Leonard
  12 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

Signed-off-by: Thomas Leonard <talex5@gmail.com>

---

- Exit with SHUTDOWN_crash on BUG or fault (suggested by Ian Campbell).
- Fixed printk format types.
---
 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

diff --git a/extras/mini-os/ARM-TODO.txt b/extras/mini-os/ARM-TODO.txt
index 3226d39..1e40db1 100644
--- a/extras/mini-os/ARM-TODO.txt
+++ b/extras/mini-os/ARM-TODO.txt
@@ -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 (?)
diff --git a/extras/mini-os/arch/arm/arm32.S b/extras/mini-os/arch/arm/arm32.S
index 73223c8..a08a170 100644
--- a/extras/mini-os/arch/arm/arm32.S
+++ b/extras/mini-os/arch/arm/arm32.S
@@ -162,8 +162,69 @@ irqstack:
 	.fill (1024), 4, 0x0
 irqstack_end:
 
+fault_dump:
+	.fill 18, 4, 0x0		@ On fault, we save the registers + CPSR + handler address
+
 .popsection
 
+fault:
+	cpsid	aif			@ Disable interrupts
+
+	ldr	r13, =fault_dump
+	stmia	r13, {r0-r12}		@ Dump the non-banked registers directly (well, unless from FIQ mode)
+	str	r14, [r13, #15 << 2]	@ Our r14 is the faulting r15
+	mov	r0, r13
+
+	@ Save the caller's CPSR (our SPSR) too.
+	mrs	r1, SPSR
+	str	r1, [r13, #16 << 2]
+
+	@ Switch to the mode we came from to get r13 and r14.
+	@ If coming from user mode, use System mode instead so we're still
+	@ privileged.
+	and	r1, r1, #0x1f		@ r1 = SPSR mode
+	cmp	r1, #0x10		@ If from User mode
+	moveq	r1, #0x1f		@ Then use System mode instead
+
+	mrs	r3, CPSR		@ r3 = our CPSR
+	bic	r2, r3, #0x1f
+	orr	r2, r2, r1
+	msr	CPSR, r2		@ Change to mode r1
+
+	@ Save old mode's r13, r14
+	str	r13, [r0, #13 << 2]
+	str	r14, [r0, #14 << 2]
+
+	msr	CPSR, r3		@ Back to fault mode
+
+	ldr	r1, [r0, #17 << 2]
+	sub	r1, r1, #12		@ Fix to point at start of handler
+	str	r1, [r0, #17 << 2]
+
+	@ Call C code to format the register dump.
+	@ Clobbers the stack, but we're not going to return anyway.
+	ldr	sp, =_boot_stack_end
+	bl	dump_registers
+	b	do_exit
+
+@ 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.
+#define FAULT(name)			\
+.globl fault_##name;			\
+fault_##name:				\
+	ldr	r13, =fault_dump;	\
+	str	r15, [r13, #17 << 2];	\
+	b	fault
+
+FAULT(reset)
+FAULT(undefined_instruction)
+FAULT(svc)
+FAULT(prefetch_call)
+FAULT(prefetch_abort)
+FAULT(data_abort)
+
 @ exception base address
 .align 5
 .globl exception_vector_table
@@ -173,13 +234,13 @@ irqstack_end:
 @  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
+	b	fault_reset
+	b	fault_undefined_instruction
+	b	fault_svc
+	b	fault_prefetch_call
+	b	fault_prefetch_abort
+	b	fault_data_abort
+	b	irq_handler @ IRQ
 	.word 0xe7f000f0    @ abort on FIQ
 
 @ Call fault_undefined_instruction in "Undefined mode"
diff --git a/extras/mini-os/arch/arm/panic.c b/extras/mini-os/arch/arm/panic.c
new file mode 100644
index 0000000..a049d05
--- /dev/null
+++ b/extras/mini-os/arch/arm/panic.c
@@ -0,0 +1,98 @@
+/******************************************************************************
+ * panic.c
+ *
+ * Displays a register dump and stack trace for debugging.
+ *
+ * Copyright (c) 2014, Thomas Leonard
+ * 
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to
+ * deal in the Software without restriction, including without limitation the
+ * rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+ * sell copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ * 
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ * 
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 
+ * DEALINGS IN THE SOFTWARE.
+ */
+
+#include <mini-os/os.h>
+#include <mini-os/console.h>
+#include <arch_mm.h>
+
+extern int irqstack[];
+extern int irqstack_end[];
+
+typedef void handler(void);
+
+extern handler fault_reset;
+extern handler fault_undefined_instruction;
+extern handler fault_svc;
+extern handler fault_prefetch_call;
+extern handler fault_prefetch_abort;
+extern handler fault_data_abort;
+
+void dump_registers(int *saved_registers) {
+    static int in_dump = 0;
+    int *sp, *stack_top, *x;
+    char *fault_name;
+    void *fault_handler;
+    int i;
+
+    if (in_dump)
+    {
+        printk("Crash while in dump_registers! Not generating a second report.\n");
+        return;
+    }
+
+    in_dump = 1;
+
+    fault_handler = (handler *) saved_registers[17];
+    if (fault_handler == fault_reset)
+        fault_name = "reset";
+    else if (fault_handler == fault_undefined_instruction)
+        fault_name = "undefined_instruction";
+    else if (fault_handler == fault_svc)
+        fault_name = "svc";
+    else if (fault_handler == fault_prefetch_call)
+        fault_name = "prefetch_call";
+    else if (fault_handler == fault_prefetch_abort)
+        fault_name = "prefetch_abort";
+    else if (fault_handler == fault_data_abort)
+        fault_name = "data_abort";
+    else
+        fault_name = "unknown fault type!";
+
+    printk("Fault handler at %p called (%s)\n", fault_handler, fault_name);
+
+    for (i = 0; i < 16; i++) {
+        printk("r%d = %x\n", i, saved_registers[i]);
+    }
+    printk("CPSR = %x\n", saved_registers[16]);
+
+    printk("Stack dump (innermost last)\n");
+    sp = (int *) saved_registers[13];
+
+    if (sp >= _boot_stack && sp <= _boot_stack_end)
+        stack_top = _boot_stack_end;                    /* The boot stack */
+    else if (sp >= irqstack && sp <= irqstack_end)
+        stack_top = irqstack_end;                       /* The IRQ stack */
+    else
+        stack_top = (int *) ((((unsigned long) sp) | (__STACK_SIZE-1)) + 1);        /* A normal thread stack */
+
+    for (x = stack_top - 1; x >= sp; x--)
+    {
+        printk("  [%8p] %8x\n", x, *x);
+    }
+    printk("End of stack\n");
+
+    in_dump = 0;
+}
-- 
2.0.3


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* [PATCH ARM v7 13/13] mini-os: fixed compiling with debug=n
  2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
                   ` (11 preceding siblings ...)
  2014-08-08 15:47 ` [PATCH ARM v7 12/13] mini-os: arm: show registers, stack and exception vector on fault Thomas Leonard
@ 2014-08-08 15:47 ` Thomas Leonard
  2014-09-08 11:08   ` Ian Campbell
  12 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-08-08 15:47 UTC (permalink / raw)
  To: xen-devel
  Cc: Thomas Leonard, Dave.Scott, anil, stefano.stabellini, samuel.thibault

Without -fno-tree-loop-distribute-patterns, gcc -O3 recognises that our
"memset" is doing a memset operation and tries to make it call the
standard "memset", creating a loop.

The change to fdt_ro.c is to avoid a compiler warning.

Signed-off-by: Thomas Leonard <talex5@gmail.com>
---
 extras/mini-os/minios.mk   | 2 +-
 xen/common/libfdt/fdt_ro.c | 2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/extras/mini-os/minios.mk b/extras/mini-os/minios.mk
index 20ba64b..3e881e4 100644
--- a/extras/mini-os/minios.mk
+++ b/extras/mini-os/minios.mk
@@ -23,7 +23,7 @@ DEF_CFLAGS += -g
 #DEF_CFLAGS += -DGNT_DEBUG
 #DEF_CFLAGS += -DGNTMAP_DEBUG
 else
-DEF_CFLAGS += -O3
+DEF_CFLAGS += -O3 -fno-tree-loop-distribute-patterns
 endif
 
 # Make the headers define our internal stuff
diff --git a/xen/common/libfdt/fdt_ro.c b/xen/common/libfdt/fdt_ro.c
index 02b6d68..a34c6d6 100644
--- a/xen/common/libfdt/fdt_ro.c
+++ b/xen/common/libfdt/fdt_ro.c
@@ -444,7 +444,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
 
 int fdt_node_depth(const void *fdt, int nodeoffset)
 {
-	int nodedepth;
+	int nodedepth = -1;
 	int err;
 
 	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);
-- 
2.0.3

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

* Re: [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c
  2014-08-08 15:47 ` [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c Thomas Leonard
@ 2014-08-08 16:37   ` Samuel Thibault
  2014-08-11  7:59     ` Thomas Leonard
  0 siblings, 1 reply; 31+ messages in thread
From: Samuel Thibault @ 2014-08-08 16:37 UTC (permalink / raw)
  To: Thomas Leonard; +Cc: xen-devel, anil, Dave.Scott, stefano.stabellini

Thomas Leonard, le Fri 08 Aug 2014 16:47:32 +0100, a écrit :
> It's only used by test.c

It's also used by qemu.

Samuel

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

* Re: [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c
  2014-08-08 16:37   ` Samuel Thibault
@ 2014-08-11  7:59     ` Thomas Leonard
  2014-08-11  9:29       ` Samuel Thibault
  0 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-08-11  7:59 UTC (permalink / raw)
  To: Samuel Thibault, Thomas Leonard, xen-devel, Stefano Stabellini,
	Anil Madhavapeddy, David Scott, KarimAllah Ahmed

On 8 August 2014 17:37, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:
> Thomas Leonard, le Fri 08 Aug 2014 16:47:32 +0100, a écrit :
>> It's only used by test.c
>
> It's also used by qemu.

Oh. I thought all the existing stuff using mini-os was using it with a libc.
How can I test this?


-- 
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
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c
  2014-08-11  7:59     ` Thomas Leonard
@ 2014-08-11  9:29       ` Samuel Thibault
  2014-08-28 15:07         ` Thomas Leonard
  0 siblings, 1 reply; 31+ messages in thread
From: Samuel Thibault @ 2014-08-11  9:29 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: xen-devel, Anil Madhavapeddy, David Scott, Stefano Stabellini

Thomas Leonard, le Mon 11 Aug 2014 08:59:06 +0100, a écrit :
> On 8 August 2014 17:37, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:
> > Thomas Leonard, le Fri 08 Aug 2014 16:47:32 +0100, a écrit :
> >> It's only used by test.c
> >
> > It's also used by qemu.
> 
> Oh. I thought all the existing stuff using mini-os was using it with a libc.

Ah, sorry, I missed the #ifndef HAVE_LIBC, and thought that libc wasn't
providing it. Then,

Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

Samuel

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

* Re: [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c
  2014-08-11  9:29       ` Samuel Thibault
@ 2014-08-28 15:07         ` Thomas Leonard
  0 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-08-28 15:07 UTC (permalink / raw)
  To: Samuel Thibault, Thomas Leonard, xen-devel, Stefano Stabellini,
	Anil Madhavapeddy, David Scott, KarimAllah Ahmed

On 11 August 2014 10:29, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:
> Thomas Leonard, le Mon 11 Aug 2014 08:59:06 +0100, a écrit :
>> On 8 August 2014 17:37, Samuel Thibault <samuel.thibault@ens-lyon.org> wrote:
>> > Thomas Leonard, le Fri 08 Aug 2014 16:47:32 +0100, a écrit :
>> >> It's only used by test.c
>> >
>> > It's also used by qemu.
>>
>> Oh. I thought all the existing stuff using mini-os was using it with a libc.
>
> Ah, sorry, I missed the #ifndef HAVE_LIBC, and thought that libc wasn't
> providing it. Then,
>
> Acked-by: Samuel Thibault <samuel.thibault@ens-lyon.org>

Thanks. Any other comments on this patch series?


-- 
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
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH ARM v7 09/13] mini-os: arm: time
  2014-08-08 15:47 ` [PATCH ARM v7 09/13] mini-os: arm: time Thomas Leonard
@ 2014-09-08 10:59   ` Ian Campbell
  2014-09-08 16:08     ` Thomas Leonard
  0 siblings, 1 reply; 31+ messages in thread
From: Ian Campbell @ 2014-09-08 10:59 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: xen-devel, stefano.stabellini, Dave.Scott, samuel.thibault, anil

On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:

Sorry for how long I took to get to this, travel and the resulting
backlog conspired against me.

> +    __asm__ __volatile__("isb;mrrc p15, 1, %0, %1, c14":"=r"(c_lo), "=r"(c_hi));

Is the isb really necessary here?

> +    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));

There's quite a few of these //printk(debug) statements in this patch...

> +    return time;
> +}
> +
> +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));

I think you can use
	"mcrr p15, 3, %0, %H0, c14" :: "r" (value)
here.


> +
> +    __asm__ __volatile__("mov %0, #0x1\n"
> +            "mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */
> +            "isb":"=r"(x));

x = 1 before this would avoid the mov inside the inline stuff as well as
the strange looking use of an output register for a write.

> +}
> +
> +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));

and again. You probably just want a write_timer_ctl(uiint.. val) type
function.

> +}
> +
> +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);

More left over debug.

> +        unset_vtimer_compare();
> +
> +        /* Give the IRQ handler a chance to handle whatever woke us up. */
> +        local_irq_enable();
> +        local_irq_disable();
> +    }
> +}

Ian.

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

* Re: [PATCH ARM v7 10/13] mini-os: arm: interrupt controller
  2014-08-08 15:47 ` [PATCH ARM v7 10/13] mini-os: arm: interrupt controller Thomas Leonard
@ 2014-09-08 11:01   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2014-09-08 11:01 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: xen-devel, stefano.stabellini, Dave.Scott, samuel.thibault, anil

On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
> 
> +    /* 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.
> +     */

You probably ought to not rely on that long term but it'll do for now.

I've not dug into this too deeply but I'm ok with it going in as is.

Ian.

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

* Re: [PATCH ARM v7 11/13] mini-os: arm: build system
  2014-08-08 15:47 ` [PATCH ARM v7 11/13] mini-os: arm: build system Thomas Leonard
@ 2014-09-08 11:05   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2014-09-08 11:05 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: xen-devel, stefano.stabellini, Dave.Scott, samuel.thibault, anil

On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
> 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
> 
> The memmove implementation is from FreeBSD's
> contrib/ldns/compat/memmove.c (r246827).

This is ~= 3-clause BSD which over the existing license has:
> +    * 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.

I suppose this is somewhat tolerable but it might be nicer to avoid if
we can. Does anyone know of (or fancy knocking up) a clean room
memmove() under the 2-clause license used by the rest of minios?

> The change to fdt_ro.c is to avoid a compiler warning.

I was about to ask for it to be quoted, but I see that you don't
actually touch fdt_ro.c, so maybe this comment is just stale?

Ian.

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

* Re: [PATCH ARM v7 12/13] mini-os: arm: show registers, stack and exception vector on fault
  2014-08-08 15:47 ` [PATCH ARM v7 12/13] mini-os: arm: show registers, stack and exception vector on fault Thomas Leonard
@ 2014-09-08 11:06   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2014-09-08 11:06 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: xen-devel, stefano.stabellini, Dave.Scott, samuel.thibault, anil

On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
> Signed-off-by: Thomas Leonard <talex5@gmail.com>

Acked-by: Ian Campbell <Ian.Campbell@citrix.com>

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

* Re: [PATCH ARM v7 13/13] mini-os: fixed compiling with debug=n
  2014-08-08 15:47 ` [PATCH ARM v7 13/13] mini-os: fixed compiling with debug=n Thomas Leonard
@ 2014-09-08 11:08   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2014-09-08 11:08 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: xen-devel, stefano.stabellini, Dave.Scott, samuel.thibault, anil

On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
> Without -fno-tree-loop-distribute-patterns, gcc -O3 recognises that our
> "memset" is doing a memset operation and tries to make it call the
> standard "memset", creating a loop.

As in __builtin_memset or some such? Isn't there are -nostdthings we
could/should use? -fno-tree-loop... seems a bit abstracted from the
affect and it's not impossible that different gcc would still do this
same thing in the future under some other optimisation.

> The change to fdt_ro.c is to avoid a compiler warning.

Ah, here it is for real ;-)

> 
> Signed-off-by: Thomas Leonard <talex5@gmail.com>
> ---
>  extras/mini-os/minios.mk   | 2 +-
>  xen/common/libfdt/fdt_ro.c | 2 +-
>  2 files changed, 2 insertions(+), 2 deletions(-)
> 
> diff --git a/extras/mini-os/minios.mk b/extras/mini-os/minios.mk
> index 20ba64b..3e881e4 100644
> --- a/extras/mini-os/minios.mk
> +++ b/extras/mini-os/minios.mk
> @@ -23,7 +23,7 @@ DEF_CFLAGS += -g
>  #DEF_CFLAGS += -DGNT_DEBUG
>  #DEF_CFLAGS += -DGNTMAP_DEBUG
>  else
> -DEF_CFLAGS += -O3
> +DEF_CFLAGS += -O3 -fno-tree-loop-distribute-patterns
>  endif
>  
>  # Make the headers define our internal stuff
> diff --git a/xen/common/libfdt/fdt_ro.c b/xen/common/libfdt/fdt_ro.c
> index 02b6d68..a34c6d6 100644
> --- a/xen/common/libfdt/fdt_ro.c
> +++ b/xen/common/libfdt/fdt_ro.c
> @@ -444,7 +444,7 @@ int fdt_supernode_atdepth_offset(const void *fdt, int nodeoffset,
>  
>  int fdt_node_depth(const void *fdt, int nodeoffset)
>  {
> -	int nodedepth;
> +	int nodedepth = -1;
>  	int err;
>  
>  	err = fdt_supernode_atdepth_offset(fdt, nodeoffset, 0, &nodedepth);

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

* Re: [PATCH ARM v7 08/13] mini-os: arm: events
  2014-08-08 15:47 ` [PATCH ARM v7 08/13] mini-os: arm: events Thomas Leonard
@ 2014-09-08 11:52   ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2014-09-08 11:52 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: xen-devel, stefano.stabellini, Dave.Scott, samuel.thibault, anil

On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
> From: Karim Raslan <karim.allah.ahmed@gmail.com>
> 
> Signed-off-by: Karim Allah Ahmed <karim.allah.ahmed@gmail.com>
> Signed-off-by: Thomas Leonard <talex5@gmail.com>
> Acked-by: Ian Campbell <ian.campbell@citrix.com>

I've applied this series up to here, acking some of the arm bits as I
went.

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

* Re: [PATCH ARM v7 09/13] mini-os: arm: time
  2014-09-08 10:59   ` Ian Campbell
@ 2014-09-08 16:08     ` Thomas Leonard
  2014-09-22 10:35       ` Dave Scott
  0 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-09-08 16:08 UTC (permalink / raw)
  To: Ian Campbell
  Cc: xen-devel, Stefano Stabellini, David Scott, Samuel Thibault,
	Anil Madhavapeddy

On 8 September 2014 11:59, Ian Campbell <Ian.Campbell@citrix.com> wrote:
> On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
>
> Sorry for how long I took to get to this, travel and the resulting
> backlog conspired against me.

Hi Ian,

I'm on holiday for a few weeks now. Please feel free to apply any
minor changes if you don't want to wait. In any case, I'll take
another look at the end of Sep.

Regards,

>> +    __asm__ __volatile__("isb;mrrc p15, 1, %0, %1, c14":"=r"(c_lo), "=r"(c_hi));
>
> Is the isb really necessary here?

I don't think so.

>> +    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));
>
> There's quite a few of these //printk(debug) statements in this patch...
>
>> +    return time;
>> +}
>> +
>> +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));
>
> I think you can use
>         "mcrr p15, 3, %0, %H0, c14" :: "r" (value)
> here.
>
>
>> +
>> +    __asm__ __volatile__("mov %0, #0x1\n"
>> +            "mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */
>> +            "isb":"=r"(x));
>
> x = 1 before this would avoid the mov inside the inline stuff as well as
> the strange looking use of an output register for a write.
>
>> +}
>> +
>> +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));
>
> and again. You probably just want a write_timer_ctl(uiint.. val) type
> function.
>
>> +}
>> +
>> +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);
>
> More left over debug.
>
>> +        unset_vtimer_compare();
>> +
>> +        /* Give the IRQ handler a chance to handle whatever woke us up. */
>> +        local_irq_enable();
>> +        local_irq_disable();
>> +    }
>> +}
>
> Ian.
>



-- 
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

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

* Re: [PATCH ARM v7 09/13] mini-os: arm: time
  2014-09-08 16:08     ` Thomas Leonard
@ 2014-09-22 10:35       ` Dave Scott
  2014-09-23 16:53         ` Stefano Stabellini
                           ` (3 more replies)
  0 siblings, 4 replies; 31+ messages in thread
From: Dave Scott @ 2014-09-22 10:35 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: Dave Scott, Ian Campbell, Anil Madhavapeddy, Stefano Stabellini,
	Samuel Thibault, xen-devel

Hi,

On 8 Sep 2014, at 17:08, Thomas Leonard <talex5@gmail.com> wrote:

> On 8 September 2014 11:59, Ian Campbell <Ian.Campbell@citrix.com> wrote:
>> On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
>> 
>> Sorry for how long I took to get to this, travel and the resulting
>> backlog conspired against me.
> 
> Hi Ian,
> 
> I'm on holiday for a few weeks now. Please feel free to apply any
> minor changes if you don't want to wait. In any case, I'll take
> another look at the end of Sep.
> 
> Regards,
> 
>>> +    __asm__ __volatile__("isb;mrrc p15, 1, %0, %1, c14":"=r"(c_lo), "=r"(c_hi));
>> 
>> Is the isb really necessary here?
> 
> I don't think so.
> 
>>> +    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));
>> 
>> There's quite a few of these //printk(debug) statements in this patch...
>> 
>>> +    return time;
>>> +}
>>> +
>>> +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));
>> 
>> I think you can use
>>        "mcrr p15, 3, %0, %H0, c14" :: "r" (value)
>> here.
>> 
>> 
>>> +
>>> +    __asm__ __volatile__("mov %0, #0x1\n"
>>> +            "mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */
>>> +            "isb":"=r"(x));
>> 
>> x = 1 before this would avoid the mov inside the inline stuff as well as
>> the strange looking use of an output register for a write.
>> 
>>> +}
>>> +
>>> +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));
>> 
>> and again. You probably just want a write_timer_ctl(uiint.. val) type
>> function.
>> 
>>> +}
>>> +
>>> +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);
>> 
>> More left over debug.

I had a play with this yesterday on my cubieboard with Mirage. Using network and vchan connections worked fine, so event channels are working ok. However when I had no external event channel input and my domain blocked on a timer, it seemed to block forever in the ‘wfi’ (as I could see by enabling these debug lines and then pressing ‘enter’ to trigger an interrupt on the console). As far as I can tell the monotonic clock is giving me sensible values, and the ‘until’ value looked sensible. For now I can work around the problem by attaching a vif to a busy network :-)

Sorry for the vagueness of the bug report. I’ll try to make a more minimal repro example when I get the time.

Dave


>> 
>>> +        unset_vtimer_compare();
>>> +
>>> +        /* Give the IRQ handler a chance to handle whatever woke us up. */
>>> +        local_irq_enable();
>>> +        local_irq_disable();
>>> +    }
>>> +}
>> 
>> Ian.
>> 
> 
> 
> 
> -- 
> 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

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

* Re: [PATCH ARM v7 09/13] mini-os: arm: time
  2014-09-22 10:35       ` Dave Scott
@ 2014-09-23 16:53         ` Stefano Stabellini
  2014-09-26 10:01         ` Thomas Leonard
                           ` (2 subsequent siblings)
  3 siblings, 0 replies; 31+ messages in thread
From: Stefano Stabellini @ 2014-09-23 16:53 UTC (permalink / raw)
  To: Dave Scott
  Cc: Thomas Leonard, Ian Campbell, Anil Madhavapeddy,
	Stefano Stabellini, Samuel Thibault, xen-devel

[-- Attachment #1: Type: text/plain, Size: 5415 bytes --]

On Mon, 22 Sep 2014, Dave Scott wrote:
> Hi,
> 
> On 8 Sep 2014, at 17:08, Thomas Leonard <talex5@gmail.com> wrote:
> 
> > On 8 September 2014 11:59, Ian Campbell <Ian.Campbell@citrix.com> wrote:
> >> On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
> >> 
> >> Sorry for how long I took to get to this, travel and the resulting
> >> backlog conspired against me.
> > 
> > Hi Ian,
> > 
> > I'm on holiday for a few weeks now. Please feel free to apply any
> > minor changes if you don't want to wait. In any case, I'll take
> > another look at the end of Sep.
> > 
> > Regards,
> > 
> >>> +    __asm__ __volatile__("isb;mrrc p15, 1, %0, %1, c14":"=r"(c_lo), "=r"(c_hi));
> >> 
> >> Is the isb really necessary here?
> > 
> > I don't think so.
> > 
> >>> +    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));
> >> 
> >> There's quite a few of these //printk(debug) statements in this patch...
> >> 
> >>> +    return time;
> >>> +}
> >>> +
> >>> +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));
> >> 
> >> I think you can use
> >>        "mcrr p15, 3, %0, %H0, c14" :: "r" (value)
> >> here.
> >> 
> >> 
> >>> +
> >>> +    __asm__ __volatile__("mov %0, #0x1\n"
> >>> +            "mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */
> >>> +            "isb":"=r"(x));
> >> 
> >> x = 1 before this would avoid the mov inside the inline stuff as well as
> >> the strange looking use of an output register for a write.
> >> 
> >>> +}
> >>> +
> >>> +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));
> >> 
> >> and again. You probably just want a write_timer_ctl(uiint.. val) type
> >> function.
> >> 
> >>> +}
> >>> +
> >>> +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);
> >> 
> >> More left over debug.
> 
> I had a play with this yesterday on my cubieboard with Mirage. Using network and vchan connections worked fine, so event channels are working ok. However when I had no external event channel input and my domain blocked on a timer, it seemed to block forever in the ‘wfi’ (as I could see by enabling these debug lines and then pressing ‘enter’ to trigger an interrupt on the console). As far as I can tell the monotonic clock is giving me sensible values, and the ‘until’ value looked sensible. For now I can work around the problem by attaching a vif to a busy network :-)
> 
> Sorry for the vagueness of the bug report. I’ll try to make a more minimal repro example when I get the time.

This reminds me of many fun memories about late debugging sessions.

What Xen version are you using?

WFI means wait-for-interrupt and it is trapped into Xen, see:

xen/arch/arm/traps.c:do_trap_hypervisor, label HSR_EC_WFI_WFE.

When the guest issues a WFI instruction, Xen blocks the vcpu on its
behalf. Any interrupt for the vcpu in question should wake it up, see
the vcpu_unblock call at the end of
xen/arch/arm/vgic.c:vgic_vcpu_inject_irq. vgic_vcpu_inject_irq is called
by the timer code, both vtimer.c (emulated time) and time.c (virtual
timer).

If something goes wrong with the wake-up, the vcpu could remain blocked.

Have fun! ;-)


> Dave
> 
> 
> >> 
> >>> +        unset_vtimer_compare();
> >>> +
> >>> +        /* Give the IRQ handler a chance to handle whatever woke us up. */
> >>> +        local_irq_enable();
> >>> +        local_irq_disable();
> >>> +    }
> >>> +}
> >> 
> >> Ian.
> >> 
> > 
> > 
> > 
> > -- 
> > 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
> 

[-- Attachment #2: Type: text/plain, Size: 126 bytes --]

_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH ARM v7 09/13] mini-os: arm: time
  2014-09-22 10:35       ` Dave Scott
  2014-09-23 16:53         ` Stefano Stabellini
@ 2014-09-26 10:01         ` Thomas Leonard
  2014-10-01 11:10         ` Thomas Leonard
  2014-10-01 11:10         ` Thomas Leonard
  3 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-09-26 10:01 UTC (permalink / raw)
  To: Dave Scott
  Cc: xen-devel, Stefano Stabellini, Ian Campbell, Samuel Thibault,
	Anil Madhavapeddy

On 22 September 2014 11:35, Dave Scott <Dave.Scott@citrix.com> wrote:
> Hi,
>
> On 8 Sep 2014, at 17:08, Thomas Leonard <talex5@gmail.com> wrote:
>
>> On 8 September 2014 11:59, Ian Campbell <Ian.Campbell@citrix.com> wrote:
>>> On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
>>>
>>> Sorry for how long I took to get to this, travel and the resulting
>>> backlog conspired against me.
>>
>> Hi Ian,
>>
>> I'm on holiday for a few weeks now. Please feel free to apply any
>> minor changes if you don't want to wait. In any case, I'll take
>> another look at the end of Sep.
>>
>> Regards,
>>
>>>> +    __asm__ __volatile__("isb;mrrc p15, 1, %0, %1, c14":"=r"(c_lo), "=r"(c_hi));
>>>
>>> Is the isb really necessary here?
>>
>> I don't think so.
>>
>>>> +    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));
>>>
>>> There's quite a few of these //printk(debug) statements in this patch...
>>>
>>>> +    return time;
>>>> +}
>>>> +
>>>> +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));
>>>
>>> I think you can use
>>>        "mcrr p15, 3, %0, %H0, c14" :: "r" (value)
>>> here.
>>>
>>>
>>>> +
>>>> +    __asm__ __volatile__("mov %0, #0x1\n"
>>>> +            "mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */
>>>> +            "isb":"=r"(x));
>>>
>>> x = 1 before this would avoid the mov inside the inline stuff as well as
>>> the strange looking use of an output register for a write.
>>>
>>>> +}
>>>> +
>>>> +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));
>>>
>>> and again. You probably just want a write_timer_ctl(uiint.. val) type
>>> function.
>>>
>>>> +}
>>>> +
>>>> +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);
>>>
>>> More left over debug.
>
> I had a play with this yesterday on my cubieboard with Mirage. Using network and vchan connections worked fine, so event channels are working ok. However when I had no external event channel input and my domain blocked on a timer, it seemed to block forever in the ‘wfi’ (as I could see by enabling these debug lines and then pressing ‘enter’ to trigger an interrupt on the console). As far as I can tell the monotonic clock is giving me sensible values, and the ‘until’ value looked sensible. For now I can work around the problem by attaching a vif to a busy network :-)
>
> Sorry for the vagueness of the bug report. I’ll try to make a more minimal repro example when I get the time.
>
> Dave

After discussing this with Dave, it looks like this was a problem in a
previous version of my patches*, which didn't enable the timer
interrupt. This series (v7) does enable the timer and should work
correctly.

* https://github.com/talex5/xen/releases/tag/minios-v0.3


-- 
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
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH ARM v7 09/13] mini-os: arm: time
  2014-09-22 10:35       ` Dave Scott
  2014-09-23 16:53         ` Stefano Stabellini
  2014-09-26 10:01         ` Thomas Leonard
@ 2014-10-01 11:10         ` Thomas Leonard
  2014-10-01 11:10         ` Thomas Leonard
  3 siblings, 0 replies; 31+ messages in thread
From: Thomas Leonard @ 2014-10-01 11:10 UTC (permalink / raw)
  To: Dave Scott
  Cc: xen-devel, Stefano Stabellini, Ian Campbell, Samuel Thibault,
	Anil Madhavapeddy

On 22 September 2014 11:35, Dave Scott <Dave.Scott@citrix.com> wrote:
> Hi,
>
> On 8 Sep 2014, at 17:08, Thomas Leonard <talex5@gmail.com> wrote:
>
>> On 8 September 2014 11:59, Ian Campbell <Ian.Campbell@citrix.com> wrote:
>>> On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
>>>
>>> Sorry for how long I took to get to this, travel and the resulting
>>> backlog conspired against me.
[...]
>>>> +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);
>>>
>>> More left over debug.
[...]
> I had a play with this yesterday on my cubieboard with Mirage. Using network and vchan connections worked fine, so event channels are working ok. However when I had no external event channel input and my domain blocked on a timer, it seemed to block forever in the ‘wfi’ (as I could see by enabling these debug lines and then pressing ‘enter’ to trigger an interrupt on the console).

[...]

Given that at least one person has already made use of these debug
lines, perhaps I should leave them in?


-- 
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
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH ARM v7 09/13] mini-os: arm: time
  2014-09-22 10:35       ` Dave Scott
                           ` (2 preceding siblings ...)
  2014-10-01 11:10         ` Thomas Leonard
@ 2014-10-01 11:10         ` Thomas Leonard
  2014-10-01 11:31           ` Ian Campbell
  3 siblings, 1 reply; 31+ messages in thread
From: Thomas Leonard @ 2014-10-01 11:10 UTC (permalink / raw)
  To: Dave Scott
  Cc: xen-devel, Stefano Stabellini, Ian Campbell, Samuel Thibault,
	Anil Madhavapeddy

On 22 September 2014 11:35, Dave Scott <Dave.Scott@citrix.com> wrote:
> Hi,
>
> On 8 Sep 2014, at 17:08, Thomas Leonard <talex5@gmail.com> wrote:
>
>> On 8 September 2014 11:59, Ian Campbell <Ian.Campbell@citrix.com> wrote:
>>> On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
>>>
>>> Sorry for how long I took to get to this, travel and the resulting
>>> backlog conspired against me.
[...]
>>>> +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);
>>>
>>> More left over debug.
[...]
> I had a play with this yesterday on my cubieboard with Mirage. Using network and vchan connections worked fine, so event channels are working ok. However when I had no external event channel input and my domain blocked on a timer, it seemed to block forever in the ‘wfi’ (as I could see by enabling these debug lines and then pressing ‘enter’ to trigger an interrupt on the console).

[...]

Given that at least one person has already made use of these debug
lines, perhaps I should leave them in?


-- 
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
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

* Re: [PATCH ARM v7 09/13] mini-os: arm: time
  2014-10-01 11:10         ` Thomas Leonard
@ 2014-10-01 11:31           ` Ian Campbell
  0 siblings, 0 replies; 31+ messages in thread
From: Ian Campbell @ 2014-10-01 11:31 UTC (permalink / raw)
  To: Thomas Leonard
  Cc: xen-devel, Dave Scott, Stefano Stabellini, Samuel Thibault,
	Anil Madhavapeddy

On Wed, 2014-10-01 at 12:10 +0100, Thomas Leonard wrote:
> On 22 September 2014 11:35, Dave Scott <Dave.Scott@citrix.com> wrote:
> > Hi,
> >
> > On 8 Sep 2014, at 17:08, Thomas Leonard <talex5@gmail.com> wrote:
> >
> >> On 8 September 2014 11:59, Ian Campbell <Ian.Campbell@citrix.com> wrote:
> >>> On Fri, 2014-08-08 at 16:47 +0100, Thomas Leonard wrote:
> >>>
> >>> Sorry for how long I took to get to this, travel and the resulting
> >>> backlog conspired against me.
> [...]
> >>>> +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);
> >>>
> >>> More left over debug.
> [...]
> > I had a play with this yesterday on my cubieboard with Mirage. Using network and vchan connections worked fine, so event channels are working ok. However when I had no external event channel input and my domain blocked on a timer, it seemed to block forever in the ‘wfi’ (as I could see by enabling these debug lines and then pressing ‘enter’ to trigger an interrupt on the console).
> 
> [...]
> 
> Given that at least one person has already made use of these debug
> lines, perhaps I should leave them in?

If they are to stay they need to be done with a proper ifdef controlled
debug option (perhaps a DPRINT macro, not inline #ifdefs), commented out
as you have it isn't ok.

Ian.


_______________________________________________
Xen-devel mailing list
Xen-devel@lists.xen.org
http://lists.xen.org/xen-devel

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

end of thread, other threads:[~2014-10-01 11:31 UTC | newest]

Thread overview: 31+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2014-08-08 15:47 [PATCH ARM v7 00/13] mini-os: initial ARM support Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 01/13] mini-os: don't include lib.h from mm.h Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 02/13] mini-os: added HYPERVISOR_xsm_op Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 03/13] mini-os: move poor rand function to test.c Thomas Leonard
2014-08-08 16:37   ` Samuel Thibault
2014-08-11  7:59     ` Thomas Leonard
2014-08-11  9:29       ` Samuel Thibault
2014-08-28 15:07         ` Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 04/13] mini-os: arm: add header files Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 05/13] mini-os: arm: boot code Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 06/13] mini-os: arm: memory management Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 07/13] mini-os: arm: scheduling Thomas Leonard
2014-08-08 15:47 ` [PATCH ARM v7 08/13] mini-os: arm: events Thomas Leonard
2014-09-08 11:52   ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 09/13] mini-os: arm: time Thomas Leonard
2014-09-08 10:59   ` Ian Campbell
2014-09-08 16:08     ` Thomas Leonard
2014-09-22 10:35       ` Dave Scott
2014-09-23 16:53         ` Stefano Stabellini
2014-09-26 10:01         ` Thomas Leonard
2014-10-01 11:10         ` Thomas Leonard
2014-10-01 11:10         ` Thomas Leonard
2014-10-01 11:31           ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 10/13] mini-os: arm: interrupt controller Thomas Leonard
2014-09-08 11:01   ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 11/13] mini-os: arm: build system Thomas Leonard
2014-09-08 11:05   ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 12/13] mini-os: arm: show registers, stack and exception vector on fault Thomas Leonard
2014-09-08 11:06   ` Ian Campbell
2014-08-08 15:47 ` [PATCH ARM v7 13/13] mini-os: fixed compiling with debug=n Thomas Leonard
2014-09-08 11:08   ` Ian Campbell

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.