/* * linux/arch/arm/kernel/setup.c * * Copyright (C) 1995-2001 Russell King * * 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/module.h>#include <linux/kernel.h>#include <linux/stddef.h>#include <linux/ioport.h>#include <linux/delay.h>#include <linux/utsname.h>#include <linux/initrd.h>#include <linux/console.h>#include <linux/bootmem.h>#include <linux/seq_file.h>#include <linux/screen_info.h>#include <linux/init.h>#include <linux/kexec.h>#include <linux/of_fdt.h>#include <linux/crash_dump.h>#include <linux/root_dev.h>#include <linux/cpu.h>#include <linux/interrupt.h>#include <linux/smp.h>#include <linux/fs.h>#include <linux/proc_fs.h>#include <linux/memblock.h> #include <asm/unified.h>#include <asm/cpu.h>#include <asm/cputype.h>#include <asm/elf.h>#include <asm/procinfo.h>#include <asm/sections.h>#include <asm/setup.h>#include <asm/smp_plat.h>#include <asm/mach-types.h>#include <asm/cacheflush.h>#include <asm/cachetype.h>#include <asm/tlbflush.h> #include <asm/prom.h>#include <asm/mach/arch.h>#include <asm/mach/irq.h>#include <asm/mach/time.h>#include <asm/traps.h>#include <asm/unwind.h> #if defined(CONFIG_DEPRECATED_PARAM_STRUCT)#include "compat.h"#endif#include "atags.h"#include "tcm.h" #ifndef MEM_SIZE#define MEM_SIZE (16*1024*1024)#endif #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE)char fpe_type[8]; static int __init fpe_setup(char *line){ memcpy(fpe_type, line, 8); return 1;} __setup("fpe=", fpe_setup);#endif extern void paging_init(struct machine_desc *desc);extern void sanity_check_meminfo(void);extern void reboot_setup(char *str); unsigned int processor_id;EXPORT_SYMBOL(processor_id);unsigned int __machine_arch_type __read_mostly;EXPORT_SYMBOL(__machine_arch_type);unsigned int cacheid __read_mostly;EXPORT_SYMBOL(cacheid); unsigned int __atags_pointer __initdata; unsigned int system_rev;EXPORT_SYMBOL(system_rev); unsigned int system_serial_low;EXPORT_SYMBOL(system_serial_low); unsigned int system_serial_high;EXPORT_SYMBOL(system_serial_high); unsigned int elf_hwcap __read_mostly;EXPORT_SYMBOL(elf_hwcap); #ifdef MULTI_CPUstruct processor processor __read_mostly;#endif#ifdef MULTI_TLBstruct cpu_tlb_fns cpu_tlb __read_mostly;#endif#ifdef MULTI_USERstruct cpu_user_fns cpu_user __read_mostly;#endif#ifdef MULTI_CACHEstruct cpu_cache_fns cpu_cache __read_mostly;#endif#ifdef CONFIG_OUTER_CACHEstruct outer_cache_fns outer_cache __read_mostly;EXPORT_SYMBOL(outer_cache);#endif struct stack { u32 irq[3]; u32 abt[3]; u32 und[3];} ____cacheline_aligned; static struct stack stacks[NR_CPUS]; char elf_platform[ELF_PLATFORM_SIZE];EXPORT_SYMBOL(elf_platform); static const char *cpu_name;static const char *machine_name;static char __initdata cmd_line[COMMAND_LINE_SIZE];struct machine_desc *machine_desc __initdata; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE;static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } };#define ENDIANNESS ((char)endian_test.l) DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); /* * Standard memory resources */static struct resource mem_res[] = { { .name = "Video RAM", .start = 0, .end = 0, .flags = IORESOURCE_MEM }, { .name = "Kernel text", .start = 0, .end = 0, .flags = IORESOURCE_MEM }, { .name = "Kernel data", .start = 0, .end = 0, .flags = IORESOURCE_MEM }}; #define video_ram mem_res[0]#define kernel_code mem_res[1]#define kernel_data mem_res[2] static struct resource io_res[] = { { .name = "reserved", .start = 0x3bc, .end = 0x3be, .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .name = "reserved", .start = 0x378, .end = 0x37f, .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .name = "reserved", .start = 0x278, .end = 0x27f, .flags = IORESOURCE_IO | IORESOURCE_BUSY }}; #define lp0 io_res[0]#define lp1 io_res[1]#define lp2 io_res[2] static const char *proc_arch[] = { "undefined/unknown", "3", "4", "4T", "5", "5T", "5TE", "5TEJ", "6TEJ", "7", "?(11)", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)",}; int 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;} static int cpu_has_aliasing_icache(unsigned int arch){ int aliasing_icache; unsigned int id_reg, num_sets, line_size; /* arch specifies the register format */ switch (arch) { case CPU_ARCH_ARMv7: asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR" : /* No output operands */ : "r" (1)); isb(); asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR" : "=r" (id_reg)); line_size = 4 << ((id_reg & 0x7) + 2); num_sets = ((id_reg >> 13) & 0x7fff) + 1; aliasing_icache = (line_size * num_sets) > PAGE_SIZE; break; case CPU_ARCH_ARMv6: aliasing_icache = read_cpuid_cachetype() & (1 << 11); break; default: /* I-cache aliases will be handled by D-cache aliasing code */ aliasing_icache = 0; } return aliasing_icache;} static void __init cacheid_init(void){ unsigned int cachetype = read_cpuid_cachetype(); unsigned int arch = cpu_architecture(); if (arch >= CPU_ARCH_ARMv6) { if ((cachetype & (7 << 29)) == 4 << 29) { /* ARMv7 register format */ arch = CPU_ARCH_ARMv7; cacheid = CACHEID_VIPT_NONALIASING; if ((cachetype & (3 << 14)) == 1 << 14) cacheid |= CACHEID_ASID_TAGGED; } else { arch = CPU_ARCH_ARMv6; if (cachetype & (1 << 23)) cacheid = CACHEID_VIPT_ALIASING; else cacheid = CACHEID_VIPT_NONALIASING; } if (cpu_has_aliasing_icache(arch)) cacheid |= CACHEID_VIPT_I_ALIASING; } 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" : icache_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. */extern struct proc_info_list *lookup_processor_type(unsigned int); void __init early_print(const char *str, ...){ extern void printascii(const char *); char buf[256]; va_list ap; va_start(ap, str); vsnprintf(buf, sizeof(buf), str, ap); va_end(ap); #ifdef CONFIG_DEBUG_LL printascii(buf);#endif printk("%s", buf);} static void __init feat_v6_fixup(void){ int id = read_cpuid_id(); if ((id & 0xff0f0000) != 0x41070000) return; /* * HWCAP_TLS is available only on 1136 r1p0 and later, * see also kuser_get_tls_init. */ if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0)) elf_hwcap &= ~HWCAP_TLS;} /* * cpu_init - initialise one CPU. * * cpu_init sets up the per-CPU stacks. */void cpu_init(void){ unsigned int cpu = smp_processor_id(); struct stack *stk = &stacks[cpu]; if (cpu >= NR_CPUS) { printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); BUG(); } cpu_proc_init(); /* * Define the placement constraint for the inline asm directive below. * In Thumb-2, msr with an immediate value is not allowed. */#ifdef CONFIG_THUMB2_KERNEL#define PLC "r"#else#define PLC "I"#endif /* * setup stacks for re-entrant exception handlers */ __asm__ ( "msr cpsr_c, %1\n\t" "add r14, %0, %2\n\t" "mov sp, r14\n\t" "msr cpsr_c, %3\n\t" "add r14, %0, %4\n\t" "mov sp, r14\n\t" "msr cpsr_c, %5\n\t" "add r14, %0, %6\n\t" "mov sp, r14\n\t" "msr cpsr_c, %7" : : "r" (stk), PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), "I" (offsetof(struct stack, irq[0])), PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE), "I" (offsetof(struct stack, abt[0])), PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) : "r14");} static void __init setup_processor(void){ struct proc_info_list *list; /* * locate processor in the list of supported processor * types. The linker builds this table for us from the * entries in arch/arm/mm/proc-*.S */ list = lookup_processor_type(read_cpuid_id()); if (!list) { printk("CPU configuration botched (ID %08x), unable " "to continue.\n", read_cpuid_id()); while (1); } cpu_name = list->cpu_name; #ifdef MULTI_CPU processor = *list->proc;#endif#ifdef MULTI_TLB cpu_tlb = *list->tlb;#endif#ifdef MULTI_USER cpu_user = *list->user;#endif#ifdef MULTI_CACHE cpu_cache = *list->cache;#endif printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", 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); sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap;#ifndef CONFIG_ARM_THUMB elf_hwcap &= ~HWCAP_THUMB;#endif feat_v6_fixup(); cacheid_init(); cpu_init();} void __init dump_machine_table(void){ struct machine_desc *p; early_print("Available machine support:\n\nID (hex)\tNAME\n"); for_each_machine_desc(p) early_print("%08x\t%s\n", p->nr, p->name); early_print("\nPlease check your kernel config and/or bootloader.\n"); while (true) /* can't use cpu_relax() here as it may require MMU setup */;} int __init arm_add_memory(phys_addr_t start, unsigned long size){ struct membank *bank = &meminfo.bank[meminfo.nr_banks]; if (meminfo.nr_banks >= NR_BANKS) { printk(KERN_CRIT "NR_BANKS too low, " "ignoring memory at 0x%08llx\n", (long long)start); return -EINVAL; } /* * Ensure that start/size are aligned to a page boundary. * Size is appropriately rounded down, start is rounded up. */ size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); bank->size = size & PAGE_MASK; /* * Check whether this memory region has non-zero size or * invalid node number. */ if (bank->size == 0) return -EINVAL; meminfo.nr_banks++; return 0;} /* * Pick out the memory size. We look for mem=size@start, * where start and size are "size[KkMm]" */static int __init early_mem(char *p){ static int usermem __initdata = 0; unsigned long size; phys_addr_t start; char *endp;Lines 1–500 of 1080. Load more
/* * linux/arch/arm/kernel/setup.c * * Copyright (C) 1995-2001 Russell King * * 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/module.h> #include <linux/kernel.h> #include <linux/stddef.h> #include <linux/ioport.h> #include <linux/delay.h> #include <linux/utsname.h> #include <linux/initrd.h> #include <linux/console.h> #include <linux/bootmem.h> #include <linux/seq_file.h> #include <linux/screen_info.h> #include <linux/init.h> #include <linux/kexec.h> #include <linux/of_fdt.h> #include <linux/crash_dump.h> #include <linux/root_dev.h> #include <linux/cpu.h> #include <linux/interrupt.h> #include <linux/smp.h> #include <linux/fs.h> #include <linux/proc_fs.h> #include <linux/memblock.h> #include <asm/unified.h> #include <asm/cpu.h> #include <asm/cputype.h> #include <asm/elf.h> #include <asm/procinfo.h> #include <asm/sections.h> #include <asm/setup.h> #include <asm/smp_plat.h> #include <asm/mach-types.h> #include <asm/cacheflush.h> #include <asm/cachetype.h> #include <asm/tlbflush.h> #include <asm/prom.h> #include <asm/mach/arch.h> #include <asm/mach/irq.h> #include <asm/mach/time.h> #include <asm/traps.h> #include <asm/unwind.h> #if defined(CONFIG_DEPRECATED_PARAM_STRUCT) #include "compat.h" #endif #include "atags.h" #include "tcm.h" #ifndef MEM_SIZE #define MEM_SIZE (16*1024*1024) #endif #if defined(CONFIG_FPE_NWFPE) || defined(CONFIG_FPE_FASTFPE) char fpe_type[8]; static int __init fpe_setup(char *line) { memcpy(fpe_type, line, 8); return 1; } __setup("fpe=", fpe_setup); #endif extern void paging_init(struct machine_desc *desc); extern void sanity_check_meminfo(void); extern void reboot_setup(char *str); unsigned int processor_id; EXPORT_SYMBOL(processor_id); unsigned int __machine_arch_type __read_mostly; EXPORT_SYMBOL(__machine_arch_type); unsigned int cacheid __read_mostly; EXPORT_SYMBOL(cacheid); unsigned int __atags_pointer __initdata; unsigned int system_rev; EXPORT_SYMBOL(system_rev); unsigned int system_serial_low; EXPORT_SYMBOL(system_serial_low); unsigned int system_serial_high; EXPORT_SYMBOL(system_serial_high); unsigned int elf_hwcap __read_mostly; EXPORT_SYMBOL(elf_hwcap); #ifdef MULTI_CPU struct processor processor __read_mostly; #endif #ifdef MULTI_TLB struct cpu_tlb_fns cpu_tlb __read_mostly; #endif #ifdef MULTI_USER struct cpu_user_fns cpu_user __read_mostly; #endif #ifdef MULTI_CACHE struct cpu_cache_fns cpu_cache __read_mostly; #endif #ifdef CONFIG_OUTER_CACHE struct outer_cache_fns outer_cache __read_mostly; EXPORT_SYMBOL(outer_cache); #endif struct stack { u32 irq[3]; u32 abt[3]; u32 und[3]; } ____cacheline_aligned; static struct stack stacks[NR_CPUS]; char elf_platform[ELF_PLATFORM_SIZE]; EXPORT_SYMBOL(elf_platform); static const char *cpu_name; static const char *machine_name; static char __initdata cmd_line[COMMAND_LINE_SIZE]; struct machine_desc *machine_desc __initdata; static char default_command_line[COMMAND_LINE_SIZE] __initdata = CONFIG_CMDLINE; static union { char c[4]; unsigned long l; } endian_test __initdata = { { 'l', '?', '?', 'b' } }; #define ENDIANNESS ((char)endian_test.l) DEFINE_PER_CPU(struct cpuinfo_arm, cpu_data); /* * Standard memory resources */ static struct resource mem_res[] = { { .name = "Video RAM", .start = 0, .end = 0, .flags = IORESOURCE_MEM }, { .name = "Kernel text", .start = 0, .end = 0, .flags = IORESOURCE_MEM }, { .name = "Kernel data", .start = 0, .end = 0, .flags = IORESOURCE_MEM } }; #define video_ram mem_res[0] #define kernel_code mem_res[1] #define kernel_data mem_res[2] static struct resource io_res[] = { { .name = "reserved", .start = 0x3bc, .end = 0x3be, .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .name = "reserved", .start = 0x378, .end = 0x37f, .flags = IORESOURCE_IO | IORESOURCE_BUSY }, { .name = "reserved", .start = 0x278, .end = 0x27f, .flags = IORESOURCE_IO | IORESOURCE_BUSY } }; #define lp0 io_res[0] #define lp1 io_res[1] #define lp2 io_res[2] static const char *proc_arch[] = { "undefined/unknown", "3", "4", "4T", "5", "5T", "5TE", "5TEJ", "6TEJ", "7", "?(11)", "?(12)", "?(13)", "?(14)", "?(15)", "?(16)", "?(17)", }; int 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; } static int cpu_has_aliasing_icache(unsigned int arch) { int aliasing_icache; unsigned int id_reg, num_sets, line_size; /* arch specifies the register format */ switch (arch) { case CPU_ARCH_ARMv7: asm("mcr p15, 2, %0, c0, c0, 0 @ set CSSELR" : /* No output operands */ : "r" (1)); isb(); asm("mrc p15, 1, %0, c0, c0, 0 @ read CCSIDR" : "=r" (id_reg)); line_size = 4 << ((id_reg & 0x7) + 2); num_sets = ((id_reg >> 13) & 0x7fff) + 1; aliasing_icache = (line_size * num_sets) > PAGE_SIZE; break; case CPU_ARCH_ARMv6: aliasing_icache = read_cpuid_cachetype() & (1 << 11); break; default: /* I-cache aliases will be handled by D-cache aliasing code */ aliasing_icache = 0; } return aliasing_icache; } static void __init cacheid_init(void) { unsigned int cachetype = read_cpuid_cachetype(); unsigned int arch = cpu_architecture(); if (arch >= CPU_ARCH_ARMv6) { if ((cachetype & (7 << 29)) == 4 << 29) { /* ARMv7 register format */ arch = CPU_ARCH_ARMv7; cacheid = CACHEID_VIPT_NONALIASING; if ((cachetype & (3 << 14)) == 1 << 14) cacheid |= CACHEID_ASID_TAGGED; } else { arch = CPU_ARCH_ARMv6; if (cachetype & (1 << 23)) cacheid = CACHEID_VIPT_ALIASING; else cacheid = CACHEID_VIPT_NONALIASING; } if (cpu_has_aliasing_icache(arch)) cacheid |= CACHEID_VIPT_I_ALIASING; } 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" : icache_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. */ extern struct proc_info_list *lookup_processor_type(unsigned int); void __init early_print(const char *str, ...) { extern void printascii(const char *); char buf[256]; va_list ap; va_start(ap, str); vsnprintf(buf, sizeof(buf), str, ap); va_end(ap); #ifdef CONFIG_DEBUG_LL printascii(buf); #endif printk("%s", buf); } static void __init feat_v6_fixup(void) { int id = read_cpuid_id(); if ((id & 0xff0f0000) != 0x41070000) return; /* * HWCAP_TLS is available only on 1136 r1p0 and later, * see also kuser_get_tls_init. */ if ((((id >> 4) & 0xfff) == 0xb36) && (((id >> 20) & 3) == 0)) elf_hwcap &= ~HWCAP_TLS; } /* * cpu_init - initialise one CPU. * * cpu_init sets up the per-CPU stacks. */ void cpu_init(void) { unsigned int cpu = smp_processor_id(); struct stack *stk = &stacks[cpu]; if (cpu >= NR_CPUS) { printk(KERN_CRIT "CPU%u: bad primary CPU number\n", cpu); BUG(); } cpu_proc_init(); /* * Define the placement constraint for the inline asm directive below. * In Thumb-2, msr with an immediate value is not allowed. */ #ifdef CONFIG_THUMB2_KERNEL #define PLC "r" #else #define PLC "I" #endif /* * setup stacks for re-entrant exception handlers */ __asm__ ( "msr cpsr_c, %1\n\t" "add r14, %0, %2\n\t" "mov sp, r14\n\t" "msr cpsr_c, %3\n\t" "add r14, %0, %4\n\t" "mov sp, r14\n\t" "msr cpsr_c, %5\n\t" "add r14, %0, %6\n\t" "mov sp, r14\n\t" "msr cpsr_c, %7" : : "r" (stk), PLC (PSR_F_BIT | PSR_I_BIT | IRQ_MODE), "I" (offsetof(struct stack, irq[0])), PLC (PSR_F_BIT | PSR_I_BIT | ABT_MODE), "I" (offsetof(struct stack, abt[0])), PLC (PSR_F_BIT | PSR_I_BIT | UND_MODE), "I" (offsetof(struct stack, und[0])), PLC (PSR_F_BIT | PSR_I_BIT | SVC_MODE) : "r14"); } static void __init setup_processor(void) { struct proc_info_list *list; /* * locate processor in the list of supported processor * types. The linker builds this table for us from the * entries in arch/arm/mm/proc-*.S */ list = lookup_processor_type(read_cpuid_id()); if (!list) { printk("CPU configuration botched (ID %08x), unable " "to continue.\n", read_cpuid_id()); while (1); } cpu_name = list->cpu_name; #ifdef MULTI_CPU processor = *list->proc; #endif #ifdef MULTI_TLB cpu_tlb = *list->tlb; #endif #ifdef MULTI_USER cpu_user = *list->user; #endif #ifdef MULTI_CACHE cpu_cache = *list->cache; #endif printk("CPU: %s [%08x] revision %d (ARMv%s), cr=%08lx\n", 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); sprintf(elf_platform, "%s%c", list->elf_name, ENDIANNESS); elf_hwcap = list->elf_hwcap; #ifndef CONFIG_ARM_THUMB elf_hwcap &= ~HWCAP_THUMB; #endif feat_v6_fixup(); cacheid_init(); cpu_init(); } void __init dump_machine_table(void) { struct machine_desc *p; early_print("Available machine support:\n\nID (hex)\tNAME\n"); for_each_machine_desc(p) early_print("%08x\t%s\n", p->nr, p->name); early_print("\nPlease check your kernel config and/or bootloader.\n"); while (true) /* can't use cpu_relax() here as it may require MMU setup */; } int __init arm_add_memory(phys_addr_t start, unsigned long size) { struct membank *bank = &meminfo.bank[meminfo.nr_banks]; if (meminfo.nr_banks >= NR_BANKS) { printk(KERN_CRIT "NR_BANKS too low, " "ignoring memory at 0x%08llx\n", (long long)start); return -EINVAL; } /* * Ensure that start/size are aligned to a page boundary. * Size is appropriately rounded down, start is rounded up. */ size -= start & ~PAGE_MASK; bank->start = PAGE_ALIGN(start); bank->size = size & PAGE_MASK; /* * Check whether this memory region has non-zero size or * invalid node number. */ if (bank->size == 0) return -EINVAL; meminfo.nr_banks++; return 0; } /* * Pick out the memory size. We look for mem=size@start, * where start and size are "size[KkMm]" */ static int __init early_mem(char *p) { static int usermem __initdata = 0; unsigned long size; phys_addr_t start; char *endp;