1 /* 1 /* 2 * Copyright (C) 2007-2009 Michal Simek <monst !! 2 * Common prep/pmac/chrp boot and setup code. 3 * Copyright (C) 2007-2009 PetaLogix << 4 * Copyright (C) 2006 Atmark Techno, Inc. << 5 * << 6 * This file is subject to the terms and condi << 7 * License. See the file "COPYING" in the main << 8 * for more details. << 9 */ 3 */ 10 4 11 #include <linux/init.h> !! 5 #include <linux/config.h> 12 #include <linux/of_clk.h> !! 6 #include <linux/module.h> 13 #include <linux/clocksource.h> << 14 #include <linux/string.h> 7 #include <linux/string.h> >> 8 #include <linux/sched.h> >> 9 #include <linux/init.h> >> 10 #include <linux/reboot.h> >> 11 #include <linux/delay.h> >> 12 #include <linux/initrd.h> >> 13 #include <linux/ide.h> >> 14 #include <linux/tty.h> >> 15 #include <linux/bootmem.h> 15 #include <linux/seq_file.h> 16 #include <linux/seq_file.h> >> 17 #include <linux/root_dev.h> 16 #include <linux/cpu.h> 18 #include <linux/cpu.h> 17 #include <linux/initrd.h> << 18 #include <linux/console.h> << 19 #include <linux/debugfs.h> << 20 #include <linux/of_fdt.h> << 21 #include <linux/pgtable.h> << 22 19 >> 20 #include <asm/residual.h> >> 21 #include <asm/io.h> >> 22 #include <asm/prom.h> >> 23 #include <asm/processor.h> >> 24 #include <asm/pgtable.h> >> 25 #include <asm/bootinfo.h> 23 #include <asm/setup.h> 26 #include <asm/setup.h> >> 27 #include <asm/amigappc.h> >> 28 #include <asm/smp.h> >> 29 #include <asm/elf.h> >> 30 #include <asm/cputable.h> >> 31 #include <asm/bootx.h> >> 32 #include <asm/btext.h> >> 33 #include <asm/machdep.h> >> 34 #include <asm/uaccess.h> >> 35 #include <asm/system.h> >> 36 #include <asm/pmac_feature.h> 24 #include <asm/sections.h> 37 #include <asm/sections.h> 25 #include <asm/page.h> !! 38 #include <asm/xmon.h> 26 #include <linux/io.h> !! 39 27 #include <linux/bug.h> !! 40 #if defined CONFIG_KGDB 28 #include <linux/param.h> !! 41 #include <asm/kgdb.h> 29 #include <linux/pci.h> !! 42 #endif 30 #include <linux/cache.h> !! 43 31 #include <linux/of.h> !! 44 extern void platform_init(unsigned long r3, unsigned long r4, 32 #include <linux/dma-mapping.h> !! 45 unsigned long r5, unsigned long r6, unsigned long r7); 33 #include <asm/cacheflush.h> !! 46 extern void bootx_init(unsigned long r4, unsigned long phys); 34 #include <asm/entry.h> !! 47 extern void identify_cpu(unsigned long offset, unsigned long cpu); 35 #include <asm/cpuinfo.h> !! 48 extern void do_cpu_ftr_fixups(unsigned long offset); 36 !! 49 extern void reloc_got2(unsigned long offset); 37 !! 50 38 DEFINE_PER_CPU(unsigned int, KSP); /* Sav !! 51 39 DEFINE_PER_CPU(unsigned int, KM); /* Ker !! 52 #ifdef CONFIG_KGDB 40 DEFINE_PER_CPU(unsigned int, ENTRY_SP); /* Sav !! 53 extern void kgdb_map_scc(void); 41 DEFINE_PER_CPU(unsigned int, R11_SAVE); /* Tem !! 54 #endif 42 DEFINE_PER_CPU(unsigned int, CURRENT_SAVE); !! 55 >> 56 extern void ppc6xx_idle(void); >> 57 extern void power4_idle(void); >> 58 >> 59 extern boot_infos_t *boot_infos; >> 60 char saved_command_line[256]; >> 61 unsigned char aux_device_present; >> 62 struct ide_machdep_calls ppc_ide_md; >> 63 char *sysmap; >> 64 unsigned long sysmap_size; >> 65 >> 66 /* Used with the BI_MEMSIZE bootinfo parameter to store the memory >> 67 size value reported by the boot loader. */ >> 68 unsigned long boot_mem_size; >> 69 >> 70 unsigned long ISA_DMA_THRESHOLD; >> 71 unsigned long DMA_MODE_READ, DMA_MODE_WRITE; >> 72 >> 73 #ifdef CONFIG_PPC_MULTIPLATFORM >> 74 int _machine = 0; >> 75 >> 76 extern void prep_init(unsigned long r3, unsigned long r4, >> 77 unsigned long r5, unsigned long r6, unsigned long r7); >> 78 extern void pmac_init(unsigned long r3, unsigned long r4, >> 79 unsigned long r5, unsigned long r6, unsigned long r7); >> 80 extern void chrp_init(unsigned long r3, unsigned long r4, >> 81 unsigned long r5, unsigned long r6, unsigned long r7); >> 82 #endif /* CONFIG_PPC_MULTIPLATFORM */ >> 83 >> 84 #ifdef CONFIG_MAGIC_SYSRQ >> 85 unsigned long SYSRQ_KEY = 0x54; >> 86 #endif /* CONFIG_MAGIC_SYSRQ */ >> 87 >> 88 #ifdef CONFIG_VGA_CONSOLE >> 89 unsigned long vgacon_remap_base; >> 90 #endif >> 91 >> 92 struct machdep_calls ppc_md; 43 93 44 /* 94 /* 45 * Placed cmd_line to .data section because ca !! 95 * These are used in binfmt_elf.c to put aux entries on the stack 46 * ASM code. Default position is BSS section w !! 96 * for each elf executable being started. 47 * in machine_early_init(). << 48 */ 97 */ 49 char cmd_line[COMMAND_LINE_SIZE] __section(".d !! 98 int dcache_bsize; >> 99 int icache_bsize; >> 100 int ucache_bsize; >> 101 >> 102 #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \ >> 103 defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA) >> 104 struct screen_info screen_info = { >> 105 0, 25, /* orig-x, orig-y */ >> 106 0, /* unused */ >> 107 0, /* orig-video-page */ >> 108 0, /* orig-video-mode */ >> 109 80, /* orig-video-cols */ >> 110 0,0,0, /* ega_ax, ega_bx, ega_cx */ >> 111 25, /* orig-video-lines */ >> 112 1, /* orig-video-isVGA */ >> 113 16 /* orig-video-points */ >> 114 }; >> 115 #endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */ 50 116 51 void __init setup_arch(char **cmdline_p) !! 117 void machine_restart(char *cmd) 52 { 118 { 53 *cmdline_p = boot_command_line; !! 119 ppc_md.restart(cmd); >> 120 } 54 121 55 setup_memory(); !! 122 EXPORT_SYMBOL(machine_restart); >> 123 >> 124 void machine_power_off(void) >> 125 { >> 126 ppc_md.power_off(); >> 127 } 56 128 57 console_verbose(); !! 129 EXPORT_SYMBOL(machine_power_off); 58 130 59 unflatten_device_tree(); !! 131 void machine_halt(void) >> 132 { >> 133 ppc_md.halt(); >> 134 } 60 135 61 setup_cpuinfo(); !! 136 EXPORT_SYMBOL(machine_halt); 62 137 63 microblaze_cache_init(); !! 138 void (*pm_power_off)(void) = machine_power_off; 64 139 65 xilinx_pci_init(); !! 140 #ifdef CONFIG_TAU 66 } !! 141 extern u32 cpu_temp(unsigned long cpu); >> 142 extern u32 cpu_temp_both(unsigned long cpu); >> 143 #endif /* CONFIG_TAU */ 67 144 68 #ifdef CONFIG_MTD_UCLINUX !! 145 int show_cpuinfo(struct seq_file *m, void *v) 69 /* Handle both romfs and cramfs types, without << 70 code (ie no point checking for CRAMFS if it's << 71 inline unsigned get_romfs_len(unsigned *addr) << 72 { 146 { 73 #ifdef CONFIG_ROMFS_FS !! 147 int i = (int) v - 1; 74 if (memcmp(&addr[0], "-rom1fs-", 8) == !! 148 int err = 0; 75 return be32_to_cpu(addr[2]); !! 149 unsigned int pvr; >> 150 unsigned short maj, min; >> 151 unsigned long lpj; >> 152 >> 153 if (i >= NR_CPUS) { >> 154 /* Show summary information */ >> 155 #ifdef CONFIG_SMP >> 156 unsigned long bogosum = 0; >> 157 for (i = 0; i < NR_CPUS; ++i) >> 158 if (cpu_online(i)) >> 159 bogosum += cpu_data[i].loops_per_jiffy; >> 160 seq_printf(m, "total bogomips\t: %lu.%02lu\n", >> 161 bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); >> 162 #endif /* CONFIG_SMP */ >> 163 >> 164 if (ppc_md.show_cpuinfo != NULL) >> 165 err = ppc_md.show_cpuinfo(m); >> 166 return err; >> 167 } >> 168 >> 169 #ifdef CONFIG_SMP >> 170 if (!cpu_online(i)) >> 171 return 0; >> 172 pvr = cpu_data[i].pvr; >> 173 lpj = cpu_data[i].loops_per_jiffy; >> 174 #else >> 175 pvr = mfspr(PVR); >> 176 lpj = loops_per_jiffy; 76 #endif 177 #endif 77 178 78 #ifdef CONFIG_CRAMFS !! 179 seq_printf(m, "processor\t: %d\n", i); 79 if (addr[0] == le32_to_cpu(0x28cd3d45) !! 180 seq_printf(m, "cpu\t\t: "); 80 return le32_to_cpu(addr[1]); !! 181 >> 182 if (cur_cpu_spec[i]->pvr_mask) >> 183 seq_printf(m, "%s", cur_cpu_spec[i]->cpu_name); >> 184 else >> 185 seq_printf(m, "unknown (%08x)", pvr); >> 186 #ifdef CONFIG_ALTIVEC >> 187 if (cur_cpu_spec[i]->cpu_features & CPU_FTR_ALTIVEC) >> 188 seq_printf(m, ", altivec supported"); 81 #endif 189 #endif >> 190 seq_printf(m, "\n"); >> 191 >> 192 #ifdef CONFIG_TAU >> 193 if (cur_cpu_spec[i]->cpu_features & CPU_FTR_TAU) { >> 194 #ifdef CONFIG_TAU_AVERAGE >> 195 /* more straightforward, but potentially misleading */ >> 196 seq_printf(m, "temperature \t: %u C (uncalibrated)\n", >> 197 cpu_temp(i)); >> 198 #else >> 199 /* show the actual temp sensor range */ >> 200 u32 temp; >> 201 temp = cpu_temp_both(i); >> 202 seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", >> 203 temp & 0xff, temp >> 16); >> 204 #endif >> 205 } >> 206 #endif /* CONFIG_TAU */ >> 207 >> 208 if (ppc_md.show_percpuinfo != NULL) { >> 209 err = ppc_md.show_percpuinfo(m, i); >> 210 if (err) >> 211 return err; >> 212 } >> 213 >> 214 switch (PVR_VER(pvr)) { >> 215 case 0x0020: /* 403 family */ >> 216 maj = PVR_MAJ(pvr) + 1; >> 217 min = PVR_MIN(pvr); >> 218 break; >> 219 case 0x1008: /* 740P/750P ?? */ >> 220 maj = ((pvr >> 8) & 0xFF) - 1; >> 221 min = pvr & 0xFF; >> 222 break; >> 223 default: >> 224 maj = (pvr >> 8) & 0xFF; >> 225 min = pvr & 0xFF; >> 226 break; >> 227 } >> 228 >> 229 seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", >> 230 maj, min, PVR_VER(pvr), PVR_REV(pvr)); >> 231 >> 232 seq_printf(m, "bogomips\t: %lu.%02lu\n", >> 233 lpj / (500000/HZ), (lpj / (5000/HZ)) % 100); >> 234 >> 235 #ifdef CONFIG_SMP >> 236 seq_printf(m, "\n"); >> 237 #endif >> 238 82 return 0; 239 return 0; 83 } 240 } 84 #endif /* CONFIG_MTD_UCLINUX_EBSS */ << 85 241 86 unsigned long kernel_tlb; !! 242 static void *c_start(struct seq_file *m, loff_t *pos) >> 243 { >> 244 int i = *pos; >> 245 >> 246 return i <= NR_CPUS? (void *) (i + 1): NULL; >> 247 } >> 248 >> 249 static void *c_next(struct seq_file *m, void *v, loff_t *pos) >> 250 { >> 251 ++*pos; >> 252 return c_start(m, pos); >> 253 } 87 254 88 void __init machine_early_init(const char *cmd !! 255 static void c_stop(struct seq_file *m, void *v) 89 unsigned int fdt, unsigned int << 90 unsigned int tlb1) << 91 { 256 { 92 unsigned long *src, *dst; !! 257 } 93 unsigned int offset = 0; !! 258 >> 259 struct seq_operations cpuinfo_op = { >> 260 .start =c_start, >> 261 .next = c_next, >> 262 .stop = c_stop, >> 263 .show = show_cpuinfo, >> 264 }; 94 265 95 /* If CONFIG_MTD_UCLINUX is defined, a !! 266 /* 96 * end of kernel. There are two positi !! 267 * We're called here very early in the boot. We determine the machine 97 * The first is __init_end and the sec !! 268 * type and call the appropriate low-level setup functions. >> 269 * -- Cort <cort@fsmlabs.com> >> 270 * >> 271 * Note that the kernel may be running at an address which is different >> 272 * from the address that it was linked at, so we must use RELOC/PTRRELOC >> 273 * to access static data (including strings). -- paulus >> 274 */ >> 275 __init >> 276 unsigned long >> 277 early_init(int r3, int r4, int r5) >> 278 { >> 279 unsigned long phys; >> 280 unsigned long offset = reloc_offset(); >> 281 >> 282 /* Default */ >> 283 phys = offset + KERNELBASE; >> 284 >> 285 /* First zero the BSS -- use memset, some arches don't have >> 286 * caches on yet */ >> 287 memset_io(PTRRELOC(&__bss_start), 0, _end - __bss_start); >> 288 >> 289 /* >> 290 * Identify the CPU type and fix up code sections >> 291 * that depend on which cpu we have. 98 */ 292 */ 99 #ifdef CONFIG_MTD_UCLINUX !! 293 identify_cpu(offset, 0); 100 int romfs_size; !! 294 do_cpu_ftr_fixups(offset); 101 unsigned int romfs_base; << 102 char *old_klimit = klimit; << 103 295 104 romfs_base = (ram ? ram : (unsigned in !! 296 #if defined(CONFIG_PPC_MULTIPLATFORM) 105 romfs_size = PAGE_ALIGN(get_romfs_len( !! 297 reloc_got2(offset); 106 if (!romfs_size) { << 107 romfs_base = (unsigned int)&__ << 108 romfs_size = PAGE_ALIGN(get_ro << 109 } << 110 298 111 /* Move ROMFS out of BSS before cleari !! 299 /* If we came here from BootX, clear the screen, 112 if (romfs_size > 0) { !! 300 * set up some pointers and return. */ 113 memmove(&__bss_stop, (int *)ro !! 301 if ((r3 == 0x426f6f58) && (r5 == 0)) 114 klimit += romfs_size; !! 302 bootx_init(r4, phys); 115 } !! 303 >> 304 /* >> 305 * don't do anything on prep >> 306 * for now, don't use bootinfo because it breaks yaboot 0.5 >> 307 * and assume that if we didn't find a magic number, we have OF >> 308 */ >> 309 else if (*(unsigned long *)(0) != 0xdeadc0de) >> 310 phys = prom_init(r3, r4, (prom_entry)r5); >> 311 >> 312 reloc_got2(-offset); 116 #endif 313 #endif 117 314 118 /* clearing bss section */ !! 315 return phys; 119 memset(__bss_start, 0, __bss_stop-__bs !! 316 } 120 memset(_ssbss, 0, _esbss-_ssbss); !! 317 >> 318 #ifdef CONFIG_PPC_OF >> 319 /* >> 320 * Assume here that all clock rates are the same in a >> 321 * smp system. -- Cort >> 322 */ >> 323 int __openfirmware >> 324 of_show_percpuinfo(struct seq_file *m, int i) >> 325 { >> 326 struct device_node *cpu_node; >> 327 int *fp, s; >> 328 >> 329 cpu_node = find_type_devices("cpu"); >> 330 if (!cpu_node) >> 331 return 0; >> 332 for (s = 0; s < i && cpu_node->next; s++) >> 333 cpu_node = cpu_node->next; >> 334 fp = (int *) get_property(cpu_node, "clock-frequency", NULL); >> 335 if (fp) >> 336 seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000); >> 337 return 0; >> 338 } 121 339 122 /* initialize device tree for usage in early_p !! 340 void __init 123 early_init_devtree(_fdt_start); !! 341 intuit_machine_type(void) >> 342 { >> 343 char *model; >> 344 struct device_node *root; >> 345 >> 346 /* ask the OF info if we're a chrp or pmac */ >> 347 root = find_path_device("/"); >> 348 if (root != 0) { >> 349 /* assume pmac unless proven to be chrp -- Cort */ >> 350 _machine = _MACH_Pmac; >> 351 model = get_property(root, "device_type", NULL); >> 352 if (model && !strncmp("chrp", model, 4)) >> 353 _machine = _MACH_chrp; >> 354 else { >> 355 model = get_property(root, "model", NULL); >> 356 if (model && !strncmp(model, "IBM", 3)) >> 357 _machine = _MACH_chrp; >> 358 } >> 359 } >> 360 } >> 361 #endif 124 362 125 /* setup kernel_tlb after BSS cleaning !! 363 #ifdef CONFIG_PPC_MULTIPLATFORM 126 * Maybe worth to move to asm code */ !! 364 /* 127 kernel_tlb = tlb0 + tlb1; !! 365 * The PPC_MULTIPLATFORM version of platform_init... 128 /* printk("TLB1 0x%08x, TLB0 0x%08x, t !! 366 */ 129 !! 367 void __init >> 368 platform_init(unsigned long r3, unsigned long r4, unsigned long r5, >> 369 unsigned long r6, unsigned long r7) >> 370 { >> 371 #ifdef CONFIG_BOOTX_TEXT >> 372 if (boot_text_mapped) { >> 373 btext_clearscreen(); >> 374 btext_welcome(); >> 375 } >> 376 #endif 130 377 131 pr_info("Ramdisk addr 0x%08x, ", ram); !! 378 parse_bootinfo(find_bootinfo()); 132 if (fdt) << 133 pr_info("FDT at 0x%08x\n", fdt << 134 else << 135 pr_info("Compiled-in FDT at %p << 136 379 137 #ifdef CONFIG_MTD_UCLINUX !! 380 /* if we didn't get any bootinfo telling us what we are... */ 138 pr_info("Found romfs @ 0x%08x (0x%08x) !! 381 if (_machine == 0) { 139 romfs_base, romfs_size !! 382 /* prep boot loader tells us if we're prep or not */ 140 pr_info("#### klimit %p ####\n", old_k !! 383 if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) 141 BUG_ON(romfs_size < 0); /* What else c !! 384 _machine = _MACH_prep; >> 385 } 142 386 143 pr_info("Moved 0x%08x bytes from 0x%08 !! 387 /* not much more to do here, if prep */ 144 romfs_size, romfs_base !! 388 if (_machine == _MACH_prep) { >> 389 prep_init(r3, r4, r5, r6, r7); >> 390 return; >> 391 } 145 392 146 pr_info("New klimit: 0x%08x\n", (unsig !! 393 /* prom_init has already been called from __start */ >> 394 if (boot_infos) >> 395 relocate_nodes(); >> 396 >> 397 /* If we aren't PReP, we can find out if we're Pmac >> 398 * or CHRP with this. */ >> 399 if (_machine == 0) >> 400 intuit_machine_type(); >> 401 >> 402 /* finish_device_tree may need _machine defined. */ >> 403 finish_device_tree(); >> 404 >> 405 /* >> 406 * If we were booted via quik, r3 points to the physical >> 407 * address of the command-line parameters. >> 408 * If we were booted from an xcoff image (i.e. netbooted or >> 409 * booted from floppy), we get the command line from the >> 410 * bootargs property of the /chosen node. >> 411 * If an initial ramdisk is present, r3 and r4 >> 412 * are used for initrd_start and initrd_size, >> 413 * otherwise they contain 0xdeadbeef. >> 414 */ >> 415 cmd_line[0] = 0; >> 416 if (r3 >= 0x4000 && r3 < 0x800000 && r4 == 0) { >> 417 strlcpy(cmd_line, (char *)r3 + KERNELBASE, >> 418 sizeof(cmd_line)); >> 419 } else if (boot_infos != 0) { >> 420 /* booted by BootX - check for ramdisk */ >> 421 if (boot_infos->kernelParamsOffset != 0) >> 422 strlcpy(cmd_line, (char *) boot_infos >> 423 + boot_infos->kernelParamsOffset, >> 424 sizeof(cmd_line)); >> 425 #ifdef CONFIG_BLK_DEV_INITRD >> 426 if (boot_infos->ramDisk) { >> 427 initrd_start = (unsigned long) boot_infos >> 428 + boot_infos->ramDisk; >> 429 initrd_end = initrd_start + boot_infos->ramDiskSize; >> 430 initrd_below_start_ok = 1; >> 431 } >> 432 #endif >> 433 } else { >> 434 struct device_node *chosen; >> 435 char *p; >> 436 >> 437 #ifdef CONFIG_BLK_DEV_INITRD >> 438 if (r3 && r4 && r4 != 0xdeadbeef) { >> 439 if (r3 < KERNELBASE) >> 440 r3 += KERNELBASE; >> 441 initrd_start = r3; >> 442 initrd_end = r3 + r4; >> 443 ROOT_DEV = Root_RAM0; >> 444 initrd_below_start_ok = 1; >> 445 } 147 #endif 446 #endif >> 447 chosen = find_devices("chosen"); >> 448 if (chosen != NULL) { >> 449 p = get_property(chosen, "bootargs", NULL); >> 450 if (p && *p) { >> 451 strlcpy(cmd_line, p, sizeof(cmd_line)); >> 452 } >> 453 } >> 454 } >> 455 #ifdef CONFIG_ADB >> 456 if (strstr(cmd_line, "adb_sync")) { >> 457 extern int __adb_probe_sync; >> 458 __adb_probe_sync = 1; >> 459 } >> 460 #endif /* CONFIG_ADB */ 148 461 149 #if CONFIG_XILINX_MICROBLAZE0_USE_MSR_INSTR !! 462 switch (_machine) { 150 if (msr) { !! 463 case _MACH_Pmac: 151 pr_info("!!!Your kernel has se !! 464 pmac_init(r3, r4, r5, r6, r7); 152 pr_cont("CPU don't have it %x\ !! 465 break; >> 466 case _MACH_chrp: >> 467 chrp_init(r3, r4, r5, r6, r7); >> 468 break; 153 } 469 } 154 #else !! 470 } 155 if (!msr) { !! 471 #endif /* CONFIG_PPC_MULTIPLATFORM */ 156 pr_info("!!!Your kernel not se !! 472 157 pr_cont("CPU have it %x\n", ms !! 473 struct bi_record *find_bootinfo(void) >> 474 { >> 475 struct bi_record *rec; >> 476 >> 477 rec = (struct bi_record *)_ALIGN((ulong)__bss_start+(1<<20)-1,(1<<20)); >> 478 if ( rec->tag != BI_FIRST ) { >> 479 /* >> 480 * This 0x10000 offset is a terrible hack but it will go away when >> 481 * we have the bootloader handle all the relocation and >> 482 * prom calls -- Cort >> 483 */ >> 484 rec = (struct bi_record *)_ALIGN((ulong)__bss_start+0x10000+(1<<20)-1,(1<<20)); >> 485 if ( rec->tag != BI_FIRST ) >> 486 return NULL; 158 } 487 } >> 488 return rec; >> 489 } >> 490 >> 491 void parse_bootinfo(struct bi_record *rec) >> 492 { >> 493 if (rec == NULL || rec->tag != BI_FIRST) >> 494 return; >> 495 while (rec->tag != BI_LAST) { >> 496 ulong *data = rec->data; >> 497 switch (rec->tag) { >> 498 case BI_CMD_LINE: >> 499 memcpy(cmd_line, (void *)data, rec->size); >> 500 break; >> 501 case BI_SYSMAP: >> 502 sysmap = (char *)((data[0] >= (KERNELBASE)) ? data[0] : >> 503 (data[0]+KERNELBASE)); >> 504 sysmap_size = data[1]; >> 505 break; >> 506 #ifdef CONFIG_BLK_DEV_INITRD >> 507 case BI_INITRD: >> 508 initrd_start = data[0] + KERNELBASE; >> 509 initrd_end = data[0] + data[1] + KERNELBASE; >> 510 break; >> 511 #endif /* CONFIG_BLK_DEV_INITRD */ >> 512 #ifdef CONFIG_PPC_MULTIPLATFORM >> 513 case BI_MACHTYPE: >> 514 _machine = data[0]; >> 515 break; 159 #endif 516 #endif >> 517 case BI_MEMSIZE: >> 518 boot_mem_size = data[0]; >> 519 break; >> 520 } >> 521 rec = (struct bi_record *)((ulong)rec + rec->size); >> 522 } >> 523 } >> 524 >> 525 /* >> 526 * Find out what kind of machine we're on and save any data we need >> 527 * from the early boot process (devtree is copied on pmac by prom_init()). >> 528 * This is called very early on the boot process, after a minimal >> 529 * MMU environment has been set up but before MMU_init is called. >> 530 */ >> 531 void __init >> 532 machine_init(unsigned long r3, unsigned long r4, unsigned long r5, >> 533 unsigned long r6, unsigned long r7) >> 534 { >> 535 #ifdef CONFIG_CMDLINE >> 536 strcpy(cmd_line, CONFIG_CMDLINE); >> 537 #endif /* CONFIG_CMDLINE */ 160 538 161 /* Do not copy reset vectors. offset = !! 539 #ifdef CONFIG_6xx 162 * two instructions. dst is pointer to !! 540 ppc_md.power_save = ppc6xx_idle; 163 * in block ram. If you want to copy r !! 541 #endif 164 #if !CONFIG_MANUAL_RESET_VECTOR !! 542 #ifdef CONFIG_POWER4 165 offset = 0x2; !! 543 ppc_md.power_save = power4_idle; 166 #endif 544 #endif 167 dst = (unsigned long *) (offset * size << 168 for (src = __ivt_start + offset; src < << 169 *dst = *src; << 170 545 171 /* Initialize global data */ !! 546 platform_init(r3, r4, r5, r6, r7); 172 per_cpu(KM, 0) = 0x1; /* We start in !! 547 173 per_cpu(CURRENT_SAVE, 0) = (unsigned l !! 548 if (ppc_md.progress) >> 549 ppc_md.progress("id mach(): done", 0x200); 174 } 550 } 175 551 176 void __init time_init(void) !! 552 /* Checks "l2cr=xxxx" command-line option */ >> 553 int __init ppc_setup_l2cr(char *str) 177 { 554 { 178 of_clk_init(NULL); !! 555 if (cur_cpu_spec[0]->cpu_features & CPU_FTR_L2CR) { 179 setup_cpuinfo_clk(); !! 556 unsigned long val = simple_strtoul(str, NULL, 0); 180 timer_probe(); !! 557 printk(KERN_INFO "l2cr set to %lx\n", val); >> 558 _set_L2CR(0); /* force invalidate by disable cache */ >> 559 _set_L2CR(val); /* and enable it */ >> 560 } >> 561 return 1; 181 } 562 } >> 563 __setup("l2cr=", ppc_setup_l2cr); 182 564 183 #ifdef CONFIG_DEBUG_FS !! 565 #ifdef CONFIG_NVRAM 184 struct dentry *of_debugfs_root; !! 566 /* Generic nvram hooks we now look into ppc_md.nvram_read_val >> 567 * on pmac too ;) >> 568 * //XX Those 2 could be moved to headers >> 569 */ >> 570 unsigned char >> 571 nvram_read_byte(int addr) >> 572 { >> 573 if (ppc_md.nvram_read_val) >> 574 return ppc_md.nvram_read_val(addr); >> 575 return 0xff; >> 576 } 185 577 186 static int microblaze_debugfs_init(void) !! 578 void >> 579 nvram_write_byte(unsigned char val, int addr) 187 { 580 { 188 of_debugfs_root = debugfs_create_dir(" !! 581 if (ppc_md.nvram_write_val) 189 return 0; !! 582 ppc_md.nvram_write_val(val, addr); 190 } 583 } 191 arch_initcall(microblaze_debugfs_init); !! 584 #endif /* CONFIG_NVRAM */ 192 585 193 static int __init debugfs_tlb(void) !! 586 static struct cpu cpu_devices[NR_CPUS]; >> 587 >> 588 int __init ppc_init(void) 194 { 589 { 195 debugfs_create_u32("tlb_skip", S_IRUGO !! 590 int i; >> 591 >> 592 /* clear the progress line */ >> 593 if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); >> 594 >> 595 /* register CPU devices */ >> 596 for (i = 0; i < NR_CPUS; i++) >> 597 if (cpu_possible(i)) >> 598 register_cpu(&cpu_devices[i], i, NULL); >> 599 >> 600 /* call platform init */ >> 601 if (ppc_md.init != NULL) { >> 602 ppc_md.init(); >> 603 } 196 return 0; 604 return 0; 197 } 605 } 198 device_initcall(debugfs_tlb); !! 606 >> 607 arch_initcall(ppc_init); >> 608 >> 609 /* Warning, IO base is not yet inited */ >> 610 void __init setup_arch(char **cmdline_p) >> 611 { >> 612 extern int panic_timeout; >> 613 extern char *klimit; >> 614 extern void do_init_bootmem(void); >> 615 >> 616 /* so udelay does something sensible, assume <= 1000 bogomips */ >> 617 loops_per_jiffy = 500000000 / HZ; >> 618 >> 619 #ifdef CONFIG_PPC_MULTIPLATFORM >> 620 /* This could be called "early setup arch", it must be done >> 621 * now because xmon need it >> 622 */ >> 623 if (_machine == _MACH_Pmac) >> 624 pmac_feature_init(); /* New cool way */ 199 #endif 625 #endif >> 626 >> 627 #ifdef CONFIG_XMON >> 628 xmon_map_scc(); >> 629 if (strstr(cmd_line, "xmon")) >> 630 xmon(0); >> 631 #endif /* CONFIG_XMON */ >> 632 if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); >> 633 >> 634 #if defined(CONFIG_KGDB) >> 635 kgdb_map_scc(); >> 636 set_debug_traps(); >> 637 if (strstr(cmd_line, "gdb")) { >> 638 if (ppc_md.progress) >> 639 ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000); >> 640 printk("kgdb breakpoint activated\n"); >> 641 breakpoint(); >> 642 } >> 643 #endif >> 644 >> 645 /* >> 646 * Set cache line size based on type of cpu as a default. >> 647 * Systems with OF can look in the properties on the cpu node(s) >> 648 * for a possibly more accurate value. >> 649 */ >> 650 if (cur_cpu_spec[0]->cpu_features & CPU_FTR_SPLIT_ID_CACHE) { >> 651 dcache_bsize = cur_cpu_spec[0]->dcache_bsize; >> 652 icache_bsize = cur_cpu_spec[0]->icache_bsize; >> 653 ucache_bsize = 0; >> 654 } else >> 655 ucache_bsize = dcache_bsize = icache_bsize >> 656 = cur_cpu_spec[0]->dcache_bsize; >> 657 >> 658 /* reboot on panic */ >> 659 panic_timeout = 180; >> 660 >> 661 init_mm.start_code = PAGE_OFFSET; >> 662 init_mm.end_code = (unsigned long) _etext; >> 663 init_mm.end_data = (unsigned long) _edata; >> 664 init_mm.brk = (unsigned long) klimit; >> 665 >> 666 /* Save unparsed command line copy for /proc/cmdline */ >> 667 strcpy(saved_command_line, cmd_line); >> 668 *cmdline_p = cmd_line; >> 669 >> 670 /* set up the bootmem stuff with available memory */ >> 671 do_init_bootmem(); >> 672 if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); >> 673 >> 674 ppc_md.setup_arch(); >> 675 if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); >> 676 >> 677 paging_init(); >> 678 sort_exception_table(); >> 679 >> 680 /* this is for modules since _machine can be a define -- Cort */ >> 681 ppc_md.ppc_machine = _machine; >> 682 } 200 683
Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.