mini-os: initial ARM support
v4 cover mini-os: initial ARM support
This series is based on Karim's ARM support commits, further broken up into smaller patches.
The comments from last time should be addressed too, plus a few other things:
- the series is rebased onto the patches that Ian already applied
- removing the "link" make target broke stubdom, so I brought that back
- the x86 stack address printk is back, and I moved all the other x86 printks to after the "WARN: don't do printk before here" line
- the TODOs in arm/os.h have been implemented (mainly using GCC intrinsics)
- added clrex to the IRQ handler return in case these get interrupted
- added an explicit -march=armv7-a to cope with other compiler defaults
- the zImage header now works with the XSA-95 fix to "xl create"
- added fixes for unbinding ports (also useful on x86)
- configued ARM not to fault on unaligned word accessess (useful for lwIP)
- fixed the off_t type to match POSIX (maybe Mini-OS shouldn't be defining it in the first place, but since it is, it should do it correctly).
- there are also some new patches adding support for using the FDT to initialise the MM, GIC and grant tables.
This patch roll is also available here:
https://github.com/talex5/xen/commits/sent-Jun-18
Please include Karim in any reply as I am not the author of much of this code.
Karim Raslan (3):
mini-os: switched initial C entry point to arch_init
mini-os: initial ARM support
mini-os: import libfdt
Thomas Leonard (9):
mini-os: build fixes
mini-os: fixed shutdown thread
mini-os: fixed format string error in unbind_evtchn
mini-os: use unbind_evtchn in unbind_all_ports
mini-os: made off_t type signed
mini-os: arm: show registers, stack and exception vector on fault
mini-os: get RAM base and size from the FDT
mini-os: get GIC addresses from FDT
mini-os: added ARM grant table initialisation
extras/mini-os/ARM-TODO.txt | 10 + extras/mini-os/COPYING | 27 + extras/mini-os/Config.mk | 2 + extras/mini-os/Makefile | 48 +- extras/mini-os/arch/arm/Makefile | 32 + extras/mini-os/arch/arm/arch.mk | 7 + extras/mini-os/arch/arm/arm32.S | 222 ++++ extras/mini-os/arch/arm/events.c | 30 + extras/mini-os/arch/arm/hypercalls32.S | 88 ++ extras/mini-os/arch/arm/minios-arm32.lds | 75 ++ extras/mini-os/arch/arm/mm.c | 162 +++ extras/mini-os/arch/arm/panic.c | 99 ++ extras/mini-os/arch/arm/sched.c | 37 + extras/mini-os/arch/arm/setup.c | 112 ++ extras/mini-os/arch/arm/time.c | 202 +++ extras/mini-os/arch/x86/events.c | 4 + extras/mini-os/arch/x86/mm.c | 13 + extras/mini-os/arch/x86/setup.c | 44 +- extras/mini-os/arch/x86/x86_32.S | 2 +- extras/mini-os/arch/x86/x86_64.S | 2 +- extras/mini-os/drivers/gic.c | 217 ++++ extras/mini-os/events.c | 39 +- extras/mini-os/gnttab.c | 11 +- extras/mini-os/hypervisor.c | 12 +- extras/mini-os/include/arm/arch_endian.h | 7 + extras/mini-os/include/arm/arch_limits.h | 9 + extras/mini-os/include/arm/arch_mm.h | 37 + extras/mini-os/include/arm/arch_sched.h | 22 + extras/mini-os/include/arm/arch_spinlock.h | 49 + extras/mini-os/include/arm/arm32/arch_wordsize.h | 1 + extras/mini-os/include/arm/hypercall-arm32.h | 173 +++ extras/mini-os/include/arm/os.h | 232 ++++ extras/mini-os/include/arm/traps.h | 20 + extras/mini-os/include/events.h | 4 + extras/mini-os/include/fdt.h | 60 + extras/mini-os/include/gic.h | 1 + extras/mini-os/include/gnttab.h | 1 + extras/mini-os/include/hypervisor.h | 4 + extras/mini-os/include/kernel.h | 6 +- extras/mini-os/include/lib.h | 4 +- extras/mini-os/include/libfdt.h | 1478 ++++++++++++++++++++++ extras/mini-os/include/libfdt_env.h | 37 + extras/mini-os/include/mm.h | 2 + extras/mini-os/include/types.h | 14 +- extras/mini-os/include/x86/os.h | 2 - extras/mini-os/kernel.c | 55 +- extras/mini-os/lib/fdt/fdt.c | 222 ++++ extras/mini-os/lib/fdt/fdt_empty_tree.c | 84 ++ extras/mini-os/lib/fdt/fdt_ro.c | 574 +++++++++ extras/mini-os/lib/fdt/fdt_rw.c | 492 +++++++ extras/mini-os/lib/fdt/fdt_strerror.c | 96 ++ extras/mini-os/lib/fdt/fdt_sw.c | 256 ++++ extras/mini-os/lib/fdt/fdt_wip.c | 118 ++ extras/mini-os/lib/fdt/libfdt_internal.h | 95 ++ extras/mini-os/lib/memmove.c | 45 + extras/mini-os/lib/string.c | 12 + extras/mini-os/main.c | 2 +- extras/mini-os/mm.c | 4 +- extras/mini-os/sched.c | 29 +- 59 files changed, 5632 insertions(+), 112 deletions(-) create mode 100644 extras/mini-os/ARM-TODO.txt create mode 100755 extras/mini-os/arch/arm/Makefile create mode 100644 extras/mini-os/arch/arm/arch.mk create mode 100644 extras/mini-os/arch/arm/arm32.S create mode 100644 extras/mini-os/arch/arm/events.c create mode 100644 extras/mini-os/arch/arm/hypercalls32.S create mode 100755 extras/mini-os/arch/arm/minios-arm32.lds create mode 100644 extras/mini-os/arch/arm/mm.c create mode 100644 extras/mini-os/arch/arm/panic.c create mode 100644 extras/mini-os/arch/arm/sched.c create mode 100644 extras/mini-os/arch/arm/setup.c create mode 100644 extras/mini-os/arch/arm/time.c create mode 100644 extras/mini-os/drivers/gic.c create mode 100644 extras/mini-os/include/arm/arch_endian.h create mode 100644 extras/mini-os/include/arm/arch_limits.h create mode 100644 extras/mini-os/include/arm/arch_mm.h create mode 100644 extras/mini-os/include/arm/arch_sched.h create mode 100755 extras/mini-os/include/arm/arch_spinlock.h create mode 100644 extras/mini-os/include/arm/arm32/arch_wordsize.h create mode 100644 extras/mini-os/include/arm/hypercall-arm32.h create mode 100644 extras/mini-os/include/arm/os.h create mode 100644 extras/mini-os/include/arm/traps.h create mode 100644 extras/mini-os/include/fdt.h create mode 100644 extras/mini-os/include/gic.h create mode 100644 extras/mini-os/include/libfdt.h create mode 100644 extras/mini-os/include/libfdt_env.h create mode 100644 extras/mini-os/lib/fdt/fdt.c create mode 100644 extras/mini-os/lib/fdt/fdt_empty_tree.c create mode 100644 extras/mini-os/lib/fdt/fdt_ro.c create mode 100644 extras/mini-os/lib/fdt/fdt_rw.c create mode 100644 extras/mini-os/lib/fdt/fdt_strerror.c create mode 100644 extras/mini-os/lib/fdt/fdt_sw.c create mode 100644 extras/mini-os/lib/fdt/fdt_wip.c create mode 100644 extras/mini-os/lib/fdt/libfdt_internal.h create mode 100644 extras/mini-os/lib/memmove.c
Signature · 1 line
2.0.0
PATCH v4 1/12 mini-os: build fixes
Make .o rules depend on the includes. Before, only the final link step depended on setting up the includes directory, making parallel builds unreliable.
Make symlinks use explicit make rules instead of using a phony target. Avoids unnecessary rebuilds.
--- extras/mini-os/Makefile | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)
extras/mini-os/Makefile +17 -6
@@ -50,6 +50,11 @@ flags-$(CONFIG_XENBUS) += -DCONFIG_XENBUS DEF_CFLAGS += $(flags-y) +# Symlinks and headers that must be created before building the C files +GENERATED_HEADERS := include/list.h $(ARCH_LINKS) include/mini-os include/xen include/$(TARGET_ARCH_FAM)/mini-os + +EXTRA_DEPS += $(GENERATED_HEADERS) + # Include common mini-os makerules. include minios.mk
@@ -124,11 +129,18 @@ include/list.h: $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue-h-seddery $ perl $^ --prefix=minios >[email protected] $(call move-if-changed,[email protected],$@) +# Used by stubdom's Makefile .PHONY: links -links: include/list.h $(ARCH_LINKS) - [ -e include/xen ] || ln -sf ../../../xen/include/public include/xen - [ -e include/mini-os ] || ln -sf . include/mini-os - [ -e include/$(TARGET_ARCH_FAM)/mini-os ] || ln -sf . include/$(TARGET_ARCH_FAM)/mini-os +links: $(GENERATED_HEADERS) + +include/xen: + ln -sf ../../../xen/include/public $@ + +include/mini-os: + ln -sf . $@ + +include/$(TARGET_ARCH_FAM)/mini-os: + ln -sf . $@ .PHONY: arch_lib arch_lib:
@@ -174,7 +186,7 @@ ifneq ($(APP_OBJS),) APP_O=$(OBJ_DIR)/$(TARGET)_app.o endif -$(OBJ_DIR)/$(TARGET): links include/list.h $(OBJS) $(APP_O) arch_lib +$(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected] $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected] $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@
@@ -212,4 +224,3 @@ tags: .PHONY: TAGS TAGS: $(all_sources) | xargs etags -
Signature · 1 line
2.0.0
Re: [PATCH ARM v4 01/12] mini-os: build fixes
Quoted 9 lines · Thomas Leonard
Make .o rules depend on the includes. Before, only the final link step depended on setting up the includes directory, making parallel builds unreliable.
Make symlinks use explicit make rules instead of using a phony target. Avoids unnecessary rebuilds.
[[email protected]: bring back "make links", for stubdom]Signed-off-by Thomas Leonard <[email protected]>
Quoted 57 lines
--- extras/mini-os/Makefile | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)extras/mini-os/Makefile +17
-6@@ -50,6 +50,11 @@ flags-$(CONFIG_XENBUS) += -DCONFIG_XENBUS DEF_CFLAGS += $(flags-y) +# Symlinks and headers that must be created before building the C files +GENERATED_HEADERS := include/list.h $(ARCH_LINKS) include/mini-os include/xen include/$(TARGET_ARCH_FAM)/mini-os + +EXTRA_DEPS += $(GENERATED_HEADERS) + # Include common mini-os makerules. include minios.mk@@ -124,11 +129,18 @@ include/list.h: $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue-h-seddery $ perl $^ --prefix=minios >[email protected] $(call move-if-changed,[email protected],$@) +# Used by stubdom's Makefile .PHONY: links -links: include/list.h $(ARCH_LINKS) - [ -e include/xen ] || ln -sf ../../../xen/include/public include/xen - [ -e include/mini-os ] || ln -sf . include/mini-os - [ -e include/$(TARGET_ARCH_FAM)/mini-os ] || ln -sf . include/$(TARGET_ARCH_FAM)/mini-os +links: $(GENERATED_HEADERS) + +include/xen: + ln -sf ../../../xen/include/public $@ + +include/mini-os: + ln -sf . $@ + +include/$(TARGET_ARCH_FAM)/mini-os: + ln -sf . $@ .PHONY: arch_lib arch_lib:@@ -174,7 +186,7 @@ ifneq ($(APP_OBJS),) APP_O=$(OBJ_DIR)/$(TARGET)_app.o endif -$(OBJ_DIR)/$(TARGET): links include/list.h $(OBJS) $(APP_O) arch_lib +$(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected] $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected] $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@@@ -212,4 +224,3 @@ tags: .PHONY: TAGS TAGS: $(all_sources) | xargs etags -
Re: [PATCH ARM v4 01/12] mini-os: build fixes
In reply to Thomas LeonardQuoted 9 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:15 +0100, a écrit :
Make .o rules depend on the includes. Before, only the final link step depended on setting up the includes directory, making parallel builds unreliable.
Make symlinks use explicit make rules instead of using a phony target. Avoids unnecessary rebuilds.
[[email protected]: bring back "make links", for stubdom]Signed-off-by Thomas Leonard <[email protected]>
Quoted 60 lines
--- extras/mini-os/Makefile | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-)extras/mini-os/Makefile +17
-6@@ -50,6 +50,11 @@ flags-$(CONFIG_XENBUS) += -DCONFIG_XENBUS DEF_CFLAGS += $(flags-y) +# Symlinks and headers that must be created before building the C files +GENERATED_HEADERS := include/list.h $(ARCH_LINKS) include/mini-os include/xen include/$(TARGET_ARCH_FAM)/mini-os + +EXTRA_DEPS += $(GENERATED_HEADERS) + # Include common mini-os makerules. include minios.mk@@ -124,11 +129,18 @@ include/list.h: $(XEN_ROOT)/tools/include/xen-external/bsd-sys-queue-h-seddery $ perl $^ --prefix=minios >[email protected] $(call move-if-changed,[email protected],$@) +# Used by stubdom's Makefile .PHONY: links -links: include/list.h $(ARCH_LINKS) - [ -e include/xen ] || ln -sf ../../../xen/include/public include/xen - [ -e include/mini-os ] || ln -sf . include/mini-os - [ -e include/$(TARGET_ARCH_FAM)/mini-os ] || ln -sf . include/$(TARGET_ARCH_FAM)/mini-os +links: $(GENERATED_HEADERS) + +include/xen: + ln -sf ../../../xen/include/public $@ + +include/mini-os: + ln -sf . $@ + +include/$(TARGET_ARCH_FAM)/mini-os: + ln -sf . $@ .PHONY: arch_lib arch_lib:@@ -174,7 +186,7 @@ ifneq ($(APP_OBJS),) APP_O=$(OBJ_DIR)/$(TARGET)_app.o endif -$(OBJ_DIR)/$(TARGET): links include/list.h $(OBJS) $(APP_O) arch_lib +$(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected] $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected] $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@@@ -212,4 +224,3 @@ tags: .PHONY: TAGS TAGS: $(all_sources) | xargs etags -Signature · 1 line
2.0.0
Signature · 4 lines
Samuel I develop for Linux for a living, I used to develop for DOS. Going from DOS to Linux is like trading a glider for an F117. (By [email protected], Lawrence Foard)
PATCH v4 2/12 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
@@ -68,7 +68,9 @@ void setup_xen_features(void)/* This should be overridden by the application we are linked against. */ __attribute__((weak))void app_shutdown (unsigned reason) { +struct sched_shutdown sched_shutdown = { .reason = reason };printk ("Shutdown requested: %d\n" , reason); +HYPERVISOR_sched_op (SCHEDOP_shutdown, &sched_shutdown); }static void shutdown_thread (void *p)
@@ -76,12 +78,14 @@ static void shutdown_thread(void *p)const char *path ="control/shutdown" ;const char *token = path;xenbus_event_queue events =NULL ; -char *shutdown, *err; +char *shutdown =NULL , *err;unsigned int shutdown_reason;xenbus_watch_path_token (XBT_NIL , path, token, &events); -while ((err =xenbus_read (XBT_NIL , path, &shutdown)) !=NULL ) +while ((err =xenbus_read (XBT_NIL , path, &shutdown)) !=NULL || !strcmp (shutdown,"" )) {free (err); +free (shutdown); + shutdown =NULL ;xenbus_wait_for_watch (&events); } err =xenbus_unwatch_path_token (XBT_NIL , path, token);
@@ -106,7 +110,7 @@ static void shutdown_thread(void *p)/* This should be overridden by the application we are linked against. */ __attribute__((weak))int app_main (start_info_t *si) { -printk ("Dummy main: start_info=%p\n" , si); +printk ("kernel.c: dummy main: start_info=%p\n" , si);return 0 ; }
extras/mini-os/main.c +1 -1
@@ -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
PATCH v4 3/12 mini-os: fixed format string error in unbind_evtchn
In reply to Thomas LeonardWould crash if HYPERVISOR_event_channel_op returned an error code. The other changes in this commit are just fixing indentation.
--- extras/mini-os/events.c | 25 ++++++++++++------------- 1 file changed, 12 insertions(+), 13 deletions(-)
extras/mini-os/events.c +12 -13
@@ -109,24 +109,23 @@ evtchn_port_t bind_evtchn(evtchn_port_t port, evtchn_handler_t handler,void unbind_evtchn (evtchn_port_t port ) { -struct evtchn_close close; +struct evtchn_close close;int rc; -if ( ev_actions[port].handler == default_handler ) -printk ("WARN: No handler for port %d when unbinding\n" , port); -mask_evtchn (port); -clear_evtchn (port); +if ( ev_actions[port].handler == default_handler ) +printk ("WARN: No handler for port %d when unbinding\n" , port); +mask_evtchn (port); +clear_evtchn (port); - ev_actions[port].handler = default_handler; -wmb (); - ev_actions[port].data =NULL ; -clear_bit (port, bound_ports); + ev_actions[port].handler = default_handler; +wmb (); + ev_actions[port].data =NULL ; +clear_bit (port, bound_ports); - close.port = port; - rc =HYPERVISOR_event_channel_op (EVTCHNOP_close, &close); + close.port = port; + rc =HYPERVISOR_event_channel_op (EVTCHNOP_close, &close);if ( rc ) -printk ("WARN: close_port %s failed rc=%d. ignored\n" , port, rc); - +printk ("WARN: close_port %d failed rc=%d. ignored\n" , port, rc); }evtchn_port_t bind_virq (uint32_t virq,evtchn_handler_t handler,void *data)
Signature · 1 line
2.0.0
Re: [PATCH ARM v4 03/12] mini-os: fixed format string error in unbind_evtchn
Quoted 2 lines · Thomas Leonard
Would crash if
HYPERVISOR_event_channel_opreturned an error code. The other changes in this commit are just fixing indentation.
A little bit of this sort of mixing is tolerable, but a 4 bit change with two dozen lines of reindenting around it might be considered by some to be going to far ;-)
Quoted 1 line
Signed-off-by Thomas Leonard <[email protected]>
(this time)
Ian.
Re: [PATCH ARM v4 03/12] mini-os: fixed format string error in unbind_evtchn
In reply to Thomas LeonardQuoted 4 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:17 +0100, a écrit :
Would crash if
HYPERVISOR_event_channel_opreturned an error code. The other changes in this commit are just fixing indentation.Signed-off-by Thomas Leonard <[email protected]>
PATCH v4 4/12 mini-os: use unbind_evtchn in unbind_all_ports
In reply to Thomas LeonardThis marks the channel as closed, in case someone tries to use it again.
--- extras/mini-os/events.c | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-)
extras/mini-os/events.c +1 -8
@@ -43,7 +43,6 @@ void unbind_all_ports(void)int cpu =0 ;shared_info_t *s = HYPERVISOR_shared_info;vcpu_info_t *vcpu_info = &s->vcpu_info[cpu]; -int rc;for ( i =0 ; i <NR_EVS ; i++ ) {
@@ -53,14 +52,8 @@ void unbind_all_ports(void)if (test_and_clear_bit (i, bound_ports) ) { -struct evtchn_close close;printk ("port %d still bound!\n" , i); -mask_evtchn (i); - close.port = i; - rc =HYPERVISOR_event_channel_op (EVTCHNOP_close, &close); -if ( rc ) -printk ("WARN: close_port %s failed rc=%d. ignored\n" , i, rc); -clear_evtchn (i); +unbind_evtchn (i); } } vcpu_info->evtchn_upcall_pending =0 ;
Signature · 1 line
2.0.0
Re: [PATCH ARM v4 04/12] mini-os: use unbind_evtchn in unbind_all_ports
Quoted 3 lines · Thomas Leonard
This marks the channel as closed, in case someone tries to use it again.
Signed-off-by Thomas Leonard <[email protected]>
Re: [PATCH ARM v4 04/12] mini-os: use unbind_evtchn in unbind_all_ports
In reply to Thomas LeonardQuoted 3 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:18 +0100, a écrit :
This marks the channel as closed, in case someone tries to use it again.
Signed-off-by Thomas Leonard <[email protected]>
PATCH v4 5/12 mini-os: made off_t type signed
In reply to Thomas LeonardPOSIX requires this.
--- extras/mini-os/include/types.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
extras/mini-os/include/types.h +1 -1
@@ -73,7 +73,7 @@ typedef unsigned long uint64_t;#endif typedef uint64_t uintmax_t ;typedef int64_t intmax_t ; -typedef uint64_t off_t ; +typedef int64_t off_t ;#endif typedef intptr_t ptrdiff_t ;
Signature · 1 line
2.0.0
Re: [PATCH ARM v4 05/12] mini-os: made off_t type signed
Quoted 3 lines · Thomas Leonard
POSIX requires this.
Signed-off-by Thomas Leonard <[email protected]>
Re: [PATCH ARM v4 05/12] mini-os: made off_t type signed
In reply to Thomas LeonardQuoted 3 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:19 +0100, a écrit :
POSIX requires this.
Signed-off-by Thomas Leonard <[email protected]>
PATCH v4 6/12 mini-os: switched initial C entry point to arch_init
In reply to Thomas LeonardFrom: Karim Raslan <[email protected]>
--- extras/mini-os/arch/x86/setup.c | 44 ++++++++++++++++++++++++++++++++-------- extras/mini-os/arch/x86/x86_32.S | 2 +- extras/mini-os/arch/x86/x86_64.S | 2 +- extras/mini-os/include/kernel.h | 6 ++++-- extras/mini-os/include/x86/os.h | 2 -- extras/mini-os/kernel.c | 37 ++++----------------------------- 6 files changed, 46 insertions(+), 47 deletions(-)
extras/mini-os/arch/x86/setup.c +36 -8
@@ -28,6 +28,8 @@#include <mini-os/os.h> #include <mini-os/lib.h> /* for printk, memcpy */ +#include <mini-os/kernel.h> +#include <xen/xen.h> /* * Shared page for communicating with the hypervisor.
@@ -87,20 +89,45 @@ static inline void sse_init(void) {#define sse_init ()#endif + +/* +* INITIAL C ENTRY POINT. +*/ void arch_init (start_info_t *si) { +static char hello[] ="Bootstrapping...\n" ; + + (void )HYPERVISOR_console_io (CONSOLEIO_write,strlen (hello), hello); + +trap_init (); +/*Initialize floating point unit */ -fpu_init (); +fpu_init (); -/* Initialize SSE */ -sse_init (); +/* Initialize SSE */ +sse_init ();/* Copy the start_info struct to a globally-accessible area. */ /* WARN: don't do printk before here, it uses information from shared_info. Use xprintk instead. */ memcpy (&start_info, si,sizeof (*si)); +/* print out some useful information */ +printk ("Xen Minimal OS!\n" ); +printk (" start_info: %p(VA)\n" , si); +printk (" nr_pages: 0x%lx\n" , si->nr_pages); +printk (" shared_inf: 0x%08lx(MA)\n" , si->shared_info); +printk (" pt_base: %p(VA)\n" , (void *)si->pt_base); +printk ("nr_pt_frames: 0x%lx\n" , si->nr_pt_frames); +printk (" mfn_list: %p(VA)\n" , (void *)si->mfn_list); +printk (" mod_start: 0x%lx(VA)\n" , si->mod_start); +printk (" mod_len: %lu\n" , si->mod_len); +printk (" flags: 0x%x\n" , (unsigned int )si->flags); +printk (" cmd_line: %s\n" , + si->cmd_line ? (const char *)si->cmd_line :"NULL" ); +printk (" stack: %p-%p\n" , stack, stack +sizeof (stack)); +/* set up minimal memory infos */ phys_to_machine_mapping = (unsigned long *)start_info.mfn_list;
@@ -118,12 +145,15 @@ arch_init(start_info_t *si) (unsigned long)failsafe_callback, 0);#endif - +start_kernel (); }void arch_fini (void ) { +/* Reset traps */ +trap_fini (); +#ifdef __i386__HYPERVISOR_set_callbacks (0 ,0 ,0 ,0 );#else
@@ -132,9 +162,7 @@ arch_fini(void) }void -arch_print_info (void ) +arch_do_exit (void ) { -printk (" stack: %p-%p\n" , stack, stack +sizeof (stack)); +stack_walk (); } - -
extras/mini-os/arch/x86/x86_32.S +1 -1
@@ -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 +4 -33
@@ -28,6 +28,7 @@*/ #include <mini-os/os.h> +#include <mini-os/kernel.h> #include <mini-os/hypervisor.h> #include <mini-os/mm.h> #include <mini-os/events.h>
@@ -114,41 +115,14 @@ __attribute__((weak)) int app_main(start_info_t *si)return 0 ; } -/* -* INITIAL C ENTRY POINT. -*/ -void start_kernel (start_info_t *si) +void start_kernel (void ) { -static char hello[] ="Bootstrapping...\n" ; - - (void )HYPERVISOR_console_io (CONSOLEIO_write,strlen (hello), hello); - -arch_init (si); - -trap_init (); - -/* print out some useful information */ -printk ("Xen Minimal OS!\n" ); -printk (" start_info: %p(VA)\n" , si); -printk (" nr_pages: 0x%lx\n" , si->nr_pages); -printk (" shared_inf: 0x%08lx(MA)\n" , si->shared_info); -printk (" pt_base: %p(VA)\n" , (void *)si->pt_base); -printk ("nr_pt_frames: 0x%lx\n" , si->nr_pt_frames); -printk (" mfn_list: %p(VA)\n" , (void *)si->mfn_list); -printk (" mod_start: 0x%lx(VA)\n" , si->mod_start); -printk (" mod_len: %lu\n" , si->mod_len); -printk (" flags: 0x%x\n" , (unsigned int )si->flags); -printk (" cmd_line: %s\n" , - si->cmd_line ? (const char *)si->cmd_line :"NULL" ); -/* Set up events. */ init_events (); - +/* ENABLE EVENT DELIVERY. This is disabled at start of day. */ __sti (); -arch_print_info (); -setup_xen_features ();/* Init memory management. */
@@ -201,9 +175,6 @@ void stop_kernel(void)/* Reset events. */ fini_events (); -/* Reset traps */ -trap_fini (); -/* Reset arch details */ arch_fini (); }
@@ -218,7 +189,7 @@ void stop_kernel(void)void do_exit (void ) {printk ("Do_exit called!\n" ); -stack_walk (); +arch_do_exit ();for ( ;; ) {struct sched_shutdown sched_shutdown = { .reason = SHUTDOWN_crash };
Signature · 1 line
2.0.0
PATCH v4 7/12 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 | 12 ++ extras/mini-os/Config.mk | 2 + extras/mini-os/Makefile | 14 ++ extras/mini-os/arch/arm/Makefile | 32 ++++ extras/mini-os/arch/arm/arch.mk | 7 + extras/mini-os/arch/arm/arm32.S | 155 +++++++++++++++ extras/mini-os/arch/arm/events.c | 30 +++ extras/mini-os/arch/arm/hypercalls32.S | 88 +++++++++ extras/mini-os/arch/arm/minios-arm32.lds | 75 ++++++++ extras/mini-os/arch/arm/mm.c | 44 +++++ extras/mini-os/arch/arm/sched.c | 37 ++++ extras/mini-os/arch/arm/setup.c | 102 ++++++++++ extras/mini-os/arch/arm/time.c | 202 ++++++++++++++++++++ extras/mini-os/arch/x86/events.c | 4 + extras/mini-os/drivers/gic.c | 187 ++++++++++++++++++ extras/mini-os/events.c | 5 +- extras/mini-os/hypervisor.c | 12 +- extras/mini-os/include/arm/arch_endian.h | 7 + extras/mini-os/include/arm/arch_limits.h | 9 + extras/mini-os/include/arm/arch_mm.h | 37 ++++ extras/mini-os/include/arm/arch_sched.h | 22 +++ extras/mini-os/include/arm/arch_spinlock.h | 49 +++++ extras/mini-os/include/arm/arm32/arch_wordsize.h | 1 + extras/mini-os/include/arm/hypercall-arm32.h | 173 +++++++++++++++++ extras/mini-os/include/arm/os.h | 230 +++++++++++++++++++++++ extras/mini-os/include/arm/traps.h | 20 ++ extras/mini-os/include/events.h | 4 + extras/mini-os/include/gic.h | 1 + extras/mini-os/include/hypervisor.h | 4 + extras/mini-os/include/mm.h | 2 + extras/mini-os/include/types.h | 12 +- extras/mini-os/kernel.c | 8 + extras/mini-os/sched.c | 29 +-- 33 files changed, 1595 insertions(+), 21 deletions(-) create mode 100644 extras/mini-os/ARM-TODO.txt create mode 100755 extras/mini-os/arch/arm/Makefile create mode 100644 extras/mini-os/arch/arm/arch.mk create mode 100644 extras/mini-os/arch/arm/arm32.S create mode 100644 extras/mini-os/arch/arm/events.c create mode 100644 extras/mini-os/arch/arm/hypercalls32.S create mode 100755 extras/mini-os/arch/arm/minios-arm32.lds create mode 100644 extras/mini-os/arch/arm/mm.c create mode 100644 extras/mini-os/arch/arm/sched.c create mode 100644 extras/mini-os/arch/arm/setup.c create mode 100644 extras/mini-os/arch/arm/time.c create mode 100644 extras/mini-os/drivers/gic.c create mode 100644 extras/mini-os/include/arm/arch_endian.h create mode 100644 extras/mini-os/include/arm/arch_limits.h create mode 100644 extras/mini-os/include/arm/arch_mm.h create mode 100644 extras/mini-os/include/arm/arch_sched.h create mode 100755 extras/mini-os/include/arm/arch_spinlock.h create mode 100644 extras/mini-os/include/arm/arm32/arch_wordsize.h create mode 100644 extras/mini-os/include/arm/hypercall-arm32.h create mode 100644 extras/mini-os/include/arm/os.h create mode 100644 extras/mini-os/include/arm/traps.h create mode 100644 extras/mini-os/include/gic.h
extras/mini-os/ARM-TODO.txt new file +12 -0
@@ -0,0 +1,12 @@ +* support abort exception handling ( and others ) +* scheduling! +* gic request_irq implementation, currently all IRQs all hardcoded in gic irq handler. +* use device tree instead of the currently hardcoded values +* Add virtual memory support and make vstart = 0 ( use 4k descriptors instead of 1M descriptors ) +* sched +* fini_gnttab +* bind_* +* add multiple cpu support (?) +* map_frames +* make sure that wallclock is functioning properly +* evtchn_get_peercontext
extras/mini-os/Config.mk +2 -0
@@ -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
@@ -77,6 +77,14 @@ TARGET := mini-os # Subdirectories common to mini-os SUBDIRS := lib xenbus console +ifeq ($(XEN_TARGET_ARCH),arm32) +# ARM drivers +src-y += drivers/gic.c + +# Need libgcc.a for division helpers +LDLIBS += `$(CC) -print-libgcc-file-name` +endif + src-$(CONFIG_BLKFRONT) += blkfront.c src-$(CONFIG_TPMFRONT) += tpmfront.c src-$(CONFIG_TPM_TIS) += tpm_tis.c
@@ -97,7 +105,9 @@ src-y += sched.c src-$(CONFIG_TEST) += test.c src-y += lib/ctype.c +ifneq ($(XEN_TARGET_ARCH),arm32) src-y += lib/math.c +endif src-y += lib/printf.c src-y += lib/stack_chk_fail.c src-y += lib/string.c
@@ -190,7 +200,11 @@ $(OBJ_DIR)/$(TARGET): $(OBJS) $(APP_O) arch_lib $(LD) -r $(LDFLAGS) $(HEAD_OBJ) $(APP_O) $(OBJS) $(LDARCHLIB) $(LDLIBS) -o [email protected] $(OBJCOPY) -w -G $(GLOBAL_PREFIX)* -G _start [email protected] [email protected] $(LD) $(LDFLAGS) $(LDFLAGS_FINAL) [email protected] $(EXTRA_OBJS) -o $@ +ifeq ($(XEN_TARGET_ARCH),arm32) + $(OBJCOPY) -O binary $@ [email protected] +else gzip -f -9 -c $@ >[email protected] +endif .PHONY: clean arch_clean
extras/mini-os/arch/arm/Makefile new file +32 -0
@@ -0,0 +1,32 @@ +# +# ARM architecture specific makefiles. +# + +XEN_ROOT = $(CURDIR)/../../../.. +include $(XEN_ROOT)/Config.mk +include ../../Config.mk + +# include arch.mk has to be before minios.mk! + +include arch.mk +include ../../minios.mk + +# Sources here are all *.c (without $(XEN_TARGET_ARCH).S) +# This is handled in $(HEAD_ARCH_OBJ) +ARCH_SRCS := $(wildcard *.c) + +# The objects built from the sources. +ARCH_OBJS := $(patsubst %.c,$(OBJ_DIR)/%.o,$(ARCH_SRCS)) + +ARCH_OBJS += hypercalls32.o + +all: $(OBJ_DIR)/$(ARCH_LIB) + +# $(HEAD_ARCH_OBJ) is only built here, needed on linking +# in ../../Makefile. +$(OBJ_DIR)/$(ARCH_LIB): $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ) + $(AR) rv $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) + +clean: + rm -f $(OBJ_DIR)/$(ARCH_LIB) $(ARCH_OBJS) $(OBJ_DIR)/$(HEAD_ARCH_OBJ) +
extras/mini-os/arch/arm/arch.mk new file +7 -0
@@ -0,0 +1,7 @@ +ifeq ($(XEN_TARGET_ARCH),arm32) +DEF_ASFLAGS += -march=armv7-a +ARCH_CFLAGS := -march=armv7-a -marm -fms-extensions -D__arm__ -DXEN_HAVE_PV_GUEST_ENTRY #-DCPU_EXCLUSIVE_LDST +EXTRA_INC += $(TARGET_ARCH_FAM)/$(XEN_TARGET_ARCH) +EXTRA_SRC += arch/$(EXTRA_INC) +endif +
extras/mini-os/arch/arm/arm32.S new file +155 -0
155 lines not on this page · raw message
extras/mini-os/arch/arm/events.c new file +30 -0
@@ -0,0 +1,30 @@ +#include <mini-os/os.h> +#include <mini-os/events.h> +#include <mini-os/hypervisor.h> + +static void virq_debug (evtchn_port_t port,struct pt_regs *regs,void *params) +{ +printk ("Received a virq_debug event\n" ); +} + +evtchn_port_t debug_port =-1 ; +void arch_init_events (void ) +{ + debug_port =bind_virq (VIRQ_DEBUG , (evtchn_handler_t )virq_debug,0 ); +if (debug_port ==-1 ) +BUG (); +unmask_evtchn (debug_port); +} + +void arch_unbind_ports (void ) +{ +if (debug_port !=-1 ) + { +mask_evtchn (debug_port); +unbind_evtchn (debug_port); + } +} + +void arch_fini_events (void ) +{ +}
extras/mini-os/arch/arm/hypercalls32.S new file +88 -0
88 lines not on this page · raw message
extras/mini-os/arch/arm/minios-arm32.lds new file +75 -0
75 lines not on this page · raw message
extras/mini-os/arch/arm/mm.c new file +44 -0
44 lines not on this page · raw message
extras/mini-os/arch/arm/sched.c new file +37 -0
@@ -0,0 +1,37 @@ +#include <mini-os/sched.h> +#include <mini-os/xmalloc.h> + +void arm_start_thread (void ); + +/* Architecture specific setup of thread creation */ +struct thread *arch_create_thread (char *name,void (*function)(void *), +void *data) +{ +struct thread *thread; + + thread = xmalloc(struct thread); +/* We can't use lazy allocation here since the trap handler runs on the stack */ + thread->stack = (char *)alloc_pages (STACK_SIZE_PAGE_ORDER ); + thread->name = name; +printk ("Thread \"%s\": pointer: 0x%lx, stack: 0x%lx\n" , name, thread, + thread->stack); + +/* Save pointer to the thread on the stack, used by current macro */ + *((unsigned long *)thread->stack) = (unsigned long )thread; + +/* Push the details to pass to arm_start_thread onto the stack */ +int *sp = (int *) (thread->stack +STACK_SIZE ); + *(--sp) = (int ) function; + *(--sp) = (int ) data; + thread->sp = (unsigned long ) sp; + + thread->ip = (unsigned long ) arm_start_thread; + +return thread; +} + +void run_idle_thread (void ) +{ + __asm__ __volatile__ ("mov sp, %0; mov pc, %1" ::"r" (idle_thread->sp),"r" (idle_thread->ip)); +/* Never arrive here! */ +}
extras/mini-os/arch/arm/setup.c new file +102 -0
102 lines not on this page · raw message
extras/mini-os/arch/arm/time.c new file +202 -0
202 lines not on this page · raw message
extras/mini-os/arch/x86/events.c +4 -0
@@ -23,6 +23,10 @@ void arch_init_events(void)#endif } +void arch_unbind_ports (void ) +{ +} +void arch_fini_events (void ) {#if defined(__x86_64__)
extras/mini-os/drivers/gic.c new file +187 -0
187 lines not on this page · raw message
extras/mini-os/events.c +4 -1
@@ -179,6 +179,7 @@ void init_events(void)void fini_events (void ) {/* Dealloc all events */ +arch_unbind_ports ();unbind_all_ports ();arch_fini_events (); }
@@ -238,7 +239,8 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,int evtchn_get_peercontext (evtchn_port_t local_port,char *ctx,int size) { -int rc; +int rc =0 ; +#ifndef __arm__/* TODO */ uint32_t sid;struct xen_flask_op op; op.cmd =FLASK_GET_PEER_SID ;
@@ -253,6 +255,7 @@ int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size) op.u.sid_context.size = size;set_xen_guest_handle (op.u.sid_context.context, ctx); rc =_hypercall1 (int, xsm_op, &op); +#endif return rc; }
extras/mini-os/hypervisor.c +11 -1
@@ -64,7 +64,7 @@ void do_hypervisor_callback(struct pt_regs *regs) l2 &= ~(1UL << l2i); port = (l1i * (sizeof (unsigned long ) *8 )) + l2i; -do_event (port, regs); +do_event (port, regs); } }
@@ -73,18 +73,26 @@ void do_hypervisor_callback(struct pt_regs *regs)void force_evtchn_callback (void ) { +#ifdef XEN_HAVE_PV_UPCALL_MASK int save; +#endif vcpu_info_t *vcpu; vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id ()]; +#ifdef XEN_HAVE_PV_UPCALL_MASK save = vcpu->evtchn_upcall_mask; +#endif while (vcpu->evtchn_upcall_pending) { +#ifdef XEN_HAVE_PV_UPCALL_MASK vcpu->evtchn_upcall_mask =1 ; +#endif barrier ();do_hypervisor_callback (NULL );barrier (); +#ifdef XEN_HAVE_PV_UPCALL_MASK vcpu->evtchn_upcall_mask = save;barrier (); +#endif }; }
@@ -110,7 +118,9 @@ inline void unmask_evtchn(uint32_t port) &vcpu_info->evtchn_pending_sel) ) { vcpu_info->evtchn_upcall_pending =1 ; +#ifdef XEN_HAVE_PV_UPCALL_MASK if ( !vcpu_info->evtchn_upcall_mask ) +#endif force_evtchn_callback (); } }
extras/mini-os/include/arm/arch_endian.h new file +7 -0
@@ -0,0 +1,7 @@ +#ifndef ARCH_ENDIAN_H +#error "Do not include arch_endian by itself, include endian.h" +#else + +#define __BYTE_ORDER __LITTLE_ENDIAN + +#endif
extras/mini-os/include/arm/arch_limits.h new file +9 -0
@@ -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) (PFN_DOWN(to_phys(_virt))) +#define mach_to_virt (_mach) (_mach) +#define virt_to_mach (_virt) (_virt) +#define mfn_to_virt (_mfn) (to_virt(PFN_PHYS(_mfn))) +#define pfn_to_virt (_pfn) (to_virt(PFN_PHYS(_pfn))) + +// FIXME +#define map_frames (f, n) (NULL) + +#endif
extras/mini-os/include/arm/arch_sched.h new file +22 -0
@@ -0,0 +1,22 @@ + +#ifndef __ARCH_SCHED_H__ +#define __ARCH_SCHED_H__ + +#include "arch_limits.h" + +static inline struct thread *get_current (void ) +{ +struct thread **current; +unsigned long sp; + __asm__ __volatile__ ("mov %0, sp" :"=r" (sp)); + current = (void *)(unsigned long )(sp & ~(__STACK_SIZE-1 )); +return *current; +} + + +extern void __arch_switch_threads (unsigned long *prevctx,unsigned long *nextctx); + +#define arch_switch_threads (prev,next) __arch_switch_threads(&(prev)->sp, &(next)->sp) + + +#endif /* __ARCH_SCHED_H__ */
extras/mini-os/include/arm/arch_spinlock.h new file +49 -0
49 lines not on this page · raw message
extras/mini-os/include/arm/arm32/arch_wordsize.h new file +1 -0
@@ -0,0 +1 @@ +#define __WORDSIZE 32
extras/mini-os/include/arm/hypercall-arm32.h new file +173 -0
173 lines not on this page · raw message
extras/mini-os/include/arm/os.h new file +230 -0
230 lines not on this page · raw message
extras/mini-os/include/arm/traps.h new file +20 -0
@@ -0,0 +1,20 @@ +#ifndef _TRAPS_H_ +#define _TRAPS_H_ + +struct pt_regs { +unsigned long r0; +unsigned long r1; +unsigned long r2; +unsigned long r3; +unsigned long r4; +unsigned long r5; +unsigned long r6; +unsigned long r7; +unsigned long r8; +unsigned long r9; +unsigned long r10; +unsigned long r11; +unsigned long r12; +}; + +#endif
extras/mini-os/include/events.h +4 -0
@@ -26,6 +26,10 @@ typedef void (*evtchn_handler_t)(evtchn_port_t, struct pt_regs *, void *);/* prototypes */ void arch_init_events (void ); + +/* Called by fini_events. Close any arch-specific ports (e.g. debug ports) */ +void arch_unbind_ports (void ); +void arch_fini_events (void );int do_event (evtchn_port_t port,struct pt_regs *regs);
extras/mini-os/include/gic.h new file +1 -0
@@ -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
@@ -47,6 +47,10 @@#include <xen/features.h> #include <xen/version.h> +#ifdef __arm__ +#include <mini-os/gic.h> +#endif +uint8_t xen_features[XENFEAT_NR_SUBMAPS *32 ];void setup_xen_features (void )
@@ -147,6 +151,10 @@ void start_kernel(void)create_thread ("shutdown" , shutdown_thread,NULL );#endif +#ifdef __arm__ +gic_init (); +#endif +/* Call (possibly overridden) app_main() */ app_main (&start_info);
extras/mini-os/sched.c +16 -13
@@ -145,6 +145,9 @@ struct thread* create_thread(char *name, void (*function)(void *), void *data)unsigned long flags;/* Call architecture specific setup. */ thread =arch_create_thread (name, function, data); +if (!thread) +BUG ();//For now, FIXME should just return NULL +/* Not runable, not exited, not sleeping */ thread->flags =0 ; thread->wakeup_time =0LL ;
@@ -165,28 +168,28 @@ struct _reent *__getreent(void)struct _reent *_reent;if (!threads_started) - _reent = _impure_ptr; + _reent = _impure_ptr;else if (in_callback) - _reent = &callback_reent; + _reent = &callback_reent;else - _reent = &get_current ()->reent; + _reent = &get_current ()->reent;#ifndef NDEBUG #if defined(__x86_64__) || defined(__x86__) {#ifdef __x86_64__ - registerunsigned long sp asm ("rsp" ); + registerunsigned long sp asm ("rsp" );#else - registerunsigned long sp asm ("esp" ); + registerunsigned long sp asm ("esp" );#endif -if ((sp & (STACK_SIZE -1 )) <STACK_SIZE /16 ) { -static int overflowing; -if (!overflowing) { - overflowing =1 ; -printk ("stack overflow\n" ); -BUG (); - } - } +if ((sp & (STACK_SIZE -1 )) <STACK_SIZE /16 ) { +static int overflowing; +if (!overflowing) { + overflowing =1 ; +printk ("stack overflow\n" ); +BUG (); + } + } }#endif #else
Signature · 7 lines
2.0.0 _______________________________________________ Xen-devel mailing list [email protected] http://lists.xen.org/xen-devel
Quoted 31 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:21 +0100, a écrit :
From: Karim Raslan <[email protected]>
On ARM, Mini-OS will boot and display some output on the console. Tested with:
make XEN_TARGET_ARCH=arm32 CROSS_COMPILE=arm-linux-gnueabihf- \ CONFIG_TEST=y CONFIG_START_NETWORK=n CONFIG_BLKFRONT=n \ CONFIG_NETFRONT=n CONFIG_FBFRONT=n CONFIG_KBDFRONT=n \ CONFIG_CONSFRONT=n CONFIG_XC=n -j4Signed-off-by Karim Allah Ahmed <[email protected]>[[email protected]: made x86_64 support work again][[email protected]: split into multiple patches][[email protected]: re-enabled force_evtchn_callback][[email protected]: enable regular console][[email protected]: fixed initialisation code:
- Configure write-back caching in page table. This is needed for reliable hypercalls to Xen (thanks to Julien Grall).
- Use "client mode" for access control (domains are deprecated, according to ARM Cortex-A Series Programmer’s Guide version 4.0, section 9.6.4).
- Enable more SCTLR features (icache, branch prediction)][[email protected]: use Virtual Count register for monotonic time][[email protected]: fixed HYPERVISOR_shutdown][[email protected]: get xenstore details from hypervisor][[email protected]: use GCC implementation of division][[email protected]: include hypervisor.h from os.h, as on x86][[email protected]: cleaned up interrupt handlers and threading][[email protected]: call exit_thread when a thread returns][[email protected]: implemented block_domain for ARM][[email protected]: fixed hang when enabling interrupts]
Quoted 8 lines
[[email protected]: added -march=armv7-a to flags][[email protected]: implemented bitops for ARM][[email protected]: CLREX after handling IRQs][[email protected]: unbind debug port at shutdown][[email protected]: allow unaligned accesses][[email protected]: added arch_endian.h for ARM][[email protected]: fix zImage header for XSA-95]Signed-off-by Thomas Leonard <[email protected]>
It looks good to me, although I haven't reviewed the purely arm parts such as bootup. I don't know how I'm supposed to tag it :)
Samuel
_______________________________________________
Xen-devel mailing list
[email protected]
http://lists.xen.org/xen-devel
Hi Thomas,
extras/mini-os/arch/arm/arm32.S line 1
Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S new file +1
-0@@ -0,0 +1,155 @@ +#define PHYS_START (0x80008000)
This address is wrong with the latest xen unstable. Any reason to make mini-os tight to a specific physical address?
[..]
extras/mini-os/arch/arm/hypercalls32.S
Quoted 5 lines
extras/mini-os/arch/arm/hypercalls32.S new file +0
-0
This code is based on the one in Linux (arch/arm/xen/hypercall.S), right? IIRC it's a BSD license but you have to keep it.
[..]
extras/mini-os/arch/arm/mm.c line 5
Quoted 11 lines
extras/mini-os/arch/arm/mm.c new file +5
-0@@ -0,0 +1,44 @@ +#include <console.h> +#include <arch_mm.h> + +#define PHYS_START (0x80008000 + (1000 * 4 * 1024)) +#define PHYS_SIZE (40*1024*1024)
Same remark as earlier in arm/arm32.S. But I see you don't use them anymore after patch #10. So please drop the both defines in #10.
[..]
extras/mini-os/arch/arm/mm.c line 18
Quoted 13 lines
extras/mini-os/arch/arm/mm.c new file +13
-0+void set_vtimer_compare (uint64_t value) { +uint32_t x, y; + +DEBUG ("New CompareValue : %llx\n" , value); + x =0xFFFFFFFFULL & value; + y = (value >>32 ) &0xFFFFFFFF ; + + __asm__ __volatile__("mcrr p15, 3, %0, %1, c14\n" +"isb" ::"r" (x),"r" (y)); + + __asm__ __volatile__("mov %0, #0x1\n" +"mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */ +"isb" :"=r" (x));
I don't think you need to add an isb per instruction. One should be enough.
[..]
Quoted 22 lines
extras/mini-os/drivers/gic.c new file +16
-0@@ -0,0 +1,187 @@ +// ARM GIC implementation + +#include <mini-os/os.h> +#include <mini-os/hypervisor.h> + +//#define VGIC_DEBUG +#ifdef VGIC_DEBUG +#define DEBUG(_f, _a...) \ + DEBUG("MINI_OS(file=vgic.c, line=%d) " _f , __LINE__, ## _a) +#else +#define DEBUG(_f, _a...) ((void)0) +#endif + +extern void (*IRQ_handler)(void ); + +struct gic {
extras/mini-os/drivers/gic.c line 26
Quoted 10 lines
extras/mini-os/drivers/gic.c new file +10
-0+volatile char *gicd_base; +volatile char *gicc_base; +}; + +static struct gic gic; + +// Distributor Interface +#define GICD_CTLR 0x0 +#define GICD_ISENABLER 0x100 +#define GICD_PRIORITY 0x400
You use the right name for every macro except this one. I would rename it to GICD_IPRIORITYR to stay consistent.
Quoted 20 lines
extras/mini-os/drivers/gic.c new file +20
-0+#define GICD_ITARGETSR 0x800 +#define GICD_ICFGR 0xC00 + +// CPU Interface +#define GICC_CTLR 0x0 +#define GICC_PMR 0x4 +#define GICC_IAR 0xc +#define GICC_EOIR 0x10 +#define GICC_HPPIR 0x18 + +#define gicd (gic, offset) ((gic)->gicd_base + (offset)) +#define gicc (gic, offset) ((gic)->gicc_base + (offset)) + +#define REG (addr) ((uint32_t *)(addr)) + +static inline uint32_t REG_READ32 (volatile uint32_t *addr) +{ +uint32_t value; + __asm__ __volatile__("ldr %0, [%1]" :"=&r" (value):"r" (addr)); +rmb ();
extras/mini-os/drivers/gic.c line 56
Quoted 10 lines
extras/mini-os/drivers/gic.c new file +10
-0+return value; +} + +static inline void REG_WRITE32 (volatile uint32_t *addr,unsigned int value) +{ + __asm__ __volatile__("str %0, [%1]" ::"r" (value),"r" (addr)); +wmb (); +} + +static void gic_set_priority (struct gic *gic,unsigned char irq_number,unsigned char priority)
hmmmm why do you use unsigned char to describe the interrupt?
extras/mini-os/drivers/gic.c line 59
Quoted 3 lines
extras/mini-os/drivers/gic.c new file +3
-0+{ +uint32_t value; + value =REG_READ32 (REG (gicd (gic,GICD_PRIORITY )) + irq_number);
There is 4 interrupts describe per register, this should be (irq_number & ~3).
extras/mini-os/drivers/gic.c line 61
Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2
-0+ value &= ~(0xff << (8 * (irq_number &0x3 )));// set priority to '0' + value |= priority << (8 * (irq_number &0x3 ));// add our priority
It looks strange that you correctly handle the shift here.
extras/mini-os/drivers/gic.c line 62
Quoted 1 line
extras/mini-os/drivers/gic.c new file +1
-0+REG_WRITE32 (REG (gicd (gic,GICD_PRIORITY )) + irq_number, value);
irq_number & ~3
extras/mini-os/drivers/gic.c line 68
Quoted 6 lines
extras/mini-os/drivers/gic.c new file +6
-0+} + +static void gic_route_interrupt (struct gic *gic,unsigned char irq_number,unsigned char cpu_set) +{ +uint32_t value; + value =REG_READ32 (REG (gicd (gic,GICD_ITARGETSR )) + irq_number);
Same remark as gic_set_priority here.
extras/mini-os/drivers/gic.c line 70
Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2
-0+ value &= ~(0xff << (8 * (irq_number &0x3 )));// set priority to '0' + value |= cpu_set << (8 * (irq_number &0x3 ));// add our priority
The comments are wrong in the 2 lines above.
extras/mini-os/drivers/gic.c line 71
Quoted 1 line
extras/mini-os/drivers/gic.c new file +1
-0+REG_WRITE32 (REG (gicd (gic,GICD_ITARGETSR )) + irq_number, value);
irq_number & ~3;
extras/mini-os/drivers/gic.c line 77
Quoted 6 lines
extras/mini-os/drivers/gic.c new file +6
-0+} + +/* When accessing the GIC registers, we can't use LDREX/STREX because it's not regular memory. */ +static __inline__void clear_bit_non_atomic (int nr,volatile void *base) +{ +uint32_t *tmp = (uint32_t *)base;
You don't need to cast here and I suspect your variable need to be volatile otherwise the compiler may do some assumption.
extras/mini-os/drivers/gic.c line 83
Quoted 6 lines
extras/mini-os/drivers/gic.c new file +6
-0+ tmp[nr >>5 ] &= (unsigned long )~(1 << (nr &0x1f )); +} + +static __inline__void set_bit_non_atomic (int nr,volatile void *base) +{ +uint32_t *tmp = (uint32_t *)base;
Same remark here.
extras/mini-os/drivers/gic.c line 173
Quoted 4 lines
extras/mini-os/drivers/gic.c new file +4
-0+void gic_init (void ) { +// FIXME Get from dt! + gic.gicd_base = (char *)0x2c001000ULL ; + gic.gicc_base = (char *)0x2c002000ULL ;
Those values are wrong.
Quoted 13 lines
extras/mini-os/events.c +1
-0@@ -179,6 +179,7 @@ void init_events(void)void fini_events (void ) {/* Dealloc all events */ +arch_unbind_ports ();unbind_all_ports ();arch_fini_events (); }
extras/mini-os/events.c int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port, · line 243
Quoted 6 lines
extras/mini-os/events.c +2
-1@@ -238,7 +239,8 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,int evtchn_get_peercontext (evtchn_port_t local_port,char *ctx,int size) { -int rc; +int rc =0 ; +#ifndef __arm__/* TODO */
Do you still need this TODO & ifdef? XSM is working correctly on ARM. And even if it was not implemented the compilation should not failed.
Quoted 16 lines
extras/mini-os/events.c +1
-0uint32_t sid;struct xen_flask_op op; op.cmd =FLASK_GET_PEER_SID ;@@ -253,6 +255,7 @@ int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size) op.u.sid_context.size = size;set_xen_guest_handle (op.u.sid_context.context, ctx); rc =_hypercall1 (int, xsm_op, &op); +#endif return rc; }extras/mini-os/hypervisor.c +0
-0
extras/mini-os/hypervisor.c void do_hypervisor_callback(struct pt_regs *regs) · line 67
Quoted 5 lines
extras/mini-os/hypervisor.c +1
-1@@ -64,7 +64,7 @@ void do_hypervisor_callback(struct pt_regs *regs) l2 &= ~(1UL << l2i); port = (l1i * (sizeof (unsigned long ) *8 )) + l2i; -do_event (port, regs); +do_event (port, regs);
This patch is long and difficult to read. Please avoid indentation change in non-modified code at the same time.
Quoted 31 lines
extras/mini-os/hypervisor.c +8
-0} }@@ -73,18 +73,26 @@ void do_hypervisor_callback(struct pt_regs *regs)void force_evtchn_callback (void ) { +#ifdef XEN_HAVE_PV_UPCALL_MASK int save; +#endif vcpu_info_t *vcpu; vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id ()]; +#ifdef XEN_HAVE_PV_UPCALL_MASK save = vcpu->evtchn_upcall_mask; +#endif while (vcpu->evtchn_upcall_pending) { +#ifdef XEN_HAVE_PV_UPCALL_MASK vcpu->evtchn_upcall_mask =1 ; +#endif barrier ();do_hypervisor_callback (NULL );barrier (); +#ifdef XEN_HAVE_PV_UPCALL_MASK vcpu->evtchn_upcall_mask = save;barrier (); +#endif }; }
extras/mini-os/hypervisor.c inline void unmask_evtchn(uint32_t port) · line 126
Quoted 9 lines
extras/mini-os/hypervisor.c +2
-0@@ -110,7 +118,9 @@ inline void unmask_evtchn(uint32_t port) &vcpu_info->evtchn_pending_sel) ) { vcpu_info->evtchn_upcall_pending =1 ; +#ifdef XEN_HAVE_PV_UPCALL_MASK if ( !vcpu_info->evtchn_upcall_mask ) +#endif force_evtchn_callback (); } }
I would have move those change in a separate patch.
[..]
Quoted 21 lines
extras/mini-os/include/arm/arch_spinlock.h new file +15
-0@@ -0,0 +1,49 @@ + + +#ifndef __ARCH_ASM_SPINLOCK_H +#define __ARCH_ASM_SPINLOCK_H + +#include "os.h" + + +#define ARCH_SPIN_LOCK_UNLOCKED { 1 } + +/* +* Simple spin lock operations. There are two variants, one clears IRQ's +* on the local processor, one does not. +* +* We make no fairness assumptions. They have a cost.
extras/mini-os/include/arm/arch_spinlock.h line 25
Quoted 10 lines
extras/mini-os/include/arm/arch_spinlock.h new file +10
-0+*/ + +#define arch_spin_is_locked (x) (*(volatile signed char *)(&(x)->slock) <= 0) +#define arch_spin_unlock_wait (x) do { barrier(); } while(spin_is_locked(x)) + +/* +* This works. Despite all the confusion. +* (except on PPro SMP or if we are using OOSTORE) +* (PPro errata 66, 92) +*/
This comment is x86... It should not have been copied here.
Quoted 11 lines
extras/mini-os/include/arm/arch_spinlock.h new file +11
-0+ +static inline void _raw_spin_unlock (spinlock_t *lock) +{ +xchg (&lock->slock,1 ); +} + +static inline int _raw_spin_trylock (spinlock_t *lock) +{ +return xchg (&lock->slock,0 ) !=0 ?1 :0 ; +} +
extras/mini-os/include/arm/arch_spinlock.h line 46
Quoted 10 lines
extras/mini-os/include/arm/arch_spinlock.h new file +10
-0+static inline void _raw_spin_lock (spinlock_t *lock) +{ +volatile int was_locked; +do { + was_locked =xchg (&lock->slock,0 ) ==0 ?1 :0 ; + }while (was_locked); +} + +static inline void _raw_spin_lock_flags (spinlock_t *lock,unsigned long flags) +{
You didn't implement this function. It looks like it's not used in mini-os, right? If so, please add a BUG_ON just in case that someone decide to use it later.
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 5 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +0
-0
Actually this file can be name hypercall.h. On ARM64 the set of hypercall is exactly the same. The only different that you will have between both architecture is the assembly code and the system registers.
[..]
extras/mini-os/include/arm/hypercall-arm32.h line 43
Quoted 3 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +3
-0+inline int +HYPERVISOR_mmu_update ( +mmu_update_t *req,int count,int *success_count,domid_t domid);
Why do you use inline in all external functions in this include?
Hence most of this hypercall doesn't exist on ARM. Please define only the necessary one.
[..]
Quoted 1 line
+#endif /*
__HYPERCALL_X86_64_H__*/
__HYPERCALL_ARM_H__
[..]
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2
-0+// disable interrupts +static inline __cli (void) {
I see that you use __cli and __sti only__cli and __sti are only in 2 defines below. These name are only x86 specific. Please rename them or merge this code in local_irq_{disable,enable}
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2
-0+int x; + __asm__ __volatile__("mrs %0, cpsr;cpsid i" :"=r" (x)::"memory" );
Why do you need to read cpsr. cpsid i is enough here.
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 9 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +9
-0+} + +// enable interrupts +static inline __sti (void) { +int x; + __asm__ __volatile__("mrs %0, cpsr\n" +"bic %0, %0, #0x80\n" +"msr cpsr_c, %0" + :"=r" (x)::"memory" );
This can simply be done by cpsie i
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 6 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +6
-0+} + +static inline int irqs_disabled () { +int x; + __asm__ __volatile__("mrs %0, cpsr\n" :"=r" (x)::"memory" ); +return (x &0x80 );
You can use local_save_flags directly.
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 9 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +9
-0+} + +#define local_irq_save (x) { \ + __asm__ __volatile__("mrs %0, cpsr;cpsid i; and %0, %0, #0x80":"=r"(x)::"memory"); \ +} + +#define local_irq_restore (x) { \ + __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory"); \ +}
If you mask the result in local_irq_save, and use this value directly is local_irq_restore, you will disable by mistake the Asynchronous Abort exception....
You have to remove the and %0... at the end.
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 3 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +3
-0+#define local_save_flags (x) { \ + __asm__ __volatile__("mrs %0, cpsr; and %0, %0, 0x80":"=r"(x)::"memory"); \ +}
Same remark here.
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 7 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +7
-0+#define local_irq_disable () __cli() +#define local_irq_enable () __sti() + +#if defined(__arm__) +#define mb () __asm__("dmb"); +#define rmb () __asm__("dmb"); +#define wmb () __asm__("dmb");
I suspect you want to dsb here. You want to make sure that every memory access has finished avoid executing new instruction until this is done.
dmb only ensure the memory ordering.
Also, you want to clobber the memory to avoid the compiler:
1) reordering the instructions
2) prefetch data from the memory
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 4 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +4
-0+#elif defined(__aarch64__) +#define mb () +#define rmb () +#define wmb ()
I'm confused with this piece of code... memory barrier are also required on aarch64. Hence dmb/isb also exist on this architecture
You don't need the if ... elif ... else
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2
-0+#define unlikely (x) __builtin_expect((x),0) +#define likely (x) __builtin_expect((x),1)
Can't it be common with x86?
[..]
Quoted 13 lines
int
do_event(evtchn_port_t port, struct pt_regs *regs);extras/mini-os/include/gic.h new file +1
-0@@ -0,0 +1 @@ +void gic_init (void );extras/mini-os/include/hypervisor.h +0
-0
extras/mini-os/include/hypervisor.h line 24
Quoted 7 lines
extras/mini-os/include/hypervisor.h +4
-0@@ -18,6 +18,10 @@#include <hypercall-x86_32.h> #elif defined(__x86_64__)#include <hypercall-x86_64.h> +#elif defined(__arm__) +#include <hypercall-arm32.h> +#elif defined(__aarch64__) +#include <hypercall-arm64.h>
Hmmm, the filehypercall-arm64.h doesn't exists in this series...
Futhermore, as I said ealier the set of hypercall is exactly the same on arm64.
[..]
extras/mini-os/include/hypervisor.h typedef unsigned long u_quad_t; · line 44
Quoted 11 lines
extras/mini-os/include/hypervisor.h +2
-1+#if defined(__i386__) || defined(__arm__)typedef long long quad_t ;typedef unsigned long long u_quad_t ;@@ -40,7 +40,7 @@ typedef unsigned long u_quad_t;typedef struct {unsigned long pte; }pte_t ;#endif /* __i386__ || __x86_64__ */ -#ifdef __x86_64__ +#if defined(__x86_64__) || defined(__aarch64__)#define __pte (x) ((pte_t) { (x) } )
This looks wrong to me. The pte layout is exactly the same on arm32 and arm64. Hence, this is only used in the x86 code. Please either move pte_t in x86 part or define it correctly on ARM...
[..]
Quoted 16 lines
extras/mini-os/kernel.c +4
-0@@ -47,6 +47,10 @@#include <xen/features.h> #include <xen/version.h> +#ifdef __arm__ +#include <mini-os/gic.h> +#endif +uint8_t xen_features[XENFEAT_NR_SUBMAPS *32 ];void setup_xen_features (void )
extras/mini-os/kernel.c void start_kernel(void) · line 157
Quoted 7 lines
extras/mini-os/kernel.c +4
-0@@ -147,6 +151,10 @@ void start_kernel(void)create_thread ("shutdown" , shutdown_thread,NULL );#endif +#ifdef __arm__ +gic_init (); +#endif +
I would define a function arch_init. This will avoid the #ifdef __arm__ in the code common.
Hence, it looks strange that sometime you have #if __arm__ && __arch64__ and sometimes not...
Quoted 8 lines
extras/mini-os/kernel.c +0
-0/* Call (possibly overridden) app_main() */ app_main (&start_info);extras/mini-os/sched.c +0
-0
extras/mini-os/sched.c struct thread* create_thread(char *name, void (*function)(void *), void *data) · line 150
Quoted 6 lines
extras/mini-os/sched.c +3
-0@@ -145,6 +145,9 @@ struct thread* create_thread(char *name, void (*function)(void *), void *data)unsigned long flags;/* Call architecture specific setup. */ thread =arch_create_thread (name, function, data); +if (!thread) +BUG ();//For now, FIXME should just return NULL +
This change is in the common code. I think this should go in a separate patch.
Hence looking again to arch_create_thread for ARM you:
1) never return NULL
2) never check the xmalloc/alloc_pages return.
Quoted 31 lines
extras/mini-os/sched.c +5
-11/* Not runable, not exited, not sleeping */ thread->flags =0 ; thread->wakeup_time =0LL ;@@ -165,28 +168,28 @@ struct _reent *__getreent(void)struct _reent *_reent;if (!threads_started) - _reent = _impure_ptr; + _reent = _impure_ptr;else if (in_callback) - _reent = &callback_reent; + _reent = &callback_reent;else - _reent = &get_current ()->reent; + _reent = &get_current ()->reent; #ifndef NDEBUG #if defined(__x86_64__) || defined(__x86__) { #ifdef __x86_64__ - register unsigned long sp asm ("rsp"); + register unsigned long sp asm ("rsp"); #else - register unsigned long sp asm ("esp"); + register unsigned long sp asm ("esp"); #endif - if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) { - static int overflowing; - if (!overflowing) { - overflowing = 1; - printk("stack overflow\n"); - BUG();
extras/mini-os/sched.c struct _reent *__getreent(void) · line 191
Quoted 10 lines
extras/mini-os/sched.c +8
-2- } - } +if ((sp & (STACK_SIZE -1 )) <STACK_SIZE /16 ) { +static int overflowing; +if (!overflowing) { + overflowing =1 ; +printk ("stack overflow\n" ); +BUG (); + } + }
all this chunk: spurious changes?
Regards,
Signature · 1 line
Julien Grall
Quoted 1 line · Julien Grall
Hi Thomas,
Hi Julien,
Thanks for reviewing this!
Quoted 14 lines · Thomas Leonard
extras/mini-os/arch/arm/arm32.S line 1
Quoted 9 lines
extras/mini-os/arch/arm/arm32.S new file +1
-0@@ -0,0 +1,155 @@ +#define PHYS_START (0x80008000)This address is wrong with the latest xen unstable. Any reason to make mini-os tight to a specific physical address?
I'll remove this in the next version.
Quoted 13 lines
[..]
extras/mini-os/arch/arm/hypercalls32.S
Quoted 6 lines
extras/mini-os/arch/arm/hypercalls32.S new file +0
-0This code is based on the one in Linux (
arch/arm/xen/hypercall.S), right? IIRC it's a BSD license but you have to keep it.
I don't know where it came from, but you're probably right. I've added the header back in.
Quoted 18 lines
[..]
extras/mini-os/arch/arm/mm.c line 5
Quoted 11 lines
extras/mini-os/arch/arm/mm.c new file +5
-0@@ -0,0 +1,44 @@ +#include <console.h> +#include <arch_mm.h> + +#define PHYS_START (0x80008000 + (1000 * 4 * 1024)) +#define PHYS_SIZE (40*1024*1024)Same remark as earlier in
arm/arm32.S. But I see you don't use them anymore after patch #10. So please drop the both defines in #10.
I've reordered the patches so we don't need this now.
Quoted 12 lines
[..]
Quoted 9 lines
extras/mini-os/arch/arm/mm.c new file +9
-0+void set_vtimer_compare (uint64_t value) { +uint32_t x, y; + +DEBUG ("New CompareValue : %llx\n" , value); + x =0xFFFFFFFFULL & value; + y = (value >>32 ) &0xFFFFFFFF ; + + __asm__ __volatile__("mcrr p15, 3, %0, %1, c14\n" +"isb" ::"r" (x),"r" (y));
Quoted 8 lines
Quoted 5 lines
extras/mini-os/arch/arm/mm.c new file +3
-0+ + __asm__ __volatile__("mov %0, #0x1\n" +"mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */
+ "isb":"=r"(x));I don't think you need to add an isb per instruction. One should be enough.
Actually, do we need one at all? Setting the timer shouldn't affect the instruction pipline, I think.
Quoted 31 lines
[..]
Quoted 28 lines
extras/mini-os/drivers/gic.c new file +22
-0@@ -0,0 +1,187 @@ +// ARM GIC implementation + +#include <mini-os/os.h> +#include <mini-os/hypervisor.h> + +//#define VGIC_DEBUG +#ifdef VGIC_DEBUG +#define DEBUG(_f, _a...) \ + DEBUG("MINI_OS(file=vgic.c, line=%d) " _f , __LINE__, ## _a) +#else +#define DEBUG(_f, _a...) ((void)0) +#endif + +extern void (*IRQ_handler)(void ); + +struct gic { +volatile char *gicd_base; +volatile char *gicc_base; +}; + +static struct gic gic; +
Quoted 8 lines
extras/mini-os/drivers/gic.c line 26
Quoted 4 lines
extras/mini-os/drivers/gic.c new file +4
-0+// Distributor Interface +#define GICD_CTLR 0x0 +#define GICD_ISENABLER 0x100 +#define GICD_PRIORITY 0x400You use the right name for every macro except this one. I would rename it to
GICD_IPRIORITYRto stay consistent.
Done.
Quoted 22 lines
Quoted 22 lines
extras/mini-os/drivers/gic.c new file +22
-0+#define GICD_ITARGETSR 0x800 +#define GICD_ICFGR 0xC00 + +// CPU Interface +#define GICC_CTLR 0x0 +#define GICC_PMR 0x4 +#define GICC_IAR 0xc +#define GICC_EOIR 0x10 +#define GICC_HPPIR 0x18 + +#define gicd (gic, offset) ((gic)->gicd_base + (offset)) +#define gicc (gic, offset) ((gic)->gicc_base + (offset)) + +#define REG (addr) ((uint32_t *)(addr)) + +static inline uint32_t REG_READ32 (volatile uint32_t *addr) +{ +uint32_t value; + __asm__ __volatile__("ldr %0, [%1]" :"=&r" (value):"r" (addr)); +rmb (); +return value; +}
Quoted 8 lines
extras/mini-os/drivers/gic.c line 55
Quoted 8 lines
extras/mini-os/drivers/gic.c new file +2
-0+ +static inline void REG_WRITE32(volatile uint32_t *addr, unsigned intvalue)
extras/mini-os/drivers/gic.c new file +5
-0+{ + __asm__ __volatile__("str %0, [%1]" ::"r" (value),"r" (addr)); +wmb (); +} +
Do we need inline assembler to write these values? I'd imagine that a plain C store to a volatile 32-bit pointer would always do the same thing.
Quoted 5 lines
Quoted 2 lines
+static void
gic_set_priority(struct gic *gic, unsigned char irq_number, unsigned char priority)hmmmm why do you use unsigned char to describe the interrupt?
Yes, that's clearly wrong. Interrupt numbers don't fit in 8 bits.
Quoted 7 lines
extras/mini-os/drivers/gic.c line 59
Quoted 3 lines
extras/mini-os/drivers/gic.c new file +3
-0+{ +uint32_t value; + value =REG_READ32 (REG (gicd (gic,GICD_PRIORITY )) + irq_number);There is 4 interrupts describe per register, this should be (
irq_number& ~3).
Or should it be (irq_number >> 2)? REG casts to uint32_t.
Quoted 29 lines
extras/mini-os/drivers/gic.c line 61
Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2
-0+ value &= ~(0xff << (8 * (irq_number &0x3 )));// set priority to '0' + value |= priority << (8 * (irq_number &0x3 ));// add our priority It looks strange that you correctly handle the shift here.
Quoted 1 line
+
REG_WRITE32(REG(gicd(gic, GICD_PRIORITY)) + irq_number, value);
irq_number& ~3extras/mini-os/drivers/gic.c line 68
Quoted 7 lines
extras/mini-os/drivers/gic.c new file +3
-0+} + +static void gic_route_interrupt(struct gic *gic, unsigned char
irq_number, unsigned charcpu_set)extras/mini-os/drivers/gic.c new file +3
-0+{ +uint32_t value; + value =REG_READ32 (REG (gicd (gic,GICD_ITARGETSR )) + irq_number);Same remark as
gic_set_priorityhere.extras/mini-os/drivers/gic.c
Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2
-0+ value &= ~(0xff << (8 * (irq_number &0x3 )));// set priority to '0' + value |= cpu_set << (8 * (irq_number &0x3 ));// add our priority
Quoted 7 lines
The comments are wrong in the 2 lines above.
Quoted 1 line
+
REG_WRITE32(REG(gicd(gic, GICD_ITARGETSR)) + irq_number, value);
irq_number& ~3;
The ARM Generic Interrupt Controller Architecture Specification says "These registers are byte-accessible.". So we should be able to write the byte directly. I thought this might work:
static void gic_route_interrupt(struct gic *gic, int irq_number, unsigned char cpu_set)
{
gicd(gic, GICD_ITARGETSR)[irq_number] = cpu_set;
wmb();
}But it doesn't, because Xen's write_ignore handler (vgic.c:656 on the 4.4 branch) does:
write_ignore:
if ( dabt.size != 2 ) goto bad_width;
Bug?
Quoted 11 lines
extras/mini-os/drivers/gic.c line 77
Quoted 7 lines
extras/mini-os/drivers/gic.c new file +3
-0+} + +/* When accessing the GIC registers, we can't use LDREX/STREX because it's not regular memory. */
extras/mini-os/drivers/gic.c new file +3
-0+static __inline__void clear_bit_non_atomic (int nr,volatile void *base) +{ +uint32_t *tmp = (uint32_t *)base;You don't need to cast here and I suspect your variable need to be volatile otherwise the compiler may do some assumption.
OK.
Quoted 9 lines
extras/mini-os/drivers/gic.c line 83
Quoted 6 lines
extras/mini-os/drivers/gic.c new file +6
-0+ tmp[nr >>5 ] &= (unsigned long )~(1 << (nr &0x1f )); +} + +static __inline__void set_bit_non_atomic (int nr,volatile void *base) +{ +uint32_t *tmp = (uint32_t *)base;Same remark here.
OK.
Quoted 7 lines
extras/mini-os/drivers/gic.c line 173
Quoted 4 lines
extras/mini-os/drivers/gic.c new file +4
-0+void gic_init (void ) { +// FIXME Get from dt! + gic.gicd_base = (char *)0x2c001000ULL ; + gic.gicc_base = (char *)0x2c002000ULL ;Those values are wrong.
Now fixed by patch reordering.
Quoted 15 lines
Quoted 15 lines
extras/mini-os/events.c +1
-0@@ -179,6 +179,7 @@ void init_events(void)void fini_events (void ) {/* Dealloc all events */ +arch_unbind_ports ();unbind_all_ports ();arch_fini_events (); }@@ -238,7 +239,8 @@ int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port,
Quoted 9 lines
extras/mini-os/events.c int evtchn_bind_interdomain(domid_t pal, evtchn_port_t remote_port, · line 243
Quoted 5 lines
extras/mini-os/events.c +2
-1int evtchn_get_peercontext (evtchn_port_t local_port,char *ctx,int size) { -int rc; +int rc =0 ; +#ifndef __arm__/* TODO */ Do you still need this TODO & ifdef? XSM is working correctly on ARM. And even if it was not implemented the compilation should not failed.
It used "_hypercall1", which was missing from ARM. I've now added HYPERVISOR_xsm_op and changed it to use that instead.
Quoted 19 lines
Quoted 19 lines
extras/mini-os/events.c +0
-0uint32_t sid;struct xen_flask_op op;op.cmd = FLASK_GET_PEER_SID;extras/mini-os/events.c +1
-0@@ -253,6 +255,7 @@ int evtchn_get_peercontext(evtchn_port_t local_port, char *ctx, int size) op.u.sid_context.size = size;set_xen_guest_handle (op.u.sid_context.context, ctx); rc =_hypercall1 (int, xsm_op, &op); +#endif return rc; }extras/mini-os/hypervisor.c +0
-0@@ -64,7 +64,7 @@ void do_hypervisor_callback(struct pt_regs *regs) l2 &= ~(1UL << l2i);
Quoted 7 lines
extras/mini-os/hypervisor.c void do_hypervisor_callback(struct pt_regs *regs) · line 67
Quoted 3 lines
extras/mini-os/hypervisor.c +1
-1port = (l1i * (sizeof (unsigned long ) *8 )) + l2i; -do_event (port, regs); +do_event (port, regs);This patch is long and difficult to read. Please avoid indentation change in non-modified code at the same time.
OK, split off.
Quoted 30 lines
Quoted 30 lines
extras/mini-os/hypervisor.c +8
-0} }@@ -73,18 +73,26 @@ void do_hypervisor_callback(struct pt_regs *regs)void force_evtchn_callback (void ) { +#ifdef XEN_HAVE_PV_UPCALL_MASK int save; +#endif vcpu_info_t *vcpu; vcpu = &HYPERVISOR_shared_info->vcpu_info[smp_processor_id ()]; +#ifdef XEN_HAVE_PV_UPCALL_MASK save = vcpu->evtchn_upcall_mask; +#endif while (vcpu->evtchn_upcall_pending) { +#ifdef XEN_HAVE_PV_UPCALL_MASK vcpu->evtchn_upcall_mask =1 ; +#endif barrier ();do_hypervisor_callback (NULL );barrier (); +#ifdef XEN_HAVE_PV_UPCALL_MASK vcpu->evtchn_upcall_mask = save;barrier (); +#endif }; }
Quoted 13 lines
extras/mini-os/hypervisor.c inline void unmask_evtchn(uint32_t port) · line 126
Quoted 10 lines
extras/mini-os/hypervisor.c +2
-0@@ -110,7 +118,9 @@ inline void unmask_evtchn(uint32_t port) &vcpu_info->evtchn_pending_sel) ) { vcpu_info->evtchn_upcall_pending =1 ; +#ifdef XEN_HAVE_PV_UPCALL_MASK if ( !vcpu_info->evtchn_upcall_mask ) +#endif force_evtchn_callback (); } }I would have move those change in a separate patch.
OK.
Quoted 32 lines
[..]
Quoted 29 lines
extras/mini-os/include/arm/arch_spinlock.h new file +18
-0@@ -0,0 +1,49 @@ + + +#ifndef __ARCH_ASM_SPINLOCK_H +#define __ARCH_ASM_SPINLOCK_H + +#include "os.h" + + +#define ARCH_SPIN_LOCK_UNLOCKED { 1 } + +/* +* Simple spin lock operations. There are two variants, one clears IRQ's +* on the local processor, one does not. +* +* We make no fairness assumptions. They have a cost. +*/ + +#define arch_spin_is_locked (x) (*(volatile signed char *)(&(x)->slock)<= 0)
+#definearch_spin_unlock_wait(x)do {barrier(); } while(spin_is_locked(x))
+
Quoted 8 lines
Quoted 5 lines
+/*
+ * This works. Despite all the confusion.
+ * (except on PPro SMP or if we are using OOSTORE)
+ * (PPro errata 66, 92)
+ */This comment is x86... It should not have been copied here.
OK.
Quoted 19 lines
Quoted 19 lines
extras/mini-os/include/arm/arch_spinlock.h new file +19
-0+ +static inline void _raw_spin_unlock (spinlock_t *lock) +{ +xchg (&lock->slock,1 ); +} + +static inline int _raw_spin_trylock (spinlock_t *lock) +{ +return xchg (&lock->slock,0 ) !=0 ?1 :0 ; +} + +static inline void _raw_spin_lock (spinlock_t *lock) +{ +volatile int was_locked; +do { + was_locked =xchg (&lock->slock,0 ) ==0 ?1 :0 ; + }while (was_locked); +} +
Quoted 8 lines
Quoted 3 lines
+static inline void
_raw_spin_lock_flags(spinlock_t*lock, unsigned long flags)
+{You didn't implement this function. It looks like it's not used in mini-os, right? If so, please add a
BUG_ONjust in case that someone decide to use it later.
I'll remove it completely. Better to find out it's missing at compile time.
Quoted 12 lines
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 7 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +0
-0Actually this file can be name
hypercall.h. On ARM64 the set of hypercall is exactly the same. The only different that you will have between both architecture is the assembly code and the system registers.
I've renamed it to hypercall-arm.h (to match the x86 naming).
Quoted 9 lines
[..]
extras/mini-os/include/arm/hypercall-arm32.h line 43
Quoted 3 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +3
-0+inline int +HYPERVISOR_mmu_update ( +mmu_update_t *req,int count,int *success_count,domid_t domid);Why do you use inline in all external functions in this include?
No idea. I've removed all the inlines.
Quoted 2 lines
Hence most of this hypercall doesn't exist on ARM. Please define only the necessary one.
OK.
Quoted 6 lines
[..]
Quoted 1 line
+#endif /*
__HYPERCALL_X86_64_H__*/
__HYPERCALL_ARM_H__
Fixed.
Quoted 11 lines
[..]
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2
-0+// disable interrupts +static inline __cli (void) {I see that you use
__cliand__stionly__cliand__stiare only in 2 defines below. These name are only x86 specific. Please rename them or merge this code in local_irq_{disable,enable}
Done.
Quoted 5 lines
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2
-0+int x; + __asm__ __volatile__("mrs %0, cpsr;cpsid i" :"=r" (x)::"memory" );Why do you need to read cpsr. cpsid i is enough here.
Removed.
Quoted 4 lines
Quoted 4 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +4
-0+} + +// enable interrupts +static inline __sti (void) {
Quoted 8 lines
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 5 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +5
-0+int x; + __asm__ __volatile__("mrs %0, cpsr\n" +"bic %0, %0, #0x80\n" +"msr cpsr_c, %0" + :"=r" (x)::"memory" );This can simply be done by cpsie i
Done.
Quoted 9 lines
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 6 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +6
-0+} + +static inline int irqs_disabled () { +int x; + __asm__ __volatile__("mrs %0, cpsr\n" :"=r" (x)::"memory" ); +return (x &0x80 );You can use
local_save_flagsdirectly.
OK.
Quoted 16 lines
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 10 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +4
-0+} + +#define local_irq_save (x) { \ + __asm__ __volatile__("mrs %0, cpsr;cpsid i; and %0, %0,#0x80":"=r"(x)::"memory"); \
extras/mini-os/include/arm/hypercall-arm32.h new file +5
-0+} + +#define local_irq_restore (x) { \ + __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory"); \ +}If you mask the result in
local_irq_save, and use this value directly islocal_irq_restore, you will disable by mistake the Asynchronous Abort exception....
Quoted 1 line
You have to remove the and %0... at the end.
This makes schedule() fail, because it checks whether the result is zero. Perhaps we should continue to mask it, but only apply the IRQ bit in local_irq_restore?
Quoted 7 lines
Quoted 4 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2
-0+#define local_save_flags (x) { \ + __asm__ __volatile__("mrs %0, cpsr; and %0, %0,0x80":"=r"(x)::"memory"); \
+}Same remark here.
If we mask on restore, this is OK.
Quoted 11 lines
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 7 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +7
-0+#define local_irq_disable () __cli() +#define local_irq_enable () __sti() + +#if defined(__arm__) +#define mb () __asm__("dmb"); +#define rmb () __asm__("dmb"); +#define wmb () __asm__("dmb");I suspect you want to dsb here. You want to make sure that every memory access has finished avoid executing new instruction until this is done.
Is this necessary? As I understand it, using Xen's ring system requires a strict ordering (dmb), but we don't need to stall the processor waiting for each write to complete before going on to the next one.
Quoted 5 lines
dmb only ensure the memory ordering.
Also, you want to clobber the memory to avoid the compiler:
1) reordering the instructions
2) prefetch data from the memory
OK.
Quoted 10 lines
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 4 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +4
-0+#elif defined(__aarch64__) +#define mb () +#define rmb () +#define wmb ()I'm confused with this piece of code... memory barrier are also required on aarch64. Hence dmb/isb also exist on this architecture
You don't need the if ... elif ... else
Removed.
Quoted 5 lines
extras/mini-os/include/arm/hypercall-arm32.h
Quoted 2 lines
extras/mini-os/include/arm/hypercall-arm32.h new file +2
-0+#define unlikely (x) __builtin_expect((x),0) +#define likely (x) __builtin_expect((x),1)Can't it be common with x86?
Which header file should it go in?
Quoted 28 lines
[..]
Quoted 14 lines
int
do_event(evtchn_port_t port, struct pt_regs *regs);extras/mini-os/include/gic.h new file +1
-0@@ -0,0 +1 @@ +void gic_init (void );extras/mini-os/include/hypervisor.h +0
-0extras/mini-os/include/hypervisor.h line 24
Quoted 7 lines
extras/mini-os/include/hypervisor.h +4
-0@@ -18,6 +18,10 @@#include <hypercall-x86_32.h> #elif defined(__x86_64__)#include <hypercall-x86_64.h> +#elif defined(__arm__) +#include <hypercall-arm32.h> +#elif defined(__aarch64__) +#include <hypercall-arm64.h> Hmmm, the
filehypercall-arm64.hdoesn't exists in this series...
Quoted 2 lines
Futhermore, as I said ealier the set of hypercall is exactly the same on arm64.
Fixed.
Quoted 11 lines
[..]
Quoted 8 lines
extras/mini-os/include/hypervisor.h +1
-0+#if defined(__i386__) || defined(__arm__)typedef long long quad_t ;typedef unsigned long long u_quad_t ;@@ -40,7 +40,7 @@ typedef unsigned long u_quad_t;typedef struct {unsigned long pte; }pte_t ;#endif /* __i386__ || __x86_64__ */
Quoted 8 lines
extras/mini-os/include/hypervisor.h typedef unsigned long u_quad_t; · line 44
Quoted 3 lines
extras/mini-os/include/hypervisor.h +1
-1-#ifdef __x86_64__ +#if defined(__x86_64__) || defined(__aarch64__)#define __pte (x) ((pte_t) { (x) } )This looks wrong to me. The pte layout is exactly the same on arm32 and arm64. Hence, this is only used in the x86 code. Please either move
pte_tin x86 part or define it correctly on ARM...
Moved to x86. Actually, this simplifies things further, because it can go in the separate hypercall-*.h files and lose the #ifdef completely.
Quoted 22 lines
[..]
Quoted 19 lines
extras/mini-os/kernel.c +4
-0@@ -47,6 +47,10 @@#include <xen/features.h> #include <xen/version.h> +#ifdef __arm__ +#include <mini-os/gic.h> +#endif +uint8_t xen_features[XENFEAT_NR_SUBMAPS *32 ];void setup_xen_features (void )@@ -147,6 +151,10 @@ void start_kernel(void)create_thread ("shutdown" , shutdown_thread,NULL );#endif
Quoted 8 lines
extras/mini-os/kernel.c void start_kernel(void) · line 157
Quoted 4 lines
extras/mini-os/kernel.c +4
-0+#ifdef __arm__ +gic_init (); +#endif +I would define a function
arch_init. This will avoid the #ifdef__arm__in the code common.
I've moved it to the existing arch_init. I can't see any obvious reason why we should init the GIC long after enabling interrupts anyway.
Quoted 7 lines
Hence, it looks strange that sometime you have #if
__arm__&&__arch64__and sometimes not...Quoted 3 lines
extras/mini-os/kernel.c +0
-0/* Call (possibly overridden) app_main() */ app_main (&start_info);
Quoted 16 lines
extras/mini-os/sched.c struct thread* create_thread(char *name, void · line 151
Quoted 12 lines
extras/mini-os/sched.c +3
-0@@ -145,6 +145,9 @@ struct thread* create_thread(char *name, void (*function)(void *), void *data)unsigned long flags;/* Call architecture specific setup. */ thread =arch_create_thread (name, function, data); +if (!thread) +BUG ();//For now, FIXME should just return NULL +This change is in the common code. I think this should go in a separate patch.
I'll remove this for now.
Quoted 41 lines
Hence looking again to
arch_create_threadfor ARM you:
1) never return NULL
2) never check the xmalloc/alloc_pages return.Quoted 36 lines
extras/mini-os/sched.c +0
-0/* Not runable, not exited, not sleeping */ thread->flags =0 ;thread->wakeup_time = 0LL;extras/mini-os/sched.c +8
-13@@ -165,28 +168,28 @@ struct _reent *__getreent(void)struct _reent *_reent;if (!threads_started) - _reent = _impure_ptr; + _reent = _impure_ptr;else if (in_callback) - _reent = &callback_reent; + _reent = &callback_reent;else - _reent = &get_current ()->reent; + _reent = &get_current ()->reent; #ifndef NDEBUG #if defined(__x86_64__) || defined(__x86__) { #ifdef __x86_64__ - register unsigned long sp asm ("rsp"); + register unsigned long sp asm ("rsp"); #else - register unsigned long sp asm ("esp"); + register unsigned long sp asm ("esp"); #endif - if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) { - static int overflowing; - if (!overflowing) { - overflowing = 1; - printk("stack overflow\n"); - BUG(); - } - } + if ((sp & (STACK_SIZE-1)) < STACK_SIZE / 16) { + static int overflowing; + if (!overflowing) {
Quoted 8 lines
extras/mini-os/sched.c struct _reent *__getreent(void) · line 192
Quoted 5 lines
extras/mini-os/sched.c +5
-0+ overflowing =1 ; +printk ("stack overflow\n" ); +BUG (); + } + }all this chunk: spurious changes?
I'll move the whitespace fixes to a separate patch.
Thanks! I'll do some more clean ups and send another patch series soon.
Signature · 3 lines
Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA
Quoted 2 lines · Thomas Leonard
On 18 June 2014 23:40, Julien Grall <[email protected]> wrote:
Hi Julien,
Hi Thomas,
Quoted 20 lines
Quoted 11 lines
Quoted 11 lines
extras/mini-os/arch/arm/time.c new file +9
-0+void set_vtimer_compare (uint64_t value) { +uint32_t x, y; + +DEBUG ("New CompareValue : %llx\n" , value); + x =0xFFFFFFFFULL & value; + y = (value >>32 ) &0xFFFFFFFF ; + + __asm__ __volatile__("mcrr p15, 3, %0, %1, c14\n" +"isb" ::"r" (x),"r" (y));Quoted 8 lines
Quoted 5 lines
extras/mini-os/arch/arm/time.c new file +3
-0+ + __asm__ __volatile__("mov %0, #0x1\n" +"mcr p15, 0, %0, c14, c3, 1\n" /* Enable timer and unmask the output signal */
+ "isb":"=r"(x));I don't think you need to add an isb per instruction. One should be enough.
Quoted 2 lines
Actually, do we need one at all? Setting the timer shouldn't affect the instruction pipline, I think.
The isb is also used to make sure that an access to a system control registers (such as setting the page table) has finished before executing the next instruction.
Quoted 40 lines
Quoted 31 lines
[..]
Quoted 28 lines
extras/mini-os/drivers/gic.c new file +22
-0@@ -0,0 +1,187 @@ +// ARM GIC implementation + +#include <mini-os/os.h> +#include <mini-os/hypervisor.h> + +//#define VGIC_DEBUG +#ifdef VGIC_DEBUG +#define DEBUG(_f, _a...) \ + DEBUG("MINI_OS(file=vgic.c, line=%d) " _f , __LINE__, ## _a) +#else +#define DEBUG(_f, _a...) ((void)0) +#endif + +extern void (*IRQ_handler)(void ); + +struct gic { +volatile char *gicd_base; +volatile char *gicc_base; +}; + +static struct gic gic; +Quoted 8 lines
extras/mini-os/drivers/gic.c line 26
Quoted 4 lines
extras/mini-os/drivers/gic.c new file +4
-0+// Distributor Interface +#define GICD_CTLR 0x0 +#define GICD_ISENABLER 0x100 +#define GICD_PRIORITY 0x400You use the right name for every macro except this one. I would rename it to
GICD_IPRIORITYRto stay consistent.
Quoted 1 line
Done.
Thanks !
Quoted 11 lines
Quoted 7 lines
extras/mini-os/drivers/gic.c line 55
Quoted 7 lines
extras/mini-os/drivers/gic.c new file +1
-0+static inline void REG_WRITE32(volatile uint32_t *addr, unsigned intvalue)
extras/mini-os/drivers/gic.c new file +5
-0+{ + __asm__ __volatile__("str %0, [%1]" ::"r" (value),"r" (addr)); +wmb (); +} +Do we need inline assembler to write these values? I'd imagine that a plain C store to a volatile 32-bit pointer would always do the same thing.
The compiler may do strange things to store the value, such as 4 byte-store instead of a word-store.
So we have to use inline assembly to make sure the correct access will be done.
Quoted 9 lines
Quoted 7 lines
extras/mini-os/drivers/gic.c line 59
Quoted 3 lines
extras/mini-os/drivers/gic.c new file +3
-0+{ +uint32_t value; + value =REG_READ32 (REG (gicd (gic,GICD_PRIORITY )) + irq_number);There is 4 interrupts describe per register, this should be (
irq_number& ~3).Or should it be (
irq_number>> 2)? REG casts touint32_t.
It's the same :).
Quoted 28 lines
Quoted 16 lines
extras/mini-os/drivers/gic.c line 68
Quoted 7 lines
extras/mini-os/drivers/gic.c new file +3
-0+} + +static void gic_route_interrupt(struct gic *gic, unsigned char
irq_number, unsigned charcpu_set)extras/mini-os/drivers/gic.c new file +3
-0+{ +uint32_t value; + value =REG_READ32 (REG (gicd (gic,GICD_ITARGETSR )) + irq_number);Same remark as
gic_set_priorityhere.extras/mini-os/drivers/gic.c
Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2
-0+ value &= ~(0xff << (8 * (irq_number &0x3 )));// set priority to '0' + value |= cpu_set << (8 * (irq_number &0x3 ));// add our priority Quoted 7 lines
The comments are wrong in the 2 lines above.
Quoted 1 line
+
REG_WRITE32(REG(gicd(gic, GICD_ITARGETSR)) + irq_number, value);
irq_number& ~3;The ARM Generic Interrupt Controller Architecture Specification says "These registers are byte-accessible.". So we should be able to write the byte directly. I thought this might work:
Quoted 6 lines
static void
gic_route_interrupt(struct gic *gic, int irq_number, unsigned char cpu_set){ gicd(gic, GICD_ITARGETSR)[irq_number] = cpu_set; wmb(); }
This code looks good to me.
Quoted 8 lines
But it doesn't, because Xen's
write_ignorehandler (vgic.c:656 on the 4.4 branch) does:
write_ignore:
if ( dabt.size != 2 ) gotobad_width;Bug?
This is a bug in Xen. I think, write_ignore should just ignore the write rather checking badly the size.
Can you send a patch for it?
Quoted 16 lines
Quoted 16 lines
extras/mini-os/drivers/gic.c
Quoted 10 lines
extras/mini-os/drivers/gic.c new file +4
-0+} + +#define local_irq_save (x) { \ + __asm__ __volatile__("mrs %0, cpsr;cpsid i; and %0, %0,#0x80":"=r"(x)::"memory"); \
extras/mini-os/drivers/gic.c new file +5
-0+} + +#define local_irq_restore (x) { \ + __asm__ __volatile__("msr cpsr_c, %0"::"r"(x):"memory"); \ +}If you mask the result in
local_irq_save, and use this value directly islocal_irq_restore, you will disable by mistake the Asynchronous Abort exception....
Quoted 5 lines
Quoted 1 line
You have to remove the and %0... at the end.
This makes
schedule()fail, because it checks whether the result is zero. Perhaps we should continue to mask it, but only apply the IRQ bit inlocal_irq_restore?
I would prefer to change the schedule code if it's possible to keep local_irq_restore as simple as possible. This helper is often used.
I don't know much the code of schedule. Why don't we only check that the IRQ are disabled rather than call local_irq_{save,restore}?
Quoted 12 lines
Quoted 11 lines
extras/mini-os/drivers/gic.c
Quoted 7 lines
extras/mini-os/drivers/gic.c new file +7
-0+#define local_irq_disable () __cli() +#define local_irq_enable () __sti() + +#if defined(__arm__) +#define mb () __asm__("dmb"); +#define rmb () __asm__("dmb"); +#define wmb () __asm__("dmb");I suspect you want to dsb here. You want to make sure that every memory access has finished avoid executing new instruction until this is done.
Quoted 4 lines
Is this necessary? As I understand it, using Xen's ring system requires a strict ordering (dmb), but we don't need to stall the processor waiting for each write to complete before going on to the next one.
Is it written somewhere? FIY, Linux is using dsb with ring system. Even tho, I think dmb is fine here. I'd like confirmation for either Ian C. or Stefano.
Futhermore, there is other place in mini-os (such as the GIC) where I think we have to use dsb.
Quoted 7 lines
Quoted 5 lines
extras/mini-os/drivers/gic.c
Quoted 2 lines
extras/mini-os/drivers/gic.c new file +2
-0+#define unlikely (x) __builtin_expect((x),0) +#define likely (x) __builtin_expect((x),1)Can't it be common with x86?
Which header file should it go in?
I don't know much mini-os, but I would add either in lib.h or create a new header compiler.h.
Quoted 20 lines
Quoted 11 lines
[..]
Quoted 8 lines
extras/mini-os/drivers/gic.c new file +1
-0+#if defined(__i386__) || defined(__arm__)typedef long long quad_t ;typedef unsigned long long u_quad_t ;@@ -40,7 +40,7 @@ typedef unsigned long u_quad_t;typedef struct {unsigned long pte; }pte_t ;#endif /* __i386__ || __x86_64__ */ Quoted 8 lines
extras/mini-os/drivers/gic.c typedef unsigned long u_quad_t; · line 44
Quoted 3 lines
extras/mini-os/drivers/gic.c new file +1
-1-#ifdef __x86_64__ +#if defined(__x86_64__) || defined(__aarch64__)#define __pte (x) ((pte_t) { (x) } )This looks wrong to me. The pte layout is exactly the same on arm32 and arm64. Hence, this is only used in the x86 code. Please either move
pte_tin x86 part or define it correctly on ARM...
Quoted 2 lines
Moved to x86. Actually, this simplifies things further, because it can go in the separate hypercall-*.h files and lose the #ifdef completely.
Great, thanks!
Regards,
Signature · 1 line
Julien Grall
Quoted 10 lines · Julien Grall, le Mon 23 Jun 2014 17:55:05 +0100, a écrit :
Quoted 7 lines
Quoted 5 lines
extras/mini-os/include/arm/os.h line 70
Quoted 2 lines
extras/mini-os/include/arm/os.h new file +2
-0+#define unlikely (x) __builtin_expect((x),0) +#define likely (x) __builtin_expect((x),1)Can't it be common with x86?
Which header file should it go in?
I don't know much mini-os, but I would add either in
lib.hor create a new headercompiler.h.
A new compiler.h makes sense to me.
Samuel
PATCH v4 8/12 mini-os: arm: show registers, stack and exception vector on fault
In reply to Thomas Leonard--- extras/mini-os/ARM-TODO.txt | 1 - extras/mini-os/arch/arm/arm32.S | 81 ++++++++++++++++++++++++++--- extras/mini-os/arch/arm/panic.c | 99 ++++++++++++++++++++++++++++++++++++ extras/mini-os/include/arm/arch_mm.h | 2 +- extras/mini-os/include/arm/os.h | 2 +- 5 files changed, 175 insertions(+), 10 deletions(-) create mode 100644 extras/mini-os/arch/arm/panic.c
extras/mini-os/ARM-TODO.txt +0 -1
@@ -1,4 +1,3 @@ -* support abort exception handling ( and others ) * scheduling! * gic request_irq implementation, currently all IRQs all hardcoded in gic irq handler. * use device tree instead of the currently hardcoded values
extras/mini-os/arch/arm/arm32.S +74 -7
103 lines not on this page · raw message
extras/mini-os/arch/arm/panic.c new file +99 -0
99 lines not on this page · raw message
extras/mini-os/include/arm/arch_mm.h +1 -1
@@ -2,7 +2,7 @@#define _ARCH_MM_H_extern char _text, _etext, _erodata, _edata, _end, __bss_start; -extern char stack[]; +extern int stack[];#define PAGE_SHIFT 12#define PAGE_SIZE (1 << PAGE_SHIFT)
extras/mini-os/include/arm/os.h +1 -1
@@ -10,7 +10,7 @@void arch_fini (void );void timer_handler (evtchn_port_t port,struct pt_regs *regs,void *ign); -#define BUG () while(1){} +#define BUG () while(1){asm volatile (".word 0xe7f000f0\n");}/* Undefined instruction; will call our fault handler. */ #define smp_processor_id () 0
Signature · 7 lines
2.0.0 _______________________________________________ Xen-devel mailing list [email protected] http://lists.xen.org/xen-devel
PATCH v4 9/12 mini-os: import libfdt
In reply to Thomas LeonardFrom: Karim Raslan <[email protected]>
Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git
The memmove implementation is from FreeBSD'scontrib/ldns/compat/memmove.c
--- extras/mini-os/COPYING | 27 + extras/mini-os/Makefile | 11 + extras/mini-os/include/fdt.h | 60 ++ extras/mini-os/include/lib.h | 4 +- extras/mini-os/include/libfdt.h | 1478 ++++++++++++++++++++++++++++++ extras/mini-os/include/libfdt_env.h | 37 + extras/mini-os/lib/fdt/fdt.c | 222 +++++ extras/mini-os/lib/fdt/fdt_empty_tree.c | 84 ++ extras/mini-os/lib/fdt/fdt_ro.c | 574 ++++++++++++ extras/mini-os/lib/fdt/fdt_rw.c | 492 ++++++++++ extras/mini-os/lib/fdt/fdt_strerror.c | 96 ++ extras/mini-os/lib/fdt/fdt_sw.c | 256 ++++++ extras/mini-os/lib/fdt/fdt_wip.c | 118 +++ extras/mini-os/lib/fdt/libfdt_internal.h | 95 ++ extras/mini-os/lib/memmove.c | 45 + extras/mini-os/lib/string.c | 12 + 16 files changed, 3610 insertions(+), 1 deletion(-) create mode 100644 extras/mini-os/include/fdt.h create mode 100644 extras/mini-os/include/libfdt.h create mode 100644 extras/mini-os/include/libfdt_env.h create mode 100644 extras/mini-os/lib/fdt/fdt.c create mode 100644 extras/mini-os/lib/fdt/fdt_empty_tree.c create mode 100644 extras/mini-os/lib/fdt/fdt_ro.c create mode 100644 extras/mini-os/lib/fdt/fdt_rw.c create mode 100644 extras/mini-os/lib/fdt/fdt_strerror.c create mode 100644 extras/mini-os/lib/fdt/fdt_sw.c create mode 100644 extras/mini-os/lib/fdt/fdt_wip.c create mode 100644 extras/mini-os/lib/fdt/libfdt_internal.h create mode 100644 extras/mini-os/lib/memmove.c
extras/mini-os/COPYING +27 -0
@@ -34,3 +34,30 @@ LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +Copyright (c) 2005,2006, NLnetLabs +All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + * Neither the name of NLnetLabs nor the names of its + contributors may be used to endorse or promote products derived from this + software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE +LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS +INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN +CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) +ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE +POSSIBILITY OF SUCH DAMAGE.
extras/mini-os/Makefile +11 -0
@@ -83,6 +83,16 @@ src-y += drivers/gic.c # Need libgcc.a for division helpers LDLIBS += `$(CC) -print-libgcc-file-name` + +# Device tree support +SUBDIRS += lib/fdt +src-y += lib/fdt/fdt.c +src-y += lib/fdt/fdt_empty_tree.c +src-y += lib/fdt/fdt_ro.c +src-y += lib/fdt/fdt_rw.c +src-y += lib/fdt/fdt_strerror.c +src-y += lib/fdt/fdt_sw.c +src-y += lib/fdt/fdt_wip.c endif src-$(CONFIG_BLKFRONT) += blkfront.c
@@ -111,6 +121,7 @@ endif src-y += lib/printf.c src-y += lib/stack_chk_fail.c src-y += lib/string.c +src-y += lib/memmove.c src-y += lib/sys.c src-y += lib/xmalloc.c src-$(CONFIG_XENBUS) += lib/xs.c
extras/mini-os/include/fdt.h new file +60 -0
60 lines not on this page · raw message
extras/mini-os/include/lib.h +3 -1
@@ -86,6 +86,7 @@ char *strncpy(char * __restrict, const char * __restrict, size_t);char *strstr (const char *,const char *); +void *memmove (void * dest,const void *src,size_t count);void *memset (void *,int ,size_t );char *strchr (const char *p,int ch);
@@ -95,7 +96,8 @@ char *strrchr(const char *p, int ch);* @(#)systm.h 8.7 (Berkeley) 3/29/95 * $FreeBSD$ */ -void *memcpy (void *to,const void *from,size_t len); +void *memcpy (void *to,const void *from,size_t len); +void *memchr (const void *s,int c,size_t n);size_t strnlen (const char *,size_t );#endif
extras/mini-os/include/libfdt.h new file +1478 -0
1,478 lines not on this page · raw message
extras/mini-os/include/libfdt_env.h new file +37 -0
@@ -0,0 +1,37 @@ +#ifndef _LIBFDT_ENV_H +#define _LIBFDT_ENV_H + +#ifdef _KERNEL +#include <sys/cdefs.h> +#include <sys/param.h> +#include <sys/types.h> +#include <sys/systm.h> +#include <sys/stdint.h> +#else +#include <stddef.h> +#include <stdint.h> +#include <string.h> +#endif + +#define EXTRACT_BYTE (n) ((unsigned long long)((uint8_t *)&x)[n]) +static inline uint16_t fdt16_to_cpu (uint16_t x) +{ +return (EXTRACT_BYTE (0 ) <<8 ) |EXTRACT_BYTE (1 ); +} +#define cpu_to_fdt16 (x) fdt16_to_cpu(x) + +static inline uint32_t fdt32_to_cpu (uint32_t x) +{ +return (EXTRACT_BYTE (0 ) <<24 ) | (EXTRACT_BYTE (1 ) <<16 ) | (EXTRACT_BYTE (2 ) <<8 ) |EXTRACT_BYTE (3 ); +} +#define cpu_to_fdt32 (x) fdt32_to_cpu(x) + +static inline uint64_t fdt64_to_cpu (uint64_t x) +{ +return (EXTRACT_BYTE (0 ) <<56 ) | (EXTRACT_BYTE (1 ) <<48 ) | (EXTRACT_BYTE (2 ) <<40 ) | (EXTRACT_BYTE (3 ) <<32 ) + | (EXTRACT_BYTE (4 ) <<24 ) | (EXTRACT_BYTE (5 ) <<16 ) | (EXTRACT_BYTE (6 ) <<8 ) |EXTRACT_BYTE (7 ); +} +#define cpu_to_fdt64 (x) fdt64_to_cpu(x) +#undef EXTRACT_BYTE + +#endif /* _LIBFDT_ENV_H */
extras/mini-os/lib/fdt/fdt.c new file +222 -0
222 lines not on this page · raw message
extras/mini-os/lib/fdt/fdt_empty_tree.c new file +84 -0
84 lines not on this page · raw message
extras/mini-os/lib/fdt/fdt_ro.c new file +574 -0
574 lines not on this page · raw message
extras/mini-os/lib/fdt/fdt_rw.c new file +492 -0
476 lines not on this page · raw message
extras/mini-os/lib/fdt/fdt_strerror.c new file +96 -0
96 lines not on this page · raw message
extras/mini-os/lib/fdt/fdt_sw.c new file +256 -0
256 lines not on this page · raw message
extras/mini-os/lib/fdt/fdt_wip.c new file +118 -0
118 lines not on this page · raw message
extras/mini-os/lib/fdt/libfdt_internal.h new file +95 -0
95 lines not on this page · raw message
extras/mini-os/lib/memmove.c new file +45 -0
45 lines not on this page · raw message
The rest of this diff is not shown. View the raw message.
Signature · 1 line
2.0.0
Part of the diff is not shown here. View the raw message.
Re: [PATCH ARM v4 09/12] mini-os: import libfdt
Quoted 5 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:23 +0100, a écrit :
From: Karim Raslan <[email protected]>
Looks like this is revision v1.3.0-47-gbe60268 from
http://git.jdl.com/gitweb/?p=dtc.git
Quoted 8 lines
The memmove implementation is from FreeBSD's
contrib/ldns/compat/memmove.cSigned-off-by Karim Allah Ahmed <[email protected]>[[email protected]: split out FDT support into a separate patch][[email protected]: fixed "make clean" for FDT][[email protected]: replaced GPL memmove with BSD one]Signed-off-by Thomas Leonard <[email protected]>
Another case of "integration looks fine to me, I haven't reviewed the additional feature".
Samuel
PATCH v4 10/12 mini-os: get RAM base and size from the FDT
In reply to Thomas Leonard--- extras/mini-os/arch/arm/mm.c | 70 ++++++++++++++++++++++++++++++++++++++--- extras/mini-os/arch/arm/setup.c | 12 ++++++- extras/mini-os/include/arm/os.h | 2 ++ extras/mini-os/mm.c | 4 +-- 4 files changed, 80 insertions(+), 8 deletions(-)
extras/mini-os/arch/arm/mm.c +65 -5
@@ -1,5 +1,7 @@#include <console.h> #include <arch_mm.h> +#include <libfdt.h> +#include <lib.h> #define PHYS_START (0x80008000 + (1000 * 4 * 1024))#define PHYS_SIZE (40*1024*1024)
@@ -25,12 +27,70 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p)printk (" stack start: %p(VA)\n" , stack);printk (" _end: %p(VA)\n" , &_end); -// FIXME Get from dt! - *start_pfn_p = (((unsigned long )&_end) >>PAGE_SHIFT ) +1000 ; - *max_pfn_p = ((unsigned long )&_end +PHYS_SIZE ) >>PAGE_SHIFT ; + *start_pfn_p =0 ; + *max_pfn_p =0 ; -printk (" start_pfn: %lx\n" , *start_pfn_p); -printk (" max_pfn: %lx\n" , *max_pfn_p); +if (fdt_num_mem_rsv (device_tree) !=0 ) +printk ("WARNING: reserved memory not supported!\n" ); + +int node =0 ; +int depth =0 ; +for (;;) + { + node =fdt_next_node (device_tree, node, &depth); +if (node <=0 || depth <0 ) +break ; +/* +int name_len = 0; +const char *name = fdt_get_name(device_tree, node, &name_len); +printk("Found node: %d (%.*s)\n", node, name_len, name); +*/ + +const char *device_type =fdt_getprop (device_tree, node,"device_type" ,NULL ); +if (device_type && !strcmp (device_type,"memory" )) + { +/* Note: we assume there's only a single region of memory. +* Since Xen is already translating our "physical" +* addresses to the real physical RAM, there's no +* reason for it to give us multiple blocks. */ +int len =0 ; +const uint64_t *regs =fdt_getprop (device_tree, node,"reg" , &len); +if (regs ==NULL || len !=16 ) { +printk ("Bad 'reg' property: %p %d\n" , regs, len); +continue ; + } +unsigned int start = (unsigned int ) &_text; +unsigned int end = (unsigned int ) &_end; +unsigned int mem_base =fdt64_to_cpu (regs[0 ]); +unsigned int mem_size =fdt64_to_cpu (regs[1 ]); +printk ("Found memory at %p (len 0x%x)\n" , mem_base, mem_size); + +BUG_ON (mem_base > start);/* Our image isn't in our RAM! */ + *start_pfn_p =PFN_UP (end); +int heap_len = mem_size - ((*start_pfn_p <<PAGE_SHIFT ) - mem_base); + *max_pfn_p = *start_pfn_p +PFN_DOWN (heap_len); + +printk ("Using pages %d to %d as free space for heap.\n" , *start_pfn_p, *max_pfn_p); +break ; + } + } + +if (*max_pfn_p ==0 ) + { +printk ("No memory found in FDT!\n" ); +BUG (); + } + +/* The device tree is probably in memory that we're about to hand over to the page +* allocator, so move it to the end and reserve that space. +*/ +int fdt_size =fdt_totalsize (device_tree); +void *new_device_tree = (void *) (((*max_pfn_p <<PAGE_SHIFT ) - fdt_size) &PAGE_MASK ); +if (new_device_tree != device_tree) { +memmove (new_device_tree, device_tree, fdt_size); + } + device_tree = new_device_tree; + *max_pfn_p = ((unsigned long ) new_device_tree) >>PAGE_SHIFT ;build_pagetable (start_pfn_p, max_pfn_p); }
extras/mini-os/arch/arm/setup.c +11 -1
@@ -4,6 +4,7 @@#include <xen/memory.h> #include <xen/hvm/params.h> #include <arch_mm.h> +#include <libfdt.h> /* * This structure contains start-of-day info, such as pagetable base pointer,
@@ -20,6 +21,8 @@ shared_info_t *HYPERVISOR_shared_info;extern char shared_info_page[PAGE_SIZE ]; +void *device_tree; +static int hvm_get_parameter (int idx,uint64_t *value) {struct xen_hvm_param xhv;
@@ -72,7 +75,14 @@ void arch_init(void *dtb_pointer)memset (&__bss_start,0 , &_end - &__bss_start); -printk ("dtb_pointer : %x\n" , dtb_pointer); +printk ("Checking DTB at %x...\n" , dtb_pointer); + +int r; +if ((r =fdt_check_header (dtb_pointer))) { +printk ("Invalid DTB from Xen: %s\n" ,fdt_strerror (r)); +BUG (); + } + device_tree = dtb_pointer;/* Map shared_info page */ xatp.domid =DOMID_SELF ;
extras/mini-os/include/arm/os.h +2 -0
@@ -10,6 +10,8 @@void arch_fini (void );void timer_handler (evtchn_port_t port,struct pt_regs *regs,void *ign); +extern void *device_tree; +#define BUG () while(1){asm volatile (".word 0xe7f000f0\n");}/* Undefined instruction; will call our fault handler. */ #define smp_processor_id () 0
extras/mini-os/mm.c +2 -2
@@ -409,8 +409,8 @@ void init_mm(void)* now we can initialise the page allocator */ printk ("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n" , - (u_long )to_virt (PFN_PHYS (start_pfn)),PFN_PHYS (start_pfn), - (u_long )to_virt (PFN_PHYS (max_pfn)),PFN_PHYS (max_pfn)); + (u_long )to_virt (PFN_PHYS (start_pfn)), (u_long )PFN_PHYS (start_pfn), + (u_long )to_virt (PFN_PHYS (max_pfn)), (u_long )PFN_PHYS (max_pfn));init_page_allocator (PFN_PHYS (start_pfn),PFN_PHYS (max_pfn));printk ("MM: done\n" );
Signature · 1 line
2.0.0
Re: [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT
Hi Thomas,
extras/mini-os/arch/arm/mm.c void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) · line 55
Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7
-0+const char *device_type =fdt_getprop (device_tree, node,"device_type" ,NULL ); +if (device_type && !strcmp (device_type,"memory" )) + { +/* Note: we assume there's only a single region of memory. +* Since Xen is already translating our "physical" +* addresses to the real physical RAM, there's no +* reason for it to give us multiple blocks. */
This comment looks wrong to me. Even tho, Xen is providing a stage-2 translation to show you a virtual layout (your guest physical memory), the new layout in Xen upstream may contain multiple banks. The first bank will contain up to 3G of RAM.
extras/mini-os/mm.c void init_mm(void) · line 413
Quoted 11 lines
index d2d5264..d31ef97 100644
extras/mini-os/mm.c +2
-2@@ -409,8 +409,8 @@ void init_mm(void)* now we can initialise the page allocator */ printk ("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n" , - (u_long )to_virt (PFN_PHYS (start_pfn)),PFN_PHYS (start_pfn), - (u_long )to_virt (PFN_PHYS (max_pfn)),PFN_PHYS (max_pfn)); + (u_long )to_virt (PFN_PHYS (start_pfn)), (u_long )PFN_PHYS (start_pfn), + (u_long )to_virt (PFN_PHYS (max_pfn)), (u_long )PFN_PHYS (max_pfn));
I don't see any modification of the type of max_pfn, start_pfn, PFN_PHYS. This change should not be part of this patch.
Regards,
Signature · 1 line
Julien Grall
Re: [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT
Quoted 11 lines · Julien Grall
Hi Thomas,
extras/mini-os/arch/arm/mm.c void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) · line 55
Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7
-0+const char *device_type =fdt_getprop (device_tree, node,"device_type" ,NULL ); +if (device_type && !strcmp (device_type,"memory" )) + { +/* Note: we assume there's only a single region of memory. +* Since Xen is already translating our "physical" +* addresses to the real physical RAM, there's no +* reason for it to give us multiple blocks. */
Quoted 4 lines
This comment looks wrong to me. Even tho, Xen is providing a stage-2 translation to show you a virtual layout (your guest physical memory), the new layout in Xen upstream may contain multiple banks. The first bank will contain up to 3G of RAM.
Hi Julien,
At the Hackathon, we decided Mini-OS could always rely on Xen to provide the memory in a single block:
"ARM guests are allowed to assume one bank of memory. We need to document this in the ABI. ARM guests should assume the presence of an FDT."
http://lists.xenproject.org/archives/html/mirageos-devel/2014-06/msg00004.html
A lot of the value of running on Xen is that we only have to support a small number of configurations, because Xen hides the details of the physical hardware. I assume the only reason for using the (very flexible) FDT format to provide this information is that it's simpler for full OSs which already use FDTs.
Is the ARM guest ABI documented somewhere?
Quoted 14 lines
extras/mini-os/mm.c void init_mm(void) · line 413
Quoted 11 lines
index d2d5264..d31ef97 100644
extras/mini-os/mm.c +2
-2@@ -409,8 +409,8 @@ void init_mm(void)* now we can initialise the page allocator */ printk ("MM: Initialise page allocator for %lx(%lx)-%lx(%lx)\n" , - (u_long )to_virt (PFN_PHYS (start_pfn)),PFN_PHYS (start_pfn), - (u_long )to_virt (PFN_PHYS (max_pfn)),PFN_PHYS (max_pfn)); + (u_long )to_virt (PFN_PHYS (start_pfn)), (u_long )PFN_PHYS (start_pfn), + (u_long )to_virt (PFN_PHYS (max_pfn)), (u_long )PFN_PHYS (max_pfn));I don't see any modification of the type of
max_pfn,start_pfn,PFN_PHYS. This change should not be part of this patch.
Signature · 3 lines
Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA
Re: [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT
Quoted 12 lines · Thomas Leonard
Quoted 11 lines · Julien Grall
Hi Thomas,
Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7
-0+const char *device_type =fdt_getprop (device_tree, node,"device_type" ,NULL ); +if (device_type && !strcmp (device_type,"memory" )) + { +/* Note: we assume there's only a single region of memory. +* Since Xen is already translating our "physical" +* addresses to the real physical RAM, there's no +* reason for it to give us multiple blocks. */
Quoted 6 lines
Quoted 4 lines
This comment looks wrong to me. Even tho, Xen is providing a stage-2 translation to show you a virtual layout (your guest physical memory), the new layout in Xen upstream may contain multiple banks. The first bank will contain up to 3G of RAM.
Hi Julien,
Hello Thomas,
Quoted 6 lines
At the Hackathon, we decided Mini-OS could always rely on Xen to provide the memory in a single block:
"ARM guests are allowed to assume one bank of memory. We need to document this in the ABI. ARM guests should assume the presence of an FDT."
I'm not against only supporting one bank... I pointed that your comment is wrong and doesn't reflect this sentence.
I didn't attend to this meeting, but I guess it was meant that the guest can assume there is always one bank of memory.
I would change your comment into:
"Xen will always provide us at least one bank of memory. Mini-os will use the first bank for the time-being"
Quoted 7 lines
http://lists.xenproject.org/archives/html/mirageos-devel/2014-06/msg00004.html
A lot of the value of running on Xen is that we only have to support a small number of configurations, because Xen hides the details of the physical hardware. I assume the only reason for using the (very flexible) FDT format to provide this information is that it's simpler for full OSs which already use FDTs.
As specified in the ABI, the guest layout may change from time to time. Actually, the layout is not compatible between Xen 4.4 and 4.5.
Unless you want your OS tight to a Xen specific version, I don't think we want that for mini-os. You have to correctly support FDT and retrieve every information (MMIO, IRQ) from it.
Quoted 1 line
Is the ARM guest ABI documented somewhere?
You can find the guest layout described in xen/include/public/arch-arm.h
Regards
Signature · 1 line
Julien Grall
Re: [PATCH ARM v4 10/12] mini-os: get RAM base and size from the FDT
Quoted 32 lines · Julien Grall
Quoted 12 lines · Thomas Leonard
Quoted 11 lines · Julien Grall
Hi Thomas,
Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7
-0+const char *device_type =fdt_getprop (device_tree, node,"device_type" ,NULL ); +if (device_type && !strcmp (device_type,"memory" )) + { +/* Note: we assume there's only a single region of memory. +* Since Xen is already translating our "physical" +* addresses to the real physical RAM, there's no +* reason for it to give us multiple blocks. */ Quoted 6 lines
Quoted 4 lines
This comment looks wrong to me. Even tho, Xen is providing a stage-2 translation to show you a virtual layout (your guest physical memory), the new layout in Xen upstream may contain multiple banks. The first bank will contain up to 3G of RAM.
Hi Julien,
Hello Thomas,
Quoted 6 lines
At the Hackathon, we decided Mini-OS could always rely on Xen to provide the memory in a single block:
"ARM guests are allowed to assume one bank of memory. We need to document this in the ABI. ARM guests should assume the presence of an FDT."
I'm not against only supporting one bank... I pointed that your comment is wrong and doesn't reflect this sentence.
Quoted 7 lines
I didn't attend to this meeting, but I guess it was meant that the guest can assume there is always one bank of memory.
I would change your comment into:
"Xen will always provide us at least one bank of memory. Mini-os will use the first bank for the time-being"
Yes. The ABI definitely doesn't say "at most one bank". We already have two in 4.5 for sufficiently large guests.
Quoted 11 lines
Quoted 7 lines
http://lists.xenproject.org/archives/html/mirageos-devel/2014-06/msg00004.html
A lot of the value of running on Xen is that we only have to support a small number of configurations, because Xen hides the details of the physical hardware. I assume the only reason for using the (very flexible) FDT format to provide this information is that it's simpler for full OSs which already use FDTs.
As specified in the ABI, the guest layout may change from time to time. Actually, the layout is not compatible between Xen 4.4 and 4.5.
Quoted 7 lines
Unless you want your OS tight to a Xen specific version, I don't think we want that for mini-os. You have to correctly support FDT and retrieve every information (MMIO, IRQ) from it.
Quoted 1 line
Is the ARM guest ABI documented somewhere?
You can find the guest layout described in
xen/include/public/arch-arm.h
Note that this is for the benefit of the toolstack (matched to Xen) only. If you decide you want to use those values yourself then you are agreeing with yourself that you are happy to recompile in order to run on another version of Xen.
If you aren't happy with that then you should use the FDT which has been provided for this purpose.
Ian.
PATCH v4 11/12 mini-os: get GIC addresses from FDT
In reply to Thomas Leonard--- extras/mini-os/drivers/gic.c | 36 +++++++++++++++++++++++++++++++++--- 1 file changed, 33 insertions(+), 3 deletions(-)
extras/mini-os/drivers/gic.c +33 -3
@@ -2,6 +2,7 @@#include <mini-os/os.h> #include <mini-os/hypervisor.h> +#include <libfdt.h> //#define VGIC_DEBUG #ifdef VGIC_DEBUG
@@ -168,9 +169,38 @@ static void gic_handler(void) { }void gic_init (void ) { -// FIXME Get from dt! - gic.gicd_base = (char *)0x2c001000ULL ; - gic.gicc_base = (char *)0x2c002000ULL ; + gic.gicd_base =NULL ; +int node =0 ; +int depth =0 ; +for (;;) + { + node =fdt_next_node (device_tree, node, &depth); +if (node <=0 || depth <0 ) +break ; + +/* +int name_len = 0; +const char *name = fdt_get_name(device_tree, node, &name_len); +printk("Found node: %d (%.*s)\n", node, name_len, name); +*/ + +if (fdt_getprop (device_tree, node,"interrupt-controller" ,NULL )) { +int len =0 ; +const uint64_t *reg =fdt_getprop (device_tree, node,"reg" , &len); +if (reg ==NULL || len !=32 ) { +printk ("Bad 'reg' property: %p %d\n" , reg, len); +continue ; + } + gic.gicd_base = (char *) (long )fdt64_to_cpu (reg[0 ]); + gic.gicc_base = (char *) (long )fdt64_to_cpu (reg[2 ]); +printk ("Found GIC: gicd_base = %p, gicc_base = %p\n" , gic.gicd_base, gic.gicc_base); +break ; + } + } +if (!gic.gicd_base) { +printk ("GIC not found!\n" ); +BUG (); + }wmb (); IRQ_handler = gic_handler;
Signature · 1 line
2.0.0
Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT
Hi Thomas,
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172
Quoted 10 lines · Thomas Leonard
//#define
VGIC_DEBUG
#ifdefVGIC_DEBUGextras/mini-os/drivers/gic.c +1
-3@@ -168,9 +169,38 @@ static void gic_handler(void) { }void gic_init (void ) { -// FIXME Get from dt! - gic.gicd_base = (char *)0x2c001000ULL ; - gic.gicc_base = (char *)0x2c002000ULL ; + gic.gicd_base =NULL ;
Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?
This would avoid to hardcode a GIC address which is completely wrong with Xen unstable.
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 185
Quoted 13 lines
extras/mini-os/drivers/gic.c +13
-0+int node =0 ; +int depth =0 ; +for (;;) + { + node =fdt_next_node (device_tree, node, &depth); +if (node <=0 || depth <0 ) +break ; + +/* +int name_len = 0; +const char *name = fdt_get_name(device_tree, node, &name_len); +printk("Found node: %d (%.*s)\n", node, name_len, name); +*/
This should be drop.
Review static void gic_handler(void) { · line 187
Quoted 2 lines
(quoted diff) +2
-0+ + if (fdt_getprop(device_tree, node, "interrupt-controller", NULL)) {
You have to check the compatible string here.
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 190
Quoted 3 lines
extras/mini-os/drivers/gic.c +3
-0+int len =0 ; +const uint64_t *reg =fdt_getprop (device_tree, node,"reg" , &len); +if (reg ==NULL || len !=32 ) {
You made assumption of the layout of the device tree provided by Xen:
- #address-cells == #size-cells == 2
- regs contains a valid physical address, i.e the device is not under a bus
This can be changed by the toolstack in the future and will likely break mini-os.
I would add a layer to support FDT address and interrupt translation correctly. I'm not the maintainer of the mini-os, so I let them decide :).
I think, FreeBSD provides a good library for the translation (see sys/dev/fdt/fdt_common.c).
I spent lots of time to play with device tree on Xen side, so I can help you if you needed.
Signature · 1 line
Julien Grall
Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT
Quoted 8 lines · Julien Grall
Hi Thomas,
Quoted 5 lines · Thomas Leonard
//#define
VGIC_DEBUG
#ifdefVGIC_DEBUG(quoted diff) +0
-0@@ -168,9 +169,38 @@ static void gic_handler(void) { }
Quoted 8 lines
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172
Quoted 5 lines
extras/mini-os/drivers/gic.c +1
-3void gic_init (void ) { -// FIXME Get from dt! - gic.gicd_base = (char *)0x2c001000ULL ; - gic.gicc_base = (char *)0x2c002000ULL ; + gic.gicd_base =NULL ;Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?
It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.
Moving all the GIC code to this patch would mean that the original patch wouldn't work on its own.
Quoted 28 lines
This would avoid to hardcode a GIC address which is completely wrong with Xen unstable.
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 185
Quoted 13 lines
extras/mini-os/drivers/gic.c +13
-0+int node =0 ; +int depth =0 ; +for (;;) + { + node =fdt_next_node (device_tree, node, &depth); +if (node <=0 || depth <0 ) +break ; + +/* +int name_len = 0; +const char *name = fdt_get_name(device_tree, node, &name_len); +printk("Found node: %d (%.*s)\n", node, name_len, name); +*/ This should be drop.
Review static void gic_handler(void) { · line 187
Quoted 2 lines
(quoted diff) +2
-0+ + if (fdt_getprop(device_tree, node, "interrupt-controller", NULL)) {You have to check the compatible string here.
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 190
Quoted 3 lines
extras/mini-os/drivers/gic.c +3
-0+int len =0 ; +const uint64_t *reg =fdt_getprop (device_tree, node,"reg" , &len); +if (reg ==NULL || len !=32 ) {
Quoted 6 lines
You made assumption of the layout of the device tree provided by Xen:
- #address-cells == #size-cells == 2
- regs contains a valid physical address, i.e the device is not under a busThis can be changed by the toolstack in the future and will likely break mini-os.
Is that likely? Seems like using BUG here is the right thing to do until that happens.
Quoted 8 lines
I would add a layer to support FDT address and interrupt translation correctly. I'm not the maintainer of the mini-os, so I let them decide :).
I think, FreeBSD provides a good library for the translation (see
sys/dev/fdt/fdt_common.c).I spent lots of time to play with device tree on Xen side, so I can help you if you needed.
That would be very helpful - thanks!
Signature · 3 lines
Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA
Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT
Hi Thomas,
Quoted 18 lines · Thomas Leonard
Quoted 8 lines · Julien Grall
Hi Thomas,
Quoted 5 lines · Thomas Leonard
//#define
VGIC_DEBUG
#ifdefVGIC_DEBUG(quoted diff) +0
-0@@ -168,9 +169,38 @@ static void gic_handler(void) { }Quoted 8 lines
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172
Quoted 5 lines
extras/mini-os/drivers/gic.c +1
-3void gic_init (void ) { -// FIXME Get from dt! - gic.gicd_base = (char *)0x2c001000ULL ; - gic.gicc_base = (char *)0x2c002000ULL ; + gic.gicd_base =NULL ;Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?
Quoted 3 lines
It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.
Please make sure that this "standalone patch" works correctly on Xen unstable...
Quoted 2 lines
Moving all the GIC code to this patch would mean that the original patch wouldn't work on its own.
I'm not sure why you want to have a single big patch to support ARM... AFAIU, there is some patch requirements to work correctly.
Quoted 9 lines
Quoted 6 lines
You made assumption of the layout of the device tree provided by Xen:
- #address-cells == #size-cells == 2
- regs contains a valid physical address, i.e the device is not under a busThis can be changed by the toolstack in the future and will likely break mini-os.
Is that likely? Seems like using BUG here is the right thing to do until that happens.
You need at least to add a comment about the (len != 32). It's confusing for people that doesn't know how the device tree has been created.
I still think that a layer for IRQ and MMIO translation would be helpful for mini-os. So you will directly get the range (base + size), and won't duplicate checking code on every part of mini-os.
Quoted 1 line
That would be very helpful - thanks!
You can join #xenarm for any question if you are not already there.
Regards,
Signature · 1 line
Julien Grall
Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT
Quoted 21 lines · Julien Grall
Hi Thomas,
Quoted 18 lines · Thomas Leonard
Quoted 16 lines · Julien Grall
Hi Thomas,
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172
Quoted 10 lines · Thomas Leonard
//#define
VGIC_DEBUG
#ifdefVGIC_DEBUGextras/mini-os/drivers/gic.c +1
-3@@ -168,9 +169,38 @@ static void gic_handler(void) { }void gic_init (void ) { -// FIXME Get from dt! - gic.gicd_base = (char *)0x2c001000ULL ; - gic.gicc_base = (char *)0x2c002000ULL ; + gic.gicd_base =NULL ;Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?
Quoted 6 lines
Quoted 3 lines
It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.
Please make sure that this "standalone patch" works correctly on Xen unstable...
OK, I can make it use GUEST_GICD_BASE/GUEST_GICC_BASE (with a FIXME) so that the first commit works on unstable.
I tried installing the unstable version (staging branch) of Xen to test it, but for some reason it didn't work:
# LD_LIBRARY_PATH=/opt/xen-4.5-unstable/lib/ /opt/xen-4.5-unstable/sbin/xl dmesg
xc: error: Could not obtain handle on privileged command interface (2 = No such file or directory): Internal error
libxl: error: libxl.c:99:libxl_ctx_alloc: cannot open libxc handle: No such file or directory
cannot init xl context
It tries to open "/proc/xen/privcmd", which doesn't exist. Maybe I need a newer Linux kernel? That could be tricky, as I'm using a special fork for this board.
Quoted 5 lines
Quoted 2 lines
Moving all the GIC code to this patch would mean that the original patch wouldn't work on its own.
I'm not sure why you want to have a single big patch to support ARM... AFAIU, there is some patch requirements to work correctly.
If it isn't necessary that the first commit works, then I can split things up further (e.g. all the include files first, then just arm32.S, etc), but I'm not sure how much that would help. Let me know what's easiest for reviewing.
Quoted 25 lines
Quoted 9 lines
Quoted 6 lines
You made assumption of the layout of the device tree provided by Xen:
- #address-cells == #size-cells == 2
- regs contains a valid physical address, i.e the device is not under a busThis can be changed by the toolstack in the future and will likely break mini-os.
Is that likely? Seems like using BUG here is the right thing to do until that happens.
You need at least to add a comment about the (len != 32). It's confusing for people that doesn't know how the device tree has been created.
I still think that a layer for IRQ and MMIO translation would be helpful for mini-os. So you will directly get the range (base + size), and won't duplicate checking code on every part of mini-os.
Quoted 1 line
That would be very helpful - thanks!
You can join #xenarm for any question if you are not already there.
Regards,
--
Julien Grall
Signature · 3 lines
Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA
Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT
Quoted 24 lines · Thomas Leonard
Quoted 23 lines · Julien Grall
Quoted 21 lines · Thomas Leonard
Quoted 8 lines · Julien Grall
Hi Thomas,
Quoted 5 lines · Thomas Leonard
//#define
VGIC_DEBUG
#ifdefVGIC_DEBUG(quoted diff) +0
-0@@ -168,9 +169,38 @@ static void gic_handler(void) { }Quoted 8 lines
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172
Quoted 5 lines
extras/mini-os/drivers/gic.c +1
-3void gic_init (void ) { -// FIXME Get from dt! - gic.gicd_base = (char *)0x2c001000ULL ; - gic.gicc_base = (char *)0x2c002000ULL ; + gic.gicd_base =NULL ;Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?
It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.
Quoted 5 lines
Quoted 2 lines
Please make sure that this "standalone patch" works correctly on Xen unstable...
OK, I can make it use GUEST_GICD_BASE/GUEST_GICC_BASE (with a FIXME) so that the first commit works on unstable.
This 2 defines are only exposed to XEN and XEN tools. I don't think you will be able to use it for mini-os.
Quoted 10 lines
I tried installing the unstable version (staging branch) of Xen to test it, but for some reason it didn't work:
# LD_LIBRARY_PATH=/opt/xen-4.5-unstable/lib/
/opt/xen-4.5-unstable/sbin/xldmesg
xc: error: Could not obtain handle on privileged command interface (2 = No such file or directory): Internal error
libxl: error: libxl.c:99:libxl_ctx_alloc: cannot open libxc handle: No such file or directory
cannot init xl context
Quoted 3 lines
It tries to open "
/proc/xen/privcmd", which doesn't exist. Maybe I need a newer Linux kernel? That could be tricky, as I'm using a special fork for this board.
Did you start xencommons?
/etc/init.d/xencommons start
Regards,
Signature · 1 line
Julien Grall
Re: [PATCH ARM v4 11/12] mini-os: get GIC addresses from FDT
In reply to Thomas LeonardQuoted 18 lines · Thomas Leonard
Quoted 8 lines · Julien Grall
Hi Thomas,
Quoted 5 lines · Thomas Leonard
//#define
VGIC_DEBUG
#ifdefVGIC_DEBUG(quoted diff) +0
-0@@ -168,9 +169,38 @@ static void gic_handler(void) { }Quoted 8 lines
extras/mini-os/drivers/gic.c static void gic_handler(void) { · line 172
Quoted 5 lines
extras/mini-os/drivers/gic.c +1
-3void gic_init (void ) { -// FIXME Get from dt! - gic.gicd_base = (char *)0x2c001000ULL ; - gic.gicc_base = (char *)0x2c002000ULL ; + gic.gicd_base =NULL ;Any reason to not fold this patch in patch #7? Or better move the gic code in a separate patch?
Quoted 6 lines
It was previously requested that I split the FDT patch from the main ARM one. This patch depends on libfdt being present, so it has to go after that.
Moving all the GIC code to this patch would mean that the original patch wouldn't work on its own.
Is it not possible to put the fdt stuff before patch #7 so it is already present?
That said:
For things such as a new minios port we are more accepting of "bisection hazards" so long as they are all before some strict cut-off point, i.e. the point at which the build is actually wired up to make the series do anything.
IOW so long as this stuff isn't actually being built until patch #12 then you can play a bit fast a loose with the "it must always build" rule.
Ian.
PATCH v4 12/12 mini-os: added ARM grant table initialisation
In reply to Thomas LeonardOn x86, we get told which pages to use, but on ARM we get the base address in the FDT and have to map each page.
--- extras/mini-os/ARM-TODO.txt | 1 - extras/mini-os/arch/arm/mm.c | 58 +++++++++++++++++++++++++++++++++++++++++ extras/mini-os/arch/x86/mm.c | 13 +++++++++ extras/mini-os/gnttab.c | 11 ++------ extras/mini-os/include/gnttab.h | 1 + 5 files changed, 74 insertions(+), 10 deletions(-)
extras/mini-os/ARM-TODO.txt +0 -1
@@ -1,6 +1,5 @@ * scheduling! * gic request_irq implementation, currently all IRQs all hardcoded in gic irq handler. -* use device tree instead of the currently hardcoded values * Add virtual memory support and make vstart = 0 ( use 4k descriptors instead of 1M descriptors ) * sched * fini_gnttab
extras/mini-os/arch/arm/mm.c +58 -0
66 lines not on this page · raw message
extras/mini-os/arch/x86/mm.c +13 -0
@@ -942,3 +942,16 @@ void arch_init_mm(unsigned long* start_pfn_p, unsigned long* max_pfn_p) *start_pfn_p = start_pfn; *max_pfn_p = max_pfn; } + +grant_entry_t *arch_init_gnttab (int nr_grant_frames) +{ +struct gnttab_setup_table setup; +unsigned long frames[nr_grant_frames]; + + setup.dom =DOMID_SELF ; + setup.nr_frames = nr_grant_frames; +set_xen_guest_handle (setup.frame_list, frames); + +HYPERVISOR_grant_table_op (GNTTABOP_setup_table, &setup,1 ); +return map_frames (frames, nr_grant_frames); +}
extras/mini-os/gnttab.c +2 -9
@@ -164,7 +164,7 @@ gnttabop_error(int16_t status) { status = -status;if (status <0 || status >=ARRAY_SIZE (gnttabop_error_msgs)) -return "bad status" ; +return "bad status" ;else return gnttabop_error_msgs[status]; }
@@ -172,8 +172,6 @@ gnttabop_error(int16_t status)void init_gnttab (void ) { -struct gnttab_setup_table setup; -unsigned long frames[NR_GRANT_FRAMES ];int i;#ifdef GNT_DEBUG
@@ -182,12 +180,7 @@ init_gnttab(void)for (i =NR_RESERVED_ENTRIES ; i <NR_GRANT_ENTRIES ; i++)put_free_entry (i); - setup.dom =DOMID_SELF ; - setup.nr_frames =NR_GRANT_FRAMES ; -set_xen_guest_handle (setup.frame_list, frames); - -HYPERVISOR_grant_table_op (GNTTABOP_setup_table, &setup,1 ); - gnttab_table =map_frames (frames,NR_GRANT_FRAMES ); + gnttab_table =arch_init_gnttab (NR_GRANT_FRAMES );printk ("gnttab_table mapped at %p.\n" , gnttab_table); }
extras/mini-os/include/gnttab.h +1 -0
@@ -12,5 +12,6 @@ unsigned long gnttab_end_transfer(grant_ref_t gref);int gnttab_end_access (grant_ref_t ref);const char *gnttabop_error (int16_t status);void fini_gnttab (void ); +grant_entry_t *arch_init_gnttab (int nr_grant_frames);#endif /* !__GNTTAB_H__ */
Signature · 1 line
2.0.0
Re: [PATCH ARM v4 12/12] mini-os: added ARM grant table initialisation
Hi Thomas,
extras/mini-os/arch/arm/mm.c void arch_init_p2m(unsigned long max_pfn) · line 113
Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7
-0+ +/* Get Xen's sugggested physical page assignments for the grant table. */ +static grant_entry_t *get_gnttab_base (void ) +{ +int hypervisor; + + hypervisor =fdt_path_offset (device_tree,"/hypervisor" );
Same comment as on patch #11, you need to search the hypervisor node via the compatible string.
extras/mini-os/gnttab.c gnttabop_error(int16_t status) · line 167
Quoted 9 lines
index 2f1b3d7..f395d12 100644
extras/mini-os/gnttab.c +1
-1@@ -164,7 +164,7 @@ gnttabop_error(int16_t status) { status = -status;if (status <0 || status >=ARRAY_SIZE (gnttabop_error_msgs)) -return "bad status" ; +return "bad status" ;
Spurious change?
Regards,
Signature · 1 line
Julien Grall
Re: [PATCH ARM v4 12/12] mini-os: added ARM grant table initialisation
Quoted 13 lines · Julien Grall
Hi Thomas,
extras/mini-os/arch/arm/mm.c void arch_init_p2m(unsigned long max_pfn) · line 113
Quoted 7 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +7
-0+ +/* Get Xen's sugggested physical page assignments for the grant table. */ +static grant_entry_t *get_gnttab_base (void ) +{ +int hypervisor; + + hypervisor =fdt_path_offset (device_tree,"/hypervisor" );Same comment as on patch #11, you need to search the hypervisor node via the compatible string.
It's not clear to me what I should do with this attribute. On Xen/unstable, it contains the single value "xen,xen-4.5", meaning (I think) that Xen 4.5 is incompatible with Xen 4.4. But I'd still like Mini-OS to run. Presumably, 4.6 will be incompatible too. What could I do if the value doesn't match except try to use it anyway?
Signature · 3 lines
Dr Thomas Leonard http://0install.net/ GPG: 9242 9807 C985 3C07 44A6 8B9A AE07 8280 59A5 3CC1 GPG: DA98 25AE CAD0 8975 7CDA BD8E 0713 3F96 CA74 D8BA
Re: [PATCH ARM v4 12/12] mini-os: added ARM grant table initialisation
Quoted 6 lines · Thomas Leonard
Quoted 5 lines · Julien Grall
Hi Thomas,
extras/mini-os/arch/arm/mm.c void arch_init_p2m(unsigned long max_pfn) · line 108
Quoted 2 lines · Thomas Leonard
extras/mini-os/arch/arm/mm.c +2
-0+ +/* Get Xen's sugggested physical page assignments for the grant table. */
Too many g's.
Quoted 11 lines
Quoted 8 lines
extras/mini-os/arch/arm/mm.c void arch_init_p2m(unsigned long max_pfn) · line 113
Quoted 5 lines
extras/mini-os/arch/arm/mm.c +5
-0+static grant_entry_t *get_gnttab_base (void ) +{ +int hypervisor; + + hypervisor =fdt_path_offset (device_tree,"/hypervisor" );Same comment as on patch #11, you need to search the hypervisor node via the compatible string.
It's not clear to me what I should do with this attribute. On Xen/unstable, it contains the single value "xen,xen-4.5",
It should contain "xen,xen-X.Y\0xen,xen\0\0", i.e. multiple strings. If you don't care about the specific version then you should check for "xen,xen" somewhere in the list.
(This is how device tree compatibile strings work, more specific to more general).
Quoted 6 lines
meaning (I
think) that Xen 4.5 is incompatible with Xen 4.4. But I'd still like Mini-OS to run. Presumably, 4.6 will be incompatible too. What could I do if the value doesn't match except try to use it anyway?
Re: [PATCH ARM v4 12/12] mini-os: added ARM grant table initialisation
In reply to Thomas LeonardQuoted 4 lines · Thomas Leonard, le Wed 18 Jun 2014 16:08:26 +0100, a écrit :
On x86, we get told which pages to use, but on ARM we get the base address in the FDT and have to map each page.
Signed-off-by Thomas Leonard <[email protected]>
Integration is OK to me, I don't know about FDT :)
Samuel