⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 setup.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  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/root_dev.h>#include <linux/cpu.h>#include <linux/interrupt.h>#include <linux/smp.h>#include <linux/fs.h>#include <linux/kexec.h>#include <asm/cpu.h>#include <asm/elf.h>#include <asm/procinfo.h>#include <asm/setup.h>#include <asm/mach-types.h>#include <asm/cacheflush.h>#include <asm/tlbflush.h>#include <asm/mach/arch.h>#include <asm/mach/irq.h>#include <asm/mach/time.h>#include "compat.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);#endifextern 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;unsigned int processor_id;unsigned int __machine_arch_type;EXPORT_SYMBOL(__machine_arch_type);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;EXPORT_SYMBOL(elf_hwcap);#ifdef MULTI_CPUstruct processor processor;#endif#ifdef MULTI_TLBstruct cpu_tlb_fns cpu_tlb;#endif#ifdef MULTI_USERstruct cpu_user_fns cpu_user;#endif#ifdef MULTI_CACHEstruct cpu_cache_fns cpu_cache;#endif#ifdef CONFIG_OUTER_CACHEstruct outer_cache_fns outer_cache;#endifstruct 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);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;static char __initdata command_line[COMMAND_LINE_SIZE];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 *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",	"4",	"4T",	"5",	"5T",	"5TE",	"5TEJ",	"6TEJ",	"7",	"?(11)",	"?(12)",	"?(13)",	"?(14)",	"?(15)",	"?(16)",	"?(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) {		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;		if (cpu_arch)			cpu_arch += CPU_ARCH_ARMv3;	} else if ((processor_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;}/* * 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);extern struct machine_desc *lookup_machine_type(unsigned int);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(processor_id);	if (!list) {		printk("CPU configuration botched (ID %08x), unable "		       "to continue.\n", processor_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, processor_id, (int)processor_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	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. */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();	}	if (system_state == SYSTEM_BOOTING)		dump_cpu_info(cpu);	/*	 * setup stacks for re-entrant exception handlers	 */	__asm__ (	"msr	cpsr_c, %1\n\t"	"add	sp, %0, %2\n\t"	"msr	cpsr_c, %3\n\t"	"add	sp, %0, %4\n\t"	"msr	cpsr_c, %5\n\t"	"add	sp, %0, %6\n\t"	"msr	cpsr_c, %7"	    :	    : "r" (stk),	      "I" (PSR_F_BIT | PSR_I_BIT | IRQ_MODE),	      "I" (offsetof(struct stack, irq[0])),	      "I" (PSR_F_BIT | PSR_I_BIT | ABT_MODE),	      "I" (offsetof(struct stack, abt[0])),	      "I" (PSR_F_BIT | PSR_I_BIT | UND_MODE),	      "I" (offsetof(struct stack, und[0])),	      "I" (PSR_F_BIT | PSR_I_BIT | SVC_MODE)	    : "r14");}static struct machine_desc * __init setup_machine(unsigned int nr){	struct machine_desc *list;	/*	 * locate machine in the list of supported machines.	 */	list = lookup_machine_type(nr);	if (!list) {		printk("Machine configuration botched (nr %d), unable "		       "to continue.\n", nr);		while (1);	}	printk("Machine: %s\n", list->name);	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;	/*	 * Ensure that start/size are aligned to a page boundary.	 * Size is appropriately rounded down, start is rounded up.	 */	size -= start & ~PAGE_MASK;	bank = &meminfo.bank[meminfo.nr_banks++];	bank->start = PAGE_ALIGN(start);	bank->size  = size & PAGE_MASK;	bank->node  = PHYS_TO_NID(start);}/* * Pick out the memory size.  We look for mem=size@start, * where start and size are "size[KkMm]" */static void __init early_mem(char **p){	static int usermem __initdata = 0;	unsigned long size, start;	/*	 * If the user specifies memory size, we	 * blow away any automatically generated	 * size.	 */	if (usermem == 0) {		usermem = 1;		meminfo.nr_banks = 0;	}	start = PHYS_OFFSET;	size  = memparse(*p, p);	if (**p == '@')		start = memparse(*p + 1, p);	arm_add_memory(start, size);}__early_param("mem=", early_mem);/* * Initial parsing of the command line. */static void __init parse_cmdline(char **cmdline_p, char *from){	char c = ' ', *to = command_line;	int len = 0;	for (;;) {		if (c == ' ') {			extern struct early_params __early_begin, __early_end;			struct early_params *p;			for (p = &__early_begin; p < &__early_end; p++) {				int len = strlen(p->arg);				if (memcmp(from, p->arg, len) == 0) {					if (to != command_line)						to -= 1;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -