Skip to contentSkip to conversation

mini-os: initial ARM support

PATCH Superseded Thomas Leonard 3 participants 25 messages Jun 11, 2014 – Jun 18, 2014

v3 of 8 Superseded Latest is v8 →

lore
Share & tools
lore
#0 lore raw

v3 cover mini-os: initial ARM support

This series is based on Karim's ARM support commits, further broken up into smaller patches. Unlike the previous series, this set includes the actual ARM support.

I removed some patches where there were queries last time and no clear answer for why a change was included.

I squashed in a large number of patches from my own later work, to avoid people reviewing code that is known to be buggy and to ensure that people should be able to test the patches as they are.

I removed the libfdt code from this series. I'll include it in a future set, where it is actually used.

I also removed the division support code (previously copied in from FreeBSD). Linking in libgcc.a seems to provide the missing functions.

Another change here is that instead of removing start_info (as Karim's original changes had started to do), I now create one at start-up and populate it with the console and xenstore details. This greatly reduces the changes needed elsewhere in the code, including in programs using Mini-OS (e.g. Mirage), making the ARM and x86 interfaces more similar.

Future patches will add FDT support, grant table initialisation and networking support, so don't worry about those things being missing.

This patch roll is also available here:

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

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

Karim Raslan (4):
mini-os: tidied up code
mini-os: moved events code under arch
mini-os: switched initial C entry point to arch_init
mini-os: initial ARM support

Thomas Leonard (3):
mini-os: build fixes
mini-os: fixed shutdown thread
mini-os: don't include queue.h if there's no libc

 extras/mini-os/ARM-TODO.txt                  |  17 ++
 extras/mini-os/Config.mk                     |   2 +
 extras/mini-os/Makefile                      |  34 +++-
 extras/mini-os/README                        |   4 +-
 extras/mini-os/arch/arm/Makefile             |  32 +++
 extras/mini-os/arch/arm/arch.mk              |   6 +
 extras/mini-os/arch/arm/arm32.S              | 149 ++++++++++++++
 extras/mini-os/arch/arm/events.c             |  24 +++
 extras/mini-os/arch/arm/hypercalls32.S       |  88 ++++++++
 extras/mini-os/arch/arm/minios-arm32.lds     |  73 +++++++
 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             |  31 +++
 extras/mini-os/arch/x86/setup.c              |  44 +++-
 extras/mini-os/arch/x86/time.c               |   2 +-
 extras/mini-os/arch/x86/x86_32.S             |   2 +-
 extras/mini-os/arch/x86/x86_64.S             |   2 +-
 extras/mini-os/console/console.c             |   2 +-
 extras/mini-os/drivers/gic.c                 | 180 ++++++++++++++++
 extras/mini-os/events.c                      |  31 +--
 extras/mini-os/gntmap.c                      |  35 ++--
 extras/mini-os/hypervisor.c                  |  10 +
 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/hypercall-arm32.h | 173 ++++++++++++++++
 extras/mini-os/include/arm/os.h              | 294 +++++++++++++++++++++++++++
 extras/mini-os/include/arm/traps.h           |  20 ++
 extras/mini-os/include/events.h              |   3 +
 extras/mini-os/include/gic.h                 |   1 +
 extras/mini-os/include/hypervisor.h          |   4 +
 extras/mini-os/include/kernel.h              |   6 +-
 extras/mini-os/include/lib.h                 |   2 +-
 extras/mini-os/include/mm.h                  |   2 +
 extras/mini-os/include/types.h               |  12 +-
 extras/mini-os/include/x86/arch_spinlock.h   |   2 +-
 extras/mini-os/include/x86/os.h              |   2 -
 extras/mini-os/kernel.c                      |  56 ++---
 extras/mini-os/main.c                        |   2 +-
 extras/mini-os/sched.c                       |   6 +
 extras/mini-os/xenbus/xenbus.c               |   2 +-
 44 files changed, 1745 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/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/arch/x86/events.c
 create mode 100644 extras/mini-os/drivers/gic.c
 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/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
Signature · 1 line
2.0.0
#1 lore raw

PATCH v3 1/7 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.

---
 extras/mini-os/Makefile | 20 +++++++++++++-------
 1 file changed, 13 insertions(+), 7 deletions(-)
extras/mini-os/Makefile +13 -7
index 50d038b..5af40ad 100644
@@ -50,6 +50,10 @@ flags-$(CONFIG_XENBUS) += -DCONFIG_XENBUS
 
 DEF_CFLAGS += $(flags-y)
 
+LINKS = include/list.h $(ARCH_LINKS) include/mini-os include/xen include/$(TARGET_ARCH_FAM)/mini-os
+
+EXTRA_DEPS += $(LINKS) include/list.h
+
 # Include common mini-os makerules.
 include minios.mk
 
@@ -124,11 +128,14 @@ 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],$@)
 
-.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
+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 +181,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 +219,3 @@ tags:
 .PHONY: TAGS
 TAGS:
 	$(all_sources) | xargs etags
-
Signature · 1 line
2.0.0
#2 lore raw

Re: [PATCH ARM v3 1/7] mini-os: build fixes

Quoted 8 lines · Thomas Leonard, le Wed 11 Jun 2014 11:30:12 +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.

This makes sense, just one thing:

extras/mini-os/Makefile flags-$(CONFIG_XENBUS) += -DCONFIG_XENBUS · line 56

Quoted 4 lines
extras/mini-os/Makefile +4 -0
+LINKS = include/list.h $(ARCH_LINKS) include/mini-os include/xen include/$(TARGET_ARCH_FAM)/mini-os
+
+EXTRA_DEPS += $(LINKS) include/list.h
+

include/list.h thus appears twice in EXTRA_DEPS. I guess there is no need for an intermediate LINKS variable.

Samuel

#3 lore raw

PATCH v3 2/7 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.

---
 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..27e3c56 100644
@@ -69,6 +69,8 @@ void setup_xen_features(void)
 __attribute__((weak)) void app_shutdown(unsigned reason)
 {
     printk("Shutdown requested: %d\n", reason);
+    struct sched_shutdown sched_shutdown = { .reason = 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
#4 lore raw

Re: [PATCH ARM v3 2/7] mini-os: fixed shutdown thread

extras/mini-os/kernel.c void setup_xen_features(void) · line 73

Quoted 10 lines · Thomas Leonard
extras/mini-os/kernel.c +2 -0
index ea409f4..27e3c56 100644
@@ -69,6 +69,8 @@ void setup_xen_features(void)
 __attribute__((weak)) void app_shutdown(unsigned reason)
 {
     printk("Shutdown requested: %d\n", reason);
+    struct sched_shutdown sched_shutdown = { .reason = reason };
+    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);

I was going to apply but this causes:
kernel.c: In function ‘app_shutdown’:
kernel.c:72:5: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
cc1: all warnings being treated as errors

when building the stubdom on x86 (as it happens, I imagine it could happen elsewhere too).

Ian.

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

#5 lore raw

Re: [PATCH ARM v3 2/7] mini-os: fixed shutdown thread

Quoted 16 lines · Ian Campbell, le Thu 12 Jun 2014 10:52:29 +0100, a écrit :

extras/mini-os/kernel.c void setup_xen_features(void) · line 73

Quoted 10 lines · Thomas Leonard
extras/mini-os/kernel.c +2 -0
index ea409f4..27e3c56 100644
@@ -69,6 +69,8 @@ void setup_xen_features(void)
 __attribute__((weak)) void app_shutdown(unsigned reason)
 {
     printk("Shutdown requested: %d\n", reason);
+    struct sched_shutdown sched_shutdown = { .reason = reason };
+    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);

I was going to apply but this causes:
kernel.c: In function ‘app_shutdown’:
kernel.c:72:5: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
cc1: all warnings being treated as errors

Ah, odd that they didn't get it. Just exchanging the printk and sched_shutdown declaration will do it :)

Samuel

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

#6 lore raw

Re: [PATCH ARM v3 2/7] mini-os: fixed shutdown thread

Quoted 18 lines · Samuel Thibault
Quoted 16 lines · Ian Campbell, le Thu 12 Jun 2014 10:52:29 +0100, a écrit :

extras/mini-os/kernel.c void setup_xen_features(void) · line 73

Quoted 10 lines · Thomas Leonard
extras/mini-os/kernel.c +2 -0
index ea409f4..27e3c56 100644
@@ -69,6 +69,8 @@ void setup_xen_features(void)
 __attribute__((weak)) void app_shutdown(unsigned reason)
 {
     printk("Shutdown requested: %d\n", reason);
+    struct sched_shutdown sched_shutdown = { .reason = reason };
+    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);

I was going to apply but this causes:
kernel.c: In function ‘app_shutdown’:
kernel.c:72:5: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
cc1: all warnings being treated as errors

Quoted 2 lines

Ah, odd that they didn't get it. Just exchanging the printk and sched_shutdown declaration will do it :)

Well, I can change this. But note that Mini-OS won't compile with -Werror=declaration-after-statement even before these changes. e.g.

lib/xmalloc.c: In function ‘_xmalloc’:
lib/xmalloc.c:166:9: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]

         uintptr_t size_before = (data_begin - hdr_size) - (uintptr_t)i;
         ^
lib/xmalloc.c:193:5: error: ISO C90 forbids mixed declarations and
code [-Werror=declaration-after-statement]
     struct xmalloc_pad *pad = (struct xmalloc_pad *) data_begin - 1;
     ^

cc1: all warnings being treated as errors

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

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

Re: [PATCH ARM v3 2/7] mini-os: fixed shutdown thread

Quoted 19 lines · Thomas Leonard
Quoted 18 lines · Samuel Thibault
Quoted 16 lines · Ian Campbell, le Thu 12 Jun 2014 10:52:29 +0100, a écrit :

extras/mini-os/kernel.c void setup_xen_features(void) · line 73

Quoted 10 lines · Thomas Leonard
extras/mini-os/kernel.c +2 -0
index ea409f4..27e3c56 100644
@@ -69,6 +69,8 @@ void setup_xen_features(void)
 __attribute__((weak)) void app_shutdown(unsigned reason)
 {
     printk("Shutdown requested: %d\n", reason);
+    struct sched_shutdown sched_shutdown = { .reason = reason };
+    HYPERVISOR_sched_op(SCHEDOP_shutdown, &sched_shutdown);

I was going to apply but this causes:
kernel.c: In function ‘app_shutdown’:
kernel.c:72:5: error: ISO C90 forbids mixed declarations and code [-Werror=declaration-after-statement]
cc1: all warnings being treated as errors

Quoted 5 lines
Quoted 2 lines

Ah, odd that they didn't get it. Just exchanging the printk and sched_shutdown declaration will do it :)

Well, I can change this. But note that Mini-OS won't compile with -Werror=declaration-after-statement even before these changes.

I'm not sure how but my pre-commit builds using the Debian Wheezy toolchain work whereas with your patch they didn't. I suppose different bits of the e.g. stubdom/mini-os build are using different compiler flags and you happened to modify one which was stricter about it.

Ian.

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

#8 lore raw

PATCH v3 3/7 mini-os: tidied up code

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

[[email protected]: separated from big ARM commit]
[[email protected]: use __func__ in DEBUG macro]
[[email protected]: drop text about "xm create"]
---
 extras/mini-os/README                      |  4 ++--
 extras/mini-os/arch/x86/time.c             |  2 +-
 extras/mini-os/console/console.c           |  2 +-
 extras/mini-os/events.c                    |  3 ++-
 extras/mini-os/gntmap.c                    | 35 ++++++++++++++----------------
 extras/mini-os/include/x86/arch_spinlock.h |  2 +-
 extras/mini-os/sched.c                     |  3 +++
 extras/mini-os/xenbus/xenbus.c             |  2 +-
 8 files changed, 27 insertions(+), 26 deletions(-)
extras/mini-os/README +2 -2
index 710a303..7960314 100644
@@ -25,8 +25,8 @@ This includes:
 
 - to build it with much better libc support, see the stubdom/ directory
 
-- to start it do the following in domain0 (assuming xend is running)
-  # xm create domain_config
+- to start it do the following in domain0
+  # xl create -c domain_config
 
 This starts the kernel and prints out a bunch of stuff and then once every
 second the system time.
extras/mini-os/arch/x86/time.c +1 -1
index 89bc382..2c8d033 100644
@@ -212,7 +212,7 @@ void block_domain(s_time_t until)
 
 
 /*
- * Just a dummy 
+ * Just a dummy
  */
 static void timer_handler(evtchn_port_t ev, struct pt_regs *regs, void *ign)
 {
extras/mini-os/console/console.c +1 -1
index 380f53c..5538bd4 100644
@@ -124,7 +124,7 @@ void print(int direct, const char *fmt, va_list args)
     static char   buf[1024];
     
     (void)vsnprintf(buf, sizeof(buf), fmt, args);
- 
+
     if(direct)
     {
         (void)HYPERVISOR_console_io(CONSOLEIO_write, strlen(buf), buf);
extras/mini-os/events.c +2 -1
index 036b84b..2da9b01 100644
@@ -138,7 +138,8 @@ evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data)
 	op.virq = virq;
 	op.vcpu = smp_processor_id();
 
-	if ( (rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op)) != 0 )
+	rc = HYPERVISOR_event_channel_op(EVTCHNOP_bind_virq, &op);
+	if (rc != 0)
 	{
 		printk("Failed to bind virtual IRQ %d with rc=%d\n", virq, rc);
 		return -1;
extras/mini-os/gntmap.c +16 -19
index 22ed450..f6ab3ad 100644
@@ -38,6 +38,15 @@
 #include <inttypes.h>
 #include <mini-os/gntmap.h>
 
+//#define GNTMAP_DEBUG
+#ifdef GNTMAP_DEBUG
+#define DEBUG(_f, _a...) \
+    printk("MINI_OS(gntmap.c:%d): %s" _f "\n", __LINE__, __func__, ## _a)
+#else
+#define DEBUG(_f, _a...)    ((void)0)
+#endif
+
+
 #define DEFAULT_MAX_GRANTS 128
 
 struct gntmap_entry {
@@ -61,10 +70,8 @@ gntmap_find_free_entry(struct gntmap *map)
             return &map->entries[i];
     }
 
-#ifdef GNTMAP_DEBUG
-    printk("gntmap_find_free_entry(map=%p): all %d entries full\n",
+    DEBUG("(map=%p): all %d entries full",
            map, map->nentries);
-#endif
     return NULL;
 }
 
@@ -83,9 +90,7 @@ gntmap_find_entry(struct gntmap *map, unsigned long addr)
 int
 gntmap_set_max_grants(struct gntmap *map, int count)
 {
-#ifdef GNTMAP_DEBUG
-    printk("gntmap_set_max_grants(map=%p, count=%d)\n", map, count);
-#endif
+    DEBUG("(map=%p, count=%d)", map, count);
 
     if (map->nentries != 0)
         return -EBUSY;
@@ -157,10 +162,8 @@ gntmap_munmap(struct gntmap *map, unsigned long start_address, int count)
     int i, rc;
     struct gntmap_entry *ent;
 
-#ifdef GNTMAP_DEBUG
-    printk("gntmap_munmap(map=%p, start_address=%lx, count=%d)\n",
+    DEBUG("(map=%p, start_address=%lx, count=%d)",
            map, start_address, count);
-#endif
 
     for (i = 0; i < count; i++) {
         ent = gntmap_find_entry(map, start_address + PAGE_SIZE * i);
@@ -189,14 +192,12 @@ gntmap_map_grant_refs(struct gntmap *map,
     struct gntmap_entry *ent;
     int i;
 
-#ifdef GNTMAP_DEBUG
-    printk("gntmap_map_grant_refs(map=%p, count=%" PRIu32 ", "
+    DEBUG("(map=%p, count=%" PRIu32 ", "
            "domids=%p [%" PRIu32 "...], domids_stride=%d, "
-           "refs=%p [%" PRIu32 "...], writable=%d)\n",
+           "refs=%p [%" PRIu32 "...], writable=%d)",
            map, count,
            domids, domids == NULL ? 0 : domids[0], domids_stride,
            refs, refs == NULL ? 0 : refs[0], writable);
-#endif
 
     (void) gntmap_set_max_grants(map, DEFAULT_MAX_GRANTS);
 
@@ -224,9 +225,7 @@ gntmap_map_grant_refs(struct gntmap *map,
 void
 gntmap_init(struct gntmap *map)
 {
-#ifdef GNTMAP_DEBUG
-    printk("gntmap_init(map=%p)\n", map);
-#endif
+    DEBUG("(map=%p)", map);
     map->nentries = 0;
     map->entries = NULL;
 }
@@ -237,9 +236,7 @@ gntmap_fini(struct gntmap *map)
     struct gntmap_entry *ent;
     int i;
 
-#ifdef GNTMAP_DEBUG
-    printk("gntmap_fini(map=%p)\n", map);
-#endif
+    DEBUG("(map=%p)", map);
 
     for (i = 0; i < map->nentries; i++) {
         ent = &map->entries[i];
extras/mini-os/include/x86/arch_spinlock.h +1 -1
index c08b6f1..59f7b63 100644
@@ -61,7 +61,7 @@
 
 static inline void _raw_spin_unlock(spinlock_t *lock)
 {
-	char oldval = 1;
+	char oldval = ARCH_SPIN_LOCK_UNLOCKED;
 	__asm__ __volatile__(
 		spin_unlock_string
 	);
extras/mini-os/sched.c +3 -0
index 5ac5c1c..174945e 100644
@@ -85,6 +85,7 @@ void schedule(void)
         printk("Must not call schedule() from a callback\n");
         BUG();
     }
+
     if (flags) {
         printk("Must not call schedule() with IRQs disabled\n");
         BUG();
@@ -188,6 +189,8 @@ struct _reent *__getreent(void)
 	}
     }
 #endif
+#else
+#error Not implemented yet
 #endif
     return _reent;
 }
extras/mini-os/xenbus/xenbus.c +1 -1
index c5d9b02..934f23b 100644
@@ -276,7 +276,7 @@ static void xenbus_evtchn_handler(evtchn_port_t port, struct pt_regs *regs,
 }
 
 static int nr_live_reqs;
-static spinlock_t req_lock = SPIN_LOCK_UNLOCKED;
+static DEFINE_SPINLOCK(req_lock);
 static DECLARE_WAIT_QUEUE_HEAD(req_wq);
 
 /* Release a xenbus identifier */
Signature · 1 line
2.0.0
#9 lore raw

PATCH v3 4/7 mini-os: moved events code under arch

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

This is all code motion, except that we now initialise the ev_actions array before calling the arch-specific code to make it more robust against future changes.

[[email protected]: separated from big ARM commit]
---
 extras/mini-os/arch/x86/events.c | 31 +++++++++++++++++++++++++++++++
 extras/mini-os/events.c          | 24 ++++--------------------
 extras/mini-os/include/events.h  |  3 +++
 3 files changed, 38 insertions(+), 20 deletions(-)
 create mode 100644 extras/mini-os/arch/x86/events.c
extras/mini-os/arch/x86/events.c new file +31 -0
new file mode 100644
index 0000000..e420a98
@@ -0,0 +1,31 @@
+#include <mini-os/os.h>
+#include <mini-os/mm.h>
+#include <mini-os/events.h>
+
+#if defined(__x86_64__)
+char irqstack[2 * STACK_SIZE];
+
+static struct pda
+{
+    int irqcount;       /* offset 0 (used in x86_64.S) */
+    char *irqstackptr;  /*        8 */
+} cpu0_pda;
+#endif
+
+void arch_init_events(void)
+{
+#if defined(__x86_64__)
+    asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
+    wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
+    cpu0_pda.irqcount = -1;
+    cpu0_pda.irqstackptr = (void*) (((unsigned long)irqstack + 2 * STACK_SIZE)
+                                    & ~(STACK_SIZE - 1));
+#endif
+}
+
+void arch_fini_events(void)
+{
+#if defined(__x86_64__)
+    wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
+#endif
+}
extras/mini-os/events.c +4 -20
index 2da9b01..d60630b 100644
@@ -167,44 +167,28 @@ evtchn_port_t bind_pirq(uint32_t pirq, int will_share,
 	return op.port;
 }
 
-#if defined(__x86_64__)
-char irqstack[2 * STACK_SIZE];
-
-static struct pda
-{
-    int irqcount;       /* offset 0 (used in x86_64.S) */
-    char *irqstackptr;  /*        8 */
-} cpu0_pda;
-#endif
-
 /*
  * Initially all events are without a handler and disabled
  */
 void init_events(void)
 {
     int i;
-#if defined(__x86_64__)
-    asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
-    wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
-    cpu0_pda.irqcount = -1;
-    cpu0_pda.irqstackptr = (void*) (((unsigned long)irqstack + 2 * STACK_SIZE)
-                                    & ~(STACK_SIZE - 1));
-#endif
+
     /* initialize event handler */
     for ( i = 0; i < NR_EVS; i++ )
 	{
         ev_actions[i].handler = default_handler;
         mask_evtchn(i);
     }
+
+    arch_init_events();
 }
 
 void fini_events(void)
 {
     /* Dealloc all events */
     unbind_all_ports();
-#if defined(__x86_64__)
-    wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
-#endif
+    arch_fini_events();
 }
 
 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
extras/mini-os/include/events.h +3 -0
index 0e9d3a7..0452d21 100644
@@ -25,6 +25,9 @@
 typedef void (*evtchn_handler_t)(evtchn_port_t, struct pt_regs *, void *);
 
 /* prototypes */
+void arch_init_events(void);
+void arch_fini_events(void);
+
 int do_event(evtchn_port_t port, struct pt_regs *regs);
 evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data);
 evtchn_port_t bind_pirq(uint32_t pirq, int will_share, evtchn_handler_t handler, void *data);
Signature · 1 line
2.0.0
Acked-by on v3 4/7
#10 lore raw

Re: [PATCH ARM v3 4/7] mini-os: moved events code under arch

Quoted 9 lines · Thomas Leonard, le Wed 11 Jun 2014 11:30:15 +0100, a écrit :

From: Karim Raslan <[email protected]>

This is all code motion, except that we now initialise the ev_actions array before calling the arch-specific code to make it more robust against future changes.

[[email protected]: separated from big ARM commit]
Quoted 120 lines
---
 extras/mini-os/arch/x86/events.c | 31 +++++++++++++++++++++++++++++++
 extras/mini-os/events.c          | 24 ++++--------------------
 extras/mini-os/include/events.h  |  3 +++
 3 files changed, 38 insertions(+), 20 deletions(-)
 create mode 100644 extras/mini-os/arch/x86/events.c
extras/mini-os/arch/x86/events.c new file +31 -0
new file mode 100644
index 0000000..e420a98
@@ -0,0 +1,31 @@
+#include <mini-os/os.h>
+#include <mini-os/mm.h>
+#include <mini-os/events.h>
+
+#if defined(__x86_64__)
+char irqstack[2 * STACK_SIZE];
+
+static struct pda
+{
+    int irqcount;       /* offset 0 (used in x86_64.S) */
+    char *irqstackptr;  /*        8 */
+} cpu0_pda;
+#endif
+
+void arch_init_events(void)
+{
+#if defined(__x86_64__)
+    asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
+    wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
+    cpu0_pda.irqcount = -1;
+    cpu0_pda.irqstackptr = (void*) (((unsigned long)irqstack + 2 * STACK_SIZE)
+                                    & ~(STACK_SIZE - 1));
+#endif
+}
+
+void arch_fini_events(void)
+{
+#if defined(__x86_64__)
+    wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
+#endif
+}
extras/mini-os/events.c +4 -20
index 2da9b01..d60630b 100644
@@ -167,44 +167,28 @@ evtchn_port_t bind_pirq(uint32_t pirq, int will_share,
 	return op.port;
 }
 
-#if defined(__x86_64__)
-char irqstack[2 * STACK_SIZE];
-
-static struct pda
-{
-    int irqcount;       /* offset 0 (used in x86_64.S) */
-    char *irqstackptr;  /*        8 */
-} cpu0_pda;
-#endif
-
 /*
  * Initially all events are without a handler and disabled
  */
 void init_events(void)
 {
     int i;
-#if defined(__x86_64__)
-    asm volatile("movl %0,%%fs ; movl %0,%%gs" :: "r" (0));
-    wrmsrl(0xc0000101, &cpu0_pda); /* 0xc0000101 is MSR_GS_BASE */
-    cpu0_pda.irqcount = -1;
-    cpu0_pda.irqstackptr = (void*) (((unsigned long)irqstack + 2 * STACK_SIZE)
-                                    & ~(STACK_SIZE - 1));
-#endif
+
     /* initialize event handler */
     for ( i = 0; i < NR_EVS; i++ )
 	{
         ev_actions[i].handler = default_handler;
         mask_evtchn(i);
     }
+
+    arch_init_events();
 }
 
 void fini_events(void)
 {
     /* Dealloc all events */
     unbind_all_ports();
-#if defined(__x86_64__)
-    wrmsrl(0xc0000101, NULL); /* 0xc0000101 is MSR_GS_BASE */
-#endif
+    arch_fini_events();
 }
 
 void default_handler(evtchn_port_t port, struct pt_regs *regs, void *ignore)
extras/mini-os/include/events.h +3 -0
index 0e9d3a7..0452d21 100644
@@ -25,6 +25,9 @@
 typedef void (*evtchn_handler_t)(evtchn_port_t, struct pt_regs *, void *);
 
 /* prototypes */
+void arch_init_events(void);
+void arch_fini_events(void);
+
 int do_event(evtchn_port_t port, struct pt_regs *regs);
 evtchn_port_t bind_virq(uint32_t virq, evtchn_handler_t handler, void *data);
 evtchn_port_t bind_pirq(uint32_t pirq, int will_share, evtchn_handler_t handler, void *data);
Signature · 7 lines
2.0.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Signature · 5 lines
Samuel
<N> un driver qui fait quoi, alors ?
<y> ben pour les bips
<s> pour passer les oops en morse
 -+- #ens-mim - vive les rapports de bug -+-
#11 lore raw

PATCH v3 5/7 mini-os: switched initial C entry point to arch_init

In reply to Thomas Leonard

From: Karim Raslan <[email protected]>

arch_print_info (a debug print called during start up) was also removed.

[[email protected]: separated from big ARM commit]
[[email protected]: restored comment, moved prototypes to headers]
---
 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          | 38 +++++-----------------------------
 6 files changed, 47 insertions(+), 47 deletions(-)
extras/mini-os/arch/x86/setup.c +36 -8
index 54046d3..58ede15 100644
@@ -28,6 +28,7 @@
 
 #include <mini-os/os.h>
 #include <mini-os/lib.h> /* for printk, memcpy */
+#include <xen/xen.h>
 
 /*
  * Shared page for communicating with the hypervisor.
@@ -87,14 +88,40 @@ static inline void sse_init(void) {
 #define sse_init()
 #endif
 
+
+void start_kernel(void);
+
+/*
+ * 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();
+
+	/* 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");
+
 	/*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
@@ -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 +5 -33
index 27e3c56..b9ab0a2 100644
@@ -114,41 +114,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,13 +174,12 @@ void stop_kernel(void)
     /* Reset events. */
     fini_events();
 
-    /* Reset traps */
-    trap_fini();
-
     /* Reset arch details */
     arch_fini();
 }
 
+void arch_do_exit(void);
+
 /*
  * do_exit: This is called whenever an IRET fails in entry.S.
  * This will generally be because an application has got itself into
@@ -218,7 +190,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
Acked-by on v3 5/7
#12 lore raw

Re: [PATCH ARM v3 5/7] mini-os: switched initial C entry point to arch_init

Quoted 1 line · Thomas Leonard, le Wed 11 Jun 2014 11:30:16 +0100, a écrit :

arch_print_info (a debug print called during start up) was also removed.

Well, this information is quite useful, like start_info etc. pointers. Please bring it back.

extras/mini-os/arch/x86/setup.c static inline void sse_init(void) { · line 93

Quoted 7 lines
extras/mini-os/arch/x86/setup.c +3 -0
@@ -87,14 +88,40 @@ static inline void sse_init(void) {
 #define sse_init()
 #endif
 
+
+void start_kernel(void);
+

This shouldn't be needed any more.

Quoted 2 lines
extras/mini-os/kernel.c +0 -0
@@ -201,13 +174,12 @@ void stop_kernel(void)
     /* Reset events. */

...

Quoted 3 lines

}

+void arch_do_exit(void);

Ditto.

Apart from that,

Samuel

#13 lore raw

PATCH v3 6/7 mini-os: don't include queue.h if there's no libc

In reply to Thomas Leonard
---
 extras/mini-os/include/lib.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
extras/mini-os/include/lib.h +1 -1
index 935bede..670c14f 100644
@@ -52,10 +52,10 @@
 #include <stddef.h>
 #include <xen/xen.h>
 #include <xen/event_channel.h>
-#include <sys/queue.h>
 #include "gntmap.h"
 
 #ifdef HAVE_LIBC
+#include <sys/queue.h>
 #include <stdio.h>
 #else
 #include <lib-gpl.h>
Signature · 1 line
2.0.0
Acked-by on v3 6/7
#14 lore raw

Re: [PATCH ARM v3 6/7] mini-os: don't include queue.h if there's no libc

Quoted 1 line · Thomas Leonard, le Wed 11 Jun 2014 11:30:17 +0100, a écrit :
Quoted 29 lines
---
 extras/mini-os/include/lib.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
extras/mini-os/include/lib.h +1 -1
index 935bede..670c14f 100644
@@ -52,10 +52,10 @@
 #include <stddef.h>
 #include <xen/xen.h>
 #include <xen/event_channel.h>
-#include <sys/queue.h>
 #include "gntmap.h"
 
 #ifdef HAVE_LIBC
+#include <sys/queue.h>
 #include <stdio.h>
 #else
 #include <lib-gpl.h>
Signature · 7 lines
2.0.0


_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Signature · 5 lines
Samuel
"...very few phenomena can pull someone out of Deep Hack Mode, with two
noted exceptions: being struck by lightning, or worse, your *computer*
being struck by lightning."
(By Matt Welsh)
#15 lore raw

PATCH v3 7/7 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]
---
 extras/mini-os/ARM-TODO.txt                  |  17 ++
 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              |   6 +
 extras/mini-os/arch/arm/arm32.S              | 149 ++++++++++++++
 extras/mini-os/arch/arm/events.c             |  24 +++
 extras/mini-os/arch/arm/hypercalls32.S       |  88 ++++++++
 extras/mini-os/arch/arm/minios-arm32.lds     |  73 +++++++
 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/drivers/gic.c                 | 180 ++++++++++++++++
 extras/mini-os/events.c                      |   4 +-
 extras/mini-os/hypervisor.c                  |  10 +
 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/hypercall-arm32.h | 173 ++++++++++++++++
 extras/mini-os/include/arm/os.h              | 294 +++++++++++++++++++++++++++
 extras/mini-os/include/arm/traps.h           |  20 ++
 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                       |   3 +
 29 files changed, 1611 insertions(+), 7 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_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/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 +17 -0
new file mode 100644
index 0000000..074a304
@@ -0,0 +1,17 @@
+* os.h bit manipulation, write optimized assembly code
+* support abort exception handling ( and others )
+* scheduling!
+* use proper memory types and enable caches (L1 and L2)
+* Use LDREX and STREX in xchg implementation ( code already there but it causes an abort, I think because of using strong-ordered memory with disabled L1 caches - something to do with the implementation of the monitor on cortex-a7 )
+* 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
+* fini_time
+* bind_*
+* add multiple cpu support (?)
+* map_frames
+* clean up the code and remove redundent code between arm and x86
+* 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 5af40ad..1bfe354 100644
@@ -76,6 +76,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
@@ -96,7 +104,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
@@ -185,7 +195,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 +6 -0
new file mode 100644
index 0000000..80650fc
@@ -0,0 +1,6 @@
+ifeq ($(XEN_TARGET_ARCH),arm32)
+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 +149 -0

149 lines not on this page · raw message

extras/mini-os/arch/arm/events.c new file +24 -0
new file mode 100644
index 0000000..5fd637e
@@ -0,0 +1,24 @@
+#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_fini_events(void) {
+    if(debug_port != -1)
+    {
+        mask_evtchn(debug_port);
+        unbind_evtchn(debug_port);
+    }
+}
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 +73 -0

73 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/drivers/gic.c new file +180 -0

180 lines not on this page · raw message

extras/mini-os/events.c +3 -1
index d60630b..79ba286 100644
@@ -246,7 +246,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;
@@ -261,6 +262,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 +10 -0
index b4688a0..2a12ec4 100644
@@ -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_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..5e3953b
@@ -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)         (0)
+#define mach_to_virt(_mach)        (0)
+#define virt_to_mach(_virt)        (0)
+#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/hypercall-arm32.h new file +173 -0

173 lines not on this page · raw message

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

294 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/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 6640ede..931e853 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 b9ab0a2..cdf5928 100644
@@ -46,6 +46,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)
@@ -146,6 +150,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 +3 -0
index 174945e..ed3f8c0 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;
Signature · 7 lines
2.0.0


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

Hello,

I don't know the arm hardware very much, so I can't really review the arm-specific things, there a just a few things which catched my eyes:

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

Quoted 2 lines · Thomas Leonard, le Wed 11 Jun 2014 11:30:18 +0100, a écrit :
extras/mini-os/include/arm/os.h new file +2 -0
+#define LOCK_PREFIX ""
+#define LOCK ""

You don't need to define them, they were meant for x86 code.

Quoted 1 line

+#define ADDR (*(volatile long *) addr)

You aren't using it, no need to define it either.

Quoted 5 lines
extras/mini-os/include/arm/os.h new file +5 -0
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+    //TODO
+    unsigned volatile long y, tmp = 0;
+    switch(size){

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

Quoted 10 lines
extras/mini-os/include/arm/os.h new file +10 -0
+    case 1:
+#if CPU_EXCLUSIVE_LDST
+        __asm__ __volatile__("1:ldrexb %0, [%1]\n"
+            "strexb %3, %2, [%1]\n"
+            "cmp %3, #1\n"
+            "beq 1b\n\n"
+            "dmb\n":"=&r"(y):"r"(ptr), "r"(x), "r"(tmp):"memory");
+#else
+        y = (*(char *)ptr) & 0x000000ff;
+        *((char *)ptr) = (char)x;

The second version is very fragile :) I'd rather put a strong #warning here, to make sure nobody ever uses that code for anything close to production level.

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

Quoted 9 lines
extras/mini-os/include/arm/os.h new file +9 -0
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+    //TODO
+    unsigned long *tmp = (unsigned long *)addr;
+
+    int x = tmp[nr >> 5] & (1 << (nr & 0x1f));
+    tmp[nr >> 5] &= ~(1 << (nr & 0x1f));
+    return x;
+}

And this must be atomic, so an atomic version is really needed.

I guess we could perhaps revert to gcc instrinsics by default to save porting work here.

Quoted 4 lines
extras/mini-os/include/arm/os.h new file +4 -0
+static inline unsigned long __synch_cmpxchg(volatile void *ptr,
+        unsigned long old,
+        unsigned long new, int size)
+{

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

Quoted 10 lines
extras/mini-os/include/arm/os.h new file +10 -0
+    //TODO:
+    //BUG();
+    return 0;
+}
+
+static __inline__ void synch_set_bit(int nr, volatile void * addr)
+{
+    //TODO:
+    set_bit(nr, addr);
+}

Same story for these

Apart from these, the integration into the existing mini-os looks nice.

Samuel

#17 lore raw
Quoted 11 lines · Samuel Thibault
Quoted 11 lines
extras/mini-os/include/arm/os.h new file +11 -0
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+    //TODO
+    unsigned volatile long y, tmp = 0;
+    switch(size){
+    case 1:
+#if CPU_EXCLUSIVE_LDST
+        __asm__ __volatile__("1:ldrexb %0, [%1]\n"
+            "strexb %3, %2, [%1]\n"
+            "cmp %3, #1\n"
+            "beq 1b\n\n"
Quoted 8 lines

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

Quoted 4 lines
extras/mini-os/include/arm/os.h new file +4 -0
+            "dmb\n":"=&r"(y):"r"(ptr), "r"(x), "r"(tmp):"memory");
+#else
+        y = (*(char *)ptr) & 0x000000ff;
+        *((char *)ptr) = (char)x;

The second version is very fragile :) I'd rather put a strong #warning here, to make sure nobody ever uses that code for anything close to production level.

ldrexb is guaranteed to be available on any platform which can run Xen. For one thing xen uses them (unconditionally) itself.

I can't remember if it is the virt extensions themselves or the LPAE extension (which is in turn required by the virt extensions) which add this architectural requirement.

Ian.

#18 lore raw
Quoted 21 lines · Ian Campbell, le Thu 12 Jun 2014 08:41:54 +0100, a écrit :
Quoted 11 lines · Samuel Thibault
Quoted 11 lines
extras/mini-os/include/arm/os.h new file +11 -0
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+    //TODO
+    unsigned volatile long y, tmp = 0;
+    switch(size){
+    case 1:
+#if CPU_EXCLUSIVE_LDST
+        __asm__ __volatile__("1:ldrexb %0, [%1]\n"
+            "strexb %3, %2, [%1]\n"
+            "cmp %3, #1\n"
+            "beq 1b\n\n"
Quoted 8 lines

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

Quoted 4 lines
extras/mini-os/include/arm/os.h new file +4 -0
+            "dmb\n":"=&r"(y):"r"(ptr), "r"(x), "r"(tmp):"memory");
+#else
+        y = (*(char *)ptr) & 0x000000ff;
+        *((char *)ptr) = (char)x;

The second version is very fragile :) I'd rather put a strong #warning here, to make sure nobody ever uses that code for anything close to production level.

Quoted 2 lines

ldrexb is guaranteed to be available on any platform which can run Xen. For one thing xen uses them (unconditionally) itself.

I'd rather see minios us them unconditionally then, to avoid the risk of running unsafe code :)

Samuel

#19 lore raw
Quoted 22 lines · Samuel Thibault
Quoted 21 lines · Ian Campbell, le Thu 12 Jun 2014 08:41:54 +0100, a écrit :
Quoted 19 lines · Samuel Thibault
Quoted 5 lines
extras/mini-os/include/arm/os.h new file +5 -0
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+    //TODO
+    unsigned volatile long y, tmp = 0;
+    switch(size){

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

Quoted 10 lines
extras/mini-os/include/arm/os.h new file +10 -0
+    case 1:
+#if CPU_EXCLUSIVE_LDST
+        __asm__ __volatile__("1:ldrexb %0, [%1]\n"
+            "strexb %3, %2, [%1]\n"
+            "cmp %3, #1\n"
+            "beq 1b\n\n"
+            "dmb\n":"=&r"(y):"r"(ptr), "r"(x), "r"(tmp):"memory");
+#else
+        y = (*(char *)ptr) & 0x000000ff;
+        *((char *)ptr) = (char)x;

The second version is very fragile :) I'd rather put a strong #warning here, to make sure nobody ever uses that code for anything close to production level.

Quoted 5 lines
Quoted 2 lines

ldrexb is guaranteed to be available on any platform which can run Xen. For one thing xen uses them (unconditionally) itself.

I'd rather see minios us them unconditionally then, to avoid the risk of running unsafe code :)

Right, that's what I was trying to say but ended up not actually saying it outright ;-)

Ian

#20 lore raw
In reply to Samuel Thibault
Quoted 6 lines · Samuel Thibault

Hello,

I don't know the arm hardware very much, so I can't really review the arm-specific things, there a just a few things which catched my eyes:

Thomas Leonard, le Wed 11 Jun 2014 11:30:18 +0100, a écrit :

Quoted 8 lines

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

Quoted 2 lines
extras/mini-os/include/arm/os.h new file +2 -0
+#define LOCK_PREFIX ""
+#define LOCK ""

You don't need to define them, they were meant for x86 code.

Quoted 1 line

+#define ADDR (*(volatile long *) addr)

You aren't using it, no need to define it either.

Right, I've deleted these (and a few other bits that looked unused).

Quoted 33 lines
Quoted 5 lines
extras/mini-os/include/arm/os.h new file +5 -0
+static inline unsigned long __xchg(unsigned long x, volatile void * ptr, int size)
+{
+    //TODO
+    unsigned volatile long y, tmp = 0;
+    switch(size){

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

Quoted 10 lines
extras/mini-os/include/arm/os.h new file +10 -0
+    case 1:
+#if CPU_EXCLUSIVE_LDST
+        __asm__ __volatile__("1:ldrexb %0, [%1]\n"
+            "strexb %3, %2, [%1]\n"
+            "cmp %3, #1\n"
+            "beq 1b\n\n"
+            "dmb\n":"=&r"(y):"r"(ptr), "r"(x), "r"(tmp):"memory");
+#else
+        y = (*(char *)ptr) & 0x000000ff;
+        *((char *)ptr) = (char)x;

The second version is very fragile :) I'd rather put a strong #warning here, to make sure nobody ever uses that code for anything close to production level.

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

Quoted 9 lines
extras/mini-os/include/arm/os.h new file +9 -0
+static __inline__ int test_and_clear_bit(int nr, volatile void * addr)
+{
+    //TODO
+    unsigned long *tmp = (unsigned long *)addr;
+
+    int x = tmp[nr >> 5] & (1 << (nr & 0x1f));
+    tmp[nr >> 5] &= ~(1 << (nr & 0x1f));
+    return x;
+}

And this must be atomic, so an atomic version is really needed.

Quoted 2 lines

I guess we could perhaps revert to gcc instrinsics by default to save porting work here.

I've had a go at this (attached).

I'm not sure what the difference between the synch and non-synch versions is supposed to be. Currently, I'm just doing:

#define synch_set_bit(n, addr) set_bit(n, addr)
#define synch_clear_bit(n, addr) clear_bit(n, addr) #define synch_test_and_set_bit(n, addr) test_and_set_bit(n, addr) #define synch_test_and_clear_bit(n, addr) test_and_clear_bit(n, addr) #define synch_test_bit(nr, addr) test_bit(nr, addr)

I used __ATOMIC_SEQ_CST as the memory model as that was the safest option, but maybe it's overkill.

I also modified __ffs to use ARM's clz instruction, removing another TODO.

The main user of these operations was gic.c, but it turns out that the atomic versions don't work here as the GIC registers aren't regular memory. So I replaced those with non-atomic versions.

Does this seem reasonable?

Quoted 21 lines
Quoted 4 lines
extras/mini-os/include/arm/os.h new file +4 -0
+static inline unsigned long __synch_cmpxchg(volatile void *ptr,
+        unsigned long old,
+        unsigned long new, int size)
+{

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

Quoted 10 lines
extras/mini-os/include/arm/os.h new file +10 -0
+    //TODO:
+    //BUG();
+    return 0;
+}
+
+static __inline__ void synch_set_bit(int nr, volatile void * addr)
+{
+    //TODO:
+    set_bit(nr, addr);
+}

Same story for these

Apart from these, the integration into the existing mini-os looks nice.

Samuel

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

#ifndef _OS_H_
#define _OS_H_

#ifndef __ASSEMBLY__

#include <mini-os/hypervisor.h>
#include <mini-os/types.h>
#include <xen/xen.h>

void arch_fini(void);

#define BUG() while(1){}

#define smp_processor_id() 0

#define barrier() __asm__ __volatile__("": : :"memory")

extern shared_info_t *HYPERVISOR_shared_info;

// disable interrupts

static inline __cli(void) {
    int x;
    __asm__ __volatile__("mrs %0, cpsr;cpsid i":"=r"(x)::"memory");
}

// 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");
}
static inline int irqs_disabled() {
    int x;
    __asm__ __volatile__("mrs %0, cpsr\n":"=r"(x)::"memory");
    return (x & 0x80);
}
#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");    \
}
#define local_save_flags(x)    { \
    __asm__ __volatile__("mrs %0, cpsr; and %0, %0, 0x80":"=r"(x)::"memory");    \
}

#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");
#elif defined(__aarch64__)
#define mb()
#define rmb()
#define wmb()
#else
#error undefined architecture
#endif

#define unlikely(x) __builtin_expect((x),0)
#define likely(x) __builtin_expect((x),1)

/************************** arm *******************************/ #ifdef __INSIDE_MINIOS__
#if defined (__arm__)
#define xchg(ptr,v) __atomic_exchange_n(ptr, v, __ATOMIC_SEQ_CST)

/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/
static __inline__ int test_and_clear_bit(int nr, volatile void * addr)

{
    uint8_t *byte = ((uint8_t *)addr) + (nr >> 3);
    uint8_t bit = 1 << (nr & 7);
    uint8_t orig;

    orig = __atomic_fetch_and(byte, ~bit, __ATOMIC_SEQ_CST);

    return (orig & bit) != 0;
}

static __inline__ int test_and_set_bit(int nr, volatile void *base)

{
    uint8_t *byte = ((uint8_t *)base) + (nr >> 3);
    uint8_t bit = 1 << (nr & 7);
    uint8_t orig;

    orig = __atomic_fetch_or(byte, bit, __ATOMIC_SEQ_CST);

    return (orig & bit) != 0;
}

static __inline__ int test_bit(int nr, const volatile unsigned long *addr)

{
    const uint8_t *ptr = (const uint8_t *) addr;
    return ((1 << (nr & 7)) & (ptr[nr >> 3])) != 0;
}

/**
* set_bit - Atomically set a bit in memory
* @nr: the bit to set
* @addr: the address to start counting from
*
* This function is atomic and may not be reordered. See __set_bit()
* if you do not require the atomic guarantees.
* Note that @nr may be almost arbitrarily large; this function is not
* restricted to acting on a single-word quantity.
*/
static __inline__ void set_bit(int nr, volatile unsigned long *addr)

{
    test_and_set_bit(nr, addr);
}

/**
* clear_bit - Clears a bit in memory
* @nr: Bit to clear
* @addr: Address to start counting from
*
* clear_bit() is atomic and may not be reordered. However, it does
* not contain a memory barrier, so if it is used for locking purposes,
* you should call smp_mb__before_clear_bit() and/or smp_mb__after_clear_bit()
* in order to ensure changes are visible on other processors.
*/
static __inline__ void clear_bit(int nr, volatile unsigned long *addr)

{
    test_and_clear_bit(nr, addr);
}

/**
* __ffs - find first bit in word.
* @word: The word to search
*
* Undefined if no bit exists, so code should check against 0 first. */
static __inline__ unsigned long __ffs(unsigned long word)

{
    int clz;

    /* xxxxx10000 = word
     * xxxxx01111 = word - 1
     * 0000011111 = word ^ (word - 1)
     *      4     = 31 - clz(word ^ (word - 1))
     */

    __asm__ (
        "sub r0, %[word], #1\n"
        "eor r0, r0, %[word]\n"
        "clz %[clz], r0\n":
        /* Outputs: */
        [clz] "=r"(clz):
        /* Inputs: */
        [word] "r"(word):
        /* Clobbers: */
        "r0");

    return 31 - clz;
}

#else /* ifdef __arm__ */
#error "Unsupported architecture"
#endif
#endif /* ifdef __INSIDE_MINIOS */

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

/* If *ptr == old, then store new there (and return new).
* Otherwise, return the old value.
* Atomic. */
#define synch_cmpxchg(ptr, old, new) \
({ __typeof__(*ptr) stored = old; \
__atomic_compare_exchange_n(ptr, &stored, new, 0, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST) ? new : old; \
})

#define synch_set_bit(n, addr) set_bit(n, addr)
#define synch_clear_bit(n, addr) clear_bit(n, addr) #define synch_test_and_set_bit(n, addr) test_and_set_bit(n, addr) #define synch_test_and_clear_bit(n, addr) test_and_clear_bit(n, addr) #define synch_test_bit(nr, addr) test_bit(nr, addr)

#endif /* not assembly */

#endif

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

#21 lore raw
Quoted 2 lines · Thomas Leonard, le Tue 17 Jun 2014 14:47:16 +0100, a écrit :

I'm not sure what the difference between the synch and non-synch versions is supposed to be. Currently, I'm just doing:

The synch version provides memory barriers (and can thus be used for synchronization of other things). The non-synch version only provides atomicity.

Quoted 2 lines

I used __ATOMIC_SEQ_CST as the memory model as that was the safest option, but maybe it's overkill.

The synch_ versions provide a full memory barrier, so seq consistency is fine. The non-synch versions can use a completely relaxed memory model.

Quoted 5 lines

The main user of these operations was gic.c, but it turns out that the atomic versions don't work here as the GIC registers aren't regular memory. So I replaced those with non-atomic versions.

Does this seem reasonable?

I guess there are other ways to make sure no two threads are accessing GIC registers, so it is fine, yes.

Samuel

#22 lore raw
Quoted 7 lines · Samuel Thibault
Quoted 2 lines · Thomas Leonard, le Tue 17 Jun 2014 14:47:16 +0100, a écrit :

I'm not sure what the difference between the synch and non-synch versions is supposed to be. Currently, I'm just doing:

The synch version provides memory barriers (and can thus be used for synchronization of other things). The non-synch version only provides atomicity.

OK, so does that mean that e.g. this comment in x86/os.h is wrong?

/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/

Quoted 16 lines
Quoted 2 lines

I used __ATOMIC_SEQ_CST as the memory model as that was the safest option, but maybe it's overkill.

The synch_ versions provide a full memory barrier, so seq consistency is fine. The non-synch versions can use a completely relaxed memory model.

Quoted 5 lines

The main user of these operations was gic.c, but it turns out that the atomic versions don't work here as the GIC registers aren't regular memory. So I replaced those with non-atomic versions.

Does this seem reasonable?

I guess there are other ways to make sure no two threads are accessing GIC registers, so it is fine, yes.

Samuel

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

_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
#23 lore raw
Quoted 11 lines · Thomas Leonard, le Wed 18 Jun 2014 08:55:45 +0100, a écrit :
Quoted 7 lines · Samuel Thibault
Quoted 2 lines · Thomas Leonard, le Tue 17 Jun 2014 14:47:16 +0100, a écrit :

I'm not sure what the difference between the synch and non-synch versions is supposed to be. Currently, I'm just doing:

The synch version provides memory barriers (and can thus be used for synchronization of other things). The non-synch version only provides atomicity.

OK, so does that mean that e.g. this comment in x86/os.h is wrong?

Quoted 8 lines

/**
* test_and_clear_bit - Clear a bit and return its old value
* @nr: Bit to clear
* @addr: Address to count from
*
* This operation is atomic and cannot be reordered.
* It also implies a memory barrier.
*/

Yes, it is wrong: LOCK is apparently defined to "".

Samuel

#24 lore raw
In reply to Thomas Leonard

On Wed, 2014-06-11 at 11:30 +0100, Thomas Leonard wrote:

I've applied the bits which Samuel has acked. Namely:

Quoted 3 lines

mini-os: tidied up code
mini-os: moved events code under arch
mini-os: don't include queue.h if there's no libc

Ian.