From b542ad1161d3b1771ea6fa3e7cedd311a49f91c9 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Tue, 20 Nov 2007 15:14:31 +0900 Subject: sh: Plug in the SHmedia ELF relocations. Signed-off-by: Paul Mundt --- include/asm-sh/elf.h | 30 +++++++++++++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) (limited to 'include/asm-sh/elf.h') diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h index 12cc4b392bf..5a1e920f059 100644 --- a/include/asm-sh/elf.h +++ b/include/asm-sh/elf.h @@ -5,7 +5,7 @@ #include #include -/* SH relocation types */ +/* SH (particularly SHcompact) relocation types */ #define R_SH_NONE 0 #define R_SH_DIR32 1 #define R_SH_REL32 2 @@ -43,6 +43,11 @@ #define R_SH_RELATIVE 165 #define R_SH_GOTOFF 166 #define R_SH_GOTPC 167 +/* SHmedia relocs */ +#define R_SH_IMM_LOW16 246 +#define R_SH_IMM_LOW16_PCREL 247 +#define R_SH_IMM_MEDLOW16 248 +#define R_SH_IMM_MEDLOW16_PCREL 249 /* Keep this the last entry. */ #define R_SH_NUM 256 @@ -103,12 +108,35 @@ typedef struct user_fpu_struct elf_fpregset_t; #define ELF_PLATFORM (NULL) +#ifdef __SH5__ +#define ELF_PLAT_INIT(_r, load_addr) \ + do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \ + _r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \ + _r->regs[8]=0; _r->regs[9]=0; _r->regs[10]=0; _r->regs[11]=0; \ + _r->regs[12]=0; _r->regs[13]=0; _r->regs[14]=0; _r->regs[15]=0; \ + _r->regs[16]=0; _r->regs[17]=0; _r->regs[18]=0; _r->regs[19]=0; \ + _r->regs[20]=0; _r->regs[21]=0; _r->regs[22]=0; _r->regs[23]=0; \ + _r->regs[24]=0; _r->regs[25]=0; _r->regs[26]=0; _r->regs[27]=0; \ + _r->regs[28]=0; _r->regs[29]=0; _r->regs[30]=0; _r->regs[31]=0; \ + _r->regs[32]=0; _r->regs[33]=0; _r->regs[34]=0; _r->regs[35]=0; \ + _r->regs[36]=0; _r->regs[37]=0; _r->regs[38]=0; _r->regs[39]=0; \ + _r->regs[40]=0; _r->regs[41]=0; _r->regs[42]=0; _r->regs[43]=0; \ + _r->regs[44]=0; _r->regs[45]=0; _r->regs[46]=0; _r->regs[47]=0; \ + _r->regs[48]=0; _r->regs[49]=0; _r->regs[50]=0; _r->regs[51]=0; \ + _r->regs[52]=0; _r->regs[53]=0; _r->regs[54]=0; _r->regs[55]=0; \ + _r->regs[56]=0; _r->regs[57]=0; _r->regs[58]=0; _r->regs[59]=0; \ + _r->regs[60]=0; _r->regs[61]=0; _r->regs[62]=0; \ + _r->tregs[0]=0; _r->tregs[1]=0; _r->tregs[2]=0; _r->tregs[3]=0; \ + _r->tregs[4]=0; _r->tregs[5]=0; _r->tregs[6]=0; _r->tregs[7]=0; \ + _r->sr = SR_FD | SR_MMU; } while (0) +#else #define ELF_PLAT_INIT(_r, load_addr) \ do { _r->regs[0]=0; _r->regs[1]=0; _r->regs[2]=0; _r->regs[3]=0; \ _r->regs[4]=0; _r->regs[5]=0; _r->regs[6]=0; _r->regs[7]=0; \ _r->regs[8]=0; _r->regs[9]=0; _r->regs[10]=0; _r->regs[11]=0; \ _r->regs[12]=0; _r->regs[13]=0; _r->regs[14]=0; \ _r->sr = SR_FD; } while (0) +#endif #ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT) -- cgit v1.2.3-70-g09d2 From cd01204b82933754a7276838656420477f64d4b8 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 10 Dec 2007 15:50:28 +0900 Subject: sh: Encode L1/L2 cache shape in auxvt. This adds in the L1I/L1D/L2 cache shape support to their respective entries in the ELF auxvt, based on the Alpha implementation. We use this on the userspace libc side for calculating a tightly packed SHMLBA amongst other things. Signed-off-by: Paul Mundt --- arch/sh/kernel/cpu/init.c | 29 ++++++++++++++++++++++++++++- arch/sh/kernel/setup.c | 3 +++ include/asm-sh/auxvec.h | 12 ++++++++++++ include/asm-sh/elf.h | 19 ++++++++++++++++--- include/asm-sh/system.h | 2 +- 5 files changed, 60 insertions(+), 5 deletions(-) (limited to 'include/asm-sh/elf.h') diff --git a/arch/sh/kernel/cpu/init.c b/arch/sh/kernel/cpu/init.c index 0f0c76a842e..80a31329ead 100644 --- a/arch/sh/kernel/cpu/init.c +++ b/arch/sh/kernel/cpu/init.c @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -20,6 +21,7 @@ #include #include #include +#include #include #include #ifdef CONFIG_SUPERH32 @@ -151,6 +153,27 @@ static void __uses_jump_to_uncached cache_init(void) #define cache_init() do { } while (0) #endif +#define CSHAPE(totalsize, linesize, assoc) \ + ((totalsize & ~0xff) | (linesize << 4) | assoc) + +#define CACHE_DESC_SHAPE(desc) \ + CSHAPE((desc).way_size * (desc).ways, ilog2((desc).linesz), (desc).ways) + +static void detect_cache_shape(void) +{ + l1d_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.dcache); + + if (current_cpu_data.dcache.flags & SH_CACHE_COMBINED) + l1i_cache_shape = l1d_cache_shape; + else + l1i_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.icache); + + if (current_cpu_data.flags & CPU_HAS_L2_CACHE) + l2_cache_shape = CACHE_DESC_SHAPE(current_cpu_data.scache); + else + l2_cache_shape = -1; /* No S-cache */ +} + #ifdef CONFIG_SH_DSP static void __init release_dsp(void) { @@ -237,11 +260,15 @@ asmlinkage void __cpuinit sh_cpu_init(void) /* Init the cache */ cache_init(); - if (raw_smp_processor_id() == 0) + if (raw_smp_processor_id() == 0) { shm_align_mask = max_t(unsigned long, current_cpu_data.dcache.way_size - 1, PAGE_SIZE - 1); + /* Boot CPU sets the cache shape */ + detect_cache_shape(); + } + /* Disable the FPU */ if (fpu_disabled) { printk("FPU Disabled\n"); diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c index f48ce8e5d0a..9c105c827e8 100644 --- a/arch/sh/kernel/setup.c +++ b/arch/sh/kernel/setup.c @@ -26,6 +26,7 @@ #include #include #include +#include #include #include #include @@ -78,6 +79,8 @@ EXPORT_SYMBOL(memory_start); unsigned long memory_end = 0; EXPORT_SYMBOL(memory_end); +int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; + static int __init early_parse_mem(char *p) { unsigned long size; diff --git a/include/asm-sh/auxvec.h b/include/asm-sh/auxvec.h index 1b6916e63e9..4069858f813 100644 --- a/include/asm-sh/auxvec.h +++ b/include/asm-sh/auxvec.h @@ -15,4 +15,16 @@ #define AT_SYSINFO_EHDR 33 #endif +/* + * More complete cache descriptions than AT_[DIU]CACHEBSIZE. If the + * value is -1, then the cache doesn't exist. Otherwise: + * + * bit 0-3: Cache set-associativity; 0 means fully associative. + * bit 4-7: Log2 of cacheline size. + * bit 8-31: Size of the entire cache >> 8. + */ +#define AT_L1I_CACHESHAPE 34 +#define AT_L1D_CACHESHAPE 35 +#define AT_L2_CACHESHAPE 36 + #endif /* __ASM_SH_AUXVEC_H */ diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h index 5a1e920f059..61960408e6e 100644 --- a/include/asm-sh/elf.h +++ b/include/asm-sh/elf.h @@ -161,12 +161,25 @@ extern void __kernel_vsyscall; #define VDSO_BASE ((unsigned long)current->mm->context.vdso) #define VDSO_SYM(x) (VDSO_BASE + (unsigned long)(x)) +#define VSYSCALL_AUX_ENT \ + if (vdso_enabled) \ + NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); +#else +#define VSYSCALL_AUX_ENT +#endif /* CONFIG_VSYSCALL */ + +extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; + /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ #define ARCH_DLINFO \ do { \ - if (vdso_enabled) \ - NEW_AUX_ENT(AT_SYSINFO_EHDR, VDSO_BASE); \ + /* Optional vsyscall entry */ \ + VSYSCALL_AUX_ENT \ + \ + /* Cache desc */ \ + NEW_AUX_ENT(AT_L1I_CACHESHAPE, l1i_cache_shape); \ + NEW_AUX_ENT(AT_L1D_CACHESHAPE, l1d_cache_shape); \ + NEW_AUX_ENT(AT_L2_CACHESHAPE, l2_cache_shape); \ } while (0) -#endif /* CONFIG_VSYSCALL */ #endif /* __ASM_SH_ELF_H */ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 9bda8d063ec..84592555ba2 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -12,7 +12,7 @@ #include #include -#define AT_VECTOR_SIZE_ARCH 1 /* entries in ARCH_DLINFO */ +#define AT_VECTOR_SIZE_ARCH 4 /* entries in ARCH_DLINFO */ #if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5) #define __icbi() \ -- cgit v1.2.3-70-g09d2 From a9f1365e5e4963705f85a6381cbed74c5615dbac Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 10 Dec 2007 16:06:32 +0900 Subject: sh: Use utsname()->machine for ELF_PLATFORM. Signed-off-by: Paul Mundt --- include/asm-sh/elf.h | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'include/asm-sh/elf.h') diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h index 61960408e6e..9a95f8cb2e1 100644 --- a/include/asm-sh/elf.h +++ b/include/asm-sh/elf.h @@ -62,11 +62,6 @@ typedef elf_greg_t elf_gregset_t[ELF_NGREG]; typedef struct user_fpu_struct elf_fpregset_t; -/* - * This is used to ensure we don't load something for the wrong architecture. - */ -#define elf_check_arch(x) ( (x)->e_machine == EM_SH ) - /* * These are used to set parameters in the core dumps. */ @@ -78,6 +73,12 @@ typedef struct user_fpu_struct elf_fpregset_t; #endif #define ELF_ARCH EM_SH +#ifdef __KERNEL__ +/* + * This is used to ensure we don't load something for the wrong architecture. + */ +#define elf_check_arch(x) ( (x)->e_machine == EM_SH ) + #define USE_ELF_CORE_DUMP #define ELF_EXEC_PAGESIZE PAGE_SIZE @@ -106,7 +107,7 @@ typedef struct user_fpu_struct elf_fpregset_t; For the moment, we have only optimizations for the Intel generations, but that could change... */ -#define ELF_PLATFORM (NULL) +#define ELF_PLATFORM (utsname()->machine) #ifdef __SH5__ #define ELF_PLAT_INIT(_r, load_addr) \ @@ -182,4 +183,5 @@ do { \ NEW_AUX_ENT(AT_L2_CACHESHAPE, l2_cache_shape); \ } while (0) +#endif /* __KERNEL__ */ #endif /* __ASM_SH_ELF_H */ -- cgit v1.2.3-70-g09d2 From 98c4ecde9da14fafbcf1b6c025b08342a327e644 Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 10 Dec 2007 16:21:57 +0900 Subject: sh: Provide the FPSCR init through AT_FPUCW. Signed-off-by: Paul Mundt --- include/asm-sh/auxvec.h | 6 ++++++ include/asm-sh/elf.h | 11 ++++++++++- include/asm-sh/system.h | 2 +- 3 files changed, 17 insertions(+), 2 deletions(-) (limited to 'include/asm-sh/elf.h') diff --git a/include/asm-sh/auxvec.h b/include/asm-sh/auxvec.h index 4069858f813..a6b9d4f4859 100644 --- a/include/asm-sh/auxvec.h +++ b/include/asm-sh/auxvec.h @@ -6,6 +6,12 @@ * for more of them. */ +/* + * This entry gives some information about the FPU initialization + * performed by the kernel. + */ +#define AT_FPUCW 18 /* Used FPU control word. */ + #ifdef CONFIG_VSYSCALL /* * Only define this in the vsyscall case, the entry point to diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h index 9a95f8cb2e1..e00a58cb476 100644 --- a/include/asm-sh/elf.h +++ b/include/asm-sh/elf.h @@ -169,13 +169,22 @@ extern void __kernel_vsyscall; #define VSYSCALL_AUX_ENT #endif /* CONFIG_VSYSCALL */ +#ifdef CONFIG_SH_FPU +#define FPU_AUX_ENT NEW_AUX_ENT(AT_FPUCW, FPSCR_INIT) +#else +#define FPU_AUX_ENT +#endif + extern int l1i_cache_shape, l1d_cache_shape, l2_cache_shape; /* update AT_VECTOR_SIZE_ARCH if the number of NEW_AUX_ENT entries changes */ #define ARCH_DLINFO \ do { \ + /* Optional FPU initialization */ \ + FPU_AUX_ENT; \ + \ /* Optional vsyscall entry */ \ - VSYSCALL_AUX_ENT \ + VSYSCALL_AUX_ENT; \ \ /* Cache desc */ \ NEW_AUX_ENT(AT_L1I_CACHESHAPE, l1i_cache_shape); \ diff --git a/include/asm-sh/system.h b/include/asm-sh/system.h index 84592555ba2..772cd1a0a67 100644 --- a/include/asm-sh/system.h +++ b/include/asm-sh/system.h @@ -12,7 +12,7 @@ #include #include -#define AT_VECTOR_SIZE_ARCH 4 /* entries in ARCH_DLINFO */ +#define AT_VECTOR_SIZE_ARCH 5 /* entries in ARCH_DLINFO */ #if defined(CONFIG_CPU_SH4A) || defined(CONFIG_CPU_SH5) #define __icbi() \ -- cgit v1.2.3-70-g09d2 From 543d5afe5b425ef25a865656bfb76083515dc1cf Mon Sep 17 00:00:00 2001 From: Paul Mundt Date: Mon, 10 Dec 2007 16:33:32 +0900 Subject: sh: Kill off superfluous __KERNEL__ check in asm/elf.h. Signed-off-by: Paul Mundt --- include/asm-sh/elf.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/asm-sh/elf.h') diff --git a/include/asm-sh/elf.h b/include/asm-sh/elf.h index e00a58cb476..05092da1aa5 100644 --- a/include/asm-sh/elf.h +++ b/include/asm-sh/elf.h @@ -89,7 +89,6 @@ typedef struct user_fpu_struct elf_fpregset_t; #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) - #define ELF_CORE_COPY_REGS(_dest,_regs) \ memcpy((char *) &_dest, (char *) _regs, \ sizeof(struct pt_regs)); @@ -139,7 +138,6 @@ typedef struct user_fpu_struct elf_fpregset_t; _r->sr = SR_FD; } while (0) #endif -#ifdef __KERNEL__ #define SET_PERSONALITY(ex, ibcs2) set_personality(PER_LINUX_32BIT) struct task_struct; extern int dump_task_regs (struct task_struct *, elf_gregset_t *); @@ -147,7 +145,6 @@ extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *); #define ELF_CORE_COPY_TASK_REGS(tsk, elf_regs) dump_task_regs(tsk, elf_regs) #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs) -#endif #ifdef CONFIG_VSYSCALL /* vDSO has arch_setup_additional_pages */ -- cgit v1.2.3-70-g09d2