diff options
author | James Hogan <james.hogan@imgtec.com> | 2012-10-05 16:56:56 +0100 |
---|---|---|
committer | James Hogan <james.hogan@imgtec.com> | 2013-03-02 20:09:51 +0000 |
commit | 42682c6c42a5765b2c7cccfca170368fef6191ef (patch) | |
tree | adcfa5e96cd98527ee75fc541efc279357bbe6a2 /arch/metag/include | |
parent | fdabf525b4b7aab3945c19eac39d3a65b68d0c4f (diff) | |
download | lwn-42682c6c42a5765b2c7cccfca170368fef6191ef.tar.gz lwn-42682c6c42a5765b2c7cccfca170368fef6191ef.zip |
metag: SMP support
Add SMP support for metag. This allows Linux to take control of multiple
hardware threads on a single Meta core, treating them as separate Linux
CPUs.
Signed-off-by: James Hogan <james.hogan@imgtec.com>
Diffstat (limited to 'arch/metag/include')
-rw-r--r-- | arch/metag/include/asm/cachepart.h | 42 | ||||
-rw-r--r-- | arch/metag/include/asm/core_reg.h | 35 | ||||
-rw-r--r-- | arch/metag/include/asm/smp.h | 29 | ||||
-rw-r--r-- | arch/metag/include/asm/topology.h | 53 |
4 files changed, 159 insertions, 0 deletions
diff --git a/arch/metag/include/asm/cachepart.h b/arch/metag/include/asm/cachepart.h new file mode 100644 index 000000000000..cf6b44e916b5 --- /dev/null +++ b/arch/metag/include/asm/cachepart.h @@ -0,0 +1,42 @@ +/* + * Meta cache partition manipulation. + * + * Copyright 2010 Imagination Technologies Ltd. + */ + +#ifndef _METAG_CACHEPART_H_ +#define _METAG_CACHEPART_H_ + +/** + * get_dcache_size() - Get size of data cache. + */ +unsigned int get_dcache_size(void); + +/** + * get_icache_size() - Get size of code cache. + */ +unsigned int get_icache_size(void); + +/** + * get_global_dcache_size() - Get the thread's global dcache. + * + * Returns the size of the current thread's global dcache partition. + */ +unsigned int get_global_dcache_size(void); + +/** + * get_global_icache_size() - Get the thread's global icache. + * + * Returns the size of the current thread's global icache partition. + */ +unsigned int get_global_icache_size(void); + +/** + * check_for_dache_aliasing() - Ensure that the bootloader has configured the + * dache and icache properly to avoid aliasing + * @thread_id: Hardware thread ID + * + */ +void check_for_cache_aliasing(int thread_id); + +#endif diff --git a/arch/metag/include/asm/core_reg.h b/arch/metag/include/asm/core_reg.h new file mode 100644 index 000000000000..bdbc3a51f31c --- /dev/null +++ b/arch/metag/include/asm/core_reg.h @@ -0,0 +1,35 @@ +#ifndef __ASM_METAG_CORE_REG_H_ +#define __ASM_METAG_CORE_REG_H_ + +#include <asm/metag_regs.h> + +extern void core_reg_write(int unit, int reg, int thread, unsigned int val); +extern unsigned int core_reg_read(int unit, int reg, int thread); + +/* + * These macros allow direct access from C to any register known to the + * assembler. Example candidates are TXTACTCYC, TXIDLECYC, and TXPRIVEXT. + */ + +#define __core_reg_get(reg) ({ \ + unsigned int __grvalue; \ + asm volatile("MOV %0," #reg \ + : "=r" (__grvalue)); \ + __grvalue; \ +}) + +#define __core_reg_set(reg, value) do { \ + unsigned int __srvalue = (value); \ + asm volatile("MOV " #reg ",%0" \ + : \ + : "r" (__srvalue)); \ +} while (0) + +#define __core_reg_swap(reg, value) do { \ + unsigned int __srvalue = (value); \ + asm volatile("SWAP " #reg ",%0" \ + : "+r" (__srvalue)); \ + (value) = __srvalue; \ +} while (0) + +#endif diff --git a/arch/metag/include/asm/smp.h b/arch/metag/include/asm/smp.h new file mode 100644 index 000000000000..e0373f81a117 --- /dev/null +++ b/arch/metag/include/asm/smp.h @@ -0,0 +1,29 @@ +#ifndef __ASM_SMP_H +#define __ASM_SMP_H + +#include <linux/cpumask.h> + +#define raw_smp_processor_id() (current_thread_info()->cpu) + +enum ipi_msg_type { + IPI_CALL_FUNC, + IPI_CALL_FUNC_SINGLE, + IPI_RESCHEDULE, +}; + +extern void arch_send_call_function_single_ipi(int cpu); +extern void arch_send_call_function_ipi_mask(const struct cpumask *mask); +#define arch_send_call_function_ipi_mask arch_send_call_function_ipi_mask + +asmlinkage void secondary_start_kernel(void); + +extern void secondary_startup(void); + +#ifdef CONFIG_HOTPLUG_CPU +extern void __cpu_die(unsigned int cpu); +extern int __cpu_disable(void); +extern void cpu_die(void); +#endif + +extern void smp_init_cpus(void); +#endif /* __ASM_SMP_H */ diff --git a/arch/metag/include/asm/topology.h b/arch/metag/include/asm/topology.h new file mode 100644 index 000000000000..23f5118f58db --- /dev/null +++ b/arch/metag/include/asm/topology.h @@ -0,0 +1,53 @@ +#ifndef _ASM_METAG_TOPOLOGY_H +#define _ASM_METAG_TOPOLOGY_H + +#ifdef CONFIG_NUMA + +/* sched_domains SD_NODE_INIT for Meta machines */ +#define SD_NODE_INIT (struct sched_domain) { \ + .parent = NULL, \ + .child = NULL, \ + .groups = NULL, \ + .min_interval = 8, \ + .max_interval = 32, \ + .busy_factor = 32, \ + .imbalance_pct = 125, \ + .cache_nice_tries = 2, \ + .busy_idx = 3, \ + .idle_idx = 2, \ + .newidle_idx = 0, \ + .wake_idx = 0, \ + .forkexec_idx = 0, \ + .flags = SD_LOAD_BALANCE \ + | SD_BALANCE_FORK \ + | SD_BALANCE_EXEC \ + | SD_BALANCE_NEWIDLE \ + | SD_SERIALIZE, \ + .last_balance = jiffies, \ + .balance_interval = 1, \ + .nr_balance_failed = 0, \ +} + +#define cpu_to_node(cpu) ((void)(cpu), 0) +#define parent_node(node) ((void)(node), 0) + +#define cpumask_of_node(node) ((void)node, cpu_online_mask) + +#define pcibus_to_node(bus) ((void)(bus), -1) +#define cpumask_of_pcibus(bus) (pcibus_to_node(bus) == -1 ? \ + cpu_all_mask : \ + cpumask_of_node(pcibus_to_node(bus))) + +#endif + +#define mc_capable() (1) + +const struct cpumask *cpu_coregroup_mask(unsigned int cpu); + +extern cpumask_t cpu_core_map[NR_CPUS]; + +#define topology_core_cpumask(cpu) (&cpu_core_map[cpu]) + +#include <asm-generic/topology.h> + +#endif /* _ASM_METAG_TOPOLOGY_H */ |