Skip to contentSkip to conversation

mini-os: initial ARM support

PATCH Superseded Thomas Leonard 4 participants 41 messages Jun 18, 2014 – Jul 2, 2014

v4 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v4 cover mini-os: initial ARM support

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

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

- the series is rebased onto the patches that Ian already applied
- removing the "link" make target broke stubdom, so I brought that back
- the x86 stack address printk is back, and I moved all the other x86 printks to after the "WARN: don't do printk before here" line
- the TODOs in arm/os.h have been implemented (mainly using GCC intrinsics)
- added clrex to the IRQ handler return in case these get interrupted
- added an explicit -march=armv7-a to cope with other compiler defaults
- the zImage header now works with the XSA-95 fix to "xl create"
- added fixes for unbinding ports (also useful on x86)
- configued ARM not to fault on unaligned word accessess (useful for lwIP)
- fixed the off_t type to match POSIX (maybe Mini-OS shouldn't be defining it in the first place, but since it is, it should do it correctly).
- there are also some new patches adding support for using the FDT to initialise the MM, GIC and grant tables.

This patch roll is also available here:

https://github.com/talex5/xen/commits/sent-Jun-18

Please include Karim in any reply as I am not the author of much of this code.

Karim Raslan (3):
mini-os: switched initial C entry point to arch_init
mini-os: initial ARM support
mini-os: import libfdt

Thomas Leonard (9):
mini-os: build fixes
mini-os: fixed shutdown thread
mini-os: fixed format string error in unbind_evtchn
mini-os: use unbind_evtchn in unbind_all_ports
mini-os: made off_t type signed
mini-os: arm: show registers, stack and exception vector on fault
mini-os: get RAM base and size from the FDT
mini-os: get GIC addresses from FDT
mini-os: added ARM grant table initialisation

 extras/mini-os/ARM-TODO.txt                      |   10 +
 extras/mini-os/COPYING                           |   27 +
 extras/mini-os/Config.mk                         |    2 +
 extras/mini-os/Makefile                          |   48 +-
 extras/mini-os/arch/arm/Makefile                 |   32 +
 extras/mini-os/arch/arm/arch.mk                  |    7 +
 extras/mini-os/arch/arm/arm32.S                  |  222 ++++
 extras/mini-os/arch/arm/events.c                 |   30 +
 extras/mini-os/arch/arm/hypercalls32.S           |   88 ++
 extras/mini-os/arch/arm/minios-arm32.lds         |   75 ++
 extras/mini-os/arch/arm/mm.c                     |  162 +++
 extras/mini-os/arch/arm/panic.c                  |   99 ++
 extras/mini-os/arch/arm/sched.c                  |   37 +
 extras/mini-os/arch/arm/setup.c                  |  112 ++
 extras/mini-os/arch/arm/time.c                   |  202 +++
 extras/mini-os/arch/x86/events.c                 |    4 +
 extras/mini-os/arch/x86/mm.c                     |   13 +
 extras/mini-os/arch/x86/setup.c                  |   44 +-
 extras/mini-os/arch/x86/x86_32.S                 |    2 +-
 extras/mini-os/arch/x86/x86_64.S                 |    2 +-
 extras/mini-os/drivers/gic.c                     |  217 ++++
 extras/mini-os/events.c                          |   39 +-
 extras/mini-os/gnttab.c                          |   11 +-
 extras/mini-os/hypervisor.c                      |   12 +-
 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             |   37 +
 extras/mini-os/include/arm/arch_sched.h          |   22 +
 extras/mini-os/include/arm/arch_spinlock.h       |   49 +
 extras/mini-os/include/arm/arm32/arch_wordsize.h |    1 +
 extras/mini-os/include/arm/hypercall-arm32.h     |  173 +++
 extras/mini-os/include/arm/os.h                  |  232 ++++
 extras/mini-os/include/arm/traps.h               |   20 +
 extras/mini-os/include/events.h                  |    4 +
 extras/mini-os/include/fdt.h                     |   60 +
 extras/mini-os/include/gic.h                     |    1 +
 extras/mini-os/include/gnttab.h                  |    1 +
 extras/mini-os/include/hypervisor.h              |    4 +
 extras/mini-os/include/kernel.h                  |    6 +-
 extras/mini-os/include/lib.h                     |    4 +-
 extras/mini-os/include/libfdt.h                  | 1478 ++++++++++++++++++++++
 extras/mini-os/include/libfdt_env.h              |   37 +
 extras/mini-os/include/mm.h                      |    2 +
 extras/mini-os/include/types.h                   |   14 +-
 extras/mini-os/include/x86/os.h                  |    2 -
 extras/mini-os/kernel.c                          |   55 +-
 extras/mini-os/lib/fdt/fdt.c                     |  222 ++++
 extras/mini-os/lib/fdt/fdt_empty_tree.c          |   84 ++
 extras/mini-os/lib/fdt/fdt_ro.c                  |  574 +++++++++
 extras/mini-os/lib/fdt/fdt_rw.c                  |  492 +++++++
 extras/mini-os/lib/fdt/fdt_strerror.c            |   96 ++
 extras/mini-os/lib/fdt/fdt_sw.c                  |  256 ++++
 extras/mini-os/lib/fdt/fdt_wip.c                 |  118 ++
 extras/mini-os/lib/fdt/libfdt_internal.h         |   95 ++
 extras/mini-os/lib/memmove.c                     |   45 +
 extras/mini-os/lib/string.c                      |   12 +
 extras/mini-os/main.c                            |    2 +-
 extras/mini-os/mm.c                              |    4 +-
 extras/mini-os/sched.c                           |   29 +-
 59 files changed, 5632 insertions(+), 112 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/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/drivers/gic.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/hypercall-arm32.h
 create mode 100644 extras/mini-os/include/arm/os.h
 create mode 100644 extras/mini-os/include/arm/traps.h
 create mode 100644 extras/mini-os/include/fdt.h
 create mode 100644 extras/mini-os/include/gic.h
 create mode 100644 extras/mini-os/include/libfdt.h
 create mode 100644 extras/mini-os/include/libfdt_env.h
 create mode 100644 extras/mini-os/lib/fdt/fdt.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_empty_tree.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_ro.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_rw.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_strerror.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_sw.c
 create mode 100644 extras/mini-os/lib/fdt/fdt_wip.c
 create mode 100644 extras/mini-os/lib/fdt/libfdt_internal.h
 create mode 100644 extras/mini-os/lib/memmove.c
Signature · 1 line
2.0.0
#1 lore raw

PATCH v4 1/12 mini-os: build fixes

Make .o rules depend on the includes. Before, only the final link step depended on setting up the includes directory, making parallel builds unreliable.

Make symlinks use explicit make rules instead of using a phony target. Avoids unnecessary rebuilds.

[[email protected]: bring back "make links", for stubdom]
---
 extras/mini-os/Makefile | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
extras/mini-os/Makefile +17 -6
index 50d038b..6d6537e 100644
@@ -50,6 +50,11 @@ 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
+
+EXTRA_DEPS += $(GENERATED_HEADERS)
+
 # Include common mini-os makerules.
 include minios.mk
 
@@ -124,11 +129,18 @@ include/list.h: $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue-h-seddery $
 	perl $^ --prefix=minios  >[email protected]
 	$(call move-if-changed,[email protected],$@)
 
+# Used by stubdom's Makefile
 .PHONY: links
-links: include/list.h $(ARCH_LINKS)
-	[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
-	[ -e include/mini-os ] || ln -sf . include/mini-os
-	[ -e include/$(TARGET_ARCH_FAM)/mini-os ] || ln -sf . include/$(TARGET_ARCH_FAM)/mini-os
+links: $(GENERATED_HEADERS)
+
+include/xen:
+	ln -sf ../../../xen/include/public $@
+
+include/mini-os:
+	ln -sf . $@
+
+include/$(TARGET_ARCH_FAM)/mini-os:
+	ln -sf . $@
 
 .PHONY: arch_lib
 arch_lib:
@@ -174,7 +186,7 @@ ifneq ($(APP_OBJS),)
 APP_O=$(OBJ_DIR)/$(TARGET)_app.o 
 endif
 
-$(OBJ_DIR)/$(TARGET): links include/list.h $(OBJS) $(APP_O) arch_lib
+$(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib
 	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected]
 	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected]
 	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@
@@ -212,4 +224,3 @@ tags:
 .PHONY: TAGS
 TAGS:
 	$(all_sources) | xargs etags
-
Signature · 1 line
2.0.0
Acked-by on v4 1/12
#2 lore raw

Re: [PATCH ARM v4 01/12] mini-os: build fixes

Quoted 9 lines · Thomas Leonard

Make .o rules depend on the includes. Before, only the final link step depended on setting up the includes directory, making parallel builds unreliable.

Make symlinks use explicit make rules instead of using a phony target. Avoids unnecessary rebuilds.

[[email protected]: bring back "make links", for stubdom]
Quoted 57 lines
---
 extras/mini-os/Makefile | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
extras/mini-os/Makefile +17 -6
index 50d038b..6d6537e 100644
@@ -50,6 +50,11 @@ 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
+
+EXTRA_DEPS += $(GENERATED_HEADERS)
+
 # Include common mini-os makerules.
 include minios.mk
 
@@ -124,11 +129,18 @@ include/list.h: $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue-h-seddery $
 	perl $^ --prefix=minios  >[email protected]
 	$(call move-if-changed,[email protected],$@)
 
+# Used by stubdom's Makefile
 .PHONY: links
-links: include/list.h $(ARCH_LINKS)
-	[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
-	[ -e include/mini-os ] || ln -sf . include/mini-os
-	[ -e include/$(TARGET_ARCH_FAM)/mini-os ] || ln -sf . include/$(TARGET_ARCH_FAM)/mini-os
+links: $(GENERATED_HEADERS)
+
+include/xen:
+	ln -sf ../../../xen/include/public $@
+
+include/mini-os:
+	ln -sf . $@
+
+include/$(TARGET_ARCH_FAM)/mini-os:
+	ln -sf . $@
 
 .PHONY: arch_lib
 arch_lib:
@@ -174,7 +186,7 @@ ifneq ($(APP_OBJS),)
 APP_O=$(OBJ_DIR)/$(TARGET)_app.o 
 endif
 
-$(OBJ_DIR)/$(TARGET): links include/list.h $(OBJS) $(APP_O) arch_lib
+$(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib
 	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected]
 	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected]
 	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@
@@ -212,4 +224,3 @@ tags:
 .PHONY: TAGS
 TAGS:
 	$(all_sources) | xargs etags
-
Acked-by on v4 1/12
#3 lore raw

Re: [PATCH ARM v4 01/12] mini-os: build fixes

In reply to Thomas Leonard
Quoted 9 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:15 +0100, a écrit :

Make .o rules depend on the includes. Before, only the final link step depended on setting up the includes directory, making parallel builds unreliable.

Make symlinks use explicit make rules instead of using a phony target. Avoids unnecessary rebuilds.

[[email protected]: bring back "make links", for stubdom]
Quoted 60 lines
---
 extras/mini-os/Makefile | 23 +++++++++++++++++------
 1 file changed, 17 insertions(+), 6 deletions(-)
extras/mini-os/Makefile +17 -6
index 50d038b..6d6537e 100644
@@ -50,6 +50,11 @@ 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
+
+EXTRA_DEPS += $(GENERATED_HEADERS)
+
 # Include common mini-os makerules.
 include minios.mk
 
@@ -124,11 +129,18 @@ include/list.h: $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue-h-seddery $
 	perl $^ --prefix=minios  >[email protected]
 	$(call move-if-changed,[email protected],$@)
 
+# Used by stubdom's Makefile
 .PHONY: links
-links: include/list.h $(ARCH_LINKS)
-	[ -e include/xen ] || ln -sf ../../../xen/include/public include/xen
-	[ -e include/mini-os ] || ln -sf . include/mini-os
-	[ -e include/$(TARGET_ARCH_FAM)/mini-os ] || ln -sf . include/$(TARGET_ARCH_FAM)/mini-os
+links: $(GENERATED_HEADERS)
+
+include/xen:
+	ln -sf ../../../xen/include/public $@
+
+include/mini-os:
+	ln -sf . $@
+
+include/$(TARGET_ARCH_FAM)/mini-os:
+	ln -sf . $@
 
 .PHONY: arch_lib
 arch_lib:
@@ -174,7 +186,7 @@ ifneq ($(APP_OBJS),)
 APP_O=$(OBJ_DIR)/$(TARGET)_app.o 
 endif
 
-$(OBJ_DIR)/$(TARGET): links include/list.h $(OBJS) $(APP_O) arch_lib
+$(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib
 	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected]
 	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected]
 	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@
@@ -212,4 +224,3 @@ tags:
 .PHONY: TAGS
 TAGS:
 	$(all_sources) | xargs etags
-
Signature · 1 line
2.0.0
Signature · 4 lines
Samuel
I develop for Linux for a living, I used to develop for DOS.
Going from DOS to Linux is like trading a glider for an F117.
(By [email protected], Lawrence Foard)
#4 lore raw

PATCH v4 2/12 mini-os: fixed shutdown thread

In reply to Thomas Leonard

Before, it read "" and started a shutdown immediately. Now, it waits for a non-empty value and then actually shuts down.

[[email protected]: avoid declaration-after-statement in kernel.c]
---
 extras/mini-os/kernel.c | 10 +++++++---
 extras/mini-os/main.c   |  2 +-
 2 files changed, 8 insertions(+), 4 deletions(-)
extras/mini-os/kernel.c +7 -3
index ea409f4..c7410db 100644
@@ -68,7 +68,9 @@ void setup_xen_features(void)
 /* This should be overridden by the application we are linked against. */
 __attribute__((weak)) void app_shutdown(unsigned reason)
 {
+    struct sched_shutdown sched_shutdown = { .reason = reason };
     printk("Shutdown requested: %d\n", reason);
+    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);
 }
 
 static void shutdown_thread(void *p)
@@ -76,12 +78,14 @@ static void shutdown_thread(void *p)
     const char *path = "control/shutdown";
     const char *token = path;
     xenbus_event_queue events = NULL;
-    char *shutdown, *err;
+    char *shutdown = NULL, *err;
     unsigned int shutdown_reason;
     xenbus_watch_path_token(XBT_NIL, path, token, &events);
-    while ((err = xenbus_read(XBT_NIL, path, &shutdown)) != NULL)
+    while ((err = xenbus_read(XBT_NIL, path, &shutdown)) != NULL || !strcmp(shutdown, ""))
     {
         free(err);
+        free(shutdown);
+        shutdown = NULL;
         xenbus_wait_for_watch(&events);
     }
     err = xenbus_unwatch_path_token(XBT_NIL, path, token);
@@ -106,7 +110,7 @@ static void shutdown_thread(void *p)
 /* This should be overridden by the application we are linked against. */
 __attribute__((weak)) int app_main(start_info_t *si)
 {
-    printk("Dummy main: start_info=%p\n", si);
+    printk("kernel.c: dummy main: start_info=%p\n", si);
     return 0;
 }
 
extras/mini-os/main.c +1 -1
index 73eb6fb..aec0586 100644
@@ -185,7 +185,7 @@ void _exit(int ret)
 
 int app_main(start_info_t *si)
 {
-    printk("Dummy main: start_info=%p\n", si);
+    printk("main.c: dummy main: start_info=%p\n", si);
     main_thread = create_thread("main", call_main, si);
     return 0;
 }
Signature · 1 line
2.0.0
#5 lore raw

PATCH v4 3/12 mini-os: fixed format string error in unbind_evtchn

In reply to Thomas Leonard

Would crash if HYPERVISOR_event_channel_op returned an error code. The other changes in this commit are just fixing indentation.

---
 extras/mini-os/events.c | 25 ++++++++++++-------------
 1 file changed, 12 insertions(+), 13 deletions(-)
extras/mini-os/events.c +12 -13
index d60630b..f708cb4 100644
@@ -109,24 +109,23 @@ evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,
 
 void unbind_evtchn(evtchn_port_t port )
 {
-	struct evtchn_close close;
+    struct evtchn_close close;
     int rc;
 
-	if ( ev_actions[port].handler == default_handler )
-		printk("WARN: No handler for port %d when unbinding\n", port);
-	mask_evtchn(port);
-	clear_evtchn(port);
+    if ( ev_actions[port].handler == default_handler )
+        printk("WARN: No handler for port %d when unbinding\n", port);
+    mask_evtchn(port);
+    clear_evtchn(port);
 
-	ev_actions[port].handler = default_handler;
-	wmb();
-	ev_actions[port].data = NULL;
-	clear_bit(port, bound_ports);
+    ev_actions[port].handler = default_handler;
+    wmb();
+    ev_actions[port].data = NULL;
+    clear_bit(port, bound_ports);
 
-	close.port = port;
-	rc = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
+    close.port = port;
+    rc = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
     if ( rc )
-        printk("WARN: close_port %s failed rc=%d. ignored\n", port, rc);
-        
+        printk("WARN: close_port %d failed rc=%d. ignored\n", port, rc);
 }
 
 evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
Signature · 1 line
2.0.0
Acked-by on v4 3/12
#6 lore raw

Re: [PATCH ARM v4 03/12] mini-os: fixed format string error in unbind_evtchn

Quoted 2 lines · Thomas Leonard

Would crash if HYPERVISOR_event_channel_op returned an error code. The other changes in this commit are just fixing indentation.

A little bit of this sort of mixing is tolerable, but a 4 bit change with two dozen lines of reindenting around it might be considered by some to be going to far ;-)

Quoted 1 line

(this time)

Ian.

#8 lore raw

PATCH v4 4/12 mini-os: use unbind_evtchn in unbind_all_ports

In reply to Thomas Leonard

This marks the channel as closed, in case someone tries to use it again.

---
 extras/mini-os/events.c | 9 +--------
 1 file changed, 1 insertion(+), 8 deletions(-)
extras/mini-os/events.c +1 -8
index f708cb4..3c92d82 100644
@@ -43,7 +43,6 @@ void unbind_all_ports(void)
     int cpu = 0;
     shared_info_t *s = HYPERVISOR_shared_info;
     vcpu_info_t   *vcpu_info = &s->vcpu_info[cpu];
-    int rc;
 
     for ( i = 0; i < NR_EVS; i++ )
     {
@@ -53,14 +52,8 @@ void unbind_all_ports(void)
 
         if ( test_and_clear_bit(i, bound_ports) )
         {
-            struct evtchn_close close;
             printk("port %d still bound!\n", i);
-            mask_evtchn(i);
-            close.port = i;
-            rc = HYPERVISOR_event_channel_op(EVTCHNOP_close, &close);
-            if ( rc )
-                printk("WARN: close_port %s failed rc=%d. ignored\n", i, rc);
-            clear_evtchn(i);
+	    unbind_evtchn(i);
         }
     }
     vcpu_info->evtchn_upcall_pending = 0;
Signature · 1 line
2.0.0
#11 lore raw

PATCH v4 5/12 mini-os: made off_t type signed

In reply to Thomas Leonard

POSIX requires this.

---
 extras/mini-os/include/types.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
extras/mini-os/include/types.h +1 -1
index 6640ede..de356e8 100644
@@ -73,7 +73,7 @@ typedef unsigned long uint64_t;
 #endif
 typedef uint64_t uintmax_t;
 typedef  int64_t intmax_t;
-typedef uint64_t off_t;
+typedef  int64_t off_t;
 #endif
 
 typedef intptr_t            ptrdiff_t;
Signature · 1 line
2.0.0
#14 lore raw

PATCH v4 6/12 mini-os: switched initial C entry point to arch_init

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

[[email protected]: separated from big ARM commit]
[[email protected]: restored comment, moved prototypes to headers]
[[email protected]: restored stack address printk on x86]
[[email protected]: moved first printk's after start_info setup on x86]
---
 extras/mini-os/arch/x86/setup.c  | 44 ++++++++++++++++++++++++++++++++--------
 extras/mini-os/arch/x86/x86_32.S |  2 +-
 extras/mini-os/arch/x86/x86_64.S |  2 +-
 extras/mini-os/include/kernel.h  |  6 ++++--
 extras/mini-os/include/x86/os.h  |  2 --
 extras/mini-os/kernel.c          | 37 ++++-----------------------------
 6 files changed, 46 insertions(+), 47 deletions(-)
extras/mini-os/arch/x86/setup.c +36 -8
index 54046d3..5e87dd1 100644
@@ -28,6 +28,8 @@
 
 #include <mini-os/os.h>
 #include <mini-os/lib.h> /* for printk, memcpy */
+#include <mini-os/kernel.h>
+#include <xen/xen.h>
 
 /*
  * Shared page for communicating with the hypervisor.
@@ -87,20 +89,45 @@ static inline void sse_init(void) {
 #define sse_init()
 #endif
 
+
+/*
+ * INITIAL C ENTRY POINT.
+ */
 void
 arch_init(start_info_t *si)
 {
+	static char hello[] = "Bootstrapping...\n";
+
+	(void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
+
+	trap_init();
+
 	/*Initialize floating point unit */
-        fpu_init();
+	fpu_init();
 
-        /* Initialize SSE */
-        sse_init();
+	/* Initialize SSE */
+	sse_init();
 
 	/* Copy the start_info struct to a globally-accessible area. */
 	/* WARN: don't do printk before here, it uses information from
 	   shared_info. Use xprintk instead. */
 	memcpy(&start_info, si, sizeof(*si));
 
+	/* print out some useful information  */
+	printk("Xen Minimal OS!\n");
+	printk("  start_info: %p(VA)\n", si);
+	printk("    nr_pages: 0x%lx\n", si->nr_pages);
+	printk("  shared_inf: 0x%08lx(MA)\n", si->shared_info);
+	printk("     pt_base: %p(VA)\n", (void *)si->pt_base);
+	printk("nr_pt_frames: 0x%lx\n", si->nr_pt_frames);
+	printk("    mfn_list: %p(VA)\n", (void *)si->mfn_list);
+	printk("   mod_start: 0x%lx(VA)\n", si->mod_start);
+	printk("     mod_len: %lu\n", si->mod_len);
+	printk("       flags: 0x%x\n", (unsigned int)si->flags);
+	printk("    cmd_line: %s\n",
+			si->cmd_line ? (const char *)si->cmd_line : "NULL");
+	printk("       stack: %p-%p\n", stack, stack + sizeof(stack));
+
 	/* set up minimal memory infos */
 	phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
 
@@ -118,12 +145,15 @@ arch_init(start_info_t *si)
 		(unsigned long)failsafe_callback, 0);
 #endif
 
-
+	start_kernel();
 }
 
 void
 arch_fini(void)
 {
+	/* Reset traps */
+	trap_fini();
+
 #ifdef __i386__
 	HYPERVISOR_set_callbacks(0, 0, 0, 0);
 #else
@@ -132,9 +162,7 @@ arch_fini(void)
 }
 
 void
-arch_print_info(void)
+arch_do_exit(void)
 {
-	printk("  stack:      %p-%p\n", stack, stack + sizeof(stack));
+	stack_walk();
 }
-
-
extras/mini-os/arch/x86/x86_32.S +1 -1
index fb3e30a..b9aa392 100644
@@ -20,7 +20,7 @@ _start:
         lss stack_start,%esp
         andl $(~(__STACK_SIZE-1)), %esp
         push %esi 
-        call start_kernel
+        call arch_init
 
 stack_start:
 	.long stack+(2*__STACK_SIZE), __KERNEL_SS
extras/mini-os/arch/x86/x86_64.S +1 -1
index f022eb3..df3469e 100644
@@ -21,7 +21,7 @@ _start:
         movq stack_start(%rip),%rsp
         andq $(~(__STACK_SIZE-1)), %rsp
         movq %rsi,%rdi
-        call start_kernel
+        call arch_init
 
 stack_start:
         .quad stack+(2*__STACK_SIZE)
extras/mini-os/include/kernel.h +4 -2
index b36f172..13e3274 100644
@@ -1,7 +1,9 @@
 #ifndef _KERNEL_H_
 #define _KERNEL_H_
 
-extern void do_exit(void) __attribute__((noreturn));
-extern void stop_kernel(void);
+void start_kernel(void);
+void do_exit(void) __attribute__((noreturn));
+void arch_do_exit(void);
+void stop_kernel(void);
 
 #endif /* _KERNEL_H_ */
extras/mini-os/include/x86/os.h +0 -2
index f193865..73b8297 100644
@@ -64,8 +64,6 @@ extern shared_info_t *HYPERVISOR_shared_info;
 void trap_init(void);
 void trap_fini(void);
 
-void arch_init(start_info_t *si);
-void arch_print_info(void);
 void arch_fini(void);
 
 
extras/mini-os/kernel.c +4 -33
index c7410db..9a30550 100644
@@ -28,6 +28,7 @@
  */
 
 #include <mini-os/os.h>
+#include <mini-os/kernel.h>
 #include <mini-os/hypervisor.h>
 #include <mini-os/mm.h>
 #include <mini-os/events.h>
@@ -114,41 +115,14 @@ __attribute__((weak)) int app_main(start_info_t *si)
     return 0;
 }
 
-/*
- * INITIAL C ENTRY POINT.
- */
-void start_kernel(start_info_t *si)
+void start_kernel(void)
 {
-    static char hello[] = "Bootstrapping...\n";
-
-    (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(hello), hello);
-
-    arch_init(si);
-
-    trap_init();
-
-    /* print out some useful information  */
-    printk("Xen Minimal OS!\n");
-    printk("  start_info: %p(VA)\n", si);
-    printk("    nr_pages: 0x%lx\n", si->nr_pages);
-    printk("  shared_inf: 0x%08lx(MA)\n", si->shared_info);
-    printk("     pt_base: %p(VA)\n", (void *)si->pt_base); 
-    printk("nr_pt_frames: 0x%lx\n", si->nr_pt_frames);
-    printk("    mfn_list: %p(VA)\n", (void *)si->mfn_list); 
-    printk("   mod_start: 0x%lx(VA)\n", si->mod_start);
-    printk("     mod_len: %lu\n", si->mod_len); 
-    printk("       flags: 0x%x\n", (unsigned int)si->flags);
-    printk("    cmd_line: %s\n",  
-           si->cmd_line ? (const char *)si->cmd_line : "NULL");
-
     /* Set up events. */
     init_events();
-    
+
     /* ENABLE EVENT DELIVERY. This is disabled at start of day. */
     __sti();
 
-    arch_print_info();
-
     setup_xen_features();
 
     /* Init memory management. */
@@ -201,9 +175,6 @@ void stop_kernel(void)
     /* Reset events. */
     fini_events();
 
-    /* Reset traps */
-    trap_fini();
-
     /* Reset arch details */
     arch_fini();
 }
@@ -218,7 +189,7 @@ void stop_kernel(void)
 void do_exit(void)
 {
     printk("Do_exit called!\n");
-    stack_walk();
+    arch_do_exit();
     for( ;; )
     {
         struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
Signature · 1 line
2.0.0
#15 lore raw

PATCH v4 7/12 mini-os: initial ARM support

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

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
[[email protected]: made x86_64 support work again]
[[email protected]: split into multiple patches]
[[email protected]: re-enabled force_evtchn_callback]
[[email protected]: enable regular console]

[[email protected]: fixed initialisation code:
- Configure write-back caching in page table. This is needed for reliable hypercalls to Xen (thanks to Julien Grall).
- Use "client mode" for access control (domains are deprecated, according to ARM Cortex-A Series Programmer’s Guide version 4.0, section 9.6.4).
- Enable more SCTLR features (icache, branch prediction)]

[[email protected]: use Virtual Count register for monotonic time]
[[email protected]: fixed HYPERVISOR_shutdown]
[[email protected]: get xenstore details from hypervisor]
[[email protected]: use GCC implementation of division]
[[email protected]: include hypervisor.h from os.h, as on x86]
[[email protected]: cleaned up interrupt handlers and threading]
[[email protected]: call exit_thread when a thread returns]
[[email protected]: implemented block_domain for ARM]
[[email protected]: fixed hang when enabling interrupts]
[[email protected]: added -march=armv7-a to flags]
[[email protected]: implemented bitops for ARM]
[[email protected]: CLREX after handling IRQs]
[[email protected]: unbind debug port at shutdown]
[[email protected]: allow unaligned accesses]
[[email protected]: added arch_endian.h for ARM]
[[email protected]: fix zImage header for XSA-95]
---
 extras/mini-os/ARM-TODO.txt                      |  12 ++
 extras/mini-os/Config.mk                         |   2 +
 extras/mini-os/Makefile                          |  14 ++
 extras/mini-os/arch/arm/Makefile                 |  32 ++++
 extras/mini-os/arch/arm/arch.mk                  |   7 +
 extras/mini-os/arch/arm/arm32.S                  | 155 +++++++++++++++
 extras/mini-os/arch/arm/events.c                 |  30 +++
 extras/mini-os/arch/arm/hypercalls32.S           |  88 +++++++++
 extras/mini-os/arch/arm/minios-arm32.lds         |  75 ++++++++
 extras/mini-os/arch/arm/mm.c                     |  44 +++++
 extras/mini-os/arch/arm/sched.c                  |  37 ++++
 extras/mini-os/arch/arm/setup.c                  | 102 ++++++++++
 extras/mini-os/arch/arm/time.c                   | 202 ++++++++++++++++++++
 extras/mini-os/arch/x86/events.c                 |   4 +
 extras/mini-os/drivers/gic.c                     | 187 ++++++++++++++++++
 extras/mini-os/events.c                          |   5 +-
 extras/mini-os/hypervisor.c                      |  12 +-
 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             |  37 ++++
 extras/mini-os/include/arm/arch_sched.h          |  22 +++
 extras/mini-os/include/arm/arch_spinlock.h       |  49 +++++
 extras/mini-os/include/arm/arm32/arch_wordsize.h |   1 +
 extras/mini-os/include/arm/hypercall-arm32.h     | 173 +++++++++++++++++
 extras/mini-os/include/arm/os.h                  | 230 +++++++++++++++++++++++
 extras/mini-os/include/arm/traps.h               |  20 ++
 extras/mini-os/include/events.h                  |   4 +
 extras/mini-os/include/gic.h                     |   1 +
 extras/mini-os/include/hypervisor.h              |   4 +
 extras/mini-os/include/mm.h                      |   2 +
 extras/mini-os/include/types.h                   |  12 +-
 extras/mini-os/kernel.c                          |   8 +
 extras/mini-os/sched.c                           |  29 +--
 33 files changed, 1595 insertions(+), 21 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/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/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/drivers/gic.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/hypercall-arm32.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/gic.h
extras/mini-os/ARM-TODO.txt new file +12 -0
new file mode 100644
index 0000000..3d9be10
@@ -0,0 +1,12 @@
+* support abort exception handling ( and others )
+* scheduling!
+* gic request_irq implementation, currently all IRQs all hardcoded in gic irq handler.
+* use device tree instead of the currently hardcoded values
+* Add virtual memory support and make vstart = 0 ( use 4k descriptors instead of 1M descriptors )
+* sched
+* fini_gnttab
+* bind_*
+* add multiple cpu support (?)
+* map_frames
+* make sure that wallclock is functioning properly
+* evtchn_get_peercontext
extras/mini-os/Config.mk +2 -0
index d61877b..4ecde54 100644
@@ -12,6 +12,8 @@ export XEN_INTERFACE_VERSION
 # If not x86 then use $(XEN_TARGET_ARCH)
 ifeq ($(findstring x86_,$(XEN_TARGET_ARCH)),x86_)
 TARGET_ARCH_FAM = x86
+else ifeq ($(findstring arm,$(XEN_TARGET_ARCH)),arm)
+TARGET_ARCH_FAM = arm
 else
 TARGET_ARCH_FAM = $(XEN_TARGET_ARCH)
 endif
extras/mini-os/Makefile +14 -0
index 6d6537e..535ca68 100644
@@ -77,6 +77,14 @@ TARGET := mini-os
 # Subdirectories common to mini-os
 SUBDIRS := lib xenbus console
 
+ifeq ($(XEN_TARGET_ARCH),arm32)
+# ARM drivers
+src-y += drivers/gic.c
+
+# Need libgcc.a for division helpers
+LDLIBS += `$(CC) -print-libgcc-file-name`
+endif
+
 src-$(CONFIG_BLKFRONT) += blkfront.c
 src-$(CONFIG_TPMFRONT) += tpmfront.c
 src-$(CONFIG_TPM_TIS) += tpm_tis.c
@@ -97,7 +105,9 @@ src-y += sched.c
 src-$(CONFIG_TEST) += test.c
 
 src-y += lib/ctype.c
+ifneq ($(XEN_TARGET_ARCH),arm32)
 src-y += lib/math.c
+endif
 src-y += lib/printf.c
 src-y += lib/stack_chk_fail.c
 src-y += lib/string.c
@@ -190,7 +200,11 @@ $(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib
 	$(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected]
 	$(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected]
 	$(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@
+ifeq ($(XEN_TARGET_ARCH),arm32)
+	$(OBJCOPY) -O binary $@ [email protected]
+else
 	gzip -f -9 -c $@ >[email protected]
+endif
 
 .PHONY: clean arch_clean
 
extras/mini-os/arch/arm/Makefile new file +32 -0
new file mode 100755
index 0000000..8b78651
@@ -0,0 +1,32 @@
+#
+# ARM architecture specific makefiles.
+#
+
+XEN_ROOT = $(CURDIR)/../../../..
+include $(XEN_ROOT)/Config.mk
+include ../../Config.mk
+
+# include arch.mk has to be before minios.mk!
+
+include arch.mk
+include ../../minios.mk
+
+# Sources here are all *.c (without $(XEN_TARGET_ARCH).S)
+# This is handled in $(HEAD_ARCH_OBJ)
+ARCH_SRCS := $(wildcard *.c)
+
+# The objects built from the sources.
+ARCH_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ARCH_SRCS))
+
+ARCH_OBJS += hypercalls32.o
+
+all: $(OBJ_DIR)/$(ARCH_LIB)
+
+# $(HEAD_ARCH_OBJ) is only built here, needed on linking
+# in ../../Makefile.
+$(OBJ_DIR)/$(ARCH_LIB): $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
+	$(AR) rv $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS)
+
+clean:
+	rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ)
+
extras/mini-os/arch/arm/arch.mk new file +7 -0
new file mode 100644
index 0000000..ab20d99
@@ -0,0 +1,7 @@
+ifeq ($(XEN_TARGET_ARCH),arm32)
+DEF_ASFLAGS += -march=armv7-a
+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
+
extras/mini-os/arch/arm/arm32.S new file +155 -0

155 lines not on this page · raw message

extras/mini-os/arch/arm/events.c new file +30 -0
new file mode 100644
index 0000000..517e763
@@ -0,0 +1,30 @@
+#include <mini-os/os.h>
+#include <mini-os/events.h>
+#include <mini-os/hypervisor.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)
+{
+}
extras/mini-os/arch/arm/hypercalls32.S new file +88 -0

88 lines not on this page · raw message

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

75 lines not on this page · raw message

extras/mini-os/arch/arm/mm.c new file +44 -0

44 lines not on this page · raw message

extras/mini-os/arch/arm/sched.c new file +37 -0
new file mode 100644
index 0000000..1306c1b
@@ -0,0 +1,37 @@
+#include <mini-os/sched.h>
+#include <mini-os/xmalloc.h>
+
+void arm_start_thread(void);
+
+/* Architecture specific setup of thread creation */
+struct thread* arch_create_thread(char *name, void (*function)(void *),
+                                  void *data)
+{
+    struct thread *thread;
+
+    thread = xmalloc(struct thread);
+    /* We can't use lazy allocation here since the trap handler runs on the stack */
+    thread->stack = (char *)alloc_pages(STACK_SIZE_PAGE_ORDER);
+    thread->name = name;
+    printk("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n", name, thread,
+            thread->stack);
+
+    /* Save pointer to the thread on the stack, used by current macro */
+    *((unsigned long *)thread->stack) = (unsigned long)thread;
+
+    /* Push the details to pass to arm_start_thread onto the stack */
+    int *sp = (int *) (thread->stack + STACK_SIZE);
+    *(--sp) = (int) function;
+    *(--sp) = (int) data;
+    thread->sp = (unsigned long) sp;
+
+    thread->ip = (unsigned long) arm_start_thread;
+
+    return thread;
+}
+
+void run_idle_thread(void)
+{
+    __asm__ __volatile__ ("mov sp, %0; mov pc, %1"::"r"(idle_thread->sp), "r"(idle_thread->ip));
+    /* Never arrive here! */
+}
extras/mini-os/arch/arm/setup.c new file +102 -0

102 lines not on this page · raw message

extras/mini-os/arch/arm/time.c new file +202 -0

202 lines not on this page · raw message

extras/mini-os/arch/x86/events.c +4 -0
index e420a98..5198cf3 100644
@@ -23,6 +23,10 @@ void arch_init_events(void)
 #endif
 }
 
+void arch_unbind_ports(void)
+{
+}
+
 void arch_fini_events(void)
 {
 #if defined(__x86_64__)
extras/mini-os/drivers/gic.c new file +187 -0

187 lines not on this page · raw message

extras/mini-os/events.c +4 -1
index 3c92d82..780c74a 100644
@@ -179,6 +179,7 @@ void init_events(void)
 void fini_events(void)
 {
     /* Dealloc all events */
+    arch_unbind_ports();
     unbind_all_ports();
     arch_fini_events();
 }
@@ -238,7 +239,8 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
 
 int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size)
 {
-    int rc;
+    int rc = 0;
+#ifndef __arm__			/* TODO */
     uint32_t sid;
     struct xen_flask_op op;
     op.cmd = FLASK_GET_PEER_SID;
@@ -253,6 +255,7 @@ int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size)
     op.u.sid_context.size = size;
     set_xen_guest_handle(op.u.sid_context.context, ctx);
     rc = _hypercall1(int, xsm_op, &op);
+#endif
     return rc;
 }
 
extras/mini-os/hypervisor.c +11 -1
index b4688a0..1b61d9b 100644
@@ -64,7 +64,7 @@ void do_hypervisor_callback(struct pt_regs *regs)
             l2 &= ~(1UL << l2i);
 
             port = (l1i * (sizeof(unsigned long) * 8)) + l2i;
-			do_event(port, regs);
+            do_event(port, regs);
         }
     }
 
@@ -73,18 +73,26 @@ void do_hypervisor_callback(struct pt_regs *regs)
 
 void force_evtchn_callback(void)
 {
+#ifdef XEN_HAVE_PV_UPCALL_MASK
     int save;
+#endif
     vcpu_info_t *vcpu;
     vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()];
+#ifdef XEN_HAVE_PV_UPCALL_MASK
     save = vcpu->evtchn_upcall_mask;
+#endif
 
     while (vcpu->evtchn_upcall_pending) {
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         vcpu->evtchn_upcall_mask = 1;
+#endif
         barrier();
         do_hypervisor_callback(NULL);
         barrier();
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         vcpu->evtchn_upcall_mask = save;
         barrier();
+#endif
     };
 }
 
@@ -110,7 +118,9 @@ inline void unmask_evtchn(uint32_t port)
               &vcpu_info->evtchn_pending_sel) )
     {
         vcpu_info->evtchn_upcall_pending = 1;
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         if ( !vcpu_info->evtchn_upcall_mask )
+#endif
             force_evtchn_callback();
     }
 }
extras/mini-os/include/arm/arch_endian.h new file +7 -0
new file mode 100644
index 0000000..0771683
@@ -0,0 +1,7 @@
+#ifndef	ARCH_ENDIAN_H
+#error "Do not include arch_endian by itself, include endian.h"
+#else
+
+#define __BYTE_ORDER __LITTLE_ENDIAN
+
+#endif
extras/mini-os/include/arm/arch_limits.h new file +9 -0
new file mode 100644
index 0000000..bae99e1
@@ -0,0 +1,9 @@
+#ifndef __ARCH_LIMITS_H__
+#define __ARCH_LIMITS_H__
+
+#include <mm.h>
+
+#define __STACK_SIZE_PAGE_ORDER  2
+#define __STACK_SIZE (4 * PAGE_SIZE)
+
+#endif
extras/mini-os/include/arm/arch_mm.h new file +37 -0
new file mode 100644
index 0000000..be14ada
@@ -0,0 +1,37 @@
+#ifndef _ARCH_MM_H_
+#define _ARCH_MM_H_
+
+extern char _text, _etext, _erodata, _edata, _end, __bss_start;
+extern char stack[];
+
+#define PAGE_SHIFT        12
+#define PAGE_SIZE        (1 << PAGE_SHIFT)
+#define PAGE_MASK       (~(PAGE_SIZE-1))
+
+#define L1_PAGETABLE_SHIFT      12
+
+#if 0
+#define VIRT_START                 ((unsigned long)&_text)
+#else
+#define VIRT_START                 ((unsigned long)0)
+#endif
+
+#define to_phys(x)                 ((unsigned long)(x)-VIRT_START)
+#define to_virt(x)                 ((void *)((unsigned long)(x)+VIRT_START))
+
+#define PFN_UP(x)    (((x) + PAGE_SIZE-1) >> L1_PAGETABLE_SHIFT)
+#define PFN_DOWN(x)    ((x) >> L1_PAGETABLE_SHIFT)
+#define PFN_PHYS(x)    ((uint64_t)(x) << L1_PAGETABLE_SHIFT)
+#define PHYS_PFN(x)    ((x) >> L1_PAGETABLE_SHIFT)
+
+#define virt_to_pfn(_virt)         (PFN_DOWN(to_phys(_virt)))
+#define virt_to_mfn(_virt)         (PFN_DOWN(to_phys(_virt)))
+#define mach_to_virt(_mach)        (_mach)
+#define virt_to_mach(_virt)        (_virt)
+#define mfn_to_virt(_mfn)          (to_virt(PFN_PHYS(_mfn)))
+#define pfn_to_virt(_pfn)          (to_virt(PFN_PHYS(_pfn)))
+
+// FIXME
+#define map_frames(f, n) (NULL)
+
+#endif
extras/mini-os/include/arm/arch_sched.h new file +22 -0
new file mode 100644
index 0000000..e2307ed
@@ -0,0 +1,22 @@
+
+#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;
+}
+
+
+extern void __arch_switch_threads(unsigned long *prevctx, unsigned long *nextctx);
+
+#define arch_switch_threads(prev,next) __arch_switch_threads(&(prev)->sp, &(next)->sp)
+
+
+#endif /* __ARCH_SCHED_H__ */
extras/mini-os/include/arm/arch_spinlock.h new file +49 -0

49 lines not on this page · raw message

extras/mini-os/include/arm/arm32/arch_wordsize.h new file +1 -0
new file mode 100644
index 0000000..b47eee9
@@ -0,0 +1 @@
+#define __WORDSIZE 32
extras/mini-os/include/arm/hypercall-arm32.h new file +173 -0

173 lines not on this page · raw message

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

230 lines not on this page · raw message

extras/mini-os/include/arm/traps.h new file +20 -0
new file mode 100644
index 0000000..704df22
@@ -0,0 +1,20 @@
+#ifndef _TRAPS_H_
+#define _TRAPS_H_
+
+struct pt_regs {
+    unsigned long r0;
+    unsigned long r1;
+    unsigned long r2;
+    unsigned long r3;
+    unsigned long r4;
+    unsigned long r5;
+    unsigned long r6;
+    unsigned long r7;
+    unsigned long r8;
+    unsigned long r9;
+    unsigned long r10;
+    unsigned long r11;
+    unsigned long r12;
+};
+
+#endif
extras/mini-os/include/events.h +4 -0
index 0452d21..f571b06 100644
@@ -26,6 +26,10 @@ typedef void (*evtchn_handler_t)(evtchn_port_t, struct pt_regs *, void *);
 
 /* prototypes */
 void arch_init_events(void);
+
+/* Called by fini_events. Close any arch-specific ports (e.g. debug ports) */
+void arch_unbind_ports(void);
+
 void arch_fini_events(void);
 
 int do_event(evtchn_port_t port, struct pt_regs *regs);
extras/mini-os/include/gic.h new file +1 -0
new file mode 100644
index 0000000..cead2e5
@@ -0,0 +1 @@
+void gic_init(void);
extras/mini-os/include/hypervisor.h +4 -0
index a62cb78..052f4f8 100644
@@ -18,6 +18,10 @@
 #include <hypercall-x86_32.h>
 #elif defined(__x86_64__)
 #include <hypercall-x86_64.h>
+#elif defined(__arm__)
+#include <hypercall-arm32.h>
+#elif defined(__aarch64__)
+#include <hypercall-arm64.h>
 #else
 #error "Unsupported architecture"
 #endif
extras/mini-os/include/mm.h +2 -0
index a94cd6d..644c7de 100644
@@ -29,6 +29,8 @@
 #include <xen/arch-x86_32.h>
 #elif defined(__x86_64__)
 #include <xen/arch-x86_64.h>
+#elif defined(__arm__) || defined(__aarch64__)
+#include <xen/arch-arm.h>
 #else
 #error "Unsupported architecture"
 #endif
extras/mini-os/include/types.h +6 -6
index de356e8..f79ff8c 100644
@@ -27,7 +27,7 @@ typedef unsigned char       u_char;
 typedef unsigned int        u_int;
 typedef unsigned long       u_long;
 #endif
-#ifdef __i386__
+#if defined(__i386__) || defined(__arm__)
 typedef long long           quad_t;
 typedef unsigned long long  u_quad_t;
 
@@ -40,7 +40,7 @@ typedef unsigned long       u_quad_t;
 typedef struct { unsigned long pte; } pte_t;
 #endif /* __i386__ || __x86_64__ */
 
-#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__aarch64__)
 #define __pte(x) ((pte_t) { (x) } )
 #else
 #define __pte(x) ({ unsigned long long _x = (x);        \
@@ -51,10 +51,10 @@ typedef struct { unsigned long pte; } pte_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__ */
@@ -64,10 +64,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
extras/mini-os/kernel.c +8 -0
index 9a30550..7b2b8fc 100644
@@ -47,6 +47,10 @@
 #include <xen/features.h>
 #include <xen/version.h>
 
+#ifdef __arm__
+#include <mini-os/gic.h>
+#endif
+
 uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32];
 
 void setup_xen_features(void)
@@ -147,6 +151,10 @@ void start_kernel(void)
     create_thread("shutdown", shutdown_thread, NULL);
 #endif
 
+#ifdef __arm__
+    gic_init();
+#endif
+
     /* Call (possibly overridden) app_main() */
     app_main(&start_info);
 
extras/mini-os/sched.c +16 -13
index 174945e..b99d7dc 100644
@@ -145,6 +145,9 @@ struct thread* create_thread(char *name, void (*function)(void *), void *data)
     unsigned long flags;
     /* Call architecture specific setup. */
     thread = arch_create_thread(name, function, data);
+    if(!thread)
+        BUG(); //For now, FIXME should just return NULL
+
     /* Not runable, not exited, not sleeping */
     thread->flags = 0;
     thread->wakeup_time = 0LL;
@@ -165,28 +168,28 @@ struct _reent *__getreent(void)
     struct _reent *_reent;
 
     if (!threads_started)
-	_reent = _impure_ptr;
+        _reent = _impure_ptr;
     else if (in_callback)
-	_reent = &callback_reent;
+        _reent = &callback_reent;
     else
-	_reent = &get_current()->reent;
+        _reent = &get_current()->reent;
 
 #ifndef NDEBUG
 #if defined(__x86_64__) || defined(__x86__)
     {
 #ifdef __x86_64__
-	register unsigned long sp asm ("rsp");
+        register unsigned long sp asm ("rsp");
 #else
-	register unsigned long sp asm ("esp");
+        register unsigned long sp asm ("esp");
 #endif
-	if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) {
-	    static int overflowing;
-	    if (!overflowing) {
-		overflowing = 1;
-		printk("stack overflow\n");
-		BUG();
-	    }
-	}
+        if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) {
+            static int overflowing;
+            if (!overflowing) {
+                overflowing = 1;
+                printk("stack overflow\n");
+                BUG();
+            }
+        }
     }
 #endif
 #else
Signature · 7 lines
2.0.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#16 lore raw
Quoted 31 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:21 +0100, a écrit :

From: Karim Raslan <[email protected]>

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
[[email protected]: made x86_64 support work again]
[[email protected]: split into multiple patches]
[[email protected]: re-enabled force_evtchn_callback]
[[email protected]: enable regular console]

[[email protected]: fixed initialisation code:
- Configure write-back caching in page table. This is needed for reliable hypercalls to Xen (thanks to Julien Grall).
- Use "client mode" for access control (domains are deprecated, according to ARM Cortex-A Series Programmer’s Guide version 4.0, section 9.6.4).
- Enable more SCTLR features (icache, branch prediction)]

[[email protected]: use Virtual Count register for monotonic time]
[[email protected]: fixed HYPERVISOR_shutdown]
[[email protected]: get xenstore details from hypervisor]
[[email protected]: use GCC implementation of division]
[[email protected]: include hypervisor.h from os.h, as on x86]
[[email protected]: cleaned up interrupt handlers and threading]
[[email protected]: call exit_thread when a thread returns]
[[email protected]: implemented block_domain for ARM]
[[email protected]: fixed hang when enabling interrupts]
Quoted 8 lines
[[email protected]: added -march=armv7-a to flags]
[[email protected]: implemented bitops for ARM]
[[email protected]: CLREX after handling IRQs]
[[email protected]: unbind debug port at shutdown]
[[email protected]: allow unaligned accesses]
[[email protected]: added arch_endian.h for ARM]
[[email protected]: fix zImage header for XSA-95]

It looks good to me, although I haven't reviewed the purely arm parts such as bootup. I don't know how I'm supposed to tag it :)

Samuel

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

#17 lore raw
In reply to Thomas Leonard

Hi Thomas,

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

Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S new file +1 -0
new file mode 100644
index 0000000..4f953ec
@@ -0,0 +1,155 @@
+#define PHYS_START (0x80008000)

This address is wrong with the latest xen unstable. Any reason to make mini-os tight to a specific physical address?

[..]

extras/mini-os/arch/arm/hypercalls32.S

Quoted 5 lines
extras/mini-os/arch/arm/hypercalls32.S new file +0 -0
new file mode 100644
index 0000000..e2f21c4

This code is based on the one in Linux (arch/arm/xen/hypercall.S), right? IIRC it's a BSD license but you have to keep it.

[..]

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

Quoted 11 lines
extras/mini-os/arch/arm/mm.c new file +5 -0
new file mode 100644
index 0000000..bb6aa0e
@@ -0,0 +1,44 @@
+#include <console.h>
+#include <arch_mm.h>
+
+#define PHYS_START (0x80008000 + (1000 * 4 * 1024))
+#define PHYS_SIZE (40*1024*1024)

Same remark as earlier in arm/arm32.S. But I see you don't use them anymore after patch #10. So please drop the both defines in #10.

[..]

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

Quoted 13 lines
extras/mini-os/arch/arm/mm.c new file +13 -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\n"
+            "isb"::"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));

I don't think you need to add an isb per instruction. One should be enough.

[..]

Quoted 22 lines
extras/mini-os/drivers/gic.c new file +16 -0
new file mode 100644
index 0000000..3141830
@@ -0,0 +1,187 @@
+// ARM GIC implementation
+
+#include <mini-os/os.h>
+#include <mini-os/hypervisor.h>
+
+//#define VGIC_DEBUG
+#ifdef VGIC_DEBUG
+#define DEBUG(_f, _a...) \
+    DEBUG("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 {

extras/mini-os/drivers/gic.c line 26

Quoted 10 lines
extras/mini-os/drivers/gic.c new file +10 -0
+    volatile char *gicd_base;
+    volatile char *gicc_base;
+};
+
+static struct gic gic;
+
+// Distributor Interface
+#define GICD_CTLR        0x0
+#define GICD_ISENABLER    0x100
+#define GICD_PRIORITY    0x400

You use the right name for every macro except this one. I would rename it to GICD_IPRIORITYR to stay consistent.

Quoted 20 lines
extras/mini-os/drivers/gic.c new file +20 -0
+#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();

extras/mini-os/drivers/gic.c line 56

Quoted 10 lines
extras/mini-os/drivers/gic.c new file +10 -0
+    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, unsigned char irq_number, unsigned char priority)

hmmmm why do you use unsigned char to describe the interrupt?

extras/mini-os/drivers/gic.c line 59

Quoted 3 lines
extras/mini-os/drivers/gic.c new file +3 -0
+{
+    uint32_t value;
+    value = REG_READ32(REG(gicd(gic, GICD_PRIORITY)) + irq_number);

There is 4 interrupts describe per register, this should be (irq_number & ~3).

extras/mini-os/drivers/gic.c line 61

Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2 -0
+    value &= ~(0xff << (8 * (irq_number & 0x3))); // set priority to '0'
+    value |= priority << (8 * (irq_number & 0x3)); // add our priority

It looks strange that you correctly handle the shift here.

extras/mini-os/drivers/gic.c line 62

Quoted 1 line
extras/mini-os/drivers/gic.c new file +1 -0
+    REG_WRITE32(REG(gicd(gic, GICD_PRIORITY)) + irq_number, value);

irq_number & ~3

extras/mini-os/drivers/gic.c line 68

Quoted 6 lines
extras/mini-os/drivers/gic.c new file +6 -0
+}
+
+static void gic_route_interrupt(struct gic *gic, unsigned char irq_number, unsigned char cpu_set)
+{
+    uint32_t value;
+    value = REG_READ32(REG(gicd(gic, GICD_ITARGETSR)) + irq_number);

Same remark as gic_set_priority here.

extras/mini-os/drivers/gic.c line 70

Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2 -0
+    value &= ~(0xff << (8 * (irq_number & 0x3))); // set priority to '0'
+    value |= cpu_set << (8 * (irq_number & 0x3)); // add our priority

The comments are wrong in the 2 lines above.

extras/mini-os/drivers/gic.c line 71

Quoted 1 line
extras/mini-os/drivers/gic.c new file +1 -0
+    REG_WRITE32(REG(gicd(gic, GICD_ITARGETSR)) + irq_number, value);

irq_number & ~3;

extras/mini-os/drivers/gic.c line 77

Quoted 6 lines
extras/mini-os/drivers/gic.c new file +6 -0
+}
+
+/* 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)
+{
+    uint32_t *tmp = (uint32_t *)base;

You don't need to cast here and I suspect your variable need to be volatile otherwise the compiler may do some assumption.

extras/mini-os/drivers/gic.c line 83

Quoted 6 lines
extras/mini-os/drivers/gic.c new file +6 -0
+    tmp[nr >> 5] &= (unsigned long)~(1 << (nr & 0x1f));
+}
+
+static __inline__ void set_bit_non_atomic(int nr, volatile void *base)
+{
+    uint32_t *tmp = (uint32_t *)base;

Same remark here.

extras/mini-os/drivers/gic.c line 173

Quoted 4 lines
extras/mini-os/drivers/gic.c new file +4 -0
+void gic_init(void) {
+    // FIXME Get from dt!
+    gic.gicd_base = (char *)0x2c001000ULL;
+    gic.gicc_base = (char *)0x2c002000ULL;

Those values are wrong.

Quoted 13 lines
extras/mini-os/events.c +1 -0
index 3c92d82..780c74a 100644
@@ -179,6 +179,7 @@ void init_events(void)
 void fini_events(void)
 {
     /* Dealloc all events */
+    arch_unbind_ports();
     unbind_all_ports();
     arch_fini_events();
 }

extras/mini-os/events.c int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port, · line 243

Quoted 6 lines
extras/mini-os/events.c +2 -1
@@ -238,7 +239,8 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
 
 int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size)
 {
-    int rc;
+    int rc = 0;
+#ifndef __arm__			/* TODO */

Do you still need this TODO & ifdef? XSM is working correctly on ARM. And even if it was not implemented the compilation should not failed.

Quoted 16 lines
extras/mini-os/events.c +1 -0
     uint32_t sid;
     struct xen_flask_op op;
     op.cmd = FLASK_GET_PEER_SID;
@@ -253,6 +255,7 @@ int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size)
     op.u.sid_context.size = size;
     set_xen_guest_handle(op.u.sid_context.context, ctx);
     rc = _hypercall1(int, xsm_op, &op);
+#endif
     return rc;
 }
 
extras/mini-os/hypervisor.c +0 -0
index b4688a0..1b61d9b 100644

extras/mini-os/hypervisor.c void do_hypervisor_callback(struct pt_regs *regs) · line 67

Quoted 5 lines
extras/mini-os/hypervisor.c +1 -1
@@ -64,7 +64,7 @@ void do_hypervisor_callback(struct pt_regs *regs)
             l2 &= ~(1UL << l2i);
 
             port = (l1i * (sizeof(unsigned long) * 8)) + l2i;
-			do_event(port, regs);
+            do_event(port, regs);

This patch is long and difficult to read. Please avoid indentation change in non-modified code at the same time.

Quoted 31 lines
extras/mini-os/hypervisor.c +8 -0
         }
     }
 
@@ -73,18 +73,26 @@ void do_hypervisor_callback(struct pt_regs *regs)
 
 void force_evtchn_callback(void)
 {
+#ifdef XEN_HAVE_PV_UPCALL_MASK
     int save;
+#endif
     vcpu_info_t *vcpu;
     vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()];
+#ifdef XEN_HAVE_PV_UPCALL_MASK
     save = vcpu->evtchn_upcall_mask;
+#endif
 
     while (vcpu->evtchn_upcall_pending) {
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         vcpu->evtchn_upcall_mask = 1;
+#endif
         barrier();
         do_hypervisor_callback(NULL);
         barrier();
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         vcpu->evtchn_upcall_mask = save;
         barrier();
+#endif
     };
 }
 

extras/mini-os/hypervisor.c inline void unmask_evtchn(uint32_t port) · line 126

Quoted 9 lines
extras/mini-os/hypervisor.c +2 -0
@@ -110,7 +118,9 @@ inline void unmask_evtchn(uint32_t port)
               &vcpu_info->evtchn_pending_sel) )
     {
         vcpu_info->evtchn_upcall_pending = 1;
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         if ( !vcpu_info->evtchn_upcall_mask )
+#endif
             force_evtchn_callback();
     }
 }

I would have move those change in a separate patch.

[..]

Quoted 21 lines
extras/mini-os/include/arm/arch_spinlock.h new file +15 -0
new file mode 100755
index 0000000..d57f150
@@ -0,0 +1,49 @@
+
+
+#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.

extras/mini-os/include/arm/arch_spinlock.h line 25

Quoted 10 lines
extras/mini-os/include/arm/arch_spinlock.h new file +10 -0
+ */
+
+#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))
+
+/*
+ * This works. Despite all the confusion.
+ * (except on PPro SMP or if we are using OOSTORE)
+ * (PPro errata 66, 92)
+ */

This comment is x86... It should not have been copied here.

Quoted 11 lines
extras/mini-os/include/arm/arch_spinlock.h new file +11 -0
+
+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;
+}
+

extras/mini-os/include/arm/arch_spinlock.h line 46

Quoted 10 lines
extras/mini-os/include/arm/arch_spinlock.h new file +10 -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);
+}
+
+static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
+{

You didn't implement this function. It looks like it's not used in mini-os, right? If so, please add a BUG_ON just in case that someone decide to use it later.

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 5 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +0 -0
new file mode 100644
index 0000000..0fc1c03

Actually this file can be name hypercall.h. On ARM64 the set of hypercall is exactly the same. The only different that you will have between both architecture is the assembly code and the system registers.

[..]

extras/mini-os/include/arm/hypercall-arm32.h line 43

Quoted 3 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +3 -0
+inline int
+HYPERVISOR_mmu_update(
+    mmu_update_t *req, int count, int *success_count, domid_t domid);

Why do you use inline in all external functions in this include?

Hence most of this hypercall doesn't exist on ARM. Please define only the necessary one.

[..]

Quoted 1 line

+#endif /* __HYPERCALL_X86_64_H__ */

__HYPERCALL_ARM_H__

[..]

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2 -0
+// disable interrupts
+static inline __cli(void) {

I see that you use __cli and __sti only
__cli and __sti are only in 2 defines below. These name are only x86 specific. Please rename them or merge this code in local_irq_{disable,enable}

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2 -0
+    int x;
+    __asm__ __volatile__("mrs %0, cpsr;cpsid i":"=r"(x)::"memory");

Why do you need to read cpsr. cpsid i is enough here.

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 9 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +9 -0
+}
+
+// enable interrupts
+static inline __sti(void) {
+    int x;
+    __asm__ __volatile__("mrs %0, cpsr\n"
+                        "bic %0, %0, #0x80\n"
+                        "msr cpsr_c, %0"
+                        :"=r"(x)::"memory");

This can simply be done by cpsie i

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 6 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +6 -0
+}
+
+static inline int irqs_disabled() {
+    int x;
+    __asm__ __volatile__("mrs %0, cpsr\n":"=r"(x)::"memory");
+    return (x & 0x80);

You can use local_save_flags directly.

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 9 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +9 -0
+}
+
+#define local_irq_save(x) { \
+    __asm__ __volatile__("mrs %0, cpsr;cpsid i; and %0, %0, #0x80":"=r"(x)::"memory");    \
+}
+
+#define local_irq_restore(x) {    \
+    __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory");    \
+}

If you mask the result in local_irq_save, and use this value directly is local_irq_restore, you will disable by mistake the Asynchronous Abort exception....

You have to remove the and %0... at the end.

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 3 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +3 -0
+#define local_save_flags(x)    { \
+    __asm__ __volatile__("mrs %0, cpsr; and %0, %0, 0x80":"=r"(x)::"memory");    \
+}

Same remark here.

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 7 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +7 -0
+#define local_irq_disable()    __cli()
+#define local_irq_enable() __sti()
+
+#if defined(__arm__)
+#define mb() __asm__("dmb");
+#define rmb() __asm__("dmb");
+#define wmb() __asm__("dmb");

I suspect you want to dsb here. You want to make sure that every memory access has finished avoid executing new instruction until this is done.

dmb only ensure the memory ordering.

Also, you want to clobber the memory to avoid the compiler:
1) reordering the instructions
2) prefetch data from the memory

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 4 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +4 -0
+#elif defined(__aarch64__)
+#define mb()
+#define rmb()
+#define wmb()

I'm confused with this piece of code... memory barrier are also required on aarch64. Hence dmb/isb also exist on this architecture

You don't need the if ... elif ... else

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2 -0
+#define unlikely(x)  __builtin_expect((x),0)
+#define likely(x)  __builtin_expect((x),1)

Can't it be common with x86?

[..]

Quoted 13 lines

int do_event(evtchn_port_t port, struct pt_regs *regs);

extras/mini-os/include/gic.h new file +1 -0
new file mode 100644
index 0000000..cead2e5
@@ -0,0 +1 @@
+void gic_init(void);
extras/mini-os/include/hypervisor.h +0 -0
index a62cb78..052f4f8 100644

extras/mini-os/include/hypervisor.h line 24

Quoted 7 lines
extras/mini-os/include/hypervisor.h +4 -0
@@ -18,6 +18,10 @@
 #include <hypercall-x86_32.h>
 #elif defined(__x86_64__)
 #include <hypercall-x86_64.h>
+#elif defined(__arm__)
+#include <hypercall-arm32.h>
+#elif defined(__aarch64__)
+#include <hypercall-arm64.h>

Hmmm, the filehypercall-arm64.h doesn't exists in this series...

Futhermore, as I said ealier the set of hypercall is exactly the same on arm64.

[..]

extras/mini-os/include/hypervisor.h typedef unsigned long u_quad_t; · line 44

Quoted 11 lines
extras/mini-os/include/hypervisor.h +2 -1
+#if defined(__i386__) || defined(__arm__)
 typedef long long           quad_t;
 typedef unsigned long long  u_quad_t;
@@ -40,7 +40,7 @@ typedef unsigned long       u_quad_t;
 typedef struct { unsigned long pte; } pte_t;
 #endif /* __i386__ || __x86_64__ */
 
-#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__aarch64__)
 #define __pte(x) ((pte_t) { (x) } )

This looks wrong to me. The pte layout is exactly the same on arm32 and arm64. Hence, this is only used in the x86 code. Please either move pte_t in x86 part or define it correctly on ARM...

[..]

Quoted 16 lines
extras/mini-os/kernel.c +4 -0
index 9a30550..7b2b8fc 100644
@@ -47,6 +47,10 @@
 #include <xen/features.h>
 #include <xen/version.h>
 
+#ifdef __arm__
+#include <mini-os/gic.h>
+#endif
+
 uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32];
 
 void setup_xen_features(void)

extras/mini-os/kernel.c void start_kernel(void) · line 157

Quoted 7 lines
extras/mini-os/kernel.c +4 -0
@@ -147,6 +151,10 @@ void start_kernel(void)
     create_thread("shutdown", shutdown_thread, NULL);
 #endif
 
+#ifdef __arm__
+    gic_init();
+#endif
+

I would define a function arch_init. This will avoid the #ifdef __arm__ in the code common.

Hence, it looks strange that sometime you have #if __arm__ && __arch64__ and sometimes not...

Quoted 8 lines
extras/mini-os/kernel.c +0 -0
     /* Call (possibly overridden) app_main() */
     app_main(&start_info);
 
extras/mini-os/sched.c +0 -0
index 174945e..b99d7dc 100644

extras/mini-os/sched.c struct thread* create_thread(char *name, void (*function)(void *), void *data) · line 150

Quoted 6 lines
extras/mini-os/sched.c +3 -0
@@ -145,6 +145,9 @@ struct thread* create_thread(char *name, void (*function)(void *), void *data)
     unsigned long flags;
     /* Call architecture specific setup. */
     thread = arch_create_thread(name, function, data);
+    if(!thread)
+        BUG(); //For now, FIXME should just return NULL
+

This change is in the common code. I think this should go in a separate patch.

Hence looking again to arch_create_thread for ARM you:
1) never return NULL
2) never check the xmalloc/alloc_pages return.

Quoted 31 lines
extras/mini-os/sched.c +5 -11
     /* Not runable, not exited, not sleeping */
     thread->flags = 0;
     thread->wakeup_time = 0LL;
@@ -165,28 +168,28 @@ struct _reent *__getreent(void)
     struct _reent *_reent;
 
     if (!threads_started)
-	_reent = _impure_ptr;
+        _reent = _impure_ptr;
     else if (in_callback)
-	_reent = &callback_reent;
+        _reent = &callback_reent;
     else
-	_reent = &get_current()->reent;
+        _reent = &get_current()->reent;
 #ifndef NDEBUG
 #if defined(__x86_64__) || defined(__x86__)
     {
 #ifdef __x86_64__
-	register unsigned long sp asm ("rsp");
+        register unsigned long sp asm ("rsp");
 #else
-	register unsigned long sp asm ("esp");
+        register unsigned long sp asm ("esp");
 #endif
-	if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) {
-	    static int overflowing;
-	    if (!overflowing) {
-		overflowing = 1;
-		printk("stack overflow\n");
-		BUG();

extras/mini-os/sched.c struct _reent *__getreent(void) · line 191

Quoted 10 lines
extras/mini-os/sched.c +8 -2
-	    }
-	}
+        if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) {
+            static int overflowing;
+            if (!overflowing) {
+                overflowing = 1;
+                printk("stack overflow\n");
+                BUG();
+            }
+        }

all this chunk: spurious changes?

Regards,

Signature · 1 line
Julien Grall
#18 lore raw
Quoted 1 line · Julien Grall

Hi Thomas,

Hi Julien,

Thanks for reviewing this!

Quoted 14 lines · Thomas Leonard

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

Quoted 9 lines
extras/mini-os/arch/arm/arm32.S new file +1 -0
new file mode 100644
index 0000000..4f953ec
@@ -0,0 +1,155 @@
+#define PHYS_START (0x80008000)

This address is wrong with the latest xen unstable. Any reason to make mini-os tight to a specific physical address?

I'll remove this in the next version.

Quoted 13 lines

[..]

extras/mini-os/arch/arm/hypercalls32.S

Quoted 6 lines
extras/mini-os/arch/arm/hypercalls32.S new file +0 -0
new file mode 100644
index 0000000..e2f21c4

This code is based on the one in Linux (arch/arm/xen/hypercall.S), right? IIRC it's a BSD license but you have to keep it.

I don't know where it came from, but you're probably right. I've added the header back in.

Quoted 18 lines

[..]

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

Quoted 11 lines
extras/mini-os/arch/arm/mm.c new file +5 -0
new file mode 100644
index 0000000..bb6aa0e
@@ -0,0 +1,44 @@
+#include <console.h>
+#include <arch_mm.h>
+
+#define PHYS_START (0x80008000 + (1000 * 4 * 1024))
+#define PHYS_SIZE (40*1024*1024)

Same remark as earlier in arm/arm32.S. But I see you don't use them anymore after patch #10. So please drop the both defines in #10.

I've reordered the patches so we don't need this now.

Quoted 12 lines

[..]

Quoted 9 lines
extras/mini-os/arch/arm/mm.c new file +9 -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\n"
+            "isb"::"r"(x), "r"(y));
Quoted 8 lines
Quoted 5 lines
extras/mini-os/arch/arm/mm.c new file +3 -0
+
+    __asm__ __volatile__("mov %0, #0x1\n"
+            "mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the

output signal */
+ "isb":"=r"(x));

I don't think you need to add an isb per instruction. One should be enough.

Actually, do we need one at all? Setting the timer shouldn't affect the instruction pipline, I think.

Quoted 31 lines

[..]

Quoted 28 lines
extras/mini-os/drivers/gic.c new file +22 -0
new file mode 100644
index 0000000..3141830
@@ -0,0 +1,187 @@
+// ARM GIC implementation
+
+#include <mini-os/os.h>
+#include <mini-os/hypervisor.h>
+
+//#define VGIC_DEBUG
+#ifdef VGIC_DEBUG
+#define DEBUG(_f, _a...) \
+    DEBUG("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;
+
Quoted 8 lines

extras/mini-os/drivers/gic.c line 26

Quoted 4 lines
extras/mini-os/drivers/gic.c new file +4 -0
+// Distributor Interface
+#define GICD_CTLR        0x0
+#define GICD_ISENABLER    0x100
+#define GICD_PRIORITY    0x400

You use the right name for every macro except this one. I would rename it to GICD_IPRIORITYR to stay consistent.

Done.

Quoted 22 lines
Quoted 22 lines
extras/mini-os/drivers/gic.c new file +22 -0
+#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;
+}
Quoted 8 lines

extras/mini-os/drivers/gic.c line 55

Quoted 8 lines
extras/mini-os/drivers/gic.c new file +2 -0
+
+static inline void REG_WRITE32(volatile uint32_t *addr, unsigned int

value)

extras/mini-os/drivers/gic.c new file +5 -0
+{
+    __asm__ __volatile__("str %0, [%1]"::"r"(value), "r"(addr));
+    wmb();
+}
+

Do we need inline assembler to write these values? I'd imagine that a plain C store to a volatile 32-bit pointer would always do the same thing.

Quoted 5 lines
Quoted 2 lines

+static void gic_set_priority(struct gic *gic, unsigned char irq_number, unsigned char priority)

hmmmm why do you use unsigned char to describe the interrupt?

Yes, that's clearly wrong. Interrupt numbers don't fit in 8 bits.

Quoted 7 lines

extras/mini-os/drivers/gic.c line 59

Quoted 3 lines
extras/mini-os/drivers/gic.c new file +3 -0
+{
+    uint32_t value;
+    value = REG_READ32(REG(gicd(gic, GICD_PRIORITY)) + irq_number);

There is 4 interrupts describe per register, this should be (irq_number & ~3).

Or should it be (irq_number >> 2)? REG casts to uint32_t.

Quoted 29 lines

extras/mini-os/drivers/gic.c line 61

Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2 -0
+    value &= ~(0xff << (8 * (irq_number & 0x3))); // set priority to '0'
+    value |= priority << (8 * (irq_number & 0x3)); // add our priority

It looks strange that you correctly handle the shift here.

Quoted 1 line

+ REG_WRITE32(REG(gicd(gic, GICD_PRIORITY)) + irq_number, value);

irq_number & ~3

extras/mini-os/drivers/gic.c line 68

Quoted 7 lines
extras/mini-os/drivers/gic.c new file +3 -0
+}
+
+static void gic_route_interrupt(struct gic *gic, unsigned char

irq_number, unsigned char cpu_set)

extras/mini-os/drivers/gic.c new file +3 -0
+{
+    uint32_t value;
+    value = REG_READ32(REG(gicd(gic, GICD_ITARGETSR)) + irq_number);

Same remark as gic_set_priority here.

extras/mini-os/drivers/gic.c

Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2 -0
+    value &= ~(0xff << (8 * (irq_number & 0x3))); // set priority to '0'
+    value |= cpu_set << (8 * (irq_number & 0x3)); // add our priority
Quoted 7 lines

The comments are wrong in the 2 lines above.

Quoted 1 line

+ REG_WRITE32(REG(gicd(gic, GICD_ITARGETSR)) + irq_number, value);

irq_number & ~3;

The ARM Generic Interrupt Controller Architecture Specification says "These registers are byte-accessible.". So we should be able to write the byte directly. I thought this might work:

static void gic_route_interrupt(struct gic *gic, int irq_number, unsigned char cpu_set)

{
    gicd(gic, GICD_ITARGETSR)[irq_number] = cpu_set;
    wmb();
}

But it doesn't, because Xen's write_ignore handler (vgic.c:656 on the 4.4 branch) does:

write_ignore:
if ( dabt.size != 2 ) goto bad_width;

Bug?

Quoted 11 lines

extras/mini-os/drivers/gic.c line 77

Quoted 7 lines
extras/mini-os/drivers/gic.c new file +3 -0
+}
+
+/* When accessing the GIC registers, we can't use LDREX/STREX because

it's not regular memory. */

extras/mini-os/drivers/gic.c new file +3 -0
+static __inline__ void clear_bit_non_atomic(int nr, volatile void *base)
+{
+    uint32_t *tmp = (uint32_t *)base;

You don't need to cast here and I suspect your variable need to be volatile otherwise the compiler may do some assumption.

OK.

Quoted 9 lines

extras/mini-os/drivers/gic.c line 83

Quoted 6 lines
extras/mini-os/drivers/gic.c new file +6 -0
+    tmp[nr >> 5] &= (unsigned long)~(1 << (nr & 0x1f));
+}
+
+static __inline__ void set_bit_non_atomic(int nr, volatile void *base)
+{
+    uint32_t *tmp = (uint32_t *)base;

Same remark here.

OK.

Quoted 7 lines

extras/mini-os/drivers/gic.c line 173

Quoted 4 lines
extras/mini-os/drivers/gic.c new file +4 -0
+void gic_init(void) {
+    // FIXME Get from dt!
+    gic.gicd_base = (char *)0x2c001000ULL;
+    gic.gicc_base = (char *)0x2c002000ULL;

Those values are wrong.

Now fixed by patch reordering.

Quoted 15 lines
Quoted 15 lines
extras/mini-os/events.c +1 -0
index 3c92d82..780c74a 100644
@@ -179,6 +179,7 @@ void init_events(void)
 void fini_events(void)
 {
     /* Dealloc all events */
+    arch_unbind_ports();
     unbind_all_ports();
     arch_fini_events();
 }
@@ -238,7 +239,8 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t
 remote_port,
 
Quoted 9 lines

extras/mini-os/events.c int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port, · line 243

Quoted 5 lines
extras/mini-os/events.c +2 -1
 int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size)
 {
-    int rc;
+    int rc = 0;
+#ifndef __arm__                        /* TODO */

Do you still need this TODO & ifdef? XSM is working correctly on ARM. And even if it was not implemented the compilation should not failed.

It used "_hypercall1", which was missing from ARM. I've now added HYPERVISOR_xsm_op and changed it to use that instead.

Quoted 19 lines
Quoted 19 lines
extras/mini-os/events.c +0 -0
     uint32_t sid;
     struct xen_flask_op op;
     op.cmd = FLASK_GET_PEER_SID;
extras/mini-os/events.c +1 -0
@@ -253,6 +255,7 @@ int evtchn_get_peercontext(evtchn_port_t local_port,
 char *ctx, int size)
     op.u.sid_context.size = size;
     set_xen_guest_handle(op.u.sid_context.context, ctx);
     rc = _hypercall1(int, xsm_op, &op);
+#endif
     return rc;
 }
extras/mini-os/hypervisor.c +0 -0
index b4688a0..1b61d9b 100644
@@ -64,7 +64,7 @@ void do_hypervisor_callback(struct pt_regs *regs)
             l2 &= ~(1UL << l2i);
 
Quoted 7 lines

extras/mini-os/hypervisor.c void do_hypervisor_callback(struct pt_regs *regs) · line 67

Quoted 3 lines
extras/mini-os/hypervisor.c +1 -1
             port = (l1i * (sizeof(unsigned long) * 8)) + l2i;
-                       do_event(port, regs);
+            do_event(port, regs);

This patch is long and difficult to read. Please avoid indentation change in non-modified code at the same time.

OK, split off.

Quoted 30 lines
Quoted 30 lines
extras/mini-os/hypervisor.c +8 -0
         }
     }
 
@@ -73,18 +73,26 @@ void do_hypervisor_callback(struct pt_regs *regs)
 
 void force_evtchn_callback(void)
 {
+#ifdef XEN_HAVE_PV_UPCALL_MASK
     int save;
+#endif
     vcpu_info_t *vcpu;
     vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id()];
+#ifdef XEN_HAVE_PV_UPCALL_MASK
     save = vcpu->evtchn_upcall_mask;
+#endif
 
     while (vcpu->evtchn_upcall_pending) {
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         vcpu->evtchn_upcall_mask = 1;
+#endif
         barrier();
         do_hypervisor_callback(NULL);
         barrier();
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         vcpu->evtchn_upcall_mask = save;
         barrier();
+#endif
     };
 }
 
Quoted 13 lines

extras/mini-os/hypervisor.c inline void unmask_evtchn(uint32_t port) · line 126

Quoted 10 lines
extras/mini-os/hypervisor.c +2 -0
@@ -110,7 +118,9 @@ inline void unmask_evtchn(uint32_t port)
               &vcpu_info->evtchn_pending_sel) )
     {
         vcpu_info->evtchn_upcall_pending = 1;
+#ifdef XEN_HAVE_PV_UPCALL_MASK
         if ( !vcpu_info->evtchn_upcall_mask )
+#endif
             force_evtchn_callback();
     }
 }

I would have move those change in a separate patch.

OK.

Quoted 32 lines

[..]

Quoted 29 lines
extras/mini-os/include/arm/arch_spinlock.h new file +18 -0
new file mode 100755
index 0000000..d57f150
@@ -0,0 +1,49 @@
+
+
+#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))
+

Quoted 8 lines
Quoted 5 lines

+/*
+ * This works. Despite all the confusion.
+ * (except on PPro SMP or if we are using OOSTORE)
+ * (PPro errata 66, 92)
+ */

This comment is x86... It should not have been copied here.

OK.

Quoted 19 lines
Quoted 19 lines
extras/mini-os/include/arm/arch_spinlock.h new file +19 -0
+
+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);
+}
+
Quoted 8 lines
Quoted 3 lines

+static inline void _raw_spin_lock_flags (spinlock_t *lock, unsigned long flags)
+{

You didn't implement this function. It looks like it's not used in mini-os, right? If so, please add a BUG_ON just in case that someone decide to use it later.

I'll remove it completely. Better to find out it's missing at compile time.

Quoted 12 lines

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 7 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +0 -0
new file mode 100644
index 0000000..0fc1c03

Actually this file can be name hypercall.h. On ARM64 the set of hypercall is exactly the same. The only different that you will have between both architecture is the assembly code and the system registers.

I've renamed it to hypercall-arm.h (to match the x86 naming).

Quoted 9 lines

[..]

extras/mini-os/include/arm/hypercall-arm32.h line 43

Quoted 3 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +3 -0
+inline int
+HYPERVISOR_mmu_update(
+    mmu_update_t *req, int count, int *success_count, domid_t domid);

Why do you use inline in all external functions in this include?

No idea. I've removed all the inlines.

Quoted 2 lines

Hence most of this hypercall doesn't exist on ARM. Please define only the necessary one.

OK.

Quoted 6 lines

[..]

Quoted 1 line

+#endif /* __HYPERCALL_X86_64_H__ */

__HYPERCALL_ARM_H__

Fixed.

Quoted 11 lines

[..]

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2 -0
+// disable interrupts
+static inline __cli(void) {

I see that you use __cli and __sti only
__cli and __sti are only in 2 defines below. These name are only x86 specific. Please rename them or merge this code in local_irq_{disable,enable}

Done.

Quoted 5 lines

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2 -0
+    int x;
+    __asm__ __volatile__("mrs %0, cpsr;cpsid i":"=r"(x)::"memory");

Why do you need to read cpsr. cpsid i is enough here.

Removed.

Quoted 4 lines
Quoted 4 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +4 -0
+}
+
+// enable interrupts
+static inline __sti(void) {
Quoted 8 lines

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 5 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +5 -0
+    int x;
+    __asm__ __volatile__("mrs %0, cpsr\n"
+                        "bic %0, %0, #0x80\n"
+                        "msr cpsr_c, %0"
+                        :"=r"(x)::"memory");

This can simply be done by cpsie i

Done.

Quoted 9 lines

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 6 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +6 -0
+}
+
+static inline int irqs_disabled() {
+    int x;
+    __asm__ __volatile__("mrs %0, cpsr\n":"=r"(x)::"memory");
+    return (x & 0x80);

You can use local_save_flags directly.

OK.

Quoted 16 lines

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 10 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +4 -0
+}
+
+#define local_irq_save(x) { \
+    __asm__ __volatile__("mrs %0, cpsr;cpsid i; and %0, %0,

#0x80":"=r"(x)::"memory"); \

extras/mini-os/include/arm/hypercall-arm32.h new file +5 -0
+}
+
+#define local_irq_restore(x) {    \
+    __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory");    \
+}

If you mask the result in local_irq_save, and use this value directly is local_irq_restore, you will disable by mistake the Asynchronous Abort exception....

Quoted 1 line

You have to remove the and %0... at the end.

This makes schedule() fail, because it checks whether the result is zero. Perhaps we should continue to mask it, but only apply the IRQ bit in local_irq_restore?

Quoted 7 lines
Quoted 4 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2 -0
+#define local_save_flags(x)    { \
+    __asm__ __volatile__("mrs %0, cpsr; and %0, %0,

0x80":"=r"(x)::"memory"); \
+}

Same remark here.

If we mask on restore, this is OK.

Quoted 11 lines

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 7 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +7 -0
+#define local_irq_disable()    __cli()
+#define local_irq_enable() __sti()
+
+#if defined(__arm__)
+#define mb() __asm__("dmb");
+#define rmb() __asm__("dmb");
+#define wmb() __asm__("dmb");

I suspect you want to dsb here. You want to make sure that every memory access has finished avoid executing new instruction until this is done.

Is this necessary? As I understand it, using Xen's ring system requires a strict ordering (dmb), but we don't need to stall the processor waiting for each write to complete before going on to the next one.

Quoted 5 lines

dmb only ensure the memory ordering.

Also, you want to clobber the memory to avoid the compiler:
1) reordering the instructions
2) prefetch data from the memory

OK.

Quoted 10 lines

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 4 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +4 -0
+#elif defined(__aarch64__)
+#define mb()
+#define rmb()
+#define wmb()

I'm confused with this piece of code... memory barrier are also required on aarch64. Hence dmb/isb also exist on this architecture

You don't need the if ... elif ... else

Removed.

Quoted 5 lines

extras/mini-os/include/arm/hypercall-arm32.h

Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2 -0
+#define unlikely(x)  __builtin_expect((x),0)
+#define likely(x)  __builtin_expect((x),1)

Can't it be common with x86?

Which header file should it go in?

Quoted 28 lines

[..]

Quoted 14 lines

int do_event(evtchn_port_t port, struct pt_regs *regs);

extras/mini-os/include/gic.h new file +1 -0
new file mode 100644
index 0000000..cead2e5
@@ -0,0 +1 @@
+void gic_init(void);
extras/mini-os/include/hypervisor.h +0 -0
index a62cb78..052f4f8 100644

extras/mini-os/include/hypervisor.h line 24

Quoted 7 lines
extras/mini-os/include/hypervisor.h +4 -0
@@ -18,6 +18,10 @@
 #include <hypercall-x86_32.h>
 #elif defined(__x86_64__)
 #include <hypercall-x86_64.h>
+#elif defined(__arm__)
+#include <hypercall-arm32.h>
+#elif defined(__aarch64__)
+#include <hypercall-arm64.h>

Hmmm, the filehypercall-arm64.h doesn't exists in this series...

Quoted 2 lines

Futhermore, as I said ealier the set of hypercall is exactly the same on arm64.

Fixed.

Quoted 11 lines

[..]

Quoted 8 lines
extras/mini-os/include/hypervisor.h +1 -0
+#if defined(__i386__) || defined(__arm__)
 typedef long long           quad_t;
 typedef unsigned long long  u_quad_t;
@@ -40,7 +40,7 @@ typedef unsigned long       u_quad_t;
 typedef struct { unsigned long pte; } pte_t;
 #endif /* __i386__ || __x86_64__ */
 
Quoted 8 lines

extras/mini-os/include/hypervisor.h typedef unsigned long u_quad_t; · line 44

Quoted 3 lines
extras/mini-os/include/hypervisor.h +1 -1
-#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__aarch64__)
 #define __pte(x) ((pte_t) { (x) } )

This looks wrong to me. The pte layout is exactly the same on arm32 and arm64. Hence, this is only used in the x86 code. Please either move pte_t in x86 part or define it correctly on ARM...

Moved to x86. Actually, this simplifies things further, because it can go in the separate hypercall-*.h files and lose the #ifdef completely.

Quoted 22 lines

[..]

Quoted 19 lines
extras/mini-os/kernel.c +4 -0
index 9a30550..7b2b8fc 100644
@@ -47,6 +47,10 @@
 #include <xen/features.h>
 #include <xen/version.h>
 
+#ifdef __arm__
+#include <mini-os/gic.h>
+#endif
+
 uint8_t xen_features[XENFEAT_NR_SUBMAPS * 32];
 
 void setup_xen_features(void)
@@ -147,6 +151,10 @@ void start_kernel(void)
     create_thread("shutdown", shutdown_thread, NULL);
 #endif
 
Quoted 8 lines

extras/mini-os/kernel.c void start_kernel(void) · line 157

Quoted 4 lines
extras/mini-os/kernel.c +4 -0
+#ifdef __arm__
+    gic_init();
+#endif
+

I would define a function arch_init. This will avoid the #ifdef __arm__ in the code common.

I've moved it to the existing arch_init. I can't see any obvious reason why we should init the GIC long after enabling interrupts anyway.

Quoted 7 lines

Hence, it looks strange that sometime you have #if __arm__ && __arch64__ and sometimes not...

Quoted 3 lines
extras/mini-os/kernel.c +0 -0
     /* Call (possibly overridden) app_main() */
     app_main(&start_info);
 
Quoted 16 lines

extras/mini-os/sched.c struct thread* create_thread(char *name, void · line 151

Quoted 12 lines
extras/mini-os/sched.c +3 -0
index 174945e..b99d7dc 100644
@@ -145,6 +145,9 @@ struct thread* create_thread(char *name, void
 (*function)(void *), void *data)
     unsigned long flags;
     /* Call architecture specific setup. */
     thread = arch_create_thread(name, function, data);
+    if(!thread)
+        BUG(); //For now, FIXME should just return NULL
+

This change is in the common code. I think this should go in a separate patch.

I'll remove this for now.

Quoted 41 lines

Hence looking again to arch_create_thread for ARM you:
1) never return NULL
2) never check the xmalloc/alloc_pages return.

Quoted 36 lines
extras/mini-os/sched.c +0 -0
     /* Not runable, not exited, not sleeping */
     thread->flags = 0;
     thread->wakeup_time = 0LL;
extras/mini-os/sched.c +8 -13
@@ -165,28 +168,28 @@ struct _reent *__getreent(void)
     struct _reent *_reent;
 
     if (!threads_started)
-       _reent = _impure_ptr;
+        _reent = _impure_ptr;
     else if (in_callback)
-       _reent = &callback_reent;
+        _reent = &callback_reent;
     else
-       _reent = &get_current()->reent;
+        _reent = &get_current()->reent;
 #ifndef NDEBUG
 #if defined(__x86_64__) || defined(__x86__)
     {
 #ifdef __x86_64__
-       register unsigned long sp asm ("rsp");
+        register unsigned long sp asm ("rsp");
 #else
-       register unsigned long sp asm ("esp");
+        register unsigned long sp asm ("esp");
 #endif
-       if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) {
-           static int overflowing;
-           if (!overflowing) {
-               overflowing = 1;
-               printk("stack overflow\n");
-               BUG();
-           }
-       }
+        if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) {
+            static int overflowing;
+            if (!overflowing) {
Quoted 8 lines

extras/mini-os/sched.c struct _reent *__getreent(void) · line 192

Quoted 5 lines
extras/mini-os/sched.c +5 -0
+                overflowing = 1;
+                printk("stack overflow\n");
+                BUG();
+            }
+        }

all this chunk: spurious changes?

I'll move the whitespace fixes to a separate patch.

Thanks! I'll do some more clean ups and send another patch series soon.

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

On 18 June 2014 23:40, Julien Grall <[email protected]> wrote:
Hi Julien,

Hi Thomas,

Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
extras/mini-os/arch/arm/time.c new file +9 -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\n"
+            "isb"::"r"(x), "r"(y));
Quoted 8 lines
Quoted 5 lines
extras/mini-os/arch/arm/time.c new file +3 -0
+
+    __asm__ __volatile__("mov %0, #0x1\n"
+            "mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the

output signal */
+ "isb":"=r"(x));

I don't think you need to add an isb per instruction. One should be enough.

Quoted 2 lines

Actually, do we need one at all? Setting the timer shouldn't affect the instruction pipline, I think.

The isb is also used to make sure that an access to a system control registers (such as setting the page table) has finished before executing the next instruction.

Quoted 40 lines
Quoted 31 lines

[..]

Quoted 28 lines
extras/mini-os/drivers/gic.c new file +22 -0
new file mode 100644
index 0000000..3141830
@@ -0,0 +1,187 @@
+// ARM GIC implementation
+
+#include <mini-os/os.h>
+#include <mini-os/hypervisor.h>
+
+//#define VGIC_DEBUG
+#ifdef VGIC_DEBUG
+#define DEBUG(_f, _a...) \
+    DEBUG("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;
+
Quoted 8 lines

extras/mini-os/drivers/gic.c line 26

Quoted 4 lines
extras/mini-os/drivers/gic.c new file +4 -0
+// Distributor Interface
+#define GICD_CTLR        0x0
+#define GICD_ISENABLER    0x100
+#define GICD_PRIORITY    0x400

You use the right name for every macro except this one. I would rename it to GICD_IPRIORITYR to stay consistent.

Quoted 1 line

Done.

Thanks !

Quoted 11 lines
Quoted 7 lines

extras/mini-os/drivers/gic.c line 55

Quoted 7 lines
extras/mini-os/drivers/gic.c new file +1 -0
+static inline void REG_WRITE32(volatile uint32_t *addr, unsigned int

value)

extras/mini-os/drivers/gic.c new file +5 -0
+{
+    __asm__ __volatile__("str %0, [%1]"::"r"(value), "r"(addr));
+    wmb();
+}
+

Do we need inline assembler to write these values? I'd imagine that a plain C store to a volatile 32-bit pointer would always do the same thing.

The compiler may do strange things to store the value, such as 4 byte-store instead of a word-store.

So we have to use inline assembly to make sure the correct access will be done.

Quoted 9 lines
Quoted 7 lines

extras/mini-os/drivers/gic.c line 59

Quoted 3 lines
extras/mini-os/drivers/gic.c new file +3 -0
+{
+    uint32_t value;
+    value = REG_READ32(REG(gicd(gic, GICD_PRIORITY)) + irq_number);

There is 4 interrupts describe per register, this should be (irq_number & ~3).

Or should it be (irq_number >> 2)? REG casts to uint32_t.

It's the same :).

Quoted 28 lines
Quoted 16 lines

extras/mini-os/drivers/gic.c line 68

Quoted 7 lines
extras/mini-os/drivers/gic.c new file +3 -0
+}
+
+static void gic_route_interrupt(struct gic *gic, unsigned char

irq_number, unsigned char cpu_set)

extras/mini-os/drivers/gic.c new file +3 -0
+{
+    uint32_t value;
+    value = REG_READ32(REG(gicd(gic, GICD_ITARGETSR)) + irq_number);

Same remark as gic_set_priority here.

extras/mini-os/drivers/gic.c

Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2 -0
+    value &= ~(0xff << (8 * (irq_number & 0x3))); // set priority to '0'
+    value |= cpu_set << (8 * (irq_number & 0x3)); // add our priority
Quoted 7 lines

The comments are wrong in the 2 lines above.

Quoted 1 line

+ REG_WRITE32(REG(gicd(gic, GICD_ITARGETSR)) + irq_number, value);

irq_number & ~3;

The ARM Generic Interrupt Controller Architecture Specification says "These registers are byte-accessible.". So we should be able to write the byte directly. I thought this might work:

Quoted 6 lines

static void gic_route_interrupt(struct gic *gic, int irq_number, unsigned char cpu_set)

{
    gicd(gic, GICD_ITARGETSR)[irq_number] = cpu_set;
    wmb();
}

This code looks good to me.

Quoted 8 lines

But it doesn't, because Xen's write_ignore handler (vgic.c:656 on the 4.4 branch) does:

write_ignore:
if ( dabt.size != 2 ) goto bad_width;

Bug?

This is a bug in Xen. I think, write_ignore should just ignore the write rather checking badly the size.

Can you send a patch for it?

Quoted 16 lines
Quoted 16 lines

extras/mini-os/drivers/gic.c

Quoted 10 lines
extras/mini-os/drivers/gic.c new file +4 -0
+}
+
+#define local_irq_save(x) { \
+    __asm__ __volatile__("mrs %0, cpsr;cpsid i; and %0, %0,

#0x80":"=r"(x)::"memory"); \

extras/mini-os/drivers/gic.c new file +5 -0
+}
+
+#define local_irq_restore(x) {    \
+    __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory");    \
+}

If you mask the result in local_irq_save, and use this value directly is local_irq_restore, you will disable by mistake the Asynchronous Abort exception....

Quoted 5 lines
Quoted 1 line

You have to remove the and %0... at the end.

This makes schedule() fail, because it checks whether the result is zero. Perhaps we should continue to mask it, but only apply the IRQ bit in local_irq_restore?

I would prefer to change the schedule code if it's possible to keep local_irq_restore as simple as possible. This helper is often used.

I don't know much the code of schedule. Why don't we only check that the IRQ are disabled rather than call local_irq_{save,restore}?

Quoted 12 lines
Quoted 11 lines

extras/mini-os/drivers/gic.c

Quoted 7 lines
extras/mini-os/drivers/gic.c new file +7 -0
+#define local_irq_disable()    __cli()
+#define local_irq_enable() __sti()
+
+#if defined(__arm__)
+#define mb() __asm__("dmb");
+#define rmb() __asm__("dmb");
+#define wmb() __asm__("dmb");

I suspect you want to dsb here. You want to make sure that every memory access has finished avoid executing new instruction until this is done.

Quoted 4 lines

Is this necessary? As I understand it, using Xen's ring system requires a strict ordering (dmb), but we don't need to stall the processor waiting for each write to complete before going on to the next one.

Is it written somewhere? FIY, Linux is using dsb with ring system. Even tho, I think dmb is fine here. I'd like confirmation for either Ian C. or Stefano.

Futhermore, there is other place in mini-os (such as the GIC) where I think we have to use dsb.

Quoted 7 lines
Quoted 5 lines

extras/mini-os/drivers/gic.c

Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2 -0
+#define unlikely(x)  __builtin_expect((x),0)
+#define likely(x)  __builtin_expect((x),1)

Can't it be common with x86?

Which header file should it go in?

I don't know much mini-os, but I would add either in lib.h or create a new header compiler.h.

Quoted 20 lines
Quoted 11 lines

[..]

Quoted 8 lines
extras/mini-os/drivers/gic.c new file +1 -0
+#if defined(__i386__) || defined(__arm__)
 typedef long long           quad_t;
 typedef unsigned long long  u_quad_t;
@@ -40,7 +40,7 @@ typedef unsigned long       u_quad_t;
 typedef struct { unsigned long pte; } pte_t;
 #endif /* __i386__ || __x86_64__ */
 
Quoted 8 lines

extras/mini-os/drivers/gic.c typedef unsigned long u_quad_t; · line 44

Quoted 3 lines
extras/mini-os/drivers/gic.c new file +1 -1
-#ifdef __x86_64__
+#if defined(__x86_64__) || defined(__aarch64__)
 #define __pte(x) ((pte_t) { (x) } )

This looks wrong to me. The pte layout is exactly the same on arm32 and arm64. Hence, this is only used in the x86 code. Please either move pte_t in x86 part or define it correctly on ARM...

Quoted 2 lines

Moved to x86. Actually, this simplifies things further, because it can go in the separate hypercall-*.h files and lose the #ifdef completely.

Great, thanks!

Regards,

Signature · 1 line
Julien Grall
#20 lore raw
Quoted 10 lines · Julien Grall, le Mon 23 Jun 2014 17:55:05 +0100, a écrit :
Quoted 7 lines
Quoted 5 lines

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

Quoted 2 lines
extras/mini-os/include/arm/os.h new file +2 -0
+#define unlikely(x)  __builtin_expect((x),0)
+#define likely(x)  __builtin_expect((x),1)

Can't it be common with x86?

Which header file should it go in?

I don't know much mini-os, but I would add either in lib.h or create a new header compiler.h.

A new compiler.h makes sense to me.

Samuel

#21 lore raw

PATCH v4 8/12 mini-os: arm: show registers, stack and exception vector on fault

In reply to Thomas Leonard
---
 extras/mini-os/ARM-TODO.txt          |  1 -
 extras/mini-os/arch/arm/arm32.S      | 81 ++++++++++++++++++++++++++---
 extras/mini-os/arch/arm/panic.c      | 99 ++++++++++++++++++++++++++++++++++++
 extras/mini-os/include/arm/arch_mm.h |  2 +-
 extras/mini-os/include/arm/os.h      |  2 +-
 5 files changed, 175 insertions(+), 10 deletions(-)
 create mode 100644 extras/mini-os/arch/arm/panic.c
extras/mini-os/ARM-TODO.txt +0 -1
index 3d9be10..8f4f1da 100644
@@ -1,4 +1,3 @@
-* support abort exception handling ( and others )
 * scheduling!
 * gic request_irq implementation, currently all IRQs all hardcoded in gic irq handler.
 * use device tree instead of the currently hardcoded values
extras/mini-os/arch/arm/arm32.S +74 -7

103 lines not on this page · raw message

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

99 lines not on this page · raw message

extras/mini-os/include/arm/arch_mm.h +1 -1
index be14ada..e943a9b 100644
@@ -2,7 +2,7 @@
 #define _ARCH_MM_H_
 
 extern char _text, _etext, _erodata, _edata, _end, __bss_start;
-extern char stack[];
+extern int stack[];
 
 #define PAGE_SHIFT        12
 #define PAGE_SIZE        (1 << PAGE_SHIFT)
extras/mini-os/include/arm/os.h +1 -1
index 21e9276..8d76089 100644
@@ -10,7 +10,7 @@
 void arch_fini(void);
 void timer_handler(evtchn_port_t port, struct pt_regs *regs, void *ign);
 
-#define BUG() while(1){}
+#define BUG() while(1){asm volatile (".word 0xe7f000f0\n");} /* Undefined instruction; will call our fault handler. */
 
 #define smp_processor_id() 0
 
Signature · 7 lines
2.0.0


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

PATCH v4 9/12 mini-os: import libfdt

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

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

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

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

60 lines not on this page · raw message

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

1,478 lines not on this page · raw message

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

222 lines not on this page · raw message

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

84 lines not on this page · raw message

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

574 lines not on this page · raw message

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

476 lines not on this page · raw message

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

96 lines not on this page · raw message

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

256 lines not on this page · raw message

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

118 lines not on this page · raw message

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

95 lines not on this page · raw message

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

45 lines not on this page · raw message

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

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

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

Signature · 1 line
2.0.0

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

#23 lore raw

Re: [PATCH ARM v4 09/12] mini-os: import libfdt

Quoted 5 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:23 +0100, a écrit :

From: Karim Raslan <[email protected]>

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

Quoted 8 lines

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

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

Another case of "integration looks fine to me, I haven't reviewed the additional feature".

Samuel

#24 lore raw

PATCH v4 10/12 mini-os: get RAM base and size from the FDT

In reply to Thomas Leonard
---
 extras/mini-os/arch/arm/mm.c    | 70 ++++++++++++++++++++++++++++++++++++++---
 extras/mini-os/arch/arm/setup.c | 12 ++++++-
 extras/mini-os/include/arm/os.h |  2 ++
 extras/mini-os/mm.c             |  4 +--
 4 files changed, 80 insertions(+), 8 deletions(-)
extras/mini-os/arch/arm/mm.c +65 -5
index bb6aa0e..be8e747 100644
@@ -1,5 +1,7 @@
 #include <console.h>
 #include <arch_mm.h>
+#include <libfdt.h>
+#include <lib.h>
 
 #define PHYS_START (0x80008000 + (1000 * 4 * 1024))
 #define PHYS_SIZE (40*1024*1024)
@@ -25,12 +27,70 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
     printk("    stack start: %p(VA)\n", stack);
     printk("    _end: %p(VA)\n", &_end);
 
-    // FIXME Get from dt!
-    *start_pfn_p = (((unsigned long)&_end) >> PAGE_SHIFT) + 1000;
-    *max_pfn_p = ((unsigned long)&_end + PHYS_SIZE) >> PAGE_SHIFT;
+    *start_pfn_p = 0;
+    *max_pfn_p = 0;
 
-    printk("    start_pfn: %lx\n", *start_pfn_p);
-    printk("    max_pfn: %lx\n", *max_pfn_p);
+    if (fdt_num_mem_rsv(device_tree) != 0)
+        printk("WARNING: reserved memory not supported!\n");
+
+    int node = 0;
+    int depth = 0;
+    for (;;)
+    {
+        node = fdt_next_node(device_tree, node, &depth);
+        if (node <= 0 || depth < 0)
+            break;
+        /*
+           int name_len = 0;
+           const char *name = fdt_get_name(device_tree, node, &name_len);
+           printk("Found node: %d (%.*s)\n", node, name_len, name);
+         */
+
+        const char *device_type = fdt_getprop(device_tree, node, "device_type", NULL);
+        if (device_type && !strcmp(device_type, "memory"))
+        {
+            /* Note: we assume there's only a single region of memory.
+             * Since Xen is already translating our "physical"
+             * addresses to the real physical RAM, there's no
+             * reason for it to give us multiple blocks. */
+            int len = 0;
+            const uint64_t *regs = fdt_getprop(device_tree, node, "reg", &len);
+            if (regs == NULL || len != 16) {
+                printk("Bad 'reg' property: %p %d\n", regs, len);
+                continue;
+            }
+            unsigned int start = (unsigned int) &_text;
+            unsigned int end = (unsigned int) &_end;
+            unsigned int mem_base = fdt64_to_cpu(regs[0]);
+            unsigned int mem_size = fdt64_to_cpu(regs[1]);
+            printk("Found memory at %p (len 0x%x)\n", mem_base, mem_size);
+
+            BUG_ON(mem_base > start);          /* Our image isn't in our RAM! */
+            *start_pfn_p = PFN_UP(end);
+            int heap_len = mem_size - ((*start_pfn_p << PAGE_SHIFT) - mem_base);
+            *max_pfn_p = *start_pfn_p + PFN_DOWN(heap_len);
+
+            printk("Using pages %d to %d as free space for heap.\n", *start_pfn_p, *max_pfn_p);
+            break;
+        }
+    }
+
+    if (*max_pfn_p == 0)
+    {
+        printk("No memory found in FDT!\n");
+        BUG();
+    }
+
+    /* The device tree is probably in memory that we're about to hand over to the page
+     * allocator, so move it to the end and reserve that space.
+     */
+    int fdt_size = fdt_totalsize(device_tree);
+    void *new_device_tree = (void *) (((*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 = ((unsigned long) new_device_tree) >> PAGE_SHIFT;
 
     build_pagetable(start_pfn_p, max_pfn_p);
 }
extras/mini-os/arch/arm/setup.c +11 -1
index 3499b37..e59665e 100644
@@ -4,6 +4,7 @@
 #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,
@@ -20,6 +21,8 @@ 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;
@@ -72,7 +75,14 @@ void arch_init(void *dtb_pointer)
 
     memset(&__bss_start, 0, &_end - &__bss_start);
 
-    printk("dtb_pointer : %x\n", dtb_pointer);
+    printk("Checking DTB at %x...\n", dtb_pointer);
+
+    int r;
+    if ((r = fdt_check_header(dtb_pointer))) {
+        printk("Invalid DTB from Xen: %s\n", fdt_strerror(r));
+        BUG();
+    }
+    device_tree = dtb_pointer;
 
     /* Map shared_info page */
     xatp.domid = DOMID_SELF;
extras/mini-os/include/arm/os.h +2 -0
index 8d76089..2f423c0 100644
@@ -10,6 +10,8 @@
 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
extras/mini-os/mm.c +2 -2
index d2d5264..d31ef97 100644
@@ -409,8 +409,8 @@ void init_mm(void)
      * now we can initialise the page allocator
      */
     printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
-           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
-           (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
+           (u_long)to_virt(PFN_PHYS(start_pfn)), (u_long)PFN_PHYS(start_pfn), 
+           (u_long)to_virt(PFN_PHYS(max_pfn)), (u_long)PFN_PHYS(max_pfn));
     init_page_allocator(PFN_PHYS(start_pfn), PFN_PHYS(max_pfn));
     printk("MM: done\n");
 
Signature · 1 line
2.0.0
#25 lore raw

Re: [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT

Hi Thomas,

extras/mini-os/arch/arm/mm.c void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) · line 55

Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7 -0
+        const char *device_type = fdt_getprop(device_tree, node, "device_type", NULL);
+        if (device_type && !strcmp(device_type, "memory"))
+        {
+            /* Note: we assume there's only a single region of memory.
+             * Since Xen is already translating our "physical"
+             * addresses to the real physical RAM, there's no
+             * reason for it to give us multiple blocks. */

This comment looks wrong to me. Even tho, Xen is providing a stage-2 translation to show you a virtual layout (your guest physical memory), the new layout in Xen upstream may contain multiple banks. The first bank will contain up to 3G of RAM.

extras/mini-os/mm.c void init_mm(void) · line 413

Quoted 11 lines

index d2d5264..d31ef97 100644

extras/mini-os/mm.c +2 -2
@@ -409,8 +409,8 @@ void init_mm(void)
      * now we can initialise the page allocator
      */
     printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
-           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn), 
-           (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
+           (u_long)to_virt(PFN_PHYS(start_pfn)), (u_long)PFN_PHYS(start_pfn), 
+           (u_long)to_virt(PFN_PHYS(max_pfn)), (u_long)PFN_PHYS(max_pfn));

I don't see any modification of the type of max_pfn, start_pfn, PFN_PHYS. This change should not be part of this patch.

Regards,

Signature · 1 line
Julien Grall
#26 lore raw

Re: [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT

Quoted 11 lines · Julien Grall

Hi Thomas,

extras/mini-os/arch/arm/mm.c void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) · line 55

Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7 -0
+        const char *device_type = fdt_getprop(device_tree, node, "device_type", NULL);
+        if (device_type && !strcmp(device_type, "memory"))
+        {
+            /* Note: we assume there's only a single region of memory.
+             * Since Xen is already translating our "physical"
+             * addresses to the real physical RAM, there's no
+             * reason for it to give us multiple blocks. */
Quoted 4 lines

This comment looks wrong to me. Even tho, Xen is providing a stage-2 translation to show you a virtual layout (your guest physical memory), the new layout in Xen upstream may contain multiple banks. The first bank will contain up to 3G of RAM.

Hi Julien,

At the Hackathon, we decided Mini-OS could always rely on Xen to provide the memory in a single block:

"ARM guests are allowed to assume one bank of memory. We need to document this in the ABI. ARM guests should assume the presence of an FDT."

http://lists.xenproject.org/archives/html/mirageos-devel/2014-06/msg00004.html

A lot of the value of running on Xen is that we only have to support a small number of configurations, because Xen hides the details of the physical hardware. I assume the only reason for using the (very flexible) FDT format to provide this information is that it's simpler for full OSs which already use FDTs.

Is the ARM guest ABI documented somewhere?

Quoted 14 lines

extras/mini-os/mm.c void init_mm(void) · line 413

Quoted 11 lines

index d2d5264..d31ef97 100644

extras/mini-os/mm.c +2 -2
@@ -409,8 +409,8 @@ void init_mm(void)
      * now we can initialise the page allocator
      */
     printk("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n",
-           (u_long)to_virt(PFN_PHYS(start_pfn)), PFN_PHYS(start_pfn),
-           (u_long)to_virt(PFN_PHYS(max_pfn)), PFN_PHYS(max_pfn));
+           (u_long)to_virt(PFN_PHYS(start_pfn)), (u_long)PFN_PHYS(start_pfn),
+           (u_long)to_virt(PFN_PHYS(max_pfn)), (u_long)PFN_PHYS(max_pfn));

I don't see any modification of the type of max_pfn, start_pfn, PFN_PHYS. This change should not be part of this patch.

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

Re: [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT

Quoted 12 lines · Thomas Leonard
Quoted 11 lines · Julien Grall

Hi Thomas,

Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7 -0
+        const char *device_type = fdt_getprop(device_tree, node, "device_type", NULL);
+        if (device_type && !strcmp(device_type, "memory"))
+        {
+            /* Note: we assume there's only a single region of memory.
+             * Since Xen is already translating our "physical"
+             * addresses to the real physical RAM, there's no
+             * reason for it to give us multiple blocks. */
Quoted 6 lines
Quoted 4 lines

This comment looks wrong to me. Even tho, Xen is providing a stage-2 translation to show you a virtual layout (your guest physical memory), the new layout in Xen upstream may contain multiple banks. The first bank will contain up to 3G of RAM.

Hi Julien,

Hello Thomas,

Quoted 6 lines

At the Hackathon, we decided Mini-OS could always rely on Xen to provide the memory in a single block:

"ARM guests are allowed to assume one bank of memory. We need to document this in the ABI. ARM guests should assume the presence of an FDT."

I'm not against only supporting one bank... I pointed that your comment is wrong and doesn't reflect this sentence.

I didn't attend to this meeting, but I guess it was meant that the guest can assume there is always one bank of memory.

I would change your comment into:

"Xen will always provide us at least one bank of memory. Mini-os will use the first bank for the time-being"

Quoted 7 lines

http://lists.xenproject.org/archives/html/mirageos-devel/2014-06/msg00004.html

A lot of the value of running on Xen is that we only have to support a small number of configurations, because Xen hides the details of the physical hardware. I assume the only reason for using the (very flexible) FDT format to provide this information is that it's simpler for full OSs which already use FDTs.

As specified in the ABI, the guest layout may change from time to time. Actually, the layout is not compatible between Xen 4.4 and 4.5.

Unless you want your OS tight to a Xen specific version, I don't think we want that for mini-os. You have to correctly support FDT and retrieve every information (MMIO, IRQ) from it.

Quoted 1 line

Is the ARM guest ABI documented somewhere?

You can find the guest layout described in xen/include/public/arch-arm.h

Regards

Signature · 1 line
Julien Grall
#28 lore raw

Re: [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT

Quoted 32 lines · Julien Grall
Quoted 12 lines · Thomas Leonard
Quoted 11 lines · Julien Grall

Hi Thomas,

Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7 -0
+        const char *device_type = fdt_getprop(device_tree, node, "device_type", NULL);
+        if (device_type && !strcmp(device_type, "memory"))
+        {
+            /* Note: we assume there's only a single region of memory.
+             * Since Xen is already translating our "physical"
+             * addresses to the real physical RAM, there's no
+             * reason for it to give us multiple blocks. */
Quoted 6 lines
Quoted 4 lines

This comment looks wrong to me. Even tho, Xen is providing a stage-2 translation to show you a virtual layout (your guest physical memory), the new layout in Xen upstream may contain multiple banks. The first bank will contain up to 3G of RAM.

Hi Julien,

Hello Thomas,

Quoted 6 lines

At the Hackathon, we decided Mini-OS could always rely on Xen to provide the memory in a single block:

"ARM guests are allowed to assume one bank of memory. We need to document this in the ABI. ARM guests should assume the presence of an FDT."

I'm not against only supporting one bank... I pointed that your comment is wrong and doesn't reflect this sentence.

Quoted 7 lines

I didn't attend to this meeting, but I guess it was meant that the guest can assume there is always one bank of memory.

I would change your comment into:

"Xen will always provide us at least one bank of memory. Mini-os will use the first bank for the time-being"

Yes. The ABI definitely doesn't say "at most one bank". We already have two in 4.5 for sufficiently large guests.

Quoted 11 lines
Quoted 7 lines

http://lists.xenproject.org/archives/html/mirageos-devel/2014-06/msg00004.html

A lot of the value of running on Xen is that we only have to support a small number of configurations, because Xen hides the details of the physical hardware. I assume the only reason for using the (very flexible) FDT format to provide this information is that it's simpler for full OSs which already use FDTs.

As specified in the ABI, the guest layout may change from time to time. Actually, the layout is not compatible between Xen 4.4 and 4.5.

Quoted 7 lines

Unless you want your OS tight to a Xen specific version, I don't think we want that for mini-os. You have to correctly support FDT and retrieve every information (MMIO, IRQ) from it.

Quoted 1 line

Is the ARM guest ABI documented somewhere?

You can find the guest layout described in xen/include/public/arch-arm.h

Note that this is for the benefit of the toolstack (matched to Xen) only. If you decide you want to use those values yourself then you are agreeing with yourself that you are happy to recompile in order to run on another version of Xen.

If you aren't happy with that then you should use the FDT which has been provided for this purpose.

Ian.

#29 lore raw

PATCH v4 11/12 mini-os: get GIC addresses from FDT

In reply to Thomas Leonard
---
 extras/mini-os/drivers/gic.c | 36 +++++++++++++++++++++++++++++++++---
 1 file changed, 33 insertions(+), 3 deletions(-)
extras/mini-os/drivers/gic.c +33 -3
index 3141830..8a9e427 100644
@@ -2,6 +2,7 @@
 
 #include <mini-os/os.h>
 #include <mini-os/hypervisor.h>
+#include <libfdt.h>
 
 //#define VGIC_DEBUG
 #ifdef VGIC_DEBUG
@@ -168,9 +169,38 @@ static void gic_handler(void) {
 }
 
 void gic_init(void) {
-    // FIXME Get from dt!
-    gic.gicd_base = (char *)0x2c001000ULL;
-    gic.gicc_base = (char *)0x2c002000ULL;
+    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;
+
+        /*
+           int name_len = 0;
+           const char *name = fdt_get_name(device_tree, node, &name_len);
+           printk("Found node: %d (%.*s)\n", node, name_len, name);
+         */
+
+        if (fdt_getprop(device_tree, node, "interrupt-controller", NULL)) {
+            int len = 0;
+            const uint64_t *reg = fdt_getprop(device_tree, node, "reg", &len);
+            if (reg == NULL || len != 32) {
+                printk("Bad 'reg' property: %p %d\n", reg, len);
+                continue;
+            }
+            gic.gicd_base = (char *) (long) fdt64_to_cpu(reg[0]);
+            gic.gicc_base = (char *) (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();
 
     IRQ_handler = gic_handler;
Signature · 1 line
2.0.0
#30 lore raw

Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT

Hi Thomas,

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172

Quoted 10 lines · Thomas Leonard

//#define VGIC_DEBUG
#ifdef VGIC_DEBUG

extras/mini-os/drivers/gic.c +1 -3
@@ -168,9 +169,38 @@ static void gic_handler(void) {
 }
 
 void gic_init(void) {
-    // FIXME Get from dt!
-    gic.gicd_base = (char *)0x2c001000ULL;
-    gic.gicc_base = (char *)0x2c002000ULL;
+    gic.gicd_base = NULL;

Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?

This would avoid to hardcode a GIC address which is completely wrong with Xen unstable.

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 185

Quoted 13 lines
extras/mini-os/drivers/gic.c +13 -0
+    int node = 0;
+    int depth = 0;
+    for (;;)
+    {
+        node = fdt_next_node(device_tree, node, &depth);
+        if (node <= 0 || depth < 0)
+            break;
+
+        /*
+           int name_len = 0;
+           const char *name = fdt_get_name(device_tree, node, &name_len);
+           printk("Found node: %d (%.*s)\n", node, name_len, name);
+         */

This should be drop.

Review static void gic_handler(void) { · line 187

Quoted 2 lines
(quoted diff) +2 -0
+
+        if (fdt_getprop(device_tree, node, "interrupt-controller", NULL)) {

You have to check the compatible string here.

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 190

Quoted 3 lines
extras/mini-os/drivers/gic.c +3 -0
+            int len = 0;
+            const uint64_t *reg = fdt_getprop(device_tree, node, "reg", &len);
+            if (reg == NULL || len != 32) {

You made assumption of the layout of the device tree provided by Xen:
- #address-cells == #size-cells == 2
- regs contains a valid physical address, i.e the device is not under a bus

This can be changed by the toolstack in the future and will likely break mini-os.

I would add a layer to support FDT address and interrupt translation correctly. I'm not the maintainer of the mini-os, so I let them decide :).

I think, FreeBSD provides a good library for the translation (see sys/dev/fdt/fdt_common.c).

I spent lots of time to play with device tree on Xen side, so I can help you if you needed.

Signature · 1 line
Julien Grall
#31 lore raw

Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT

Quoted 8 lines · Julien Grall

Hi Thomas,

Quoted 5 lines · Thomas Leonard

//#define VGIC_DEBUG
#ifdef VGIC_DEBUG

(quoted diff) +0 -0
@@ -168,9 +169,38 @@ static void gic_handler(void) {
 }
 
Quoted 8 lines

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172

Quoted 5 lines
extras/mini-os/drivers/gic.c +1 -3
 void gic_init(void) {
-    // FIXME Get from dt!
-    gic.gicd_base = (char *)0x2c001000ULL;
-    gic.gicc_base = (char *)0x2c002000ULL;
+    gic.gicd_base = NULL;

Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?

It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.

Moving all the GIC code to this patch would mean that the original patch wouldn't work on its own.

Quoted 28 lines

This would avoid to hardcode a GIC address which is completely wrong with Xen unstable.

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 185

Quoted 13 lines
extras/mini-os/drivers/gic.c +13 -0
+    int node = 0;
+    int depth = 0;
+    for (;;)
+    {
+        node = fdt_next_node(device_tree, node, &depth);
+        if (node <= 0 || depth < 0)
+            break;
+
+        /*
+           int name_len = 0;
+           const char *name = fdt_get_name(device_tree, node, &name_len);
+           printk("Found node: %d (%.*s)\n", node, name_len, name);
+         */

This should be drop.

Review static void gic_handler(void) { · line 187

Quoted 2 lines
(quoted diff) +2 -0
+
+        if (fdt_getprop(device_tree, node, "interrupt-controller", NULL)) {

You have to check the compatible string here.

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 190

Quoted 3 lines
extras/mini-os/drivers/gic.c +3 -0
+            int len = 0;
+            const uint64_t *reg = fdt_getprop(device_tree, node, "reg", &len);
+            if (reg == NULL || len != 32) {
Quoted 6 lines

You made assumption of the layout of the device tree provided by Xen:
- #address-cells == #size-cells == 2
- regs contains a valid physical address, i.e the device is not under a bus

This can be changed by the toolstack in the future and will likely break mini-os.

Is that likely? Seems like using BUG here is the right thing to do until that happens.

Quoted 8 lines

I would add a layer to support FDT address and interrupt translation correctly. I'm not the maintainer of the mini-os, so I let them decide :).

I think, FreeBSD provides a good library for the translation (see sys/dev/fdt/fdt_common.c).

I spent lots of time to play with device tree on Xen side, so I can help you if you needed.

That would be very helpful - thanks!

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

Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT

Hi Thomas,

Quoted 18 lines · Thomas Leonard
Quoted 8 lines · Julien Grall

Hi Thomas,

Quoted 5 lines · Thomas Leonard

//#define VGIC_DEBUG
#ifdef VGIC_DEBUG

(quoted diff) +0 -0
@@ -168,9 +169,38 @@ static void gic_handler(void) {
 }
 
Quoted 8 lines

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172

Quoted 5 lines
extras/mini-os/drivers/gic.c +1 -3
 void gic_init(void) {
-    // FIXME Get from dt!
-    gic.gicd_base = (char *)0x2c001000ULL;
-    gic.gicc_base = (char *)0x2c002000ULL;
+    gic.gicd_base = NULL;

Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?

Quoted 3 lines

It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.

Please make sure that this "standalone patch" works correctly on Xen unstable...

Quoted 2 lines

Moving all the GIC code to this patch would mean that the original patch wouldn't work on its own.

I'm not sure why you want to have a single big patch to support ARM... AFAIU, there is some patch requirements to work correctly.

Quoted 9 lines
Quoted 6 lines

You made assumption of the layout of the device tree provided by Xen:
- #address-cells == #size-cells == 2
- regs contains a valid physical address, i.e the device is not under a bus

This can be changed by the toolstack in the future and will likely break mini-os.

Is that likely? Seems like using BUG here is the right thing to do until that happens.

You need at least to add a comment about the (len != 32). It's confusing for people that doesn't know how the device tree has been created.

I still think that a layer for IRQ and MMIO translation would be helpful for mini-os. So you will directly get the range (base + size), and won't duplicate checking code on every part of mini-os.

Quoted 1 line

That would be very helpful - thanks!

You can join #xenarm for any question if you are not already there.

Regards,

Signature · 1 line
Julien Grall
#33 lore raw

Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT

Quoted 21 lines · Julien Grall

Hi Thomas,

Quoted 18 lines · Thomas Leonard
Quoted 16 lines · Julien Grall

Hi Thomas,

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172

Quoted 10 lines · Thomas Leonard

//#define VGIC_DEBUG
#ifdef VGIC_DEBUG

extras/mini-os/drivers/gic.c +1 -3
@@ -168,9 +169,38 @@ static void gic_handler(void) {
 }
 
 void gic_init(void) {
-    // FIXME Get from dt!
-    gic.gicd_base = (char *)0x2c001000ULL;
-    gic.gicc_base = (char *)0x2c002000ULL;
+    gic.gicd_base = NULL;

Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?

Quoted 6 lines
Quoted 3 lines

It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.

Please make sure that this "standalone patch" works correctly on Xen unstable...

OK, I can make it use GUEST_GICD_BASE/GUEST_GICC_BASE (with a FIXME) so that the first commit works on unstable.

I tried installing the unstable version (staging branch) of Xen to test it, but for some reason it didn't work:

# LD_LIBRARY_PATH=/opt/xen-4.5-unstable/lib/ /opt/xen-4.5-unstable/sbin/xl dmesg
xc: error: Could not obtain handle on privileged command interface (2 = No such file or directory): Internal error
libxl: error: libxl.c:99:libxl_ctx_alloc: cannot open libxc handle: No such file or directory
cannot init xl context

It tries to open "/proc/xen/privcmd", which doesn't exist. Maybe I need a newer Linux kernel? That could be tricky, as I'm using a special fork for this board.

Quoted 5 lines
Quoted 2 lines

Moving all the GIC code to this patch would mean that the original patch wouldn't work on its own.

I'm not sure why you want to have a single big patch to support ARM... AFAIU, there is some patch requirements to work correctly.

If it isn't necessary that the first commit works, then I can split things up further (e.g. all the include files first, then just arm32.S, etc), but I'm not sure how much that would help. Let me know what's easiest for reviewing.

Quoted 25 lines
Quoted 9 lines
Quoted 6 lines

You made assumption of the layout of the device tree provided by Xen:
- #address-cells == #size-cells == 2
- regs contains a valid physical address, i.e the device is not under a bus

This can be changed by the toolstack in the future and will likely break mini-os.

Is that likely? Seems like using BUG here is the right thing to do until that happens.

You need at least to add a comment about the (len != 32). It's confusing for people that doesn't know how the device tree has been created.

I still think that a layer for IRQ and MMIO translation would be helpful for mini-os. So you will directly get the range (base + size), and won't duplicate checking code on every part of mini-os.

Quoted 1 line

That would be very helpful - thanks!

You can join #xenarm for any question if you are not already there.

Regards,

--
Julien Grall

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

Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT

Quoted 24 lines · Thomas Leonard
Quoted 23 lines · Julien Grall
Quoted 21 lines · Thomas Leonard
Quoted 8 lines · Julien Grall

Hi Thomas,

Quoted 5 lines · Thomas Leonard

//#define VGIC_DEBUG
#ifdef VGIC_DEBUG

(quoted diff) +0 -0
@@ -168,9 +169,38 @@ static void gic_handler(void) {
 }
 
Quoted 8 lines

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172

Quoted 5 lines
extras/mini-os/drivers/gic.c +1 -3
 void gic_init(void) {
-    // FIXME Get from dt!
-    gic.gicd_base = (char *)0x2c001000ULL;
-    gic.gicc_base = (char *)0x2c002000ULL;
+    gic.gicd_base = NULL;

Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?

It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.

Quoted 5 lines
Quoted 2 lines

Please make sure that this "standalone patch" works correctly on Xen unstable...

OK, I can make it use GUEST_GICD_BASE/GUEST_GICC_BASE (with a FIXME) so that the first commit works on unstable.

This 2 defines are only exposed to XEN and XEN tools. I don't think you will be able to use it for mini-os.

Quoted 10 lines

I tried installing the unstable version (staging branch) of Xen to test it, but for some reason it didn't work:

# LD_LIBRARY_PATH=/opt/xen-4.5-unstable/lib/ /opt/xen-4.5-unstable/sbin/xl dmesg
xc: error: Could not obtain handle on privileged command interface (2 = No such file or directory): Internal error
libxl: error: libxl.c:99:libxl_ctx_alloc: cannot open libxc handle: No such file or directory
cannot init xl context

Quoted 3 lines

It tries to open "/proc/xen/privcmd", which doesn't exist. Maybe I need a newer Linux kernel? That could be tricky, as I'm using a special fork for this board.

Did you start xencommons?

/etc/init.d/xencommons start

Regards,

Signature · 1 line
Julien Grall
#35 lore raw

Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT

In reply to Thomas Leonard
Quoted 18 lines · Thomas Leonard
Quoted 8 lines · Julien Grall

Hi Thomas,

Quoted 5 lines · Thomas Leonard

//#define VGIC_DEBUG
#ifdef VGIC_DEBUG

(quoted diff) +0 -0
@@ -168,9 +169,38 @@ static void gic_handler(void) {
 }
 
Quoted 8 lines

extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172

Quoted 5 lines
extras/mini-os/drivers/gic.c +1 -3
 void gic_init(void) {
-    // FIXME Get from dt!
-    gic.gicd_base = (char *)0x2c001000ULL;
-    gic.gicc_base = (char *)0x2c002000ULL;
+    gic.gicd_base = NULL;

Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?

Quoted 6 lines

It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.

Moving all the GIC code to this patch would mean that the original patch wouldn't work on its own.

Is it not possible to put the fdt stuff before patch #7 so it is already present?

That said:

For things such as a new minios port we are more accepting of "bisection hazards" so long as they are all before some strict cut-off point, i.e. the point at which the build is actually wired up to make the series do anything.

IOW so long as this stuff isn't actually being built until patch #12 then you can play a bit fast a loose with the "it must always build" rule.

Ian.

#36 lore raw

PATCH v4 12/12 mini-os: added ARM grant table initialisation

In reply to Thomas Leonard

On x86, we get told which pages to use, but on ARM we get the base address in the FDT and have to map each page.

---
 extras/mini-os/ARM-TODO.txt     |  1 -
 extras/mini-os/arch/arm/mm.c    | 58 +++++++++++++++++++++++++++++++++++++++++
 extras/mini-os/arch/x86/mm.c    | 13 +++++++++
 extras/mini-os/gnttab.c         | 11 ++------
 extras/mini-os/include/gnttab.h |  1 +
 5 files changed, 74 insertions(+), 10 deletions(-)
extras/mini-os/ARM-TODO.txt +0 -1
index 8f4f1da..e30760a 100644
@@ -1,6 +1,5 @@
 * scheduling!
 * gic request_irq implementation, currently all IRQs all hardcoded in gic irq handler.
-* use device tree instead of the currently hardcoded values
 * Add virtual memory support and make vstart = 0 ( use 4k descriptors instead of 1M descriptors )
 * sched
 * fini_gnttab
extras/mini-os/arch/arm/mm.c +58 -0

66 lines not on this page · raw message

extras/mini-os/arch/x86/mm.c +13 -0
index 35df15b..9c6d1b8 100644
@@ -942,3 +942,16 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)
     *start_pfn_p = start_pfn;
     *max_pfn_p = max_pfn;
 }
+
+grant_entry_t *arch_init_gnttab(int nr_grant_frames)
+{
+    struct gnttab_setup_table setup;
+    unsigned long frames[nr_grant_frames];
+
+    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);
+    return map_frames(frames, nr_grant_frames);
+}
extras/mini-os/gnttab.c +2 -9
index 2f1b3d7..f395d12 100644
@@ -164,7 +164,7 @@ gnttabop_error(int16_t status)
 {
     status = -status;
     if (status < 0 || status >= ARRAY_SIZE(gnttabop_error_msgs))
-	return "bad status";
+        return "bad status";
     else
         return gnttabop_error_msgs[status];
 }
@@ -172,8 +172,6 @@ gnttabop_error(int16_t status)
 void
 init_gnttab(void)
 {
-    struct gnttab_setup_table setup;
-    unsigned long frames[NR_GRANT_FRAMES];
     int i;
 
 #ifdef GNT_DEBUG
@@ -182,12 +180,7 @@ init_gnttab(void)
     for (i = NR_RESERVED_ENTRIES; i < NR_GRANT_ENTRIES; i++)
         put_free_entry(i);
 
-    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);
-    gnttab_table = map_frames(frames, NR_GRANT_FRAMES);
+    gnttab_table = arch_init_gnttab(NR_GRANT_FRAMES);
     printk("gnttab_table mapped at %p.\n", gnttab_table);
 }
 
extras/mini-os/include/gnttab.h +1 -0
index acd6c39..c43ad42 100644
@@ -12,5 +12,6 @@ unsigned long gnttab_end_transfer(grant_ref_t gref);
 int gnttab_end_access(grant_ref_t ref);
 const char *gnttabop_error(int16_t status);
 void fini_gnttab(void);
+grant_entry_t *arch_init_gnttab(int nr_grant_frames);
 
 #endif /* !__GNTTAB_H__ */
Signature · 1 line
2.0.0
#37 lore raw

Re: [PATCH ARM v4 12/12] mini-os: added ARM grant table initialisation

Hi Thomas,

extras/mini-os/arch/arm/mm.c void arch_init_p2m(unsigned long max_pfn) · line 113

Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7 -0
+
+/* Get Xen's sugggested physical page assignments for the grant table. */
+static grant_entry_t *get_gnttab_base(void)
+{
+    int hypervisor;
+
+    hypervisor = fdt_path_offset(device_tree, "/hypervisor");

Same comment as on patch #11, you need to search the hypervisor node via the compatible string.

extras/mini-os/gnttab.c gnttabop_error(int16_t status) · line 167

Quoted 9 lines

index 2f1b3d7..f395d12 100644

extras/mini-os/gnttab.c +1 -1
@@ -164,7 +164,7 @@ gnttabop_error(int16_t status)
 {
     status = -status;
     if (status < 0 || status >= ARRAY_SIZE(gnttabop_error_msgs))
-	return "bad status";
+        return "bad status";

Spurious change?

Regards,

Signature · 1 line
Julien Grall
#38 lore raw

Re: [PATCH ARM v4 12/12] mini-os: added ARM grant table initialisation

Quoted 13 lines · Julien Grall

Hi Thomas,

extras/mini-os/arch/arm/mm.c void arch_init_p2m(unsigned long max_pfn) · line 113

Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7 -0
+
+/* Get Xen's sugggested physical page assignments for the grant table. */
+static grant_entry_t *get_gnttab_base(void)
+{
+    int hypervisor;
+
+    hypervisor = fdt_path_offset(device_tree, "/hypervisor");

Same comment as on patch #11, you need to search the hypervisor node via the compatible string.

It's not clear to me what I should do with this attribute. On Xen/unstable, it contains the single value "xen,xen-4.5", meaning (I think) that Xen 4.5 is incompatible with Xen 4.4. But I'd still like Mini-OS to run. Presumably, 4.6 will be incompatible too. What could I do if the value doesn't match except try to use it anyway?

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

Re: [PATCH ARM v4 12/12] mini-os: added ARM grant table initialisation

Quoted 6 lines · Thomas Leonard
Quoted 5 lines · Julien Grall

Hi Thomas,

extras/mini-os/arch/arm/mm.c void arch_init_p2m(unsigned long max_pfn) · line 108

Quoted 2 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +2 -0
+
+/* Get Xen's sugggested physical page assignments for the grant table. */

Too many g's.

Quoted 11 lines
Quoted 8 lines

extras/mini-os/arch/arm/mm.c void arch_init_p2m(unsigned long max_pfn) · line 113

Quoted 5 lines
extras/mini-os/arch/arm/mm.c +5 -0
+static grant_entry_t *get_gnttab_base(void)
+{
+    int hypervisor;
+
+    hypervisor = fdt_path_offset(device_tree, "/hypervisor");

Same comment as on patch #11, you need to search the hypervisor node via the compatible string.

It's not clear to me what I should do with this attribute. On Xen/unstable, it contains the single value "xen,xen-4.5",

It should contain "xen,xen-X.Y\0xen,xen\0\0", i.e. multiple strings. If you don't care about the specific version then you should check for "xen,xen" somewhere in the list.

(This is how device tree compatibile strings work, more specific to more general).

Quoted 6 lines

meaning (I
think) that Xen 4.5 is incompatible with Xen 4.4. But I'd still like Mini-OS to run. Presumably, 4.6 will be incompatible too. What could I do if the value doesn't match except try to use it anyway?

#40 lore raw

Re: [PATCH ARM v4 12/12] mini-os: added ARM grant table initialisation

In reply to Thomas Leonard
Quoted 4 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:26 +0100, a écrit :

On x86, we get told which pages to use, but on ARM we get the base address in the FDT and have to map each page.

Integration is OK to me, I don't know about FDT :)

Samuel