1 /* !! 1 /* $Id: setup.c,v 1.126 2001/11/13 00:49:27 davem Exp $ 2 * Nios2-specific parts of system setup !! 2 * linux/arch/sparc/kernel/setup.c 3 * 3 * 4 * Copyright (C) 2010 Tobias Klauser <tklauser !! 4 * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) 5 * Copyright (C) 2004 Microtronix Datacom Ltd. !! 5 * Copyright (C) 2000 Anton Blanchard (anton@samba.org) 6 * Copyright (C) 2001 Vic Phillips <vic@microt << 7 * << 8 * This file is subject to the terms and condi << 9 * License. See the file "COPYING" in the main << 10 * for more details. << 11 */ 6 */ 12 7 13 #include <linux/export.h> !! 8 #include <linux/errno.h> >> 9 #include <linux/sched.h> 14 #include <linux/kernel.h> 10 #include <linux/kernel.h> 15 #include <linux/mm.h> 11 #include <linux/mm.h> 16 #include <linux/sched.h> !! 12 #include <linux/stddef.h> 17 #include <linux/sched/task.h> !! 13 #include <linux/unistd.h> 18 #include <linux/console.h> !! 14 #include <linux/ptrace.h> 19 #include <linux/memblock.h> !! 15 #include <linux/slab.h> 20 #include <linux/initrd.h> 16 #include <linux/initrd.h> 21 #include <linux/of_fdt.h> !! 17 #include <asm/smp.h> >> 18 #include <linux/user.h> >> 19 #include <linux/a.out.h> >> 20 #include <linux/tty.h> >> 21 #include <linux/delay.h> >> 22 #include <linux/config.h> >> 23 #include <linux/fs.h> >> 24 #include <linux/seq_file.h> >> 25 #include <linux/kdev_t.h> >> 26 #include <linux/major.h> >> 27 #include <linux/string.h> >> 28 #include <linux/init.h> >> 29 #include <linux/interrupt.h> >> 30 #include <linux/console.h> >> 31 #include <linux/spinlock.h> >> 32 #include <linux/root_dev.h> >> 33 >> 34 #include <asm/segment.h> >> 35 #include <asm/system.h> >> 36 #include <asm/io.h> >> 37 #include <asm/processor.h> >> 38 #include <asm/oplib.h> >> 39 #include <asm/page.h> >> 40 #include <asm/pgtable.h> >> 41 #include <asm/traps.h> >> 42 #include <asm/vaddrs.h> >> 43 #include <asm/kdebug.h> >> 44 #include <asm/mbus.h> >> 45 #include <asm/idprom.h> >> 46 #include <asm/hardirq.h> >> 47 #include <asm/machines.h> >> 48 >> 49 struct screen_info screen_info = { >> 50 0, 0, /* orig-x, orig-y */ >> 51 0, /* unused */ >> 52 0, /* orig-video-page */ >> 53 0, /* orig-video-mode */ >> 54 128, /* orig-video-cols */ >> 55 0,0,0, /* ega_ax, ega_bx, ega_cx */ >> 56 54, /* orig-video-lines */ >> 57 0, /* orig-video-isVGA */ >> 58 16 /* orig-video-points */ >> 59 }; >> 60 >> 61 /* Typing sync at the prom prompt calls the function pointed to by >> 62 * romvec->pv_synchook which I set to the following function. >> 63 * This should sync all filesystems and return, for now it just >> 64 * prints out pretty messages and returns. >> 65 */ >> 66 >> 67 extern unsigned long trapbase; >> 68 void (*prom_palette)(int); >> 69 asmlinkage void sys_sync(void); /* it's really int */ >> 70 >> 71 /* Pretty sick eh? */ >> 72 void prom_sync_me(void) >> 73 { >> 74 unsigned long prom_tbr, flags; >> 75 >> 76 /* XXX Badly broken. FIX! - Anton */ >> 77 save_and_cli(flags); >> 78 __asm__ __volatile__("rd %%tbr, %0\n\t" : "=r" (prom_tbr)); >> 79 __asm__ __volatile__("wr %0, 0x0, %%tbr\n\t" >> 80 "nop\n\t" >> 81 "nop\n\t" >> 82 "nop\n\t" : : "r" (&trapbase)); >> 83 >> 84 if (prom_palette) >> 85 prom_palette(1); >> 86 prom_printf("PROM SYNC COMMAND...\n"); >> 87 show_free_areas(); >> 88 if(current->pid != 0) { >> 89 sti(); >> 90 sys_sync(); >> 91 cli(); >> 92 } >> 93 prom_printf("Returning to prom\n"); 22 94 23 #include <asm/mmu_context.h> !! 95 __asm__ __volatile__("wr %0, 0x0, %%tbr\n\t" 24 #include <asm/sections.h> !! 96 "nop\n\t" 25 #include <asm/setup.h> !! 97 "nop\n\t" 26 #include <asm/cpuinfo.h> !! 98 "nop\n\t" : : "r" (prom_tbr)); >> 99 restore_flags(flags); >> 100 >> 101 return; >> 102 } 27 103 28 unsigned long memory_start; !! 104 unsigned int boot_flags __initdata = 0; 29 EXPORT_SYMBOL(memory_start); !! 105 #define BOOTME_DEBUG 0x1 >> 106 #define BOOTME_SINGLE 0x2 30 107 31 unsigned long memory_end; !! 108 static int console_fb __initdata = 0; 32 EXPORT_SYMBOL(memory_end); << 33 109 34 static struct pt_regs fake_regs = { 0, 0, 0, 0 !! 110 /* Exported for mm/init.c:paging_init. */ 35 0, 0, !! 111 unsigned long cmdline_memory_size __initdata = 0; 36 0}; << 37 112 38 /* Copy a short hook instruction sequence to t !! 113 static void 39 static inline void copy_exception_handler(unsi !! 114 prom_console_write(struct console *con, const char *s, unsigned n) 40 { 115 { 41 unsigned int start = (unsigned int) ex !! 116 prom_write(s, n); 42 volatile unsigned int tmp = 0; !! 117 } 43 118 44 if (start == addr) { !! 119 static struct console prom_debug_console = { 45 /* The CPU exception address a !! 120 .name = "debug", 46 return; !! 121 .write = prom_console_write, 47 } !! 122 .flags = CON_PRINTBUFFER, >> 123 .index = -1, >> 124 }; 48 125 49 __asm__ __volatile__ ( !! 126 int obp_system_intr(void) 50 "ldw %2,0(%0)\n" !! 127 { 51 "stw %2,0(%1)\n" !! 128 if (boot_flags & BOOTME_DEBUG) { 52 "ldw %2,4(%0)\n" !! 129 printk("OBP: system interrupted\n"); 53 "stw %2,4(%1)\n" !! 130 prom_halt(); 54 "ldw %2,8(%0)\n" !! 131 return 1; 55 "stw %2,8(%1)\n" !! 132 } 56 "flushd 0(%1)\n" !! 133 return 0; 57 "flushd 4(%1)\n" << 58 "flushd 8(%1)\n" << 59 "flushi %1\n" << 60 "addi %1,%1,4\n" << 61 "flushi %1\n" << 62 "addi %1,%1,4\n" << 63 "flushi %1\n" << 64 "flushp\n" << 65 : /* no output registers */ << 66 : "r" (start), "r" (addr), "r" << 67 : "memory" << 68 ); << 69 } << 70 << 71 /* Copy the fast TLB miss handler */ << 72 static inline void copy_fast_tlb_miss_handler( << 73 { << 74 unsigned int start = (unsigned int) fa << 75 unsigned int end = (unsigned int) fast << 76 volatile unsigned int tmp = 0; << 77 << 78 __asm__ __volatile__ ( << 79 "1:\n" << 80 " ldw %3,0(%0)\n" << 81 " stw %3,0(%1)\n" << 82 " flushd 0(%1)\n" << 83 " flushi %1\n" << 84 " flushp\n" << 85 " addi %0,%0,4\n" << 86 " addi %1,%1,4\n" << 87 " bne %0,%2,1b\n" << 88 : /* no output registers */ << 89 : "r" (start), "r" (addr), "r" << 90 : "memory" << 91 ); << 92 } 134 } 93 135 94 /* !! 136 /* 95 * save args passed from u-boot, called from h !! 137 * Process kernel command line switches that are specific to the 96 * !! 138 * SPARC or that require special low-level processing. 97 * @r4: NIOS magic << 98 * @r5: initrd start << 99 * @r6: initrd end or fdt << 100 * @r7: kernel command line << 101 */ 139 */ 102 asmlinkage void __init nios2_boot_init(unsigne !! 140 static void __init process_switch(char c) 103 unsigne << 104 { 141 { 105 unsigned dtb_passed = 0; !! 142 switch (c) { 106 char cmdline_passed[COMMAND_LINE_SIZE] !! 143 case 'd': >> 144 boot_flags |= BOOTME_DEBUG; >> 145 break; >> 146 case 's': >> 147 boot_flags |= BOOTME_SINGLE; >> 148 break; >> 149 case 'h': >> 150 prom_printf("boot_flags_init: Halt!\n"); >> 151 prom_halt(); >> 152 break; >> 153 case 'p': >> 154 /* Use PROM debug console. */ >> 155 register_console(&prom_debug_console); >> 156 break; >> 157 default: >> 158 printk("Unknown boot switch (-%c)\n", c); >> 159 break; >> 160 } >> 161 } 107 162 108 #if defined(CONFIG_NIOS2_PASS_CMDLINE) !! 163 static void __init boot_flags_init(char *commands) 109 if (r4 == 0x534f494e) { /* r4 is magic !! 164 { 110 #if defined(CONFIG_BLK_DEV_INITRD) !! 165 while (*commands) { 111 if (r5) { /* initramfs */ !! 166 /* Move to the start of the next "argument". */ 112 initrd_start = r5; !! 167 while (*commands && *commands == ' ') 113 initrd_end = r6; !! 168 commands++; >> 169 >> 170 /* Process any command switches, otherwise skip it. */ >> 171 if (*commands == '\0') >> 172 break; >> 173 if (*commands == '-') { >> 174 commands++; >> 175 while (*commands && *commands != ' ') >> 176 process_switch(*commands++); >> 177 } else { >> 178 if (!strncmp(commands, "console=", 8)) { >> 179 commands += 8; >> 180 #if defined(CONFIG_PROM_CONSOLE) >> 181 if (!strncmp (commands, "prom", 4)) { >> 182 char *p; >> 183 >> 184 for (p = commands - 8; *p && *p != ' '; p++) >> 185 *p = ' '; >> 186 conswitchp = &prom_con; >> 187 console_fb = 1; >> 188 } >> 189 #endif >> 190 } else if (!strncmp(commands, "mem=", 4)) { >> 191 /* >> 192 * "mem=XXX[kKmM] overrides the PROM-reported >> 193 * memory size. >> 194 */ >> 195 cmdline_memory_size = simple_strtoul(commands + 4, >> 196 &commands, 0); >> 197 if (*commands == 'K' || *commands == 'k') { >> 198 cmdline_memory_size <<= 10; >> 199 commands++; >> 200 } else if (*commands=='M' || *commands=='m') { >> 201 cmdline_memory_size <<= 20; >> 202 commands++; >> 203 } >> 204 } >> 205 while (*commands && *commands != ' ') >> 206 commands++; 114 } 207 } 115 #endif /* CONFIG_BLK_DEV_INITRD */ !! 208 } 116 dtb_passed = r6; !! 209 } >> 210 >> 211 /* This routine will in the future do all the nasty prom stuff >> 212 * to probe for the mmu type and its parameters, etc. This will >> 213 * also be where SMP things happen plus the Sparc specific memory >> 214 * physical memory probe as on the alpha. >> 215 */ >> 216 >> 217 extern int prom_probe_memory(void); >> 218 extern void sun4c_probe_vac(void); >> 219 extern char cputypval; >> 220 extern unsigned long start, end; >> 221 extern void panic_setup(char *, int *); >> 222 extern void srmmu_end_memory(unsigned long, unsigned long *); >> 223 extern void sun_serial_setup(void); >> 224 >> 225 extern unsigned short root_flags; >> 226 extern unsigned short root_dev; >> 227 extern unsigned short ram_flags; >> 228 #define RAMDISK_IMAGE_START_MASK 0x07FF >> 229 #define RAMDISK_PROMPT_FLAG 0x8000 >> 230 #define RAMDISK_LOAD_FLAG 0x4000 >> 231 >> 232 extern int root_mountflags; >> 233 >> 234 char saved_command_line[256]; >> 235 char reboot_command[256]; >> 236 enum sparc_cpu sparc_cpu_model; >> 237 >> 238 struct tt_entry *sparc_ttable; >> 239 >> 240 struct pt_regs fake_swapper_regs; >> 241 >> 242 extern void paging_init(void); >> 243 >> 244 void __init setup_arch(char **cmdline_p) >> 245 { >> 246 int i; >> 247 unsigned long highest_paddr; >> 248 >> 249 sparc_ttable = (struct tt_entry *) &start; 117 250 118 if (r7) !! 251 /* Initialize PROM console and command line. */ 119 strscpy(cmdline_passed !! 252 *cmdline_p = prom_getbootargs(); >> 253 strcpy(saved_command_line, *cmdline_p); >> 254 >> 255 /* Set sparc_cpu_model */ >> 256 sparc_cpu_model = sun_unknown; >> 257 if(!strcmp(&cputypval,"sun4 ")) { sparc_cpu_model=sun4; } >> 258 if(!strcmp(&cputypval,"sun4c")) { sparc_cpu_model=sun4c; } >> 259 if(!strcmp(&cputypval,"sun4m")) { sparc_cpu_model=sun4m; } >> 260 if(!strcmp(&cputypval,"sun4s")) { sparc_cpu_model=sun4m; } /* CP-1200 with PROM 2.30 -E */ >> 261 if(!strcmp(&cputypval,"sun4d")) { sparc_cpu_model=sun4d; } >> 262 if(!strcmp(&cputypval,"sun4e")) { sparc_cpu_model=sun4e; } >> 263 if(!strcmp(&cputypval,"sun4u")) { sparc_cpu_model=sun4u; } >> 264 >> 265 #ifdef CONFIG_SUN4 >> 266 if (sparc_cpu_model != sun4) { >> 267 prom_printf("This kernel is for Sun4 architecture only.\n"); >> 268 prom_halt(); 120 } 269 } 121 #endif 270 #endif >> 271 printk("ARCH: "); >> 272 switch(sparc_cpu_model) { >> 273 case sun4: >> 274 printk("SUN4\n"); >> 275 break; >> 276 case sun4c: >> 277 printk("SUN4C\n"); >> 278 break; >> 279 case sun4m: >> 280 printk("SUN4M\n"); >> 281 break; >> 282 case sun4d: >> 283 printk("SUN4D\n"); >> 284 break; >> 285 case sun4e: >> 286 printk("SUN4E\n"); >> 287 break; >> 288 case sun4u: >> 289 printk("SUN4U\n"); >> 290 break; >> 291 default: >> 292 printk("UNKNOWN!\n"); >> 293 break; >> 294 }; >> 295 >> 296 #ifdef CONFIG_DUMMY_CONSOLE >> 297 conswitchp = &dummy_con; >> 298 #elif defined(CONFIG_PROM_CONSOLE) >> 299 conswitchp = &prom_con; >> 300 #endif >> 301 boot_flags_init(*cmdline_p); 122 302 123 early_init_devtree((void *)dtb_passed) !! 303 idprom_init(); >> 304 if (ARCH_SUN4C_SUN4) >> 305 sun4c_probe_vac(); >> 306 load_mmu(); >> 307 (void) prom_probe_memory(); >> 308 >> 309 phys_base = 0xffffffffUL; >> 310 highest_paddr = 0UL; >> 311 for (i = 0; sp_banks[i].num_bytes != 0; i++) { >> 312 unsigned long top; >> 313 >> 314 if (sp_banks[i].base_addr < phys_base) >> 315 phys_base = sp_banks[i].base_addr; >> 316 top = sp_banks[i].base_addr + >> 317 sp_banks[i].num_bytes; >> 318 if (highest_paddr < top) >> 319 highest_paddr = top; >> 320 } 124 321 125 #ifndef CONFIG_CMDLINE_FORCE !! 322 if (!root_flags) 126 if (cmdline_passed[0]) !! 323 root_mountflags &= ~MS_RDONLY; 127 strscpy(boot_command_line, cmd !! 324 ROOT_DEV = old_decode_dev(root_dev); 128 #ifdef CONFIG_NIOS2_CMDLINE_IGNORE_DTB !! 325 #ifdef CONFIG_BLK_DEV_INITRD 129 else !! 326 rd_image_start = ram_flags & RAMDISK_IMAGE_START_MASK; 130 strscpy(boot_command_line, CON !! 327 rd_prompt = ((ram_flags & RAMDISK_PROMPT_FLAG) != 0); >> 328 rd_doload = ((ram_flags & RAMDISK_LOAD_FLAG) != 0); 131 #endif 329 #endif >> 330 >> 331 prom_setsync(prom_sync_me); >> 332 >> 333 #ifndef CONFIG_SERIAL_CONSOLE /* Not CONFIG_SERIAL_SUNCORE: to be gone. */ >> 334 serial_console = 0; >> 335 #else >> 336 if (console_fb != 0) { >> 337 serial_console = 0; >> 338 } else { >> 339 int idev = prom_query_input_device(); >> 340 int odev = prom_query_output_device(); >> 341 if (idev == PROMDEV_IKBD && odev == PROMDEV_OSCREEN) { >> 342 serial_console = 0; >> 343 } else if (idev == PROMDEV_ITTYA && odev == PROMDEV_OTTYA) { >> 344 serial_console = 1; >> 345 } else if (idev == PROMDEV_ITTYB && odev == PROMDEV_OTTYB) { >> 346 serial_console = 2; >> 347 } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OTTYA) { >> 348 prom_printf("MrCoffee ttya\n"); >> 349 serial_console = 1; >> 350 } else if (idev == PROMDEV_I_UNK && odev == PROMDEV_OSCREEN) { >> 351 serial_console = 0; >> 352 prom_printf("MrCoffee keyboard\n"); >> 353 } else { >> 354 prom_printf("Confusing console (idev %d, odev %d)\n", >> 355 idev, odev); >> 356 serial_console = 1; >> 357 } >> 358 } 132 #endif 359 #endif 133 360 134 parse_early_param(); !! 361 if((boot_flags&BOOTME_DEBUG) && (linux_dbvec!=0) && 135 } !! 362 ((*(short *)linux_dbvec) != -1)) { >> 363 printk("Booted under KADB. Syncing trap table.\n"); >> 364 (*(linux_dbvec->teach_debugger))(); >> 365 } 136 366 137 static void __init find_limits(unsigned long * !! 367 init_mm.context = (unsigned long) NO_CONTEXT; 138 unsigned long * !! 368 init_task.thread.kregs = &fake_swapper_regs; 139 { !! 369 140 *max_low = PFN_DOWN(memblock_get_curre !! 370 paging_init(); 141 *min = PFN_UP(memblock_start_of_DRAM() << 142 *max_high = PFN_DOWN(memblock_end_of_D << 143 } 371 } 144 372 145 void __init setup_arch(char **cmdline_p) !! 373 asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on) 146 { 374 { 147 console_verbose(); !! 375 return -EIO; 148 !! 376 } 149 memory_start = memblock_start_of_DRAM( << 150 memory_end = memblock_end_of_DRAM(); << 151 377 152 setup_initial_init_mm(_stext, _etext, !! 378 extern char *sparc_cpu_type[]; 153 init_task.thread.kregs = &fake_regs; !! 379 extern char *sparc_fpu_type[]; 154 380 155 /* Keep a copy of command line */ !! 381 static int show_cpuinfo(struct seq_file *m, void *__unused) 156 *cmdline_p = boot_command_line; !! 382 { >> 383 int cpuid = hard_smp_processor_id(); 157 384 158 find_limits(&min_low_pfn, &max_low_pfn !! 385 seq_printf(m, 159 max_mapnr = max_low_pfn; !! 386 "cpu\t\t: %s\n" >> 387 "fpu\t\t: %s\n" >> 388 "promlib\t\t: Version %d Revision %d\n" >> 389 "prom\t\t: %d.%d\n" >> 390 "type\t\t: %s\n" >> 391 "ncpus probed\t: %d\n" >> 392 "ncpus active\t: %d\n" >> 393 #ifndef CONFIG_SMP >> 394 "BogoMips\t: %lu.%02lu\n" >> 395 #endif >> 396 , >> 397 sparc_cpu_type[cpuid] ? : "undetermined", >> 398 sparc_fpu_type[cpuid] ? : "undetermined", >> 399 romvec->pv_romvers, >> 400 prom_rev, >> 401 romvec->pv_printrev >> 16, >> 402 (short) romvec->pv_printrev, >> 403 &cputypval, >> 404 linux_num_cpus, >> 405 num_online_cpus() >> 406 #ifndef CONFIG_SMP >> 407 , loops_per_jiffy/(500000/HZ), >> 408 (loops_per_jiffy/(5000/HZ)) % 100 >> 409 #endif >> 410 ); 160 411 161 memblock_reserve(__pa_symbol(_stext), !! 412 #ifdef CONFIG_SMP 162 #ifdef CONFIG_BLK_DEV_INITRD !! 413 smp_bogo_info(m); 163 if (initrd_start) { !! 414 #endif 164 memblock_reserve(virt_to_phys( !! 415 mmu_info(m); 165 initrd_end - i !! 416 #ifdef CONFIG_SMP 166 } !! 417 smp_info(m); 167 #endif /* CONFIG_BLK_DEV_INITRD */ !! 418 #endif >> 419 return 0; >> 420 } 168 421 169 early_init_fdt_reserve_self(); !! 422 static void *c_start(struct seq_file *m, loff_t *pos) 170 early_init_fdt_scan_reserved_mem(); !! 423 { >> 424 /* The pointer we are returning is arbitrary, >> 425 * it just has to be non-NULL and not IS_ERR >> 426 * in the success case. >> 427 */ >> 428 return *pos == 0 ? &c_start : NULL; >> 429 } 171 430 172 unflatten_and_copy_device_tree(); !! 431 static void *c_next(struct seq_file *m, void *v, loff_t *pos) >> 432 { >> 433 ++*pos; >> 434 return c_start(m, pos); >> 435 } 173 436 174 setup_cpuinfo(); !! 437 static void c_stop(struct seq_file *m, void *v) >> 438 { >> 439 } 175 440 176 copy_exception_handler(cpuinfo.excepti !! 441 struct seq_operations cpuinfo_op = { >> 442 .start =c_start, >> 443 .next = c_next, >> 444 .stop = c_stop, >> 445 .show = show_cpuinfo, >> 446 }; 177 447 178 mmu_init(); !! 448 extern int stop_a_enabled; 179 449 180 copy_fast_tlb_miss_handler(cpuinfo.fas !! 450 void sun_do_break(void) >> 451 { >> 452 if (!stop_a_enabled) >> 453 return; 181 454 182 /* !! 455 printk("\n"); 183 * Initialize MMU context handling her !! 456 flush_user_windows(); 184 * needed for this. << 185 */ << 186 mmu_context_init(); << 187 457 188 /* !! 458 prom_cmdline(); 189 * get kmalloc into gear << 190 */ << 191 paging_init(); << 192 } 459 } >> 460 >> 461 int serial_console; >> 462 int stop_a_enabled = 1; 193 463
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.