diff options
author | Sascha Hauer <s.hauer@pengutronix.de> | 2013-04-04 14:20:42 +0200 |
---|---|---|
committer | Sascha Hauer <s.hauer@pengutronix.de> | 2013-04-04 14:20:42 +0200 |
commit | dd9f6d08a2736bf8ddc0004779c563a4c3a77cef (patch) | |
tree | 9e829ce3e8a29e76b6e8f1459b2636768d170a71 /arch/arm/include/asm | |
parent | 2143dfda8b32b8d1cda16982efeca57ca97b3996 (diff) | |
parent | a81ec0225f5a100341c20b4329c8b1d81ab025c4 (diff) | |
download | barebox-dd9f6d08a2736bf8ddc0004779c563a4c3a77cef.tar.gz barebox-dd9f6d08a2736bf8ddc0004779c563a4c3a77cef.tar.xz |
Merge branch 'for-next/relocate'
Conflicts:
arch/arm/lib/barebox.lds.S
Diffstat (limited to 'arch/arm/include/asm')
-rw-r--r-- | arch/arm/include/asm/barebox-arm.h | 34 | ||||
-rw-r--r-- | arch/arm/include/asm/cache.h | 8 | ||||
-rw-r--r-- | arch/arm/include/asm/mmu.h | 1 | ||||
-rw-r--r-- | arch/arm/include/asm/sections.h | 33 | ||||
-rw-r--r-- | arch/arm/include/asm/system_info.h | 43 |
5 files changed, 118 insertions, 1 deletions
diff --git a/arch/arm/include/asm/barebox-arm.h b/arch/arm/include/asm/barebox-arm.h index f09709221e..cd8decfccd 100644 --- a/arch/arm/include/asm/barebox-arm.h +++ b/arch/arm/include/asm/barebox-arm.h @@ -26,6 +26,7 @@ #define _BAREBOX_ARM_H_ #include <sizes.h> +#include <asm-generic/memory_layout.h> /* cpu/.../cpu.c */ int cleanup_before_linux(void); @@ -40,7 +41,40 @@ void board_init_lowlevel(void); uint32_t get_runtime_offset(void); void setup_c(void); +void relocate_to_current_adr(void); +void relocate_to_adr(unsigned long target); void __noreturn barebox_arm_entry(uint32_t membase, uint32_t memsize, uint32_t boarddata); unsigned long barebox_arm_boarddata(void); +#if defined(CONFIG_RELOCATABLE) && defined(CONFIG_ARM_EXCEPTIONS) +void arm_fixup_vectors(void); +#else +static inline void arm_fixup_vectors(void) +{ +} +#endif + +/* + * For relocatable binaries find a suitable start address for the + * relocated binary. Beginning at the memory end substract the reserved + * space and round down a bit at the end. This is used by the pbl to + * extract the image to a suitable place so that the uncompressed image + * does not have to copy itself to another place. Also it's used by + * the uncompressed image to relocate itself to the same place. + */ +static inline unsigned long arm_barebox_image_place(unsigned long endmem) +{ + endmem -= STACK_SIZE; + endmem -= SZ_32K; /* ttb */ + endmem -= SZ_128K; /* early malloc */ + endmem -= SZ_1M; /* place for barebox image */ + + /* + * round down to make translating the objdump easier + */ + endmem &= ~(SZ_1M - 1); + + return endmem; +} + #endif /* _BAREBOX_ARM_H_ */ diff --git a/arch/arm/include/asm/cache.h b/arch/arm/include/asm/cache.h index d5877ffc44..e5621ebbca 100644 --- a/arch/arm/include/asm/cache.h +++ b/arch/arm/include/asm/cache.h @@ -8,4 +8,12 @@ static inline void flush_icache(void) int arm_set_cache_functions(void); +#ifdef CONFIG_MMU +void arm_early_mmu_cache_flush(void); +#else +static inline void arm_early_mmu_cache_flush(void) +{ +} +#endif + #endif diff --git a/arch/arm/include/asm/mmu.h b/arch/arm/include/asm/mmu.h index f32cea639d..4234979190 100644 --- a/arch/arm/include/asm/mmu.h +++ b/arch/arm/include/asm/mmu.h @@ -122,4 +122,3 @@ void __dma_flush_range(unsigned long, unsigned long); void __dma_inv_range(unsigned long, unsigned long); #endif /* __ASM_MMU_H */ - diff --git a/arch/arm/include/asm/sections.h b/arch/arm/include/asm/sections.h index 2b8c516038..8c7bc8cccc 100644 --- a/arch/arm/include/asm/sections.h +++ b/arch/arm/include/asm/sections.h @@ -1 +1,34 @@ +#ifndef __ASM_SECTIONS_H +#define __ASM_SECTIONS_H + +#ifndef __ASSEMBLY__ #include <asm-generic/sections.h> + +/* + * Access a linker supplied variable. Use this if your code might not be running + * at the address it is linked at. + */ +#define ld_var(name) ({ \ + unsigned long __ld_var_##name(void); \ + __ld_var_##name(); \ +}) + +#else + +/* + * Access a linker supplied variable, assembler macro version + */ +.macro ld_var name, reg, scratch + 1000: + ldr \reg, 1001f + ldr \scratch, =1000b + add \reg, \reg, \scratch + b 1002f + 1001: + .word \name - 1000b + 1002: +.endm + +#endif + +#endif /* __ASM_SECTIONS_H */ diff --git a/arch/arm/include/asm/system_info.h b/arch/arm/include/asm/system_info.h index 13171cc5ef..61828602ef 100644 --- a/arch/arm/include/asm/system_info.h +++ b/arch/arm/include/asm/system_info.h @@ -115,8 +115,51 @@ #ifndef __ASSEMBLY__ #ifdef ARM_MULTIARCH +/* + * Early version to get the ARM cpu architecture. Only needed during + * early startup when the C environment is not yet fully initialized. + * Normally you should use cpu_architecture() instead. + */ +static inline int arm_early_get_cpu_architecture(void) +{ + int cpu_arch; + + if ((read_cpuid_id() & 0x0008f000) == 0) { + cpu_arch = CPU_ARCH_UNKNOWN; + } else if ((read_cpuid_id() & 0x0008f000) == 0x00007000) { + cpu_arch = (read_cpuid_id() & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3; + } else if ((read_cpuid_id() & 0x00080000) == 0x00000000) { + cpu_arch = (read_cpuid_id() >> 16) & 7; + if (cpu_arch) + cpu_arch += CPU_ARCH_ARMv3; + } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { + unsigned int mmfr0; + + /* Revised CPUID format. Read the Memory Model Feature + * Register 0 and check for VMSAv7 or PMSAv7 */ + asm("mrc p15, 0, %0, c0, c1, 4" + : "=r" (mmfr0)); + if ((mmfr0 & 0x0000000f) >= 0x00000003 || + (mmfr0 & 0x000000f0) >= 0x00000030) + cpu_arch = CPU_ARCH_ARMv7; + else if ((mmfr0 & 0x0000000f) == 0x00000002 || + (mmfr0 & 0x000000f0) == 0x00000020) + cpu_arch = CPU_ARCH_ARMv6; + else + cpu_arch = CPU_ARCH_UNKNOWN; + } else + cpu_arch = CPU_ARCH_UNKNOWN; + + return cpu_arch; +} + extern int __pure cpu_architecture(void); #else +static inline int __pure arm_early_get_cpu_architecture(void) +{ + return ARM_ARCH; +} + static inline int __pure cpu_architecture(void) { return ARM_ARCH; |