#include <linux/root_dev.h>
#include <linux/highmem.h>
#include <linux/console.h>
+#include <linux/mmzone.h>
#include <asm/addrspace.h>
#include <asm/bootinfo.h>
+#include <asm/cache.h>
#include <asm/cpu.h>
#include <asm/sections.h>
+#include <asm/setup.h>
#include <asm/system.h>
-struct cpuinfo_mips cpu_data[NR_CPUS];
+struct cpuinfo_mips cpu_data[NR_CPUS] __read_mostly;
EXPORT_SYMBOL(cpu_data);
EXPORT_SYMBOL(PCI_DMA_BUS_IS_PHYS);
-extern void * __rd_start, * __rd_end;
-
/*
* Setup information
*
* These are initialized so they are in the .data section
*/
-unsigned long mips_machtype = MACH_UNKNOWN;
-unsigned long mips_machgroup = MACH_GROUP_UNKNOWN;
+unsigned long mips_machtype __read_mostly = MACH_UNKNOWN;
+unsigned long mips_machgroup __read_mostly = MACH_GROUP_UNKNOWN;
EXPORT_SYMBOL(mips_machtype);
EXPORT_SYMBOL(mips_machgroup);
struct boot_mem_map boot_mem_map;
static char command_line[CL_SIZE];
- char saved_command_line[CL_SIZE];
char arcs_cmdline[CL_SIZE]=CONFIG_CMDLINE;
/*
* mips_io_port_base is the begin of the address space to which x86 style
* I/O ports are mapped.
*/
-const unsigned long mips_io_port_base = -1;
+const unsigned long mips_io_port_base __read_mostly = -1;
EXPORT_SYMBOL(mips_io_port_base);
/*
unsigned long isa_slot_offset;
EXPORT_SYMBOL(isa_slot_offset);
-static struct resource code_resource = { "Kernel code" };
-static struct resource data_resource = { "Kernel data" };
+static struct resource code_resource = { .name = "Kernel code", };
+static struct resource data_resource = { .name = "Kernel data", };
void __init add_memory_region(phys_t start, phys_t size, long type)
{
}
}
+static inline int parse_rd_cmdline(unsigned long* rd_start, unsigned long* rd_end)
+{
+ /*
+ * "rd_start=0xNNNNNNNN" defines the memory address of an initrd
+ * "rd_size=0xNN" it's size
+ */
+ unsigned long start = 0;
+ unsigned long size = 0;
+ unsigned long end;
+ char cmd_line[CL_SIZE];
+ char *start_str;
+ char *size_str;
+ char *tmp;
+
+ strcpy(cmd_line, command_line);
+ *command_line = 0;
+ tmp = cmd_line;
+ /* Ignore "rd_start=" strings in other parameters. */
+ start_str = strstr(cmd_line, "rd_start=");
+ if (start_str && start_str != cmd_line && *(start_str - 1) != ' ')
+ start_str = strstr(start_str, " rd_start=");
+ while (start_str) {
+ if (start_str != cmd_line)
+ strncat(command_line, tmp, start_str - tmp);
+ start = memparse(start_str + 9, &start_str);
+ tmp = start_str + 1;
+ start_str = strstr(start_str, " rd_start=");
+ }
+ if (*tmp)
+ strcat(command_line, tmp);
+
+ strcpy(cmd_line, command_line);
+ *command_line = 0;
+ tmp = cmd_line;
+ /* Ignore "rd_size" strings in other parameters. */
+ size_str = strstr(cmd_line, "rd_size=");
+ if (size_str && size_str != cmd_line && *(size_str - 1) != ' ')
+ size_str = strstr(size_str, " rd_size=");
+ while (size_str) {
+ if (size_str != cmd_line)
+ strncat(command_line, tmp, size_str - tmp);
+ size = memparse(size_str + 8, &size_str);
+ tmp = size_str + 1;
+ size_str = strstr(size_str, " rd_size=");
+ }
+ if (*tmp)
+ strcat(command_line, tmp);
+
+#ifdef CONFIG_64BIT
+ /* HACK: Guess if the sign extension was forgotten */
+ if (start > 0x0000000080000000 && start < 0x00000000ffffffff)
+ start |= 0xffffffff00000000;
+#endif
+
+ end = start + size;
+ if (start && end) {
+ *rd_start = start;
+ *rd_end = end;
+ return 1;
+ }
+ return 0;
+}
#define PFN_UP(x) (((x) + PAGE_SIZE - 1) >> PAGE_SHIFT)
#define PFN_DOWN(x) ((x) >> PAGE_SHIFT)
static inline void bootmem_init(void)
{
unsigned long start_pfn;
+ unsigned long reserved_end = (unsigned long)&_end;
#ifndef CONFIG_SGI_IP27
- unsigned long bootmap_size, max_low_pfn, first_usable_pfn;
+ unsigned long first_usable_pfn;
+ unsigned long bootmap_size;
int i;
#endif
#ifdef CONFIG_BLK_DEV_INITRD
- unsigned long tmp;
- unsigned long *initrd_header;
-
- tmp = (((unsigned long)&_end + PAGE_SIZE-1) & PAGE_MASK) - 8;
- if (tmp < (unsigned long)&_end)
- tmp += PAGE_SIZE;
- initrd_header = (unsigned long *)tmp;
- if (initrd_header[0] == 0x494E5244) {
- initrd_start = (unsigned long)&initrd_header[2];
- initrd_end = initrd_start + initrd_header[1];
+ int initrd_reserve_bootmem = 0;
+
+ /* Board specific code should have set up initrd_start and initrd_end */
+ ROOT_DEV = Root_RAM0;
+ if (parse_rd_cmdline(&initrd_start, &initrd_end)) {
+ reserved_end = max(reserved_end, initrd_end);
+ initrd_reserve_bootmem = 1;
+ } else {
+ unsigned long tmp;
+ u32 *initrd_header;
+
+ tmp = ((reserved_end + PAGE_SIZE-1) & PAGE_MASK) - sizeof(u32) * 2;
+ if (tmp < reserved_end)
+ tmp += PAGE_SIZE;
+ initrd_header = (u32 *)tmp;
+ if (initrd_header[0] == 0x494E5244) {
+ initrd_start = (unsigned long)&initrd_header[2];
+ initrd_end = initrd_start + initrd_header[1];
+ reserved_end = max(reserved_end, initrd_end);
+ initrd_reserve_bootmem = 1;
+ }
}
- start_pfn = PFN_UP(CPHYSADDR((&_end)+(initrd_end - initrd_start) + PAGE_SIZE));
-#else
+#endif /* CONFIG_BLK_DEV_INITRD */
+
/*
* Partially used pages are not usable - thus
* we are rounding upwards.
*/
- start_pfn = PFN_UP(CPHYSADDR(&_end));
-#endif /* CONFIG_BLK_DEV_INITRD */
+ start_pfn = PFN_UP(CPHYSADDR(reserved_end));
#ifndef CONFIG_SGI_IP27
/* Find the highest page frame number we have available. */
}
#endif
+ memory_present(0, first_usable_pfn, max_low_pfn);
+
/* Initialize the boot-time allocator with low memory only. */
bootmap_size = init_bootmem(first_usable_pfn, max_low_pfn);
/* Reserve the bootmap memory. */
reserve_bootmem(PFN_PHYS(first_usable_pfn), bootmap_size);
-#endif
+#endif /* CONFIG_SGI_IP27 */
#ifdef CONFIG_BLK_DEV_INITRD
- /* Board specific code should have set up initrd_start and initrd_end */
- ROOT_DEV = Root_RAM0;
- if (&__rd_start != &__rd_end) {
- initrd_start = (unsigned long)&__rd_start;
- initrd_end = (unsigned long)&__rd_end;
- }
initrd_below_start_ok = 1;
if (initrd_start) {
unsigned long initrd_size = ((unsigned char *)initrd_end) - ((unsigned char *)initrd_start);
printk("Initial ramdisk at: 0x%p (%lu bytes)\n",
- (void *)initrd_start,
- initrd_size);
+ (void *)initrd_start, initrd_size);
if (CPHYSADDR(initrd_end) > PFN_PHYS(max_low_pfn)) {
printk("initrd extends beyond end of memory "
"(0x%0*Lx > 0x%0*Lx)\ndisabling initrd\n",
- sizeof(long) * 2, CPHYSADDR(initrd_end),
- sizeof(long) * 2, PFN_PHYS(max_low_pfn));
+ sizeof(long) * 2,
+ (unsigned long long)CPHYSADDR(initrd_end),
+ sizeof(long) * 2,
+ (unsigned long long)PFN_PHYS(max_low_pfn));
initrd_start = initrd_end = 0;
+ initrd_reserve_bootmem = 0;
}
+
+ if (initrd_reserve_bootmem)
+ reserve_bootmem(CPHYSADDR(initrd_start), initrd_size);
}
#endif /* CONFIG_BLK_DEV_INITRD */
}
{
int i;
+#if defined(CONFIG_64BIT) && !defined(CONFIG_BUILD_ELF64)
+ /*
+ * The 64bit code in 32bit object format trick can't represent
+ * 64bit wide relocations for linker script symbols.
+ */
+ code_resource.start = CPHYSADDR(&_text);
+ code_resource.end = CPHYSADDR(&_etext) - 1;
+ data_resource.start = CPHYSADDR(&_etext);
+ data_resource.end = CPHYSADDR(&_edata) - 1;
+#else
code_resource.start = virt_to_phys(&_text);
code_resource.end = virt_to_phys(&_etext) - 1;
data_resource.start = virt_to_phys(&_etext);
data_resource.end = virt_to_phys(&_edata) - 1;
+#endif
/*
* Request address space for all standard RAM.
#undef MAXMEM
#undef MAXMEM_PFN
-static int __initdata earlyinit_debug;
-
-static int __init earlyinit_debug_setup(char *str)
-{
- earlyinit_debug = 1;
- return 1;
-}
-__setup("earlyinit_debug", earlyinit_debug_setup);
-
-extern initcall_t __earlyinitcall_start, __earlyinitcall_end;
-
-static void __init do_earlyinitcalls(void)
-{
- initcall_t *call, *start, *end;
-
- start = &__earlyinitcall_start;
- end = &__earlyinitcall_end;
-
- for (call = start; call < end; call++) {
- if (earlyinit_debug)
- printk("calling earlyinitcall 0x%p\n", *call);
-
- (*call)();
- }
-}
+extern void plat_setup(void);
void __init setup_arch(char **cmdline_p)
{
prom_init();
cpu_report();
-#ifdef CONFIG_MIPS32
- /* Disable coprocessors and set FPU for 16/32 FPR register model */
- clear_c0_status(ST0_CU1|ST0_CU2|ST0_CU3|ST0_KX|ST0_SX|ST0_FR);
- set_c0_status(ST0_CU0);
-#endif
-#ifdef CONFIG_MIPS64
- /*
- * On IP27, I am seeing the TS bit set when the kernel is loaded.
- * Maybe because the kernel is in ckseg0 and not xkphys? Clear it
- * anyway ...
- */
- clear_c0_status(ST0_BEV|ST0_TS|ST0_CU1|ST0_CU2|ST0_CU3);
- set_c0_status(ST0_CU0|ST0_KX|ST0_SX|ST0_FR);
-#endif
-
#if defined(CONFIG_VT)
#if defined(CONFIG_VGA_CONSOLE)
conswitchp = &vga_con;
#endif
/* call board setup routine */
- do_earlyinitcalls();
+ plat_setup();
strlcpy(command_line, arcs_cmdline, sizeof(command_line));
- strlcpy(saved_command_line, command_line, sizeof(saved_command_line));
+ strlcpy(saved_command_line, command_line, COMMAND_LINE_SIZE);
*cmdline_p = command_line;
parse_cmdline_early();
bootmem_init();
+ sparse_init();
paging_init();
resource_init();
+#ifdef CONFIG_SMP
+ plat_smp_setup();
+#endif
}
int __init fpu_disable(char *s)
}
__setup("nofpu", fpu_disable);
+
+int __init dsp_disable(char *s)
+{
+ cpu_data[0].ases &= ~MIPS_ASE_DSP;
+
+ return 1;
+}
+
+__setup("nodsp", dsp_disable);