1*70d64ceaSPaul Mackerras /* 2*70d64ceaSPaul Mackerras * Common prep/pmac/chrp boot and setup code. 3*70d64ceaSPaul Mackerras */ 4*70d64ceaSPaul Mackerras 5*70d64ceaSPaul Mackerras #include <linux/config.h> 6*70d64ceaSPaul Mackerras #include <linux/module.h> 7*70d64ceaSPaul Mackerras #include <linux/string.h> 8*70d64ceaSPaul Mackerras #include <linux/sched.h> 9*70d64ceaSPaul Mackerras #include <linux/init.h> 10*70d64ceaSPaul Mackerras #include <linux/kernel.h> 11*70d64ceaSPaul Mackerras #include <linux/reboot.h> 12*70d64ceaSPaul Mackerras #include <linux/delay.h> 13*70d64ceaSPaul Mackerras #include <linux/initrd.h> 14*70d64ceaSPaul Mackerras #include <linux/ide.h> 15*70d64ceaSPaul Mackerras #include <linux/tty.h> 16*70d64ceaSPaul Mackerras #include <linux/bootmem.h> 17*70d64ceaSPaul Mackerras #include <linux/seq_file.h> 18*70d64ceaSPaul Mackerras #include <linux/root_dev.h> 19*70d64ceaSPaul Mackerras #include <linux/cpu.h> 20*70d64ceaSPaul Mackerras #include <linux/console.h> 21*70d64ceaSPaul Mackerras 22*70d64ceaSPaul Mackerras #include <asm/residual.h> 23*70d64ceaSPaul Mackerras #include <asm/io.h> 24*70d64ceaSPaul Mackerras #include <asm/prom.h> 25*70d64ceaSPaul Mackerras #include <asm/processor.h> 26*70d64ceaSPaul Mackerras #include <asm/pgtable.h> 27*70d64ceaSPaul Mackerras #include <asm/bootinfo.h> 28*70d64ceaSPaul Mackerras #include <asm/setup.h> 29*70d64ceaSPaul Mackerras #include <asm/amigappc.h> 30*70d64ceaSPaul Mackerras #include <asm/smp.h> 31*70d64ceaSPaul Mackerras #include <asm/elf.h> 32*70d64ceaSPaul Mackerras #include <asm/cputable.h> 33*70d64ceaSPaul Mackerras #include <asm/bootx.h> 34*70d64ceaSPaul Mackerras #include <asm/btext.h> 35*70d64ceaSPaul Mackerras #include <asm/machdep.h> 36*70d64ceaSPaul Mackerras #include <asm/uaccess.h> 37*70d64ceaSPaul Mackerras #include <asm/system.h> 38*70d64ceaSPaul Mackerras #include <asm/pmac_feature.h> 39*70d64ceaSPaul Mackerras #include <asm/sections.h> 40*70d64ceaSPaul Mackerras #include <asm/nvram.h> 41*70d64ceaSPaul Mackerras #include <asm/xmon.h> 42*70d64ceaSPaul Mackerras #include <asm/ocp.h> 43*70d64ceaSPaul Mackerras 44*70d64ceaSPaul Mackerras #define USES_PPC_SYS (defined(CONFIG_85xx) || defined(CONFIG_83xx) || \ 45*70d64ceaSPaul Mackerras defined(CONFIG_MPC10X_BRIDGE) || defined(CONFIG_8260) || \ 46*70d64ceaSPaul Mackerras defined(CONFIG_PPC_MPC52xx)) 47*70d64ceaSPaul Mackerras 48*70d64ceaSPaul Mackerras #if USES_PPC_SYS 49*70d64ceaSPaul Mackerras #include <asm/ppc_sys.h> 50*70d64ceaSPaul Mackerras #endif 51*70d64ceaSPaul Mackerras 52*70d64ceaSPaul Mackerras #if defined CONFIG_KGDB 53*70d64ceaSPaul Mackerras #include <asm/kgdb.h> 54*70d64ceaSPaul Mackerras #endif 55*70d64ceaSPaul Mackerras 56*70d64ceaSPaul Mackerras extern void platform_init(void); 57*70d64ceaSPaul Mackerras extern void bootx_init(unsigned long r4, unsigned long phys); 58*70d64ceaSPaul Mackerras 59*70d64ceaSPaul Mackerras extern void ppc6xx_idle(void); 60*70d64ceaSPaul Mackerras extern void power4_idle(void); 61*70d64ceaSPaul Mackerras 62*70d64ceaSPaul Mackerras boot_infos_t *boot_infos; 63*70d64ceaSPaul Mackerras struct ide_machdep_calls ppc_ide_md; 64*70d64ceaSPaul Mackerras 65*70d64ceaSPaul Mackerras /* Used with the BI_MEMSIZE bootinfo parameter to store the memory 66*70d64ceaSPaul Mackerras size value reported by the boot loader. */ 67*70d64ceaSPaul Mackerras unsigned long boot_mem_size; 68*70d64ceaSPaul Mackerras 69*70d64ceaSPaul Mackerras unsigned long ISA_DMA_THRESHOLD; 70*70d64ceaSPaul Mackerras unsigned int DMA_MODE_READ; 71*70d64ceaSPaul Mackerras unsigned int DMA_MODE_WRITE; 72*70d64ceaSPaul Mackerras 73*70d64ceaSPaul Mackerras #ifdef CONFIG_PPC_MULTIPLATFORM 74*70d64ceaSPaul Mackerras int _machine = 0; 75*70d64ceaSPaul Mackerras 76*70d64ceaSPaul Mackerras extern void prep_init(void); 77*70d64ceaSPaul Mackerras extern void pmac_init(void); 78*70d64ceaSPaul Mackerras extern void chrp_init(void); 79*70d64ceaSPaul Mackerras 80*70d64ceaSPaul Mackerras dev_t boot_dev; 81*70d64ceaSPaul Mackerras #endif /* CONFIG_PPC_MULTIPLATFORM */ 82*70d64ceaSPaul Mackerras 83*70d64ceaSPaul Mackerras #ifdef CONFIG_MAGIC_SYSRQ 84*70d64ceaSPaul Mackerras unsigned long SYSRQ_KEY = 0x54; 85*70d64ceaSPaul Mackerras #endif /* CONFIG_MAGIC_SYSRQ */ 86*70d64ceaSPaul Mackerras 87*70d64ceaSPaul Mackerras #ifdef CONFIG_VGA_CONSOLE 88*70d64ceaSPaul Mackerras unsigned long vgacon_remap_base; 89*70d64ceaSPaul Mackerras #endif 90*70d64ceaSPaul Mackerras 91*70d64ceaSPaul Mackerras struct machdep_calls ppc_md; 92*70d64ceaSPaul Mackerras 93*70d64ceaSPaul Mackerras /* 94*70d64ceaSPaul Mackerras * These are used in binfmt_elf.c to put aux entries on the stack 95*70d64ceaSPaul Mackerras * for each elf executable being started. 96*70d64ceaSPaul Mackerras */ 97*70d64ceaSPaul Mackerras int dcache_bsize; 98*70d64ceaSPaul Mackerras int icache_bsize; 99*70d64ceaSPaul Mackerras int ucache_bsize; 100*70d64ceaSPaul Mackerras 101*70d64ceaSPaul Mackerras #if defined(CONFIG_VGA_CONSOLE) || defined(CONFIG_FB_VGA16) || \ 102*70d64ceaSPaul Mackerras defined(CONFIG_FB_VGA16_MODULE) || defined(CONFIG_FB_VESA) 103*70d64ceaSPaul Mackerras struct screen_info screen_info = { 104*70d64ceaSPaul Mackerras 0, 25, /* orig-x, orig-y */ 105*70d64ceaSPaul Mackerras 0, /* unused */ 106*70d64ceaSPaul Mackerras 0, /* orig-video-page */ 107*70d64ceaSPaul Mackerras 0, /* orig-video-mode */ 108*70d64ceaSPaul Mackerras 80, /* orig-video-cols */ 109*70d64ceaSPaul Mackerras 0,0,0, /* ega_ax, ega_bx, ega_cx */ 110*70d64ceaSPaul Mackerras 25, /* orig-video-lines */ 111*70d64ceaSPaul Mackerras 1, /* orig-video-isVGA */ 112*70d64ceaSPaul Mackerras 16 /* orig-video-points */ 113*70d64ceaSPaul Mackerras }; 114*70d64ceaSPaul Mackerras #endif /* CONFIG_VGA_CONSOLE || CONFIG_FB_VGA16 || CONFIG_FB_VESA */ 115*70d64ceaSPaul Mackerras 116*70d64ceaSPaul Mackerras void machine_restart(char *cmd) 117*70d64ceaSPaul Mackerras { 118*70d64ceaSPaul Mackerras #ifdef CONFIG_NVRAM 119*70d64ceaSPaul Mackerras nvram_sync(); 120*70d64ceaSPaul Mackerras #endif 121*70d64ceaSPaul Mackerras ppc_md.restart(cmd); 122*70d64ceaSPaul Mackerras } 123*70d64ceaSPaul Mackerras 124*70d64ceaSPaul Mackerras void machine_power_off(void) 125*70d64ceaSPaul Mackerras { 126*70d64ceaSPaul Mackerras #ifdef CONFIG_NVRAM 127*70d64ceaSPaul Mackerras nvram_sync(); 128*70d64ceaSPaul Mackerras #endif 129*70d64ceaSPaul Mackerras ppc_md.power_off(); 130*70d64ceaSPaul Mackerras } 131*70d64ceaSPaul Mackerras 132*70d64ceaSPaul Mackerras void machine_halt(void) 133*70d64ceaSPaul Mackerras { 134*70d64ceaSPaul Mackerras #ifdef CONFIG_NVRAM 135*70d64ceaSPaul Mackerras nvram_sync(); 136*70d64ceaSPaul Mackerras #endif 137*70d64ceaSPaul Mackerras ppc_md.halt(); 138*70d64ceaSPaul Mackerras } 139*70d64ceaSPaul Mackerras 140*70d64ceaSPaul Mackerras void (*pm_power_off)(void) = machine_power_off; 141*70d64ceaSPaul Mackerras 142*70d64ceaSPaul Mackerras #ifdef CONFIG_TAU 143*70d64ceaSPaul Mackerras extern u32 cpu_temp(unsigned long cpu); 144*70d64ceaSPaul Mackerras extern u32 cpu_temp_both(unsigned long cpu); 145*70d64ceaSPaul Mackerras #endif /* CONFIG_TAU */ 146*70d64ceaSPaul Mackerras 147*70d64ceaSPaul Mackerras int show_cpuinfo(struct seq_file *m, void *v) 148*70d64ceaSPaul Mackerras { 149*70d64ceaSPaul Mackerras int i = (int) v - 1; 150*70d64ceaSPaul Mackerras int err = 0; 151*70d64ceaSPaul Mackerras unsigned int pvr; 152*70d64ceaSPaul Mackerras unsigned short maj, min; 153*70d64ceaSPaul Mackerras unsigned long lpj; 154*70d64ceaSPaul Mackerras 155*70d64ceaSPaul Mackerras if (i >= NR_CPUS) { 156*70d64ceaSPaul Mackerras /* Show summary information */ 157*70d64ceaSPaul Mackerras #ifdef CONFIG_SMP 158*70d64ceaSPaul Mackerras unsigned long bogosum = 0; 159*70d64ceaSPaul Mackerras for (i = 0; i < NR_CPUS; ++i) 160*70d64ceaSPaul Mackerras if (cpu_online(i)) 161*70d64ceaSPaul Mackerras bogosum += cpu_data[i].loops_per_jiffy; 162*70d64ceaSPaul Mackerras seq_printf(m, "total bogomips\t: %lu.%02lu\n", 163*70d64ceaSPaul Mackerras bogosum/(500000/HZ), bogosum/(5000/HZ) % 100); 164*70d64ceaSPaul Mackerras #endif /* CONFIG_SMP */ 165*70d64ceaSPaul Mackerras 166*70d64ceaSPaul Mackerras if (ppc_md.show_cpuinfo != NULL) 167*70d64ceaSPaul Mackerras err = ppc_md.show_cpuinfo(m); 168*70d64ceaSPaul Mackerras return err; 169*70d64ceaSPaul Mackerras } 170*70d64ceaSPaul Mackerras 171*70d64ceaSPaul Mackerras #ifdef CONFIG_SMP 172*70d64ceaSPaul Mackerras if (!cpu_online(i)) 173*70d64ceaSPaul Mackerras return 0; 174*70d64ceaSPaul Mackerras pvr = cpu_data[i].pvr; 175*70d64ceaSPaul Mackerras lpj = cpu_data[i].loops_per_jiffy; 176*70d64ceaSPaul Mackerras #else 177*70d64ceaSPaul Mackerras pvr = mfspr(SPRN_PVR); 178*70d64ceaSPaul Mackerras lpj = loops_per_jiffy; 179*70d64ceaSPaul Mackerras #endif 180*70d64ceaSPaul Mackerras 181*70d64ceaSPaul Mackerras seq_printf(m, "processor\t: %d\n", i); 182*70d64ceaSPaul Mackerras seq_printf(m, "cpu\t\t: "); 183*70d64ceaSPaul Mackerras 184*70d64ceaSPaul Mackerras if (cur_cpu_spec->pvr_mask) 185*70d64ceaSPaul Mackerras seq_printf(m, "%s", cur_cpu_spec->cpu_name); 186*70d64ceaSPaul Mackerras else 187*70d64ceaSPaul Mackerras seq_printf(m, "unknown (%08x)", pvr); 188*70d64ceaSPaul Mackerras #ifdef CONFIG_ALTIVEC 189*70d64ceaSPaul Mackerras if (cur_cpu_spec->cpu_features & CPU_FTR_ALTIVEC) 190*70d64ceaSPaul Mackerras seq_printf(m, ", altivec supported"); 191*70d64ceaSPaul Mackerras #endif 192*70d64ceaSPaul Mackerras seq_printf(m, "\n"); 193*70d64ceaSPaul Mackerras 194*70d64ceaSPaul Mackerras #ifdef CONFIG_TAU 195*70d64ceaSPaul Mackerras if (cur_cpu_spec->cpu_features & CPU_FTR_TAU) { 196*70d64ceaSPaul Mackerras #ifdef CONFIG_TAU_AVERAGE 197*70d64ceaSPaul Mackerras /* more straightforward, but potentially misleading */ 198*70d64ceaSPaul Mackerras seq_printf(m, "temperature \t: %u C (uncalibrated)\n", 199*70d64ceaSPaul Mackerras cpu_temp(i)); 200*70d64ceaSPaul Mackerras #else 201*70d64ceaSPaul Mackerras /* show the actual temp sensor range */ 202*70d64ceaSPaul Mackerras u32 temp; 203*70d64ceaSPaul Mackerras temp = cpu_temp_both(i); 204*70d64ceaSPaul Mackerras seq_printf(m, "temperature \t: %u-%u C (uncalibrated)\n", 205*70d64ceaSPaul Mackerras temp & 0xff, temp >> 16); 206*70d64ceaSPaul Mackerras #endif 207*70d64ceaSPaul Mackerras } 208*70d64ceaSPaul Mackerras #endif /* CONFIG_TAU */ 209*70d64ceaSPaul Mackerras 210*70d64ceaSPaul Mackerras if (ppc_md.show_percpuinfo != NULL) { 211*70d64ceaSPaul Mackerras err = ppc_md.show_percpuinfo(m, i); 212*70d64ceaSPaul Mackerras if (err) 213*70d64ceaSPaul Mackerras return err; 214*70d64ceaSPaul Mackerras } 215*70d64ceaSPaul Mackerras 216*70d64ceaSPaul Mackerras /* If we are a Freescale core do a simple check so 217*70d64ceaSPaul Mackerras * we dont have to keep adding cases in the future */ 218*70d64ceaSPaul Mackerras if ((PVR_VER(pvr) & 0x8000) == 0x8000) { 219*70d64ceaSPaul Mackerras maj = PVR_MAJ(pvr); 220*70d64ceaSPaul Mackerras min = PVR_MIN(pvr); 221*70d64ceaSPaul Mackerras } else { 222*70d64ceaSPaul Mackerras switch (PVR_VER(pvr)) { 223*70d64ceaSPaul Mackerras case 0x0020: /* 403 family */ 224*70d64ceaSPaul Mackerras maj = PVR_MAJ(pvr) + 1; 225*70d64ceaSPaul Mackerras min = PVR_MIN(pvr); 226*70d64ceaSPaul Mackerras break; 227*70d64ceaSPaul Mackerras case 0x1008: /* 740P/750P ?? */ 228*70d64ceaSPaul Mackerras maj = ((pvr >> 8) & 0xFF) - 1; 229*70d64ceaSPaul Mackerras min = pvr & 0xFF; 230*70d64ceaSPaul Mackerras break; 231*70d64ceaSPaul Mackerras default: 232*70d64ceaSPaul Mackerras maj = (pvr >> 8) & 0xFF; 233*70d64ceaSPaul Mackerras min = pvr & 0xFF; 234*70d64ceaSPaul Mackerras break; 235*70d64ceaSPaul Mackerras } 236*70d64ceaSPaul Mackerras } 237*70d64ceaSPaul Mackerras 238*70d64ceaSPaul Mackerras seq_printf(m, "revision\t: %hd.%hd (pvr %04x %04x)\n", 239*70d64ceaSPaul Mackerras maj, min, PVR_VER(pvr), PVR_REV(pvr)); 240*70d64ceaSPaul Mackerras 241*70d64ceaSPaul Mackerras seq_printf(m, "bogomips\t: %lu.%02lu\n", 242*70d64ceaSPaul Mackerras lpj / (500000/HZ), (lpj / (5000/HZ)) % 100); 243*70d64ceaSPaul Mackerras 244*70d64ceaSPaul Mackerras #if USES_PPC_SYS 245*70d64ceaSPaul Mackerras if (cur_ppc_sys_spec->ppc_sys_name) 246*70d64ceaSPaul Mackerras seq_printf(m, "chipset\t\t: %s\n", 247*70d64ceaSPaul Mackerras cur_ppc_sys_spec->ppc_sys_name); 248*70d64ceaSPaul Mackerras #endif 249*70d64ceaSPaul Mackerras 250*70d64ceaSPaul Mackerras #ifdef CONFIG_SMP 251*70d64ceaSPaul Mackerras seq_printf(m, "\n"); 252*70d64ceaSPaul Mackerras #endif 253*70d64ceaSPaul Mackerras 254*70d64ceaSPaul Mackerras return 0; 255*70d64ceaSPaul Mackerras } 256*70d64ceaSPaul Mackerras 257*70d64ceaSPaul Mackerras static void *c_start(struct seq_file *m, loff_t *pos) 258*70d64ceaSPaul Mackerras { 259*70d64ceaSPaul Mackerras int i = *pos; 260*70d64ceaSPaul Mackerras 261*70d64ceaSPaul Mackerras return i <= NR_CPUS? (void *) (i + 1): NULL; 262*70d64ceaSPaul Mackerras } 263*70d64ceaSPaul Mackerras 264*70d64ceaSPaul Mackerras static void *c_next(struct seq_file *m, void *v, loff_t *pos) 265*70d64ceaSPaul Mackerras { 266*70d64ceaSPaul Mackerras ++*pos; 267*70d64ceaSPaul Mackerras return c_start(m, pos); 268*70d64ceaSPaul Mackerras } 269*70d64ceaSPaul Mackerras 270*70d64ceaSPaul Mackerras static void c_stop(struct seq_file *m, void *v) 271*70d64ceaSPaul Mackerras { 272*70d64ceaSPaul Mackerras } 273*70d64ceaSPaul Mackerras 274*70d64ceaSPaul Mackerras struct seq_operations cpuinfo_op = { 275*70d64ceaSPaul Mackerras .start =c_start, 276*70d64ceaSPaul Mackerras .next = c_next, 277*70d64ceaSPaul Mackerras .stop = c_stop, 278*70d64ceaSPaul Mackerras .show = show_cpuinfo, 279*70d64ceaSPaul Mackerras }; 280*70d64ceaSPaul Mackerras 281*70d64ceaSPaul Mackerras /* 282*70d64ceaSPaul Mackerras * We're called here very early in the boot. We determine the machine 283*70d64ceaSPaul Mackerras * type and call the appropriate low-level setup functions. 284*70d64ceaSPaul Mackerras * -- Cort <cort@fsmlabs.com> 285*70d64ceaSPaul Mackerras * 286*70d64ceaSPaul Mackerras * Note that the kernel may be running at an address which is different 287*70d64ceaSPaul Mackerras * from the address that it was linked at, so we must use RELOC/PTRRELOC 288*70d64ceaSPaul Mackerras * to access static data (including strings). -- paulus 289*70d64ceaSPaul Mackerras */ 290*70d64ceaSPaul Mackerras unsigned long __init early_init(unsigned long dt_ptr) 291*70d64ceaSPaul Mackerras { 292*70d64ceaSPaul Mackerras unsigned long offset = reloc_offset(); 293*70d64ceaSPaul Mackerras 294*70d64ceaSPaul Mackerras reloc_got2(offset); 295*70d64ceaSPaul Mackerras 296*70d64ceaSPaul Mackerras /* 297*70d64ceaSPaul Mackerras * Identify the CPU type and fix up code sections 298*70d64ceaSPaul Mackerras * that depend on which cpu we have. 299*70d64ceaSPaul Mackerras */ 300*70d64ceaSPaul Mackerras identify_cpu(offset, 0); 301*70d64ceaSPaul Mackerras do_cpu_ftr_fixups(offset); 302*70d64ceaSPaul Mackerras 303*70d64ceaSPaul Mackerras #ifdef CONFIG_BOOTX_TEXT 304*70d64ceaSPaul Mackerras btext_prepare_BAT(); 305*70d64ceaSPaul Mackerras #endif 306*70d64ceaSPaul Mackerras 307*70d64ceaSPaul Mackerras reloc_got2(-offset); 308*70d64ceaSPaul Mackerras 309*70d64ceaSPaul Mackerras return KERNELBASE + offset; 310*70d64ceaSPaul Mackerras } 311*70d64ceaSPaul Mackerras 312*70d64ceaSPaul Mackerras #ifdef CONFIG_PPC_OF 313*70d64ceaSPaul Mackerras /* 314*70d64ceaSPaul Mackerras * Assume here that all clock rates are the same in a 315*70d64ceaSPaul Mackerras * smp system. -- Cort 316*70d64ceaSPaul Mackerras */ 317*70d64ceaSPaul Mackerras int 318*70d64ceaSPaul Mackerras of_show_percpuinfo(struct seq_file *m, int i) 319*70d64ceaSPaul Mackerras { 320*70d64ceaSPaul Mackerras struct device_node *cpu_node; 321*70d64ceaSPaul Mackerras u32 *fp; 322*70d64ceaSPaul Mackerras int s; 323*70d64ceaSPaul Mackerras 324*70d64ceaSPaul Mackerras cpu_node = find_type_devices("cpu"); 325*70d64ceaSPaul Mackerras if (!cpu_node) 326*70d64ceaSPaul Mackerras return 0; 327*70d64ceaSPaul Mackerras for (s = 0; s < i && cpu_node->next; s++) 328*70d64ceaSPaul Mackerras cpu_node = cpu_node->next; 329*70d64ceaSPaul Mackerras fp = (u32 *)get_property(cpu_node, "clock-frequency", NULL); 330*70d64ceaSPaul Mackerras if (fp) 331*70d64ceaSPaul Mackerras seq_printf(m, "clock\t\t: %dMHz\n", *fp / 1000000); 332*70d64ceaSPaul Mackerras return 0; 333*70d64ceaSPaul Mackerras } 334*70d64ceaSPaul Mackerras 335*70d64ceaSPaul Mackerras void __init 336*70d64ceaSPaul Mackerras intuit_machine_type(void) 337*70d64ceaSPaul Mackerras { 338*70d64ceaSPaul Mackerras char *model; 339*70d64ceaSPaul Mackerras struct device_node *root; 340*70d64ceaSPaul Mackerras 341*70d64ceaSPaul Mackerras /* ask the OF info if we're a chrp or pmac */ 342*70d64ceaSPaul Mackerras root = find_path_device("/"); 343*70d64ceaSPaul Mackerras if (root != 0) { 344*70d64ceaSPaul Mackerras /* assume pmac unless proven to be chrp -- Cort */ 345*70d64ceaSPaul Mackerras _machine = _MACH_Pmac; 346*70d64ceaSPaul Mackerras model = get_property(root, "device_type", NULL); 347*70d64ceaSPaul Mackerras if (model && !strncmp("chrp", model, 4)) 348*70d64ceaSPaul Mackerras _machine = _MACH_chrp; 349*70d64ceaSPaul Mackerras else { 350*70d64ceaSPaul Mackerras model = get_property(root, "model", NULL); 351*70d64ceaSPaul Mackerras if (model && !strncmp(model, "IBM", 3)) 352*70d64ceaSPaul Mackerras _machine = _MACH_chrp; 353*70d64ceaSPaul Mackerras } 354*70d64ceaSPaul Mackerras } 355*70d64ceaSPaul Mackerras } 356*70d64ceaSPaul Mackerras #endif 357*70d64ceaSPaul Mackerras 358*70d64ceaSPaul Mackerras #ifdef CONFIG_PPC_MULTIPLATFORM 359*70d64ceaSPaul Mackerras /* 360*70d64ceaSPaul Mackerras * The PPC_MULTIPLATFORM version of platform_init... 361*70d64ceaSPaul Mackerras */ 362*70d64ceaSPaul Mackerras void __init platform_init(void) 363*70d64ceaSPaul Mackerras { 364*70d64ceaSPaul Mackerras /* if we didn't get any bootinfo telling us what we are... */ 365*70d64ceaSPaul Mackerras if (_machine == 0) { 366*70d64ceaSPaul Mackerras /* prep boot loader tells us if we're prep or not */ 367*70d64ceaSPaul Mackerras if ( *(unsigned long *)(KERNELBASE) == (0xdeadc0de) ) 368*70d64ceaSPaul Mackerras _machine = _MACH_prep; 369*70d64ceaSPaul Mackerras } 370*70d64ceaSPaul Mackerras 371*70d64ceaSPaul Mackerras #ifdef CONFIG_PPC_PREP 372*70d64ceaSPaul Mackerras /* not much more to do here, if prep */ 373*70d64ceaSPaul Mackerras if (_machine == _MACH_prep) { 374*70d64ceaSPaul Mackerras prep_init(); 375*70d64ceaSPaul Mackerras return; 376*70d64ceaSPaul Mackerras } 377*70d64ceaSPaul Mackerras #endif 378*70d64ceaSPaul Mackerras 379*70d64ceaSPaul Mackerras #ifdef CONFIG_ADB 380*70d64ceaSPaul Mackerras if (strstr(cmd_line, "adb_sync")) { 381*70d64ceaSPaul Mackerras extern int __adb_probe_sync; 382*70d64ceaSPaul Mackerras __adb_probe_sync = 1; 383*70d64ceaSPaul Mackerras } 384*70d64ceaSPaul Mackerras #endif /* CONFIG_ADB */ 385*70d64ceaSPaul Mackerras 386*70d64ceaSPaul Mackerras switch (_machine) { 387*70d64ceaSPaul Mackerras #ifdef CONFIG_PPC_PMAC 388*70d64ceaSPaul Mackerras case _MACH_Pmac: 389*70d64ceaSPaul Mackerras pmac_init(); 390*70d64ceaSPaul Mackerras break; 391*70d64ceaSPaul Mackerras #endif 392*70d64ceaSPaul Mackerras #ifdef CONFIG_PPC_CHRP 393*70d64ceaSPaul Mackerras case _MACH_chrp: 394*70d64ceaSPaul Mackerras chrp_init(); 395*70d64ceaSPaul Mackerras break; 396*70d64ceaSPaul Mackerras #endif 397*70d64ceaSPaul Mackerras } 398*70d64ceaSPaul Mackerras } 399*70d64ceaSPaul Mackerras 400*70d64ceaSPaul Mackerras #ifdef CONFIG_SERIAL_CORE_CONSOLE 401*70d64ceaSPaul Mackerras extern char *of_stdout_device; 402*70d64ceaSPaul Mackerras 403*70d64ceaSPaul Mackerras static int __init set_preferred_console(void) 404*70d64ceaSPaul Mackerras { 405*70d64ceaSPaul Mackerras struct device_node *prom_stdout; 406*70d64ceaSPaul Mackerras char *name; 407*70d64ceaSPaul Mackerras int offset = 0; 408*70d64ceaSPaul Mackerras 409*70d64ceaSPaul Mackerras if (of_stdout_device == NULL) 410*70d64ceaSPaul Mackerras return -ENODEV; 411*70d64ceaSPaul Mackerras 412*70d64ceaSPaul Mackerras /* The user has requested a console so this is already set up. */ 413*70d64ceaSPaul Mackerras if (strstr(saved_command_line, "console=")) 414*70d64ceaSPaul Mackerras return -EBUSY; 415*70d64ceaSPaul Mackerras 416*70d64ceaSPaul Mackerras prom_stdout = find_path_device(of_stdout_device); 417*70d64ceaSPaul Mackerras if (!prom_stdout) 418*70d64ceaSPaul Mackerras return -ENODEV; 419*70d64ceaSPaul Mackerras 420*70d64ceaSPaul Mackerras name = (char *)get_property(prom_stdout, "name", NULL); 421*70d64ceaSPaul Mackerras if (!name) 422*70d64ceaSPaul Mackerras return -ENODEV; 423*70d64ceaSPaul Mackerras 424*70d64ceaSPaul Mackerras if (strcmp(name, "serial") == 0) { 425*70d64ceaSPaul Mackerras int i; 426*70d64ceaSPaul Mackerras u32 *reg = (u32 *)get_property(prom_stdout, "reg", &i); 427*70d64ceaSPaul Mackerras if (i > 8) { 428*70d64ceaSPaul Mackerras switch (reg[1]) { 429*70d64ceaSPaul Mackerras case 0x3f8: 430*70d64ceaSPaul Mackerras offset = 0; 431*70d64ceaSPaul Mackerras break; 432*70d64ceaSPaul Mackerras case 0x2f8: 433*70d64ceaSPaul Mackerras offset = 1; 434*70d64ceaSPaul Mackerras break; 435*70d64ceaSPaul Mackerras case 0x898: 436*70d64ceaSPaul Mackerras offset = 2; 437*70d64ceaSPaul Mackerras break; 438*70d64ceaSPaul Mackerras case 0x890: 439*70d64ceaSPaul Mackerras offset = 3; 440*70d64ceaSPaul Mackerras break; 441*70d64ceaSPaul Mackerras default: 442*70d64ceaSPaul Mackerras /* We dont recognise the serial port */ 443*70d64ceaSPaul Mackerras return -ENODEV; 444*70d64ceaSPaul Mackerras } 445*70d64ceaSPaul Mackerras } 446*70d64ceaSPaul Mackerras } else if (strcmp(name, "ch-a") == 0) 447*70d64ceaSPaul Mackerras offset = 0; 448*70d64ceaSPaul Mackerras else if (strcmp(name, "ch-b") == 0) 449*70d64ceaSPaul Mackerras offset = 1; 450*70d64ceaSPaul Mackerras else 451*70d64ceaSPaul Mackerras return -ENODEV; 452*70d64ceaSPaul Mackerras return add_preferred_console("ttyS", offset, NULL); 453*70d64ceaSPaul Mackerras } 454*70d64ceaSPaul Mackerras console_initcall(set_preferred_console); 455*70d64ceaSPaul Mackerras #endif /* CONFIG_SERIAL_CORE_CONSOLE */ 456*70d64ceaSPaul Mackerras #endif /* CONFIG_PPC_MULTIPLATFORM */ 457*70d64ceaSPaul Mackerras 458*70d64ceaSPaul Mackerras struct bi_record *find_bootinfo(void) 459*70d64ceaSPaul Mackerras { 460*70d64ceaSPaul Mackerras struct bi_record *rec; 461*70d64ceaSPaul Mackerras 462*70d64ceaSPaul Mackerras rec = (struct bi_record *)_ALIGN((ulong)__bss_start+(1<<20)-1,(1<<20)); 463*70d64ceaSPaul Mackerras if ( rec->tag != BI_FIRST ) { 464*70d64ceaSPaul Mackerras /* 465*70d64ceaSPaul Mackerras * This 0x10000 offset is a terrible hack but it will go away when 466*70d64ceaSPaul Mackerras * we have the bootloader handle all the relocation and 467*70d64ceaSPaul Mackerras * prom calls -- Cort 468*70d64ceaSPaul Mackerras */ 469*70d64ceaSPaul Mackerras rec = (struct bi_record *)_ALIGN((ulong)__bss_start+0x10000+(1<<20)-1,(1<<20)); 470*70d64ceaSPaul Mackerras if ( rec->tag != BI_FIRST ) 471*70d64ceaSPaul Mackerras return NULL; 472*70d64ceaSPaul Mackerras } 473*70d64ceaSPaul Mackerras return rec; 474*70d64ceaSPaul Mackerras } 475*70d64ceaSPaul Mackerras 476*70d64ceaSPaul Mackerras /* 477*70d64ceaSPaul Mackerras * Find out what kind of machine we're on and save any data we need 478*70d64ceaSPaul Mackerras * from the early boot process (devtree is copied on pmac by prom_init()). 479*70d64ceaSPaul Mackerras * This is called very early on the boot process, after a minimal 480*70d64ceaSPaul Mackerras * MMU environment has been set up but before MMU_init is called. 481*70d64ceaSPaul Mackerras */ 482*70d64ceaSPaul Mackerras void __init machine_init(unsigned long dt_ptr, unsigned long phys) 483*70d64ceaSPaul Mackerras { 484*70d64ceaSPaul Mackerras early_init_devtree(__va(dt_ptr)); 485*70d64ceaSPaul Mackerras 486*70d64ceaSPaul Mackerras #ifdef CONFIG_CMDLINE 487*70d64ceaSPaul Mackerras strlcpy(cmd_line, CONFIG_CMDLINE, sizeof(cmd_line)); 488*70d64ceaSPaul Mackerras #endif /* CONFIG_CMDLINE */ 489*70d64ceaSPaul Mackerras 490*70d64ceaSPaul Mackerras #ifdef CONFIG_6xx 491*70d64ceaSPaul Mackerras ppc_md.power_save = ppc6xx_idle; 492*70d64ceaSPaul Mackerras #endif 493*70d64ceaSPaul Mackerras #ifdef CONFIG_POWER4 494*70d64ceaSPaul Mackerras ppc_md.power_save = power4_idle; 495*70d64ceaSPaul Mackerras #endif 496*70d64ceaSPaul Mackerras 497*70d64ceaSPaul Mackerras platform_init(); 498*70d64ceaSPaul Mackerras 499*70d64ceaSPaul Mackerras if (ppc_md.progress) 500*70d64ceaSPaul Mackerras ppc_md.progress("id mach(): done", 0x200); 501*70d64ceaSPaul Mackerras } 502*70d64ceaSPaul Mackerras 503*70d64ceaSPaul Mackerras #ifdef CONFIG_BOOKE_WDT 504*70d64ceaSPaul Mackerras /* Checks wdt=x and wdt_period=xx command-line option */ 505*70d64ceaSPaul Mackerras int __init early_parse_wdt(char *p) 506*70d64ceaSPaul Mackerras { 507*70d64ceaSPaul Mackerras if (p && strncmp(p, "0", 1) != 0) 508*70d64ceaSPaul Mackerras booke_wdt_enabled = 1; 509*70d64ceaSPaul Mackerras 510*70d64ceaSPaul Mackerras return 0; 511*70d64ceaSPaul Mackerras } 512*70d64ceaSPaul Mackerras early_param("wdt", early_parse_wdt); 513*70d64ceaSPaul Mackerras 514*70d64ceaSPaul Mackerras int __init early_parse_wdt_period (char *p) 515*70d64ceaSPaul Mackerras { 516*70d64ceaSPaul Mackerras if (p) 517*70d64ceaSPaul Mackerras booke_wdt_period = simple_strtoul(p, NULL, 0); 518*70d64ceaSPaul Mackerras 519*70d64ceaSPaul Mackerras return 0; 520*70d64ceaSPaul Mackerras } 521*70d64ceaSPaul Mackerras early_param("wdt_period", early_parse_wdt_period); 522*70d64ceaSPaul Mackerras #endif /* CONFIG_BOOKE_WDT */ 523*70d64ceaSPaul Mackerras 524*70d64ceaSPaul Mackerras /* Checks "l2cr=xxxx" command-line option */ 525*70d64ceaSPaul Mackerras int __init ppc_setup_l2cr(char *str) 526*70d64ceaSPaul Mackerras { 527*70d64ceaSPaul Mackerras if (cpu_has_feature(CPU_FTR_L2CR)) { 528*70d64ceaSPaul Mackerras unsigned long val = simple_strtoul(str, NULL, 0); 529*70d64ceaSPaul Mackerras printk(KERN_INFO "l2cr set to %lx\n", val); 530*70d64ceaSPaul Mackerras _set_L2CR(0); /* force invalidate by disable cache */ 531*70d64ceaSPaul Mackerras _set_L2CR(val); /* and enable it */ 532*70d64ceaSPaul Mackerras } 533*70d64ceaSPaul Mackerras return 1; 534*70d64ceaSPaul Mackerras } 535*70d64ceaSPaul Mackerras __setup("l2cr=", ppc_setup_l2cr); 536*70d64ceaSPaul Mackerras 537*70d64ceaSPaul Mackerras #ifdef CONFIG_GENERIC_NVRAM 538*70d64ceaSPaul Mackerras 539*70d64ceaSPaul Mackerras /* Generic nvram hooks used by drivers/char/gen_nvram.c */ 540*70d64ceaSPaul Mackerras unsigned char nvram_read_byte(int addr) 541*70d64ceaSPaul Mackerras { 542*70d64ceaSPaul Mackerras if (ppc_md.nvram_read_val) 543*70d64ceaSPaul Mackerras return ppc_md.nvram_read_val(addr); 544*70d64ceaSPaul Mackerras return 0xff; 545*70d64ceaSPaul Mackerras } 546*70d64ceaSPaul Mackerras EXPORT_SYMBOL(nvram_read_byte); 547*70d64ceaSPaul Mackerras 548*70d64ceaSPaul Mackerras void nvram_write_byte(unsigned char val, int addr) 549*70d64ceaSPaul Mackerras { 550*70d64ceaSPaul Mackerras if (ppc_md.nvram_write_val) 551*70d64ceaSPaul Mackerras ppc_md.nvram_write_val(addr, val); 552*70d64ceaSPaul Mackerras } 553*70d64ceaSPaul Mackerras EXPORT_SYMBOL(nvram_write_byte); 554*70d64ceaSPaul Mackerras 555*70d64ceaSPaul Mackerras void nvram_sync(void) 556*70d64ceaSPaul Mackerras { 557*70d64ceaSPaul Mackerras if (ppc_md.nvram_sync) 558*70d64ceaSPaul Mackerras ppc_md.nvram_sync(); 559*70d64ceaSPaul Mackerras } 560*70d64ceaSPaul Mackerras EXPORT_SYMBOL(nvram_sync); 561*70d64ceaSPaul Mackerras 562*70d64ceaSPaul Mackerras #endif /* CONFIG_NVRAM */ 563*70d64ceaSPaul Mackerras 564*70d64ceaSPaul Mackerras static struct cpu cpu_devices[NR_CPUS]; 565*70d64ceaSPaul Mackerras 566*70d64ceaSPaul Mackerras int __init ppc_init(void) 567*70d64ceaSPaul Mackerras { 568*70d64ceaSPaul Mackerras int i; 569*70d64ceaSPaul Mackerras 570*70d64ceaSPaul Mackerras /* clear the progress line */ 571*70d64ceaSPaul Mackerras if ( ppc_md.progress ) ppc_md.progress(" ", 0xffff); 572*70d64ceaSPaul Mackerras 573*70d64ceaSPaul Mackerras /* register CPU devices */ 574*70d64ceaSPaul Mackerras for (i = 0; i < NR_CPUS; i++) 575*70d64ceaSPaul Mackerras if (cpu_possible(i)) 576*70d64ceaSPaul Mackerras register_cpu(&cpu_devices[i], i, NULL); 577*70d64ceaSPaul Mackerras 578*70d64ceaSPaul Mackerras /* call platform init */ 579*70d64ceaSPaul Mackerras if (ppc_md.init != NULL) { 580*70d64ceaSPaul Mackerras ppc_md.init(); 581*70d64ceaSPaul Mackerras } 582*70d64ceaSPaul Mackerras return 0; 583*70d64ceaSPaul Mackerras } 584*70d64ceaSPaul Mackerras 585*70d64ceaSPaul Mackerras arch_initcall(ppc_init); 586*70d64ceaSPaul Mackerras 587*70d64ceaSPaul Mackerras /* Warning, IO base is not yet inited */ 588*70d64ceaSPaul Mackerras void __init setup_arch(char **cmdline_p) 589*70d64ceaSPaul Mackerras { 590*70d64ceaSPaul Mackerras extern char *klimit; 591*70d64ceaSPaul Mackerras extern void do_init_bootmem(void); 592*70d64ceaSPaul Mackerras 593*70d64ceaSPaul Mackerras /* so udelay does something sensible, assume <= 1000 bogomips */ 594*70d64ceaSPaul Mackerras loops_per_jiffy = 500000000 / HZ; 595*70d64ceaSPaul Mackerras 596*70d64ceaSPaul Mackerras #ifdef CONFIG_BOOTX_TEXT 597*70d64ceaSPaul Mackerras map_boot_text(); 598*70d64ceaSPaul Mackerras #endif 599*70d64ceaSPaul Mackerras 600*70d64ceaSPaul Mackerras unflatten_device_tree(); 601*70d64ceaSPaul Mackerras finish_device_tree(); 602*70d64ceaSPaul Mackerras 603*70d64ceaSPaul Mackerras #ifdef CONFIG_PPC_MULTIPLATFORM 604*70d64ceaSPaul Mackerras /* This could be called "early setup arch", it must be done 605*70d64ceaSPaul Mackerras * now because xmon need it 606*70d64ceaSPaul Mackerras */ 607*70d64ceaSPaul Mackerras if (_machine == _MACH_Pmac) 608*70d64ceaSPaul Mackerras pmac_feature_init(); /* New cool way */ 609*70d64ceaSPaul Mackerras #endif 610*70d64ceaSPaul Mackerras 611*70d64ceaSPaul Mackerras #ifdef CONFIG_XMON 612*70d64ceaSPaul Mackerras xmon_map_scc(); 613*70d64ceaSPaul Mackerras if (strstr(cmd_line, "xmon")) 614*70d64ceaSPaul Mackerras xmon(NULL); 615*70d64ceaSPaul Mackerras #endif /* CONFIG_XMON */ 616*70d64ceaSPaul Mackerras if ( ppc_md.progress ) ppc_md.progress("setup_arch: enter", 0x3eab); 617*70d64ceaSPaul Mackerras 618*70d64ceaSPaul Mackerras #if defined(CONFIG_KGDB) 619*70d64ceaSPaul Mackerras if (ppc_md.kgdb_map_scc) 620*70d64ceaSPaul Mackerras ppc_md.kgdb_map_scc(); 621*70d64ceaSPaul Mackerras set_debug_traps(); 622*70d64ceaSPaul Mackerras if (strstr(cmd_line, "gdb")) { 623*70d64ceaSPaul Mackerras if (ppc_md.progress) 624*70d64ceaSPaul Mackerras ppc_md.progress("setup_arch: kgdb breakpoint", 0x4000); 625*70d64ceaSPaul Mackerras printk("kgdb breakpoint activated\n"); 626*70d64ceaSPaul Mackerras breakpoint(); 627*70d64ceaSPaul Mackerras } 628*70d64ceaSPaul Mackerras #endif 629*70d64ceaSPaul Mackerras 630*70d64ceaSPaul Mackerras /* 631*70d64ceaSPaul Mackerras * Set cache line size based on type of cpu as a default. 632*70d64ceaSPaul Mackerras * Systems with OF can look in the properties on the cpu node(s) 633*70d64ceaSPaul Mackerras * for a possibly more accurate value. 634*70d64ceaSPaul Mackerras */ 635*70d64ceaSPaul Mackerras if (cpu_has_feature(CPU_FTR_SPLIT_ID_CACHE)) { 636*70d64ceaSPaul Mackerras dcache_bsize = cur_cpu_spec->dcache_bsize; 637*70d64ceaSPaul Mackerras icache_bsize = cur_cpu_spec->icache_bsize; 638*70d64ceaSPaul Mackerras ucache_bsize = 0; 639*70d64ceaSPaul Mackerras } else 640*70d64ceaSPaul Mackerras ucache_bsize = dcache_bsize = icache_bsize 641*70d64ceaSPaul Mackerras = cur_cpu_spec->dcache_bsize; 642*70d64ceaSPaul Mackerras 643*70d64ceaSPaul Mackerras /* reboot on panic */ 644*70d64ceaSPaul Mackerras panic_timeout = 180; 645*70d64ceaSPaul Mackerras 646*70d64ceaSPaul Mackerras init_mm.start_code = PAGE_OFFSET; 647*70d64ceaSPaul Mackerras init_mm.end_code = (unsigned long) _etext; 648*70d64ceaSPaul Mackerras init_mm.end_data = (unsigned long) _edata; 649*70d64ceaSPaul Mackerras init_mm.brk = (unsigned long) klimit; 650*70d64ceaSPaul Mackerras 651*70d64ceaSPaul Mackerras /* Save unparsed command line copy for /proc/cmdline */ 652*70d64ceaSPaul Mackerras strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); 653*70d64ceaSPaul Mackerras *cmdline_p = cmd_line; 654*70d64ceaSPaul Mackerras 655*70d64ceaSPaul Mackerras parse_early_param(); 656*70d64ceaSPaul Mackerras 657*70d64ceaSPaul Mackerras /* set up the bootmem stuff with available memory */ 658*70d64ceaSPaul Mackerras do_init_bootmem(); 659*70d64ceaSPaul Mackerras if ( ppc_md.progress ) ppc_md.progress("setup_arch: bootmem", 0x3eab); 660*70d64ceaSPaul Mackerras 661*70d64ceaSPaul Mackerras #ifdef CONFIG_PPC_OCP 662*70d64ceaSPaul Mackerras /* Initialize OCP device list */ 663*70d64ceaSPaul Mackerras ocp_early_init(); 664*70d64ceaSPaul Mackerras if ( ppc_md.progress ) ppc_md.progress("ocp: exit", 0x3eab); 665*70d64ceaSPaul Mackerras #endif 666*70d64ceaSPaul Mackerras 667*70d64ceaSPaul Mackerras #ifdef CONFIG_DUMMY_CONSOLE 668*70d64ceaSPaul Mackerras conswitchp = &dummy_con; 669*70d64ceaSPaul Mackerras #endif 670*70d64ceaSPaul Mackerras 671*70d64ceaSPaul Mackerras ppc_md.setup_arch(); 672*70d64ceaSPaul Mackerras if ( ppc_md.progress ) ppc_md.progress("arch: exit", 0x3eab); 673*70d64ceaSPaul Mackerras 674*70d64ceaSPaul Mackerras paging_init(); 675*70d64ceaSPaul Mackerras 676*70d64ceaSPaul Mackerras /* this is for modules since _machine can be a define -- Cort */ 677*70d64ceaSPaul Mackerras ppc_md.ppc_machine = _machine; 678*70d64ceaSPaul Mackerras } 679