mini-os: initial ARM support
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
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
@@ -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
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.
Signed-off-by Thomas Leonard <[email protected]>
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
PATCH v3 2/7 mini-os: fixed shutdown thread
In reply to Thomas LeonardBefore, 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
@@ -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
@@ -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
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@@ -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
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@@ -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
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@@ -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_shutdowndeclaration 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
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@@ -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_shutdowndeclaration 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
PATCH v3 3/7 mini-os: tidied up code
In reply to Thomas LeonardFrom: Karim Raslan <[email protected]>
--- 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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 128struct 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
@@ -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
@@ -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
@@ -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
PATCH v3 4/7 mini-os: moved events code under arch
In reply to Thomas LeonardFrom: 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.
--- 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
@@ -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__) + asmvolatile ("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
@@ -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__) - asmvolatile ("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
@@ -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
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_actionsarray before calling the arch-specific code to make it more robust against future changes.Signed-off-by Karim Allah Ahmed <[email protected]>[[email protected]: separated from big ARM commit]Signed-off-by Thomas Leonard <[email protected]>
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.cextras/mini-os/arch/x86/events.c new file +31
-0@@ -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__) + asmvolatile ("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@@ -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__) - asmvolatile ("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@@ -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 -+-
PATCH v3 5/7 mini-os: switched initial C entry point to arch_init
In reply to Thomas LeonardFrom: Karim Raslan <[email protected]>
arch_print_info (a debug print called during start up) was also removed.
--- 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
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
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
@@ -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
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 :
Signed-off-by Thomas Leonard <[email protected]>
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@@ -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)
PATCH v3 7/7 mini-os: initial ARM support
In reply to Thomas LeonardFrom: 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]: 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)]
--- 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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -0,0 +1 @@ +void gic_init (void );
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> #else #error "Unsupported architecture"#endif
extras/mini-os/include/mm.h +2 -0
@@ -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
@@ -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
@@ -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
@@ -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
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
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.
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
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
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
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_CSTas 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
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_CSTas 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
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.his 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
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 includequeue.hif there's no libc
Ian.