setup.c revision 43cd34645d3bf35cbaa68f28b85d12d0b9e08ab9
11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * This file is subject to the terms and conditions of the GNU General Public 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * License. See the file "COPYING" in the main directory of this archive 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for more details. 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1995 Linus Torvalds 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1995 Waldorf Electronics 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1994, 95, 96, 97, 98, 99, 2000, 01, 02, 03 Ralf Baechle 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1996 Stoned Elipot 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 1999 Silicon Graphics, Inc. 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Copyright (C) 2000 2001, 2002 Maciej W. Rozycki 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/ioport.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/module.h> 16894673ee6122a3ce1958e1fe096901ba5356a96bJon Smirl#include <linux/screen_info.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/bootmem.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/initrd.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/root_dev.h> 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/highmem.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/console.h> 2222a9835c350782a5c3257343713932af3ac92ee0Dave Hansen#include <linux/pfn.h> 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/addrspace.h> 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/bootinfo.h> 26ec74e361f1e71a2498e48b62abdc4bd8d2423354Ralf Baechle#include <asm/cache.h> 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/cpu.h> 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/sections.h> 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/setup.h> 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/system.h> 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 32ec74e361f1e71a2498e48b62abdc4bd8d2423354Ralf Baechlestruct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly; 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(cpu_data); 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#ifdef CONFIG_VT 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct screen_info screen_info; 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Despite it's name this variable is even if we don't have PCI 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned int PCI_DMA_BUS_IS_PHYS; 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS); 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Setup information 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * These are initialized so they are in the .data section 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 52ec74e361f1e71a2498e48b62abdc4bd8d2423354Ralf Baechleunsigned long mips_machtype __read_mostly = MACH_UNKNOWN; 53ec74e361f1e71a2498e48b62abdc4bd8d2423354Ralf Baechleunsigned long mips_machgroup __read_mostly = MACH_GROUP_UNKNOWN; 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mips_machtype); 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mips_machgroup); 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct boot_mem_map boot_mem_map; 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic char command_line[CL_SIZE]; 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE; 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * mips_io_port_base is the begin of the address space to which x86 style 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * I/O ports are mapped. 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 67ec74e361f1e71a2498e48b62abdc4bd8d2423354Ralf Baechleconst unsigned long mips_io_port_base __read_mostly = -1; 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(mips_io_port_base); 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * isa_slot_offset is the address where E(ISA) busaddress 0 is mapped 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * for the processor. 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsunsigned long isa_slot_offset; 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus TorvaldsEXPORT_SYMBOL(isa_slot_offset); 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct resource code_resource = { .name = "Kernel code", }; 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic struct resource data_resource = { .name = "Kernel data", }; 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init add_memory_region(phys_t start, phys_t size, long type) 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int x = boot_mem_map.nr_map; 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct boot_mem_map_entry *prev = boot_mem_map.map + x - 1; 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 85b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu /* Sanity check */ 86b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu if (start + size < start) { 87b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu printk("Trying to add an invalid memory region, skipped\n"); 88b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu return; 89b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu } 90b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu 911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Try to merge with previous entry if any. This is far less than 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * perfect but is sufficient for most real world cases. 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (x && prev->addr + prev->size == start && prev->type == type) { 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds prev->size += size; 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (x == BOOT_MEM_MAP_MAX) { 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("Ooops! Too many entries in the memory map!\n"); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds boot_mem_map.map[x].addr = start; 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds boot_mem_map.map[x].size = size; 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds boot_mem_map.map[x].type = type; 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds boot_mem_map.nr_map++; 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init print_memory_map(void) 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds const int field = 2 * sizeof(unsigned long); 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < boot_mem_map.nr_map; i++) { 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" memory: %0*Lx @ %0*Lx ", 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds field, (unsigned long long) boot_mem_map.map[i].size, 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds field, (unsigned long long) boot_mem_map.map[i].addr); 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (boot_mem_map.map[i].type) { 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BOOT_MEM_RAM: 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("(usable)\n"); 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BOOT_MEM_ROM_DATA: 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("(ROM data)\n"); 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BOOT_MEM_RESERVED: 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("(reserved)\n"); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("type %lu\n", boot_mem_map.map[i].type); 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 138d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu/* 139d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu * Manage initrd 140d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu */ 141d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu#ifdef CONFIG_BLK_DEV_INITRD 142d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 143a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huustatic int __init rd_start_early(char *p) 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 145a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu unsigned long start = memparse(p, &p); 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 147875d43e72b5bf22161a81de7554f88eccf8a51aeRalf Baechle#ifdef CONFIG_64BIT 148a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu /* Guess if the sign extension was forgotten by bootloader */ 149a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu if (start < XKPHYS) 150a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu start = (int)start; 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 152a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu initrd_start = start; 153a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu initrd_end += start; 154a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu return 0; 155a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu} 156a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huuearly_param("rd_start", rd_start_early); 157a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu 158a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huustatic int __init rd_size_early(char *p) 159a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu{ 160a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu initrd_end += memparse(p, &p); 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 163a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huuearly_param("rd_size", rd_size_early); 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 165a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu/* it returns the next free pfn after initrd */ 166d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huustatic unsigned long __init init_initrd(void) 167d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu{ 168a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu unsigned long end; 169d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu u32 *initrd_header; 170d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 171d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu /* 172a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu * Board specific code or command line parser should have 173a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu * already set up initrd_start and initrd_end. In these cases 174a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu * perfom sanity checks and use them if all looks good. 175d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu */ 176a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu if (initrd_start && initrd_end > initrd_start) 177a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu goto sanitize; 178a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu 179a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu /* 180a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * See if initrd has been added to the kernel image by 181a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * arch/mips/boot/addinitrd.c. In that case a header is 182a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * prepended to initrd and is made up by 8 bytes. The fisrt 183a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * word is a magic number and the second one is the size of 184a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * initrd. Initrd start must be page aligned in any cases. 185a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu */ 186a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu initrd_header = __va(PAGE_ALIGN(__pa_symbol(&_end) + 8)) - 8; 187a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu if (initrd_header[0] != 0x494E5244) 188a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu goto disable; 189a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu initrd_start = (unsigned long)(initrd_header + 2); 190a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu initrd_end = initrd_start + initrd_header[1]; 191a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu 192a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huusanitize: 193a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu if (initrd_start & ~PAGE_MASK) { 194a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu printk(KERN_ERR "initrd start must be page aligned\n"); 195a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu goto disable; 196d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu } 197a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu if (initrd_start < PAGE_OFFSET) { 198a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu printk(KERN_ERR "initrd start < PAGE_OFFSET\n"); 199a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu goto disable; 200a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu } 201a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu 202a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu /* 203a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * Sanitize initrd addresses. For example firmware 204a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * can't guess if they need to pass them through 205a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * 64-bits values if the kernel has been built in pure 206a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * 32-bit. We need also to switch from KSEG0 to XKPHYS 207a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu * addresses now, so the code can now safely use __pa(). 208a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu */ 209a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu end = __pa(initrd_end); 210a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu initrd_end = (unsigned long)__va(end); 211a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu initrd_start = (unsigned long)__va(__pa(initrd_start)); 212a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu 213a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu ROOT_DEV = Root_RAM0; 214a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu return PFN_UP(end); 215a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huudisable: 216a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu initrd_start = 0; 217a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu initrd_end = 0; 218a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu return 0; 219d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu} 220d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 221d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huustatic void __init finalize_initrd(void) 222d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu{ 223d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu unsigned long size = initrd_end - initrd_start; 224d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 225d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu if (size == 0) { 226d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu printk(KERN_INFO "Initrd not found or empty"); 227d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu goto disable; 228d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu } 229d4df6d4e7a66b7a9bd57f5dc7d80d6b55dc12dbbFranck Bui-Huu if (__pa(initrd_end) > PFN_PHYS(max_low_pfn)) { 230d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu printk("Initrd extends beyond end of memory"); 231d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu goto disable; 232d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu } 233d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 234d4df6d4e7a66b7a9bd57f5dc7d80d6b55dc12dbbFranck Bui-Huu reserve_bootmem(__pa(initrd_start), size); 235d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu initrd_below_start_ok = 1; 236d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 237d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu printk(KERN_INFO "Initial ramdisk at: 0x%lx (%lu bytes)\n", 238d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu initrd_start, size); 239d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu return; 240d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huudisable: 241d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu printk(" - disabling initrd\n"); 242d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu initrd_start = 0; 243d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu initrd_end = 0; 244d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu} 245d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 246d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu#else /* !CONFIG_BLK_DEV_INITRD */ 247d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 2489ba126cfbf505f4d5b39ed294cedd241321c7a91Ralf Baechlestatic unsigned long __init init_initrd(void) 2499ba126cfbf505f4d5b39ed294cedd241321c7a91Ralf Baechle{ 2509ba126cfbf505f4d5b39ed294cedd241321c7a91Ralf Baechle return 0; 2519ba126cfbf505f4d5b39ed294cedd241321c7a91Ralf Baechle} 2529ba126cfbf505f4d5b39ed294cedd241321c7a91Ralf Baechle 253d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu#define finalize_initrd() do {} while (0) 254d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 255d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu#endif 256d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 257b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu/* 258b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu * Initialize the bootmem allocator. It also setup initrd related data 259b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu * if needed. 260b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu */ 261d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu#ifdef CONFIG_SGI_IP27 262d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 263b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huustatic void __init bootmem_init(void) 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 265d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu init_initrd(); 266d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu finalize_initrd(); 267d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu} 268d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 269d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu#else /* !CONFIG_SGI_IP27 */ 270d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 271d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huustatic void __init bootmem_init(void) 272d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu{ 273d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu unsigned long reserved_end; 274db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu unsigned long mapstart = ~0UL; 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long bootmap_size; 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 279d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu * Init any data related to initrd. It's a nop if INITRD is 280d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu * not selected. Once that done we can determine the low bound 281d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu * of usable memory. 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 283a7837b76b6de932c31d0b7c71176ca8d1213a3ceFranck Bui-Huu reserved_end = max(init_initrd(), PFN_UP(__pa_symbol(&_end))); 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 285b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu /* 286db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu * max_low_pfn is not a number of pages. The number of pages 287db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu * of the system is given by 'max_low_pfn - min_low_pfn'. 288db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu */ 289db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu min_low_pfn = ~0UL; 290db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu max_low_pfn = 0; 291db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu 292db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu /* 293b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu * Find the highest page frame number we have available. 294b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu */ 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < boot_mem_map.nr_map; i++) { 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long start, end; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (boot_mem_map.map[i].type != BOOT_MEM_RAM) 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start = PFN_UP(boot_mem_map.map[i].addr); 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds end = PFN_DOWN(boot_mem_map.map[i].addr 303b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu + boot_mem_map.map[i].size); 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 305db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu if (end > max_low_pfn) 306db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu max_low_pfn = end; 307db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu if (start < min_low_pfn) 308db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu min_low_pfn = start; 309b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu if (end <= reserved_end) 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 311b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu if (start >= mapstart) 312b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu continue; 313b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu mapstart = max(reserved_end, start); 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 316db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu if (min_low_pfn >= max_low_pfn) 317db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu panic("Incorrect memory mapping !!!"); 3186f284a2ce7b8bc49cb8455b1763357897a899abbFranck Bui-Huu if (min_low_pfn > ARCH_PFN_OFFSET) { 319db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu printk(KERN_INFO 320db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu "Wasting %lu bytes for tracking %lu unused pages\n", 3216f284a2ce7b8bc49cb8455b1763357897a899abbFranck Bui-Huu (min_low_pfn - ARCH_PFN_OFFSET) * sizeof(struct page), 3226f284a2ce7b8bc49cb8455b1763357897a899abbFranck Bui-Huu min_low_pfn - ARCH_PFN_OFFSET); 3236f284a2ce7b8bc49cb8455b1763357897a899abbFranck Bui-Huu } else if (min_low_pfn < ARCH_PFN_OFFSET) { 3246f284a2ce7b8bc49cb8455b1763357897a899abbFranck Bui-Huu printk(KERN_INFO 3256f284a2ce7b8bc49cb8455b1763357897a899abbFranck Bui-Huu "%lu free pages won't be used\n", 3266f284a2ce7b8bc49cb8455b1763357897a899abbFranck Bui-Huu ARCH_PFN_OFFSET - min_low_pfn); 327db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu } 3286f284a2ce7b8bc49cb8455b1763357897a899abbFranck Bui-Huu min_low_pfn = ARCH_PFN_OFFSET; 329db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Determine low and high memory ranges 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 333db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu if (max_low_pfn > PFN_DOWN(HIGHMEM_START)) { 334b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu#ifdef CONFIG_HIGHMEM 335b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu highstart_pfn = PFN_DOWN(HIGHMEM_START); 336db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu highend_pfn = max_low_pfn; 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 338db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu max_low_pfn = PFN_DOWN(HIGHMEM_START); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 342b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu * Initialize the boot-time allocator with low memory only. 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 344db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu bootmap_size = init_bootmem_node(NODE_DATA(0), mapstart, 345db84dc61552ae0d198a8133d28b80c3838930ba8Franck Bui-Huu min_low_pfn, max_low_pfn); 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Register fully available low RAM pages with the bootmem allocator. 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < boot_mem_map.nr_map; i++) { 350b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu unsigned long start, end, size; 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Reserve usable memory. 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (boot_mem_map.map[i].type != BOOT_MEM_RAM) 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 358b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu start = PFN_UP(boot_mem_map.map[i].addr); 359b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu end = PFN_DOWN(boot_mem_map.map[i].addr 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds + boot_mem_map.map[i].size); 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 362b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu * We are rounding up the start address of usable memory 363b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu * and at the end of the usable range downwards. 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 365b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu if (start >= max_low_pfn) 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 367b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu if (start < reserved_end) 368b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu start = reserved_end; 369b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu if (end > max_low_pfn) 370b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu end = max_low_pfn; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 373b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu * ... finally, is the area going away? 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 375b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu if (end <= start) 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 377b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu size = end - start; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Register lowmem ranges */ 380b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu free_bootmem(PFN_PHYS(start), size << PAGE_SHIFT); 381b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu memory_present(0, start, end); 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 384b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu /* 385b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu * Reserve the bootmap memory. 386b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu */ 387b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu reserve_bootmem(PFN_PHYS(mapstart), bootmap_size); 388b6f1f0dea1469e0c956eb89399916d60dd2a3808Franck Bui-Huu 389d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu /* 390d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu * Reserve initrd memory if needed. 391d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu */ 392d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu finalize_initrd(); 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 395d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu#endif /* CONFIG_SGI_IP27 */ 396d2043ca8484d434201816267c0e23c5999df6cfdFranck Bui-Huu 3972925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle/* 3982925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * arch_mem_init - initialize memory managment subsystem 3992925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * 4002925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * o plat_mem_setup() detects the memory configuration and will record detected 4012925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * memory areas using add_memory_region. 4022925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * 4032925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * At this stage the memory configuration of the system is known to the 4042925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * kernel but generic memory managment system is still entirely uninitialized. 4052925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * 4062925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * o bootmem_init() 4072925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * o sparse_init() 4082925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * o paging_init() 4092925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * 4102925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * At this stage the bootmem allocator is ready to use. 4112925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * 4122925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * NOTE: historically plat_mem_setup did the entire platform initialization. 4132925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * This was rather impractical because it meant plat_mem_setup had to 4142925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * get away without any kind of memory allocator. To keep old code from 4152925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * breaking plat_setup was just renamed to plat_setup and a second platform 4162925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle * initialization hook for anything else was introduced. 4172925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle */ 4182925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle 419a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huustatic int usermem __initdata = 0; 420a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu 421a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huustatic int __init early_parse_mem(char *p) 422a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu{ 423a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu unsigned long start, size; 424a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu 425a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu /* 426a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu * If a user specifies memory size, we 427a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu * blow away any automatically generated 428a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu * size. 429a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu */ 430a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu if (usermem == 0) { 431a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu boot_mem_map.nr_map = 0; 432a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu usermem = 1; 433a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu } 434a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu start = 0; 435a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu size = memparse(p, &p); 436a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu if (*p == '@') 437a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu start = memparse(p + 1, &p); 438a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu 439a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu add_memory_region(start, size, BOOT_MEM_RAM); 440a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu return 0; 441a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu} 442a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huuearly_param("mem", early_parse_mem); 4432925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle 4442925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechlestatic void __init arch_mem_init(char **cmdline_p) 4452925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle{ 446a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu extern void plat_mem_setup(void); 447a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu 4482925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle /* call board setup routine */ 4492925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle plat_mem_setup(); 4502925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle 451a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu printk("Determined physical RAM map:\n"); 452a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu print_memory_map(); 453a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu 4542925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle strlcpy(command_line, arcs_cmdline, sizeof(command_line)); 45543cd34645d3bf35cbaa68f28b85d12d0b9e08ab9Alon Bar-Lev strlcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 4562925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle 4572925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle *cmdline_p = command_line; 4582925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle 459a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu parse_early_param(); 460a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu 461a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu if (usermem) { 462a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu printk("User-defined physical RAM map:\n"); 463a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu print_memory_map(); 464a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu } 465a09fc446fb6d541281d9559fe7215d7c0d3cc9ceFranck Bui-Huu 4662925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle bootmem_init(); 4672925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle sparse_init(); 4682925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle paging_init(); 4692925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle} 4702925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle 4718df32c636e785069ba7d223ceb9b72c182902295Franck Bui-Huustatic void __init resource_init(void) 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4756adb5fe7020e8f99d27da932157ea27325df9263Ralf Baechle if (UNCAC_BASE != IO_BASE) 4766adb5fe7020e8f99d27da932157ea27325df9263Ralf Baechle return; 4776adb5fe7020e8f99d27da932157ea27325df9263Ralf Baechle 478f5bffe3a9bcd6e5319b5fd3a8109625f8638425aFranck Bui-Huu code_resource.start = __pa_symbol(&_text); 479f5bffe3a9bcd6e5319b5fd3a8109625f8638425aFranck Bui-Huu code_resource.end = __pa_symbol(&_etext) - 1; 480f5bffe3a9bcd6e5319b5fd3a8109625f8638425aFranck Bui-Huu data_resource.start = __pa_symbol(&_etext); 481f5bffe3a9bcd6e5319b5fd3a8109625f8638425aFranck Bui-Huu data_resource.end = __pa_symbol(&_edata) - 1; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Request address space for all standard RAM. 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < boot_mem_map.nr_map; i++) { 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct resource *res; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long start, end; 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds start = boot_mem_map.map[i].addr; 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds end = boot_mem_map.map[i].addr + boot_mem_map.map[i].size - 1; 4921c6fd44d7ed3d105b2eaa29d72b415ca51e40d32Franck Bui-Huu if (start >= HIGHMEM_START) 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds continue; 4941c6fd44d7ed3d105b2eaa29d72b415ca51e40d32Franck Bui-Huu if (end >= HIGHMEM_START) 4951c6fd44d7ed3d105b2eaa29d72b415ca51e40d32Franck Bui-Huu end = HIGHMEM_START - 1; 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res = alloc_bootmem(sizeof(struct resource)); 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (boot_mem_map.map[i].type) { 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BOOT_MEM_RAM: 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BOOT_MEM_ROM_DATA: 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res->name = "System RAM"; 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case BOOT_MEM_RESERVED: 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res->name = "reserved"; 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res->start = start; 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res->end = end; 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds res->flags = IORESOURCE_MEM | IORESOURCE_BUSY; 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds request_resource(&iomem_resource, res); 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * We don't know which RAM region contains kernel data, 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * so we try it repeatedly and let the resource manager 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * test it. 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds request_resource(res, &code_resource); 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds request_resource(res, &data_resource); 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init setup_arch(char **cmdline_p) 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_probe(); 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds prom_init(); 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu_report(); 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_VT) 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if defined(CONFIG_VGA_CONSOLE) 532e0daad449c5195fa4552c60392eeee4e5c58d31cRalf Baechle conswitchp = &vga_con; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#elif defined(CONFIG_DUMMY_CONSOLE) 534e0daad449c5195fa4552c60392eeee4e5c58d31cRalf Baechle conswitchp = &dummy_con; 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5382925aba4223f4532e85f0c6f64584b3e0b2849c3Ralf Baechle arch_mem_init(cmdline_p); 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds resource_init(); 5419b6695a8adfe0916e81ddd810a5b9db3eb8b0e46Ralf Baechle#ifdef CONFIG_SMP 5429b6695a8adfe0916e81ddd810a5b9db3eb8b0e46Ralf Baechle plat_smp_setup(); 5439b6695a8adfe0916e81ddd810a5b9db3eb8b0e46Ralf Baechle#endif 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsint __init fpu_disable(char *s) 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 548f088fc84f94c1a36943e28ad704a9a740a35f877Ralf Baechle int i; 549f088fc84f94c1a36943e28ad704a9a740a35f877Ralf Baechle 550f088fc84f94c1a36943e28ad704a9a740a35f877Ralf Baechle for (i = 0; i < NR_CPUS; i++) 551f088fc84f94c1a36943e28ad704a9a740a35f877Ralf Baechle cpu_data[i].options &= ~MIPS_CPU_FPU; 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 1; 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds__setup("nofpu", fpu_disable); 557e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechle 558e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechleint __init dsp_disable(char *s) 559e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechle{ 560e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechle cpu_data[0].ases &= ~MIPS_ASE_DSP; 561e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechle 562e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechle return 1; 563e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechle} 564e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechle 565e50c0a8fa60da9ac0e0a70caa8a3a803815c1f2fRalf Baechle__setup("nodsp", dsp_disable); 56669a6c312e5ebb2e929ceb67e6246e2d9314f1d29Atsushi Nemoto 56769a6c312e5ebb2e929ceb67e6246e2d9314f1d29Atsushi Nemotounsigned long kernelsp[NR_CPUS]; 56869a6c312e5ebb2e929ceb67e6246e2d9314f1d29Atsushi Nemotounsigned long fw_arg0, fw_arg1, fw_arg2, fw_arg3; 569