[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Xen-devel] [RFC 22/29] xen/arm: Allow Xen to run on multiple platform without recompilation
On Mon, 29 Apr 2013, Julien Grall wrote: > Xen can include various platform support (ie: exynos5, versatile express...) > and choose during boot time a set of callbacks for the current board. > These callbacks will be called in places where each board can have specific > code. For the moment the callbacks are: > - platform_init: additional initialization for the platform > - platform_init_time: some platform (ie: Exynos 5) needs to initialize > the timer with an uncommon way > - platform_specific_mapping: add mapping to dom0 which are not specified > in the device tree > - platform_reset: reset the platform given that you added a platform_reset hook, you might as well add a platform_poweroff hook too. > Signed-off-by: Julien Grall <julien.grall@xxxxxxxxxx> > --- > xen/arch/arm/Makefile | 1 + > xen/arch/arm/domain_build.c | 4 ++ > xen/arch/arm/platform.c | 121 > ++++++++++++++++++++++++++++++++++++++++ > xen/arch/arm/setup.c | 3 + > xen/arch/arm/shutdown.c | 2 + > xen/arch/arm/time.c | 6 ++ > xen/arch/arm/xen.lds.S | 6 ++ > xen/include/asm-arm/platform.h | 70 +++++++++++++++++++++++ > 8 files changed, 213 insertions(+) > create mode 100644 xen/arch/arm/platform.c > create mode 100644 xen/include/asm-arm/platform.h > > diff --git a/xen/arch/arm/Makefile b/xen/arch/arm/Makefile > index 7a73b79..981ad78 100644 > --- a/xen/arch/arm/Makefile > +++ b/xen/arch/arm/Makefile > @@ -17,6 +17,7 @@ obj-y += p2m.o > obj-y += percpu.o > obj-y += guestcopy.o > obj-y += physdev.o > +obj-y += platform.o > obj-y += setup.o > obj-y += time.o > obj-y += smpboot.o > diff --git a/xen/arch/arm/domain_build.c b/xen/arch/arm/domain_build.c > index 11298e1..d6b8086 100644 > --- a/xen/arch/arm/domain_build.c > +++ b/xen/arch/arm/domain_build.c > @@ -12,6 +12,7 @@ > #include <xen/libfdt/libfdt.h> > #include <xen/guest_access.h> > #include <asm/setup.h> > +#include <asm/platform.h> > > #include <asm/gic.h> > #include <xen/irq.h> > @@ -516,6 +517,9 @@ int construct_dom0(struct domain *d) > return rc; > > parse_device_tree(d); > + rc = platform_specific_mapping(d); > + if ( rc < 0 ) > + return rc; > > /* The following loads use the domain's p2m */ > p2m_load_VTTBR(d); > diff --git a/xen/arch/arm/platform.c b/xen/arch/arm/platform.c > new file mode 100644 > index 0000000..ba569ea > --- /dev/null > +++ b/xen/arch/arm/platform.c > @@ -0,0 +1,121 @@ > +/* > + * xen/arch/arm/platform.c > + * > + * Helpers to execute platform specific code. > + * > + * Julien Grall <julien.grall@xxxxxxxxxx> > + * Copyright (C) 2013 Linaro Limited. > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License as published by > + * the Free Software Foundation; either version 2 of the License, or > + * (at your option) any later version. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include <asm/platform.h> > +#include <xen/device_tree.h> > +#include <xen/init.h> > + > +extern const struct platform_desc _splatform[], _eplatform[]; > + > +/* Pointer to the current platform description */ > +static const struct platform_desc *platform; > + > + > +static bool_t __init platform_is_compatible(const struct platform_desc *plat) > +{ > + const char *const *compat; > + > + if ( !plat->compatible ) > + return 0; > + > + for ( compat = plat->compatible; *compat; compat++ ) > + { > + if ( dt_machine_is_compatible(*compat) ) > + return 1; > + } > + > + return 0; > +} > + > +/* List of possible platform */ > +static void dump_platform_table(void) > +{ > + const struct platform_desc *p; > + > + printk("Available platform support:\n"); > + > + for ( p = _splatform; p != _eplatform; p++ ) > + printk(" - %s\n", p->name); > +} > + > +int __init platform_init(void) > +{ > + int res = 0; > + > + ASSERT(platform == NULL); > + > + /* Looking for the platform description */ > + for ( platform = _splatform; platform != _eplatform; platform++ ) > + { > + if ( platform_is_compatible(platform) ) > + break; > + } > + > + /* We don't have specific operations for this platform */ > + if ( platform == _eplatform ) > + { > + /* TODO: List compatible */ > + printk(XENLOG_WARNING "WARNING: Unrecognized/unsupported device tree > " > + "compatible list\n"); > + dump_platform_table(); > + platform = NULL; > + } > + else > + printk(XENLOG_INFO "Platform: %s\n", platform->name); > + > + if ( platform && platform->init ) > + res = platform->init(); > + > + return res; > +} > + > +int __init platform_init_time(void) > +{ > + int res = 0; > + > + if ( platform && platform->init_time ) > + res = platform->init_time(); > + > + return res; > +} > + > +int __init platform_specific_mapping(struct domain *d) > +{ > + int res = 0; > + > + if ( platform && platform->specific_mapping ) > + res = platform->specific_mapping(d); > + > + return res; > +} > + > +void platform_reset(void) > +{ > + if ( platform && platform->reset ) > + platform->reset(); > +} > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > diff --git a/xen/arch/arm/setup.c b/xen/arch/arm/setup.c > index aee491d..9721150 100644 > --- a/xen/arch/arm/setup.c > +++ b/xen/arch/arm/setup.c > @@ -41,6 +41,7 @@ > #include <asm/early_printk.h> > #include <asm/gic.h> > #include <asm/cpufeature.h> > +#include <asm/platform.h> > > struct cpuinfo_arm __read_mostly boot_cpu_data; > > @@ -439,6 +440,8 @@ void __init start_xen(unsigned long boot_phys_offset, > > processor_id(); > > + platform_init(); > + > init_xen_time(); > > gic_init(); > diff --git a/xen/arch/arm/shutdown.c b/xen/arch/arm/shutdown.c > index c1b60af..a5c2085 100644 > --- a/xen/arch/arm/shutdown.c > +++ b/xen/arch/arm/shutdown.c > @@ -5,6 +5,7 @@ > #include <xen/lib.h> > #include <xen/mm.h> > #include <xen/smp.h> > +#include <asm/platform.h> > > static void raw_machine_reset(void) > { > @@ -21,6 +22,7 @@ static void raw_machine_reset(void) > dsb(); isb(); > clear_fixmap(FIXMAP_MISC); > #endif > + platform_reset(); > } > > static void halt_this_cpu(void *arg) > diff --git a/xen/arch/arm/time.c b/xen/arch/arm/time.c > index 63dace2..f01be3f 100644 > --- a/xen/arch/arm/time.c > +++ b/xen/arch/arm/time.c > @@ -33,6 +33,7 @@ > #include <asm/time.h> > #include <asm/gic.h> > #include <asm/cpufeature.h> > +#include <asm/platform.h> > > /* > * Unfortunately the hypervisor timer interrupt appears to be buggy in > @@ -130,6 +131,11 @@ int __init init_xen_time(void) > panic("CPU does not support the Generic Timer v1 interface.\n"); > > cpu_khz = READ_SYSREG32(CNTFRQ_EL0) / 1000; > + > + res = platform_init_time(); > + if ( res ) > + return res; > + > boot_count = READ_SYSREG64(CNTPCT_EL0); > printk("Using generic timer at %lu KHz\n", cpu_khz); > > diff --git a/xen/arch/arm/xen.lds.S b/xen/arch/arm/xen.lds.S > index 7434e83..b5c99b7 100644 > --- a/xen/arch/arm/xen.lds.S > +++ b/xen/arch/arm/xen.lds.S > @@ -76,6 +76,12 @@ SECTIONS > __lock_profile_end = .; > #endif > > + .arch.info : { > + _splatform = .; > + *(.arch.info) > + _eplatform = .; > + } :text > + > .dev.info : { > _sdevice = .; > *(.dev.info) > diff --git a/xen/include/asm-arm/platform.h b/xen/include/asm-arm/platform.h > new file mode 100644 > index 0000000..c89a4ca > --- /dev/null > +++ b/xen/include/asm-arm/platform.h > @@ -0,0 +1,70 @@ > +#ifndef __ASM_ARM_PLATFORM_H > +#define __ASM_ARM_PLATFORM_H > + > +#include <xen/init.h> > +#include <xen/sched.h> > +#include <xen/mm.h> > + > +/* Describe specific operation for a board */ > +struct platform_desc { > + /* Platform name */ > + const char *name; > + /* Array of device tree 'compatible' strings */ > + const char *const *compatible; > + /* Platform initialization */ > + int (*init)(void); > + int (*init_time)(void); > + /* Specific mapping for dom0 */ > + int (*specific_mapping)(struct domain *d); > + /* Platform reset */ > + void (*reset)(void); > +}; > + > +int __init platform_init(void); > +int __init platform_init_time(void); > +int __init platform_specific_mapping(struct domain *d); > +void platform_reset(void); > + > +/* Helper to read/write a register */ > +static inline uint32_t platform_read_register(uint32_t addr) > +{ > + volatile const uint32_t *reg; > + uint32_t value; > + > + set_fixmap(FIXMAP_MISC, addr >> PAGE_SHIFT, DEV_SHARED); > + reg = (uint32_t *)(FIXMAP_ADDR(FIXMAP_MISC) + (addr & ~PAGE_MASK)); > + value = *reg; > + dsb(); isb(); > + clear_fixmap(FIXMAP_MISC); > + > + return value; > +} > + > +static inline void platform_write_register(uint32_t addr, uint32_t value) > +{ > + volatile uint32_t *reg; > + > + set_fixmap(FIXMAP_MISC, addr >> PAGE_SHIFT, DEV_SHARED); > + reg = (uint32_t *)(FIXMAP_ADDR(FIXMAP_MISC) + (addr & ~PAGE_MASK)); > + *reg = value; > + clear_fixmap(FIXMAP_MISC); > +} > + > +#define PLATFORM_START(_name, _namestr) \ > +static const struct platform_desc __plat_desc_##_name __used \ > +__attribute__((__section__(".arch.info"))) = { \ > + .name = _namestr, > + > +#define PLATFORM_END \ > +}; > + > +#endif /* __ASM_ARM_PLATFORM_H */ > + > +/* > + * Local variables: > + * mode: C > + * c-file-style: "BSD" > + * c-basic-offset: 4 > + * indent-tabs-mode: nil > + * End: > + */ > -- > Julien Grall > _______________________________________________ Xen-devel mailing list Xen-devel@xxxxxxxxxxxxx http://lists.xen.org/xen-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |