On 7 July 2011 21:20, Lorenzo Pieralisi lorenzo.pieralisi@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.pieralisi@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