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

📄 setup.c

📁 linux 内核源代码
💻 C
📖 第 1 页 / 共 2 页
字号:
	/*	 * Setup lowcore for boot cpu	 */	lc_pages = sizeof(void *) == 8 ? 2 : 1;	lc = (struct _lowcore *)		__alloc_bootmem(lc_pages * PAGE_SIZE, lc_pages * PAGE_SIZE, 0);	memset(lc, 0, lc_pages * PAGE_SIZE);	lc->restart_psw.mask = PSW_BASE_BITS | PSW_DEFAULT_KEY;	lc->restart_psw.addr =		PSW_ADDR_AMODE | (unsigned long) restart_int_handler;	if (switch_amode)		lc->restart_psw.mask |= PSW_ASC_HOME;	lc->external_new_psw.mask = psw_kernel_bits;	lc->external_new_psw.addr =		PSW_ADDR_AMODE | (unsigned long) ext_int_handler;	lc->svc_new_psw.mask = psw_kernel_bits | PSW_MASK_IO | PSW_MASK_EXT;	lc->svc_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) system_call;	lc->program_new_psw.mask = psw_kernel_bits;	lc->program_new_psw.addr =		PSW_ADDR_AMODE | (unsigned long)pgm_check_handler;	lc->mcck_new_psw.mask =		psw_kernel_bits & ~PSW_MASK_MCHECK & ~PSW_MASK_DAT;	lc->mcck_new_psw.addr =		PSW_ADDR_AMODE | (unsigned long) mcck_int_handler;	lc->io_new_psw.mask = psw_kernel_bits;	lc->io_new_psw.addr = PSW_ADDR_AMODE | (unsigned long) io_int_handler;	lc->ipl_device = S390_lowcore.ipl_device;	lc->jiffy_timer = -1LL;	lc->kernel_stack = ((unsigned long) &init_thread_union) + THREAD_SIZE;	lc->async_stack = (unsigned long)		__alloc_bootmem(ASYNC_SIZE, ASYNC_SIZE, 0) + ASYNC_SIZE;	lc->panic_stack = (unsigned long)		__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0) + PAGE_SIZE;	lc->current_task = (unsigned long) init_thread_union.thread_info.task;	lc->thread_info = (unsigned long) &init_thread_union;#ifndef CONFIG_64BIT	if (MACHINE_HAS_IEEE) {		lc->extended_save_area_addr = (__u32)			__alloc_bootmem(PAGE_SIZE, PAGE_SIZE, 0);		/* enable extended save area */		__ctl_set_bit(14, 29);	}#endif	set_prefix((u32)(unsigned long) lc);}static void __initsetup_resources(void){	struct resource *res, *sub_res;	int i;	code_resource.start = (unsigned long) &_text;	code_resource.end = (unsigned long) &_etext - 1;	data_resource.start = (unsigned long) &_etext;	data_resource.end = (unsigned long) &_edata - 1;	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {		res = alloc_bootmem_low(sizeof(struct resource));		res->flags = IORESOURCE_BUSY | IORESOURCE_MEM;		switch (memory_chunk[i].type) {		case CHUNK_READ_WRITE:			res->name = "System RAM";			break;		case CHUNK_READ_ONLY:			res->name = "System ROM";			res->flags |= IORESOURCE_READONLY;			break;		default:			res->name = "reserved";		}		res->start = memory_chunk[i].addr;		res->end = memory_chunk[i].addr +  memory_chunk[i].size - 1;		request_resource(&iomem_resource, res);		if (code_resource.start >= res->start  &&			code_resource.start <= res->end &&			code_resource.end > res->end) {			sub_res = alloc_bootmem_low(sizeof(struct resource));			memcpy(sub_res, &code_resource,				sizeof(struct resource));			sub_res->end = res->end;			code_resource.start = res->end + 1;			request_resource(res, sub_res);		}		if (code_resource.start >= res->start &&			code_resource.start <= res->end &&			code_resource.end <= res->end)			request_resource(res, &code_resource);		if (data_resource.start >= res->start &&			data_resource.start <= res->end &&			data_resource.end > res->end) {			sub_res = alloc_bootmem_low(sizeof(struct resource));			memcpy(sub_res, &data_resource,				sizeof(struct resource));			sub_res->end = res->end;			data_resource.start = res->end + 1;			request_resource(res, sub_res);		}		if (data_resource.start >= res->start &&			data_resource.start <= res->end &&			data_resource.end <= res->end)			request_resource(res, &data_resource);	}}unsigned long real_memory_size;EXPORT_SYMBOL_GPL(real_memory_size);static void __init setup_memory_end(void){	unsigned long memory_size;	unsigned long max_mem, max_phys;	int i;#if defined(CONFIG_ZFCPDUMP) || defined(CONFIG_ZFCPDUMP_MODULE)	if (ipl_info.type == IPL_TYPE_FCP_DUMP)		memory_end = ZFCPDUMP_HSA_SIZE;#endif	memory_size = 0;	max_phys = VMALLOC_END_INIT - VMALLOC_MIN_SIZE;	memory_end &= PAGE_MASK;	max_mem = memory_end ? min(max_phys, memory_end) : max_phys;	for (i = 0; i < MEMORY_CHUNKS; i++) {		struct mem_chunk *chunk = &memory_chunk[i];		real_memory_size = max(real_memory_size,				       chunk->addr + chunk->size);		if (chunk->addr >= max_mem) {			memset(chunk, 0, sizeof(*chunk));			continue;		}		if (chunk->addr + chunk->size > max_mem)			chunk->size = max_mem - chunk->addr;		memory_size = max(memory_size, chunk->addr + chunk->size);	}	if (!memory_end)		memory_end = memory_size;}static void __initsetup_memory(void){        unsigned long bootmap_size;	unsigned long start_pfn, end_pfn;	int i;	/*	 * partially used pages are not usable - thus	 * we are rounding upwards:	 */	start_pfn = PFN_UP(__pa(&_end));	end_pfn = max_pfn = PFN_DOWN(memory_end);#ifdef CONFIG_BLK_DEV_INITRD	/*	 * Move the initrd in case the bitmap of the bootmem allocater	 * would overwrite it.	 */	if (INITRD_START && INITRD_SIZE) {		unsigned long bmap_size;		unsigned long start;		bmap_size = bootmem_bootmap_pages(end_pfn - start_pfn + 1);		bmap_size = PFN_PHYS(bmap_size);		if (PFN_PHYS(start_pfn) + bmap_size > INITRD_START) {			start = PFN_PHYS(start_pfn) + bmap_size + PAGE_SIZE;			if (start + INITRD_SIZE > memory_end) {				printk("initrd extends beyond end of memory "				       "(0x%08lx > 0x%08lx)\n"				       "disabling initrd\n",				       start + INITRD_SIZE, memory_end);				INITRD_START = INITRD_SIZE = 0;			} else {				printk("Moving initrd (0x%08lx -> 0x%08lx, "				       "size: %ld)\n",				       INITRD_START, start, INITRD_SIZE);				memmove((void *) start, (void *) INITRD_START,					INITRD_SIZE);				INITRD_START = start;			}		}	}#endif	/*	 * Initialize the boot-time allocator	 */	bootmap_size = init_bootmem(start_pfn, end_pfn);	/*	 * Register RAM areas with the bootmem allocator.	 */	for (i = 0; i < MEMORY_CHUNKS && memory_chunk[i].size > 0; i++) {		unsigned long start_chunk, end_chunk, pfn;		if (memory_chunk[i].type != CHUNK_READ_WRITE)			continue;		start_chunk = PFN_DOWN(memory_chunk[i].addr);		end_chunk = start_chunk + PFN_DOWN(memory_chunk[i].size) - 1;		end_chunk = min(end_chunk, end_pfn);		if (start_chunk >= end_chunk)			continue;		add_active_range(0, start_chunk, end_chunk);		pfn = max(start_chunk, start_pfn);		for (; pfn <= end_chunk; pfn++)			page_set_storage_key(PFN_PHYS(pfn), PAGE_DEFAULT_KEY);	}	psw_set_key(PAGE_DEFAULT_KEY);	free_bootmem_with_active_regions(0, max_pfn);	/*	 * Reserve memory used for lowcore/command line/kernel image.	 */	reserve_bootmem(0, (unsigned long)_ehead);	reserve_bootmem((unsigned long)_stext,			PFN_PHYS(start_pfn) - (unsigned long)_stext);	/*	 * Reserve the bootmem bitmap itself as well. We do this in two	 * steps (first step was init_bootmem()) because this catches	 * the (very unlikely) case of us accidentally initializing the	 * bootmem allocator with an invalid RAM area.	 */	reserve_bootmem(start_pfn << PAGE_SHIFT, bootmap_size);#ifdef CONFIG_BLK_DEV_INITRD	if (INITRD_START && INITRD_SIZE) {		if (INITRD_START + INITRD_SIZE <= memory_end) {			reserve_bootmem(INITRD_START, INITRD_SIZE);			initrd_start = INITRD_START;			initrd_end = initrd_start + INITRD_SIZE;		} else {			printk("initrd extends beyond end of memory "			       "(0x%08lx > 0x%08lx)\ndisabling initrd\n",			       initrd_start + INITRD_SIZE, memory_end);			initrd_start = initrd_end = 0;		}	}#endif}static __init unsigned int stfl(void){	asm volatile(		"	.insn	s,0xb2b10000,0(0)\n" /* stfl */		"0:\n"		EX_TABLE(0b,0b));	return S390_lowcore.stfl_fac_list;}static __init int stfle(unsigned long long *list, int doublewords){	typedef struct { unsigned long long _[doublewords]; } addrtype;	register unsigned long __nr asm("0") = doublewords - 1;	asm volatile(".insn s,0xb2b00000,%0" /* stfle */		     : "=m" (*(addrtype *) list), "+d" (__nr) : : "cc");	return __nr + 1;}/* * Setup hardware capabilities. */static void __init setup_hwcaps(void){	static const int stfl_bits[6] = { 0, 2, 7, 17, 19, 21 };	struct cpuinfo_S390 *cpuinfo = &S390_lowcore.cpu_data;	unsigned long long facility_list_extended;	unsigned int facility_list;	int i;	facility_list = stfl();	/*	 * The store facility list bits numbers as found in the principles	 * of operation are numbered with bit 1UL<<31 as number 0 to	 * bit 1UL<<0 as number 31.	 *   Bit 0: instructions named N3, "backported" to esa-mode	 *   Bit 2: z/Architecture mode is active	 *   Bit 7: the store-facility-list-extended facility is installed	 *   Bit 17: the message-security assist is installed	 *   Bit 19: the long-displacement facility is installed	 *   Bit 21: the extended-immediate facility is installed	 * These get translated to:	 *   HWCAP_S390_ESAN3 bit 0, HWCAP_S390_ZARCH bit 1,	 *   HWCAP_S390_STFLE bit 2, HWCAP_S390_MSA bit 3,	 *   HWCAP_S390_LDISP bit 4, and HWCAP_S390_EIMM bit 5.	 */	for (i = 0; i < 6; i++)		if (facility_list & (1UL << (31 - stfl_bits[i])))			elf_hwcap |= 1UL << i;	/*	 * Check for additional facilities with store-facility-list-extended.	 * stfle stores doublewords (8 byte) with bit 1ULL<<63 as bit 0	 * and 1ULL<<0 as bit 63. Bits 0-31 contain the same information	 * as stored by stfl, bits 32-xxx contain additional facilities.	 * How many facility words are stored depends on the number of	 * doublewords passed to the instruction. The additional facilites	 * are:	 *   Bit 43: decimal floating point facility is installed	 * translated to:	 *   HWCAP_S390_DFP bit 6.	 */	if ((elf_hwcap & (1UL << 2)) &&	    stfle(&facility_list_extended, 1) > 0) {		if (facility_list_extended & (1ULL << (64 - 43)))			elf_hwcap |= 1UL << 6;	}	switch (cpuinfo->cpu_id.machine) {	case 0x9672:#if !defined(CONFIG_64BIT)	default:	/* Use "g5" as default for 31 bit kernels. */#endif		strcpy(elf_platform, "g5");		break;	case 0x2064:	case 0x2066:#if defined(CONFIG_64BIT)	default:	/* Use "z900" as default for 64 bit kernels. */#endif		strcpy(elf_platform, "z900");		break;	case 0x2084:	case 0x2086:		strcpy(elf_platform, "z990");		break;	case 0x2094:		strcpy(elf_platform, "z9-109");		break;	}}/* * Setup function called from init/main.c just after the banner * was printed. */void __initsetup_arch(char **cmdline_p){        /*         * print what head.S has found out about the machine         */#ifndef CONFIG_64BIT	printk((MACHINE_IS_VM) ?	       "We are running under VM (31 bit mode)\n" :	       "We are running native (31 bit mode)\n");	printk((MACHINE_HAS_IEEE) ?	       "This machine has an IEEE fpu\n" :	       "This machine has no IEEE fpu\n");#else /* CONFIG_64BIT */	printk((MACHINE_IS_VM) ?	       "We are running under VM (64 bit mode)\n" :	       "We are running native (64 bit mode)\n");#endif /* CONFIG_64BIT */	/* Save unparsed command line copy for /proc/cmdline */	strlcpy(boot_command_line, COMMAND_LINE, COMMAND_LINE_SIZE);	*cmdline_p = COMMAND_LINE;	*(*cmdline_p + COMMAND_LINE_SIZE - 1) = '\0';        ROOT_DEV = Root_RAM0;	init_mm.start_code = PAGE_OFFSET;	init_mm.end_code = (unsigned long) &_etext;	init_mm.end_data = (unsigned long) &_edata;	init_mm.brk = (unsigned long) &_end;	if (MACHINE_HAS_MVCOS)		memcpy(&uaccess, &uaccess_mvcos, sizeof(uaccess));	else		memcpy(&uaccess, &uaccess_std, sizeof(uaccess));	parse_early_param();	setup_ipl_info();	setup_memory_end();	setup_addressing_mode();	setup_memory();	setup_resources();	setup_lowcore();        cpu_init();        __cpu_logical_map[0] = S390_lowcore.cpu_data.cpu_addr;	smp_setup_cpu_possible_map();	/*	 * Setup capabilities (ELF_HWCAP & ELF_PLATFORM).	 */	setup_hwcaps();	/*	 * Create kernel page tables and switch to virtual addressing.	 */        paging_init();        /* Setup default console */	conmode_default();	/* Setup zfcpdump support */	setup_zfcpdump(console_devno);}void __cpuinit print_cpu_info(struct cpuinfo_S390 *cpuinfo){   printk("cpu %d "#ifdef CONFIG_SMP           "phys_idx=%d "#endif           "vers=%02X ident=%06X machine=%04X unused=%04X\n",           cpuinfo->cpu_nr,#ifdef CONFIG_SMP           cpuinfo->cpu_addr,#endif           cpuinfo->cpu_id.version,           cpuinfo->cpu_id.ident,           cpuinfo->cpu_id.machine,           cpuinfo->cpu_id.unused);}/* * show_cpuinfo - Get information on one CPU for use by procfs. */static int show_cpuinfo(struct seq_file *m, void *v){	static const char *hwcap_str[7] = {		"esan3", "zarch", "stfle", "msa", "ldisp", "eimm", "dfp"	};        struct cpuinfo_S390 *cpuinfo;	unsigned long n = (unsigned long) v - 1;	int i;	s390_adjust_jiffies();	preempt_disable();	if (!n) {		seq_printf(m, "vendor_id       : IBM/S390\n"			       "# processors    : %i\n"			       "bogomips per cpu: %lu.%02lu\n",			       num_online_cpus(), loops_per_jiffy/(500000/HZ),			       (loops_per_jiffy/(5000/HZ))%100);		seq_puts(m, "features\t: ");		for (i = 0; i < 7; i++)			if (hwcap_str[i] && (elf_hwcap & (1UL << i)))				seq_printf(m, "%s ", hwcap_str[i]);		seq_puts(m, "\n");	}	if (cpu_online(n)) {#ifdef CONFIG_SMP		if (smp_processor_id() == n)			cpuinfo = &S390_lowcore.cpu_data;		else			cpuinfo = &lowcore_ptr[n]->cpu_data;#else		cpuinfo = &S390_lowcore.cpu_data;#endif		seq_printf(m, "processor %li: "			       "version = %02X,  "			       "identification = %06X,  "			       "machine = %04X\n",			       n, cpuinfo->cpu_id.version,			       cpuinfo->cpu_id.ident,			       cpuinfo->cpu_id.machine);	}	preempt_enable();        return 0;}static void *c_start(struct seq_file *m, loff_t *pos){	return *pos < NR_CPUS ? (void *)((unsigned long) *pos + 1) : NULL;}static void *c_next(struct seq_file *m, void *v, loff_t *pos){	++*pos;	return c_start(m, pos);}static void c_stop(struct seq_file *m, void *v){}struct seq_operations cpuinfo_op = {	.start	= c_start,	.next	= c_next,	.stop	= c_stop,	.show	= show_cpuinfo,};

⌨️ 快捷键说明

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