diff options
Diffstat (limited to 'arch/arm/kernel/setup.c')
-rw-r--r-- | arch/arm/kernel/setup.c | 268 |
1 files changed, 60 insertions, 208 deletions
diff --git a/arch/arm/kernel/setup.c b/arch/arm/kernel/setup.c index b7b0720bc1b..1f1eecca7f5 100644 --- a/arch/arm/kernel/setup.c +++ b/arch/arm/kernel/setup.c @@ -26,16 +26,19 @@ #include <linux/fs.h> #include <asm/cpu.h> +#include <asm/cputype.h> #include <asm/elf.h> #include <asm/procinfo.h> #include <asm/setup.h> #include <asm/mach-types.h> #include <asm/cacheflush.h> +#include <asm/cachetype.h> #include <asm/tlbflush.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> +#include <asm/traps.h> #include "compat.h" #include "atags.h" @@ -58,13 +61,14 @@ __setup("fpe=", fpe_setup); extern void paging_init(struct meminfo *, struct machine_desc *desc); extern void reboot_setup(char *str); -extern int root_mountflags; -extern void _stext, _text, _etext, __data_start, _edata, _end; +extern void _text, _etext, __data_start, _edata, _end; unsigned int processor_id; EXPORT_SYMBOL(processor_id); unsigned int __machine_arch_type; EXPORT_SYMBOL(__machine_arch_type); +unsigned int cacheid; +EXPORT_SYMBOL(cacheid); unsigned int __atags_pointer __initdata; @@ -108,9 +112,6 @@ static struct stack stacks[NR_CPUS]; char elf_platform[ELF_PLATFORM_SIZE]; EXPORT_SYMBOL(elf_platform); -unsigned long phys_initrd_start __initdata = 0; -unsigned long phys_initrd_size __initdata = 0; - static struct meminfo meminfo __initdata = { 0, }; static const char *cpu_name; static const char *machine_name; @@ -175,63 +176,6 @@ static struct resource io_res[] = { #define lp1 io_res[1] #define lp2 io_res[2] -static const char *cache_types[16] = { - "write-through", - "write-back", - "write-back", - "undefined 3", - "undefined 4", - "undefined 5", - "write-back", - "write-back", - "undefined 8", - "undefined 9", - "undefined 10", - "undefined 11", - "undefined 12", - "undefined 13", - "write-back", - "undefined 15", -}; - -static const char *cache_clean[16] = { - "not required", - "read-block", - "cp15 c7 ops", - "undefined 3", - "undefined 4", - "undefined 5", - "cp15 c7 ops", - "cp15 c7 ops", - "undefined 8", - "undefined 9", - "undefined 10", - "undefined 11", - "undefined 12", - "undefined 13", - "cp15 c7 ops", - "undefined 15", -}; - -static const char *cache_lockdown[16] = { - "not supported", - "not supported", - "not supported", - "undefined 3", - "undefined 4", - "undefined 5", - "format A", - "format B", - "undefined 8", - "undefined 9", - "undefined 10", - "undefined 11", - "undefined 12", - "undefined 13", - "format C", - "undefined 15", -}; - static const char *proc_arch[] = { "undefined/unknown", "3", @@ -252,61 +196,19 @@ static const char *proc_arch[] = { "?(17)", }; -#define CACHE_TYPE(x) (((x) >> 25) & 15) -#define CACHE_S(x) ((x) & (1 << 24)) -#define CACHE_DSIZE(x) (((x) >> 12) & 4095) /* only if S=1 */ -#define CACHE_ISIZE(x) ((x) & 4095) - -#define CACHE_SIZE(y) (((y) >> 6) & 7) -#define CACHE_ASSOC(y) (((y) >> 3) & 7) -#define CACHE_M(y) ((y) & (1 << 2)) -#define CACHE_LINE(y) ((y) & 3) - -static inline void dump_cache(const char *prefix, int cpu, unsigned int cache) -{ - unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0); - - printk("CPU%u: %s: %d bytes, associativity %d, %d byte lines, %d sets\n", - cpu, prefix, - mult << (8 + CACHE_SIZE(cache)), - (mult << CACHE_ASSOC(cache)) >> 1, - 8 << CACHE_LINE(cache), - 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) - - CACHE_LINE(cache))); -} - -static void __init dump_cpu_info(int cpu) -{ - unsigned int info = read_cpuid(CPUID_CACHETYPE); - - if (info != processor_id) { - printk("CPU%u: D %s %s cache\n", cpu, cache_is_vivt() ? "VIVT" : "VIPT", - cache_types[CACHE_TYPE(info)]); - if (CACHE_S(info)) { - dump_cache("I cache", cpu, CACHE_ISIZE(info)); - dump_cache("D cache", cpu, CACHE_DSIZE(info)); - } else { - dump_cache("cache", cpu, CACHE_ISIZE(info)); - } - } - - if (arch_is_coherent()) - printk("Cache coherency enabled\n"); -} - int cpu_architecture(void) { int cpu_arch; - if ((processor_id & 0x0008f000) == 0) { + if ((read_cpuid_id() & 0x0008f000) == 0) { cpu_arch = CPU_ARCH_UNKNOWN; - } else if ((processor_id & 0x0008f000) == 0x00007000) { - cpu_arch = (processor_id & (1 << 23)) ? CPU_ARCH_ARMv4T : CPU_ARCH_ARMv3; - } else if ((processor_id & 0x00080000) == 0x00000000) { - cpu_arch = (processor_id >> 16) & 7; + } 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 ((processor_id & 0x000f0000) == 0x000f0000) { + } else if ((read_cpuid_id() & 0x000f0000) == 0x000f0000) { unsigned int mmfr0; /* Revised CPUID format. Read the Memory Model Feature @@ -327,6 +229,34 @@ int cpu_architecture(void) return cpu_arch; } +static void __init cacheid_init(void) +{ + unsigned int cachetype = read_cpuid_cachetype(); + unsigned int arch = cpu_architecture(); + + if (arch >= CPU_ARCH_ARMv7) { + cacheid = CACHEID_VIPT_NONALIASING; + if ((cachetype & (3 << 14)) == 1 << 14) + cacheid |= CACHEID_ASID_TAGGED; + } else if (arch >= CPU_ARCH_ARMv6) { + if (cachetype & (1 << 23)) + cacheid = CACHEID_VIPT_ALIASING; + else + cacheid = CACHEID_VIPT_NONALIASING; + } else { + cacheid = CACHEID_VIVT; + } + + printk("CPU: %s data cache, %s instruction cache\n", + cache_is_vivt() ? "VIVT" : + cache_is_vipt_aliasing() ? "VIPT aliasing" : + cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown", + cache_is_vivt() ? "VIVT" : + icache_is_vivt_asid_tagged() ? "VIVT ASID tagged" : + cache_is_vipt_aliasing() ? "VIPT aliasing" : + cache_is_vipt_nonaliasing() ? "VIPT nonaliasing" : "unknown"); +} + /* * These functions re-use the assembly code in head.S, which * already provide the required functionality. @@ -343,10 +273,10 @@ static void __init setup_processor(void) * types. The linker builds this table for us from the * entries in arch/arm/mm/proc-*.S */ - list = lookup_processor_type(processor_id); + list = lookup_processor_type(read_cpuid_id()); if (!list) { printk("CPU configuration botched (ID %08x), unable " - "to continue.\n", processor_id); + "to continue.\n", read_cpuid_id()); while (1); } @@ -366,7 +296,7 @@ static void __init setup_processor(void) #endif printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", - cpu_name, processor_id, (int)processor_id & 15, + cpu_name, read_cpuid_id(), read_cpuid_id() & 15, proc_arch[cpu_architecture()], cr_alignment); sprintf(init_utsname()->machine, "%s%c", list->arch_name, ENDIANNESS); @@ -376,14 +306,14 @@ static void __init setup_processor(void) elf_hwcap &= ~HWCAP_THUMB; #endif + cacheid_init(); cpu_proc_init(); } /* * cpu_init - initialise one CPU. * - * cpu_init dumps the cache information, initialises SMP specific - * information, and sets up the per-CPU stacks. + * cpu_init sets up the per-CPU stacks. */ void cpu_init(void) { @@ -395,9 +325,6 @@ void cpu_init(void) BUG(); } - if (system_state == SYSTEM_BOOTING) - dump_cpu_info(cpu); - /* * setup stacks for re-entrant exception handlers */ @@ -440,20 +367,6 @@ static struct machine_desc * __init setup_machine(unsigned int nr) return list; } -static void __init early_initrd(char **p) -{ - unsigned long start, size; - - start = memparse(*p, p); - if (**p == ',') { - size = memparse((*p) + 1, p); - - phys_initrd_start = start; - phys_initrd_size = size; - } -} -__early_param("initrd=", early_initrd); - static void __init arm_add_memory(unsigned long start, unsigned long size) { struct membank *bank; @@ -513,12 +426,12 @@ static void __init parse_cmdline(char **cmdline_p, char *from) struct early_params *p; for (p = &__early_begin; p < &__early_end; p++) { - int len = strlen(p->arg); + int arglen = strlen(p->arg); - if (memcmp(from, p->arg, len) == 0) { + if (memcmp(from, p->arg, arglen) == 0) { if (to != command_line) to -= 1; - from += len; + from += arglen; p->fn(&from); while (*from != ' ' && *from != '\0') @@ -565,18 +478,13 @@ request_standard_resources(struct meminfo *mi, struct machine_desc *mdesc) kernel_data.end = virt_to_phys(&_end - 1); for (i = 0; i < mi->nr_banks; i++) { - unsigned long virt_start, virt_end; - if (mi->bank[i].size == 0) continue; - virt_start = __phys_to_virt(mi->bank[i].start); - virt_end = virt_start + mi->bank[i].size - 1; - res = alloc_bootmem_low(sizeof(*res)); res->name = "System RAM"; - res->start = __virt_to_phys(virt_start); - res->end = __virt_to_phys(virt_end); + res->start = mi->bank[i].start; + res->end = mi->bank[i].start + mi->bank[i].size - 1; res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; request_resource(&iomem_resource, res); @@ -680,26 +588,6 @@ static int __init parse_tag_ramdisk(const struct tag *tag) __tagtable(ATAG_RAMDISK, parse_tag_ramdisk); -static int __init parse_tag_initrd(const struct tag *tag) -{ - printk(KERN_WARNING "ATAG_INITRD is deprecated; " - "please update your bootloader.\n"); - phys_initrd_start = __virt_to_phys(tag->u.initrd.start); - phys_initrd_size = tag->u.initrd.size; - return 0; -} - -__tagtable(ATAG_INITRD, parse_tag_initrd); - -static int __init parse_tag_initrd2(const struct tag *tag) -{ - phys_initrd_start = tag->u.initrd.start; - phys_initrd_size = tag->u.initrd.size; - return 0; -} - -__tagtable(ATAG_INITRD2, parse_tag_initrd2); - static int __init parse_tag_serialnr(const struct tag *tag) { system_serial_low = tag->u.serialnr.low; @@ -853,6 +741,7 @@ void __init setup_arch(char **cmdline_p) conswitchp = &dummy_con; #endif #endif + early_trap_init(); } @@ -886,28 +775,12 @@ static const char *hwcap_str[] = { NULL }; -static void -c_show_cache(struct seq_file *m, const char *type, unsigned int cache) -{ - unsigned int mult = 2 + (CACHE_M(cache) ? 1 : 0); - - seq_printf(m, "%s size\t\t: %d\n" - "%s assoc\t\t: %d\n" - "%s line length\t: %d\n" - "%s sets\t\t: %d\n", - type, mult << (8 + CACHE_SIZE(cache)), - type, (mult << CACHE_ASSOC(cache)) >> 1, - type, 8 << CACHE_LINE(cache), - type, 1 << (6 + CACHE_SIZE(cache) - CACHE_ASSOC(cache) - - CACHE_LINE(cache))); -} - static int c_show(struct seq_file *m, void *v) { int i; seq_printf(m, "Processor\t: %s rev %d (%s)\n", - cpu_name, (int)processor_id & 15, elf_platform); + cpu_name, read_cpuid_id() & 15, elf_platform); #if defined(CONFIG_SMP) for_each_online_cpu(i) { @@ -934,47 +807,26 @@ static int c_show(struct seq_file *m, void *v) if (elf_hwcap & (1 << i)) seq_printf(m, "%s ", hwcap_str[i]); - seq_printf(m, "\nCPU implementer\t: 0x%02x\n", processor_id >> 24); + seq_printf(m, "\nCPU implementer\t: 0x%02x\n", read_cpuid_id() >> 24); seq_printf(m, "CPU architecture: %s\n", proc_arch[cpu_architecture()]); - if ((processor_id & 0x0008f000) == 0x00000000) { + if ((read_cpuid_id() & 0x0008f000) == 0x00000000) { /* pre-ARM7 */ - seq_printf(m, "CPU part\t: %07x\n", processor_id >> 4); + seq_printf(m, "CPU part\t: %07x\n", read_cpuid_id() >> 4); } else { - if ((processor_id & 0x0008f000) == 0x00007000) { + if ((read_cpuid_id() & 0x0008f000) == 0x00007000) { /* ARM7 */ seq_printf(m, "CPU variant\t: 0x%02x\n", - (processor_id >> 16) & 127); + (read_cpuid_id() >> 16) & 127); } else { /* post-ARM7 */ seq_printf(m, "CPU variant\t: 0x%x\n", - (processor_id >> 20) & 15); + (read_cpuid_id() >> 20) & 15); } seq_printf(m, "CPU part\t: 0x%03x\n", - (processor_id >> 4) & 0xfff); - } - seq_printf(m, "CPU revision\t: %d\n", processor_id & 15); - - { - unsigned int cache_info = read_cpuid(CPUID_CACHETYPE); - if (cache_info != processor_id) { - seq_printf(m, "Cache type\t: %s\n" - "Cache clean\t: %s\n" - "Cache lockdown\t: %s\n" - "Cache format\t: %s\n", - cache_types[CACHE_TYPE(cache_info)], - cache_clean[CACHE_TYPE(cache_info)], - cache_lockdown[CACHE_TYPE(cache_info)], - CACHE_S(cache_info) ? "Harvard" : "Unified"); - - if (CACHE_S(cache_info)) { - c_show_cache(m, "I", CACHE_ISIZE(cache_info)); - c_show_cache(m, "D", CACHE_DSIZE(cache_info)); - } else { - c_show_cache(m, "Cache", CACHE_ISIZE(cache_info)); - } - } + (read_cpuid_id() >> 4) & 0xfff); } + seq_printf(m, "CPU revision\t: %d\n", read_cpuid_id() & 15); seq_puts(m, "\n"); |