On 7 July 2011 21:20, Lorenzo Pieralisi <lorenzo.pieral...@arm.com> wrote: > > This patch provides the code infrastructure needed to maintain > a generic per-cpu architecture implementation of idle code. > > sr_platform.c : > - code manages patchset initialization and memory management > > sr_context.c: > - code initializes run-time context save/restore generic > support > > sr_power.c: > - provides the generic infrastructure to enter exit low > power modes and communicate with Power Control Unit (PCU) > > v7 support hinges on the basic infrastructure to provide per-cpu > arch implementation basically through standard function pointers > signatures. > > Preprocessor defines include size of data needed to save/restore > L2 state. This define value should be moved to the respective > subsystem (PL310) once the patchset IF to that subsystem is settled. > > Signed-off-by: Lorenzo Pieralisi <lorenzo.pieral...@arm.com> > --- > arch/arm/kernel/sr.h | 162 > +++++++++++++++++++++++++++++++++++++++++ > arch/arm/kernel/sr_context.c | 23 ++++++ > arch/arm/kernel/sr_helpers.h | 56 ++++++++++++++ > arch/arm/kernel/sr_platform.c | 48 ++++++++++++ > arch/arm/kernel/sr_power.c | 26 +++++++ > 5 files changed, 315 insertions(+), 0 deletions(-) > create mode 100644 arch/arm/kernel/sr.h > create mode 100644 arch/arm/kernel/sr_context.c > create mode 100644 arch/arm/kernel/sr_helpers.h > create mode 100644 arch/arm/kernel/sr_platform.c > create mode 100644 arch/arm/kernel/sr_power.c > > diff --git a/arch/arm/kernel/sr.h b/arch/arm/kernel/sr.h > new file mode 100644 > index 0000000..6b24e53 > --- /dev/null > +++ b/arch/arm/kernel/sr.h > @@ -0,0 +1,162 @@ > +#define SR_NR_CLUSTERS 1 > + > +#define STACK_SIZE 512 > + > +#define CPU_A5 0x4100c050 > +#define CPU_A8 0x4100c080 > +#define CPU_A9 0x410fc090 > +#define L2_DATA_SIZE 16 > +#define CONTEXT_SPACE_UNCACHED (2 * PAGE_SIZE) > +#define PA(f) ((typeof(f) *)virt_to_phys((void *)f)) > + > +#ifndef __ASSEMBLY__ > + > +#include <linux/types.h> > +#include <linux/threads.h> > +#include <linux/cpumask.h> > +#include <asm/page.h> > + > +/* > + * Structures we hide from the OS API > + */ > + > +struct sr_cpu_context { > + u32 flags; > + u32 saved_items; > + u32 *mmu_data; > +}; > + > +struct sr_cluster_context { > + u32 saved_items; > + u32 *l2_data; > +}; > + > +struct sr_main_table { > + pgd_t *os_mmu_context[SR_NR_CLUSTERS][CONFIG_NR_CPUS]; > + cpumask_t cpu_idle_mask[SR_NR_CLUSTERS]; > + pgd_t *fw_mmu_context; > + u32 num_clusters; > + struct sr_cluster *cluster_table; > +}; > + > + > +/* > + * A cluster is a container for CPUs, typically either a single CPU or a > + * coherent cluster. > + * We assume the CPUs in the cluster can be switched off independently. > + */ > +struct sr_cluster { > + u32 cpu_type; /* A9mpcore, A5mpcore, etc */ > + u32 num_cpus; > + struct sr_cluster_context *context; > + struct sr_cpu *cpu_table; > + u32 power_state; > + u32 cluster_down; > + void __iomem *scu_address; > + void *lock; > +}; > + > +struct sr_cpu { > + struct sr_cpu_context *context; > + u32 power_state; > +}; > + > +/* > + * arch infrastructure > + */ > +struct sr_arch { > + unsigned int cpu_val; > + unsigned int cpu_mask; > + > + int (*init)(void); > + > + int (*save_context)(struct sr_cluster *, struct sr_cpu *, > + unsigned); > + int (*restore_context)(struct sr_cluster *, struct sr_cpu *); > + int (*enter_cstate)(unsigned cpu_index, > + struct sr_cpu *cpu, > + struct sr_cluster *cluster); > + int (*leave_cstate)(unsigned, struct sr_cpu *, > + struct sr_cluster *); > + void (*reset)(void); > + > +}; > + > +extern struct sr_arch *arch; > +extern int lookup_arch(void); > + > +/* > + * Global variables > + */ > +extern struct sr_main_table main_table; > +extern unsigned long idle_save_context; > +extern unsigned long idle_restore_context; > +extern unsigned long idle_mt; > +extern void *context_memory_uncached; > + > +/* > + * Context save/restore > + */ > +typedef u32 (sr_save_context_t) > + (struct sr_cluster *, > + struct sr_cpu*, u32); > +typedef u32 (sr_restore_context_t) > + (struct sr_cluster *, > + struct sr_cpu*); > + > +extern sr_save_context_t sr_save_context; > +extern sr_restore_context_t sr_restore_context; > + > + > +extern struct sr_arch *get_arch(void); > + > + > +/* > + * 1:1 mappings > + */ > + > +extern int linux_sr_setup_translation_tables(void); > + > +/* > + * dumb memory allocator > + */ > + > +extern void *get_memory(unsigned int size); > + > +/* > + * Entering/Leaving C-states function entries > + */ > + > +extern int sr_platform_enter_cstate(unsigned cpu_index, struct sr_cpu *cpu, > + struct sr_cluster *cluster); > +extern int sr_platform_leave_cstate(unsigned cpu_index, struct sr_cpu *cpu, > + struct sr_cluster *cluster); > + > +/* save/restore main table */ > +extern struct sr_main_table main_table; > + > +/* > + * Init functions > + */ > + > +extern int sr_platform_runtime_init(void); > +extern int sr_platform_init(void); > +extern int sr_context_init(void); > + > + > +/* > + * v7 specific > + */ > + > +extern char *cpu_v7_suspend_size; > +extern void scu_cpu_mode(void __iomem *base, int state); > + > +/* > + * These arrays keep suitable stack pointers for CPUs. > + * > + * The memory must be 8-byte aligned. > + */ > + > +extern unsigned long platform_cpu_stacks[CONFIG_NR_CPUS]; > +extern unsigned long platform_cpu_nc_stacks[CONFIG_NR_CPUS]; > +#endif > diff --git a/arch/arm/kernel/sr_context.c b/arch/arm/kernel/sr_context.c > new file mode 100644 > index 0000000..25eaa43 > --- /dev/null > +++ b/arch/arm/kernel/sr_context.c > @@ -0,0 +1,23 @@ > +/* > + * Copyright (C) 2008-2011 ARM Limited > + * Author(s): Jon Callan, Lorenzo Pieralisi > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + */ > + > +#include <linux/cache.h> > +#include <asm/cacheflush.h> > +#include "sr.h" > + > +int sr_context_init(void) > +{ > + idle_save_context = (unsigned long) arch->save_context; > + idle_restore_context = __pa(arch->restore_context); > + __cpuc_flush_dcache_area(&idle_restore_context, sizeof(unsigned > long)); > + outer_clean_range(__pa(&idle_restore_context), > + __pa(&idle_restore_context + 1)); > + return 0; > +} > diff --git a/arch/arm/kernel/sr_helpers.h b/arch/arm/kernel/sr_helpers.h > new file mode 100644 > index 0000000..1ae3a9a > --- /dev/null > +++ b/arch/arm/kernel/sr_helpers.h > @@ -0,0 +1,56 @@ > +/* > + * Copyright (C) 2008-2011 ARM Limited > + * Author(s): Jon Callan, Lorenzo Pieralisi > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + */ > + > +static inline int sr_platform_get_cpu_index(void) > +{ > + unsigned int cpu; > + __asm__ __volatile__( > + "mrc p15, 0, %0, c0, c0, 5\n\t" > + : "=r" (cpu)); > + return cpu & 0xf; > +} > + > +/* > + * Placeholder for further extensions > + */ > +static inline int sr_platform_get_cluster_index(void) > +{ > + return 0; > +} > + > +static inline void __iomem *sr_platform_cbar(void) > +{ > + void __iomem *base; > + __asm__ __volatile__( > + "mrc p15, 4, %0, c15, c0, 0\n\t" > + : "=r" (base)); > + return base; > +} > + > +#ifdef CONFIG_SMP > +static inline void exit_coherency(void) > +{ > + unsigned int v; > + asm volatile ( > + "mrc p15, 0, %0, c1, c0, 1\n" > + "bic %0, %0, %1\n" > + "mcr p15, 0, %0, c1, c0, 1\n" > + : "=&r" (v) > + : "Ir" (0x40) > + : );
The above line gives compilation error with my toolchain. Adding it as : "cc"); fixes the error. > +} > +#else > +static inline void exit_coherency(void) { } > +#endif > + > +extern void default_sleep(void); > +extern void sr_suspend(void *); > +extern void sr_resume(void *, int); > +extern void disable_clean_inv_dcache_v7_all(void); > diff --git a/arch/arm/kernel/sr_platform.c b/arch/arm/kernel/sr_platform.c > new file mode 100644 > index 0000000..530aa1b > --- /dev/null > +++ b/arch/arm/kernel/sr_platform.c > @@ -0,0 +1,48 @@ > +/* > + * Copyright (C) 2008-2011 ARM Limited > + * > + * Author(s): Jon Callan, Lorenzo Pieralisi > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + */ > + > +#include <linux/errno.h> > +#include <linux/kernel.h> > +#include <linux/string.h> > +#include <asm/memory.h> > +#include <asm/page.h> > +#include <asm/sr_platform_api.h> > +#include "sr.h" > + > +void *context_memory_uncached; > + > +/* > + * Simple memory allocator function. > + * Returns start address of allocated region > + * Memory is zero-initialized. > + */ > + > +static unsigned int watermark; > + > +void *get_memory(unsigned int size) > +{ > + unsigned ret; > + void *vmem = NULL; > + > + ret = watermark; > + watermark += size; > + BUG_ON(watermark >= CONTEXT_SPACE_UNCACHED); > + vmem = (context_memory_uncached + ret); > + watermark = ALIGN(watermark, sizeof(long long)); > + > + return vmem; > +} > + > +int sr_platform_init(void) > +{ > + memset(context_memory_uncached, 0, CONTEXT_SPACE_UNCACHED); > + return arch->init(); > +} > diff --git a/arch/arm/kernel/sr_power.c b/arch/arm/kernel/sr_power.c > new file mode 100644 > index 0000000..2585559 > --- /dev/null > +++ b/arch/arm/kernel/sr_power.c > @@ -0,0 +1,26 @@ > +/* > + * Copyright (C) 2008-2011 ARM Limited > + * > + * Author(s): Jon Callan, Lorenzo Pieralisi > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + */ > + > +#include "sr.h" > + > +int sr_platform_enter_cstate(unsigned cpu_index, > + struct sr_cpu *cpu, > + struct sr_cluster *cluster) > +{ > + return arch->enter_cstate(cpu_index, cpu, cluster); > +} > + > +int sr_platform_leave_cstate(unsigned cpu_index, > + struct sr_cpu *cpu, > + struct sr_cluster *cluster) > +{ > + return arch->leave_cstate(cpu_index, cpu, cluster); > +} > -- > 1.7.4.4 > > _______________________________________________ linaro-dev mailing list linaro-dev@lists.linaro.org http://lists.linaro.org/mailman/listinfo/linaro-dev