[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [Minios-devel] [UNIKRAFT PATCH 1/1] plat/common: UKTIME supported in the Raspberry Pi 3.
Hi Santiago, It looks to me that this patch should be split into more patches (e.g. add ukarch_{fls,flsl} for arm64, add timer support for new platform, etc). Btw, isn't raspi a new platform actually? This would mean you should put the platform-specific code under a new raspi/ subdir in plat/, along with kvm/, xen/ and linuxu/. Please see inline other comments. On 10/18/19 3:17 PM, Santiago Pagani wrote: > Added and guarded Raspberry Pi 3's SoC specific > things related to the ARM generic timer in order > to support UKTIME. > > Signed-off-by: Santiago Pagani <santiago.pagani@xxxxxxxxx> > --- > arch/arm/arm64/include/uk/asm/atomic.h | 53 ++++++++++ > lib/nolibc/include/unistd.h | 2 + > plat/common/arm/time.c | 134 ++++++++++++++++--------- > 3 files changed, 143 insertions(+), 46 deletions(-) > > diff --git a/arch/arm/arm64/include/uk/asm/atomic.h > b/arch/arm/arm64/include/uk/asm/atomic.h > index 7ee66677..98b5ed2b 100644 > --- a/arch/arm/arm64/include/uk/asm/atomic.h > +++ b/arch/arm/arm64/include/uk/asm/atomic.h > @@ -6,6 +6,7 @@ > * Authors: Karim Allah Ahmed <karim.allah.ahmed@xxxxxxxxx> > * Thomas Leonard <talex5@xxxxxxxxx> > * Wei Chen <Wei.Chen@xxxxxxx> > + * Santiago Pagani <santiago.pagani@xxxxxxxxx > * > * Copyright (c) 2014 Karim Allah Ahmed > * Copyright (c) 2014 Thomas Leonard > @@ -37,6 +38,32 @@ > #error Do not include this header directly > #endif > > +/** > + * ukarch_fls - find last (highest) set bit in word. > + * @word: The word to search > + * > + * Undefined if no bit exists, so code should check against 0 first. > + */ > +static inline unsigned int ukarch_fls(unsigned int word) > +{ > + int clz; > + > + /* 000001xxxx = word > + * 4 = 63 - clz(word) > + */ > + > + __asm__("clz %[clz], %[word]\n" > + : > + /* Outputs: */ > + [clz] "=r"(clz) > + : > + /* Inputs: */ > + [word] "r"(word) > + ); > + > + return 63 - clz; > +} > + > /** > * ukarch_ffsl - find first (lowest) set bit in word. > * @word: The word to search > @@ -68,3 +95,29 @@ static inline unsigned long ukarch_ffsl(unsigned long word) > > return 63 - clz; > } > + > +/** > + * ukarch_flsl - find last (highest) set bit in word. > + * @word: The word to search > + * > + * Undefined if no bit exists, so code should check against 0 first. > + */ > +static inline unsigned long ukarch_flsl(unsigned long word) > +{ > + int clz; > + > + /* 000001xxxx = word > + * 4 = 63 - clz(word) > + */ > + > + __asm__("clz %[clz], %[word]\n" > + : > + /* Outputs: */ > + [clz] "=r"(clz) > + : > + /* Inputs: */ > + [word] "r"(word) > + ); > + > + return 63 - clz; > +} > diff --git a/lib/nolibc/include/unistd.h b/lib/nolibc/include/unistd.h > index a6986873..263a9f49 100644 > --- a/lib/nolibc/include/unistd.h > +++ b/lib/nolibc/include/unistd.h > @@ -55,7 +55,9 @@ extern "C" { > > #include <nolibc-internal/shareddefs.h> > > +#if CONFIG_LIBUKTIME Actually, we should check if CONFIG_HAVE_TIME is set (it's a new addition). The thing is you might have some lib other than uktime implementing the same thing, but this config flag (CONFIG_HAVE_TIME) will always tell you that time-related functionality is enabled. You can even create a patch only for this change. > unsigned int sleep(unsigned int seconds); > +#endif > > #if CONFIG_LIBVFSCORE > int close(int fd); > diff --git a/plat/common/arm/time.c b/plat/common/arm/time.c > index 56d9d6e1..3ed33e8d 100644 > --- a/plat/common/arm/time.c > +++ b/plat/common/arm/time.c > @@ -32,8 +32,10 @@ > * THIS HEADER MAY NOT BE EXTRACTED OR MODIFIED IN ANY WAY. > */ > #include <stdlib.h> > -#include <libfdt.h> > -#include <ofw/fdt.h> > +#if !CONFIG_PLAT_RASPI > + #include <libfdt.h> > + #include <ofw/fdt.h> > +#endif > #include <uk/assert.h> > #include <uk/plat/time.h> > #include <uk/plat/lcpu.h> > @@ -44,17 +46,25 @@ > #include <irq.h> > #include <gic/gic-v2.h> > #include <arm/time.h> > +#if CONFIG_PLAT_RASPI > + #include <raspi/time.h> > + #include <raspi/irq.h> > +#endif > > /* TODO: For now this file is KVM dependent. As soon as we have more > * Arm platforms that are using this file, we need to introduce a > * portable way to handover the DTB entry point to common platform code */ > -#include <kvm/config.h> > +#if CONFIG_PLAT_KVM > + #include <kvm/config.h> > +#endif > > -static const char * const arch_timer_list[] = { > - "arm,armv8-timer", > - "arm,armv7-timer", > - NULL > -}; > +#if !CONFIG_PLAT_RASPI > + static const char * const arch_timer_list[] = { > + "arm,armv8-timer", > + "arm,armv7-timer", > + NULL > + }; > +#endif > > static uint64_t boot_ticks; > static uint32_t counter_freq; > @@ -163,6 +173,9 @@ static inline void generic_timer_disable(void) > static inline void generic_timer_mask_irq(void) > { > set_el0(cntv_ctl, get_el0(cntv_ctl) | GT_TIMER_MASK_IRQ); > + #if CONFIG_PLAT_RASPI > + *RASPI_ARM_C0_TIMER_IRQ_CTL = *RASPI_ARM_C0_TIMER_IRQ_CTL & ~(1 > << 3); > + #endif > > /* Ensure the write of sys register is visible */ > isb(); > @@ -171,7 +184,18 @@ static inline void generic_timer_mask_irq(void) > static inline void generic_timer_unmask_irq(void) > { > set_el0(cntv_ctl, get_el0(cntv_ctl) & ~GT_TIMER_MASK_IRQ); > + #if CONFIG_PLAT_RASPI > + *RASPI_ARM_C0_TIMER_IRQ_CTL = *RASPI_ARM_C0_TIMER_IRQ_CTL | (1 > << 3); > + #endif > + > + /* Ensure the write of sys register is visible */ > + isb(); > +} > > +static inline void generic_timer_clear_irq(void) > +{ > + set_el0(cntv_ctl, get_el0(cntv_ctl) & ~GT_TIMER_IRQ_STATUS); > + > /* Ensure the write of sys register is visible */ > isb(); > } > @@ -209,27 +233,34 @@ static inline uint64_t generic_timer_get_ticks(void) > } > #endif > > -static uint32_t generic_timer_get_frequency(int fdt_timer) > -{ > - int len; > - const uint64_t *fdt_freq; > - > - /* > - * On a few platforms the frequency is not configured correctly > - * by the firmware. A property in the DT (clock-frequency) has > - * been introduced to workaround those firmware. > - */ > - fdt_freq = fdt_getprop(_libkvmplat_cfg.dtb, > - fdt_timer, "clock-frequency", &len); > - if (!fdt_freq || (len <= 0)) { > - uk_pr_info("No clock-frequency found, reading from register > directly.\n"); > - > - /* No workaround, get from register directly */ > +#if CONFIG_PLAT_RASPI > + static uint32_t generic_timer_get_frequency(int fdt_timer __unused) > + { > return get_el0(cntfrq); > } > - > - return fdt32_to_cpu(fdt_freq[0]); > -} > +#else > + static uint32_t generic_timer_get_frequency(int fdt_timer) > + { > + int len; > + const uint64_t *fdt_freq; > + > + /* > + * On a few platforms the frequency is not configured correctly > + * by the firmware. A property in the DT (clock-frequency) has > + * been introduced to workaround those firmware. > + */ > + fdt_freq = fdt_getprop(_libkvmplat_cfg.dtb, > + fdt_timer, "clock-frequency", &len); > + if (!fdt_freq || (len <= 0)) { > + uk_pr_info("No clock-frequency found, reading from > register directly.\n"); > + > + /* No workaround, get from register directly */ > + return get_el0(cntfrq); > + } > + > + return fdt32_to_cpu(fdt_freq[0]); > + } > +#endif > > /* > * monotonic_clock(): returns # of nanoseconds passed since > @@ -263,8 +294,6 @@ static void generic_timer_cpu_block_until(uint64_t > until_ns) > { > uint64_t now_ns, until_ticks; > > - UK_ASSERT(ukplat_lcpu_irqs_disabled()); > - > /* Record current ns and until_ticks for timer */ > now_ns = ukplat_monotonic_clock(); > until_ticks = generic_timer_get_ticks() > @@ -322,6 +351,7 @@ static int generic_timer_irq_handler(void *arg __unused) > * generic_timer_cpu_block_until, and then unmask the IRQ. > */ > generic_timer_mask_irq(); > + generic_timer_clear_irq(); > > /* Yes, we handled the irq. */ > return 1; > @@ -333,8 +363,10 @@ void time_block_until(__snsec until) > { > while ((__snsec) ukplat_monotonic_clock() < until) { > generic_timer_cpu_block_until(until); > - if (__uk_test_and_clear_bit(0, &sched_have_pending_events)) > - break; > + #if !CONFIG_PLAT_RASPI > + if (__uk_test_and_clear_bit(0, > &sched_have_pending_events)) > + break; > + #endif > } > } > > @@ -354,8 +386,10 @@ __nsec ukplat_wall_clock(void) > void ukplat_time_init(void) > { > int rc, irq, fdt_timer; > - uint32_t irq_type, hwirq; > - uint32_t trigger_type; > + #if !CONFIG_PLAT_RASPI > + uint32_t irq_type, hwirq; > + uint32_t trigger_type; > + #endif > > /* > * Monotonic time begins at boot_ticks (first read of counter > @@ -364,24 +398,32 @@ void ukplat_time_init(void) > boot_ticks = generic_timer_get_ticks(); > > /* Currently, we only support 1 timer per system */ > - fdt_timer = fdt_node_offset_by_compatible_list(_libkvmplat_cfg.dtb, > - -1, arch_timer_list); > - if (fdt_timer < 0) > - UK_CRASH("Could not find arch timer!\n"); > + #if CONFIG_PLAT_RASPI > + fdt_timer = 0; > + #else > + fdt_timer = > fdt_node_offset_by_compatible_list(_libkvmplat_cfg.dtb, > + -1, arch_timer_list); > + if (fdt_timer < 0) > + UK_CRASH("Could not find arch timer!\n"); > + #endif > > rc = generic_timer_init(fdt_timer); > if (rc < 0) > UK_CRASH("Failed to initialize platform time\n"); > > - rc = gic_get_irq_from_dtb(_libkvmplat_cfg.dtb, fdt_timer, 2, > - &irq_type, &hwirq, &trigger_type); > - if (rc < 0) > - UK_CRASH("Failed to find IRQ number from DTB\n"); > - > - irq = gic_irq_translate(irq_type, hwirq); > - if (irq < 0 || irq >= __MAX_IRQ) > - UK_CRASH("Failed to translate IRQ number, type=%u, hwirq=%u\n", > - irq_type, hwirq); > + #if CONFIG_PLAT_RASPI > + irq = IRQ_ID_ARM_GENERIC_TIMER; > + #else > + rc = gic_get_irq_from_dtb(_libkvmplat_cfg.dtb, fdt_timer, 2, > + &irq_type, &hwirq, &trigger_type); > + if (rc < 0) > + UK_CRASH("Failed to find IRQ number from DTB\n"); > + > + irq = gic_irq_translate(irq_type, hwirq); > + if (irq < 0 || irq >= __MAX_IRQ) > + UK_CRASH("Failed to translate IRQ number, type=%u, > hwirq=%u\n", > + irq_type, hwirq); > + #endif > > rc = ukplat_irq_register(irq, generic_timer_irq_handler, NULL); > if (rc < 0) > _______________________________________________ Minios-devel mailing list Minios-devel@xxxxxxxxxxxxxxxxxxxx https://lists.xenproject.org/mailman/listinfo/minios-devel
|
Lists.xenproject.org is hosted with RackSpace, monitoring our |