📄 setup.c
字号:
/* * Powermac setup and early boot code plus other random bits. * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Adapted for Power Macintosh by Paul Mackerras * Copyright (C) 1996 Paul Mackerras (paulus@samba.org) * * Derived from "arch/alpha/kernel/setup.c" * Copyright (C) 1995 Linus Torvalds * * Maintained by Benjamin Herrenschmidt (benh@kernel.crashing.org) * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version * 2 of the License, or (at your option) any later version. * *//* * bootup setup stuff.. */#include <linux/init.h>#include <linux/errno.h>#include <linux/sched.h>#include <linux/kernel.h>#include <linux/mm.h>#include <linux/stddef.h>#include <linux/unistd.h>#include <linux/ptrace.h>#include <linux/slab.h>#include <linux/user.h>#include <linux/a.out.h>#include <linux/tty.h>#include <linux/string.h>#include <linux/delay.h>#include <linux/ioport.h>#include <linux/major.h>#include <linux/initrd.h>#include <linux/vt_kern.h>#include <linux/console.h>#include <linux/pci.h>#include <linux/adb.h>#include <linux/cuda.h>#include <linux/pmu.h>#include <linux/irq.h>#include <linux/seq_file.h>#include <linux/root_dev.h>#include <linux/bitops.h>#include <linux/suspend.h>#include <asm/reg.h>#include <asm/sections.h>#include <asm/prom.h>#include <asm/system.h>#include <asm/pgtable.h>#include <asm/io.h>#include <asm/kexec.h>#include <asm/pci-bridge.h>#include <asm/ohare.h>#include <asm/mediabay.h>#include <asm/machdep.h>#include <asm/dma.h>#include <asm/cputable.h>#include <asm/btext.h>#include <asm/pmac_feature.h>#include <asm/time.h>#include <asm/of_device.h>#include <asm/of_platform.h>#include <asm/mmu_context.h>#include <asm/iommu.h>#include <asm/smu.h>#include <asm/pmc.h>#include <asm/lmb.h>#include <asm/udbg.h>#include "pmac.h"#undef SHOW_GATWICK_IRQSint ppc_override_l2cr = 0;int ppc_override_l2cr_value;int has_l2cache = 0;int pmac_newworld;static int current_root_goodness = -1;extern struct machdep_calls pmac_md;#define DEFAULT_ROOT_DEVICE Root_SDA1 /* sda1 - slightly silly choice */#ifdef CONFIG_PPC64#include <asm/udbg.h>int sccdbg;#endifextern void zs_kgdb_hook(int tty_num);sys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;EXPORT_SYMBOL(sys_ctrler);#ifdef CONFIG_PMAC_SMUunsigned long smu_cmdbuf_abs;EXPORT_SYMBOL(smu_cmdbuf_abs);#endif#ifdef CONFIG_SMPextern struct smp_ops_t psurge_smp_ops;extern struct smp_ops_t core99_smp_ops;#endif /* CONFIG_SMP */static void pmac_show_cpuinfo(struct seq_file *m){ struct device_node *np; const char *pp; int plen; int mbmodel; unsigned int mbflags; char* mbname; mbmodel = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_MODEL, 0); mbflags = pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_FLAGS, 0); if (pmac_call_feature(PMAC_FTR_GET_MB_INFO, NULL, PMAC_MB_INFO_NAME, (long) &mbname) != 0) mbname = "Unknown"; /* find motherboard type */ seq_printf(m, "machine\t\t: "); np = of_find_node_by_path("/"); if (np != NULL) { pp = of_get_property(np, "model", NULL); if (pp != NULL) seq_printf(m, "%s\n", pp); else seq_printf(m, "PowerMac\n"); pp = of_get_property(np, "compatible", &plen); if (pp != NULL) { seq_printf(m, "motherboard\t:"); while (plen > 0) { int l = strlen(pp) + 1; seq_printf(m, " %s", pp); plen -= l; pp += l; } seq_printf(m, "\n"); } of_node_put(np); } else seq_printf(m, "PowerMac\n"); /* print parsed model */ seq_printf(m, "detected as\t: %d (%s)\n", mbmodel, mbname); seq_printf(m, "pmac flags\t: %08x\n", mbflags); /* find l2 cache info */ np = of_find_node_by_name(NULL, "l2-cache"); if (np == NULL) np = of_find_node_by_type(NULL, "cache"); if (np != NULL) { const unsigned int *ic = of_get_property(np, "i-cache-size", NULL); const unsigned int *dc = of_get_property(np, "d-cache-size", NULL); seq_printf(m, "L2 cache\t:"); has_l2cache = 1; if (of_get_property(np, "cache-unified", NULL) != 0 && dc) { seq_printf(m, " %dK unified", *dc / 1024); } else { if (ic) seq_printf(m, " %dK instruction", *ic / 1024); if (dc) seq_printf(m, "%s %dK data", (ic? " +": ""), *dc / 1024); } pp = of_get_property(np, "ram-type", NULL); if (pp) seq_printf(m, " %s", pp); seq_printf(m, "\n"); of_node_put(np); } /* Indicate newworld/oldworld */ seq_printf(m, "pmac-generation\t: %s\n", pmac_newworld ? "NewWorld" : "OldWorld");}#ifndef CONFIG_ADB_CUDAint find_via_cuda(void){ struct device_node *dn = of_find_node_by_name(NULL, "via-cuda"); if (!dn) return 0; of_node_put(dn); printk("WARNING ! Your machine is CUDA-based but your kernel\n"); printk(" wasn't compiled with CONFIG_ADB_CUDA option !\n"); return 0;}#endif#ifndef CONFIG_ADB_PMUint find_via_pmu(void){ struct device_node *dn = of_find_node_by_name(NULL, "via-pmu"); if (!dn) return 0; of_node_put(dn); printk("WARNING ! Your machine is PMU-based but your kernel\n"); printk(" wasn't compiled with CONFIG_ADB_PMU option !\n"); return 0;}#endif#ifndef CONFIG_PMAC_SMUint smu_init(void){ /* should check and warn if SMU is present */ return 0;}#endif#ifdef CONFIG_PPC32static volatile u32 *sysctrl_regs;static void __init ohare_init(void){ struct device_node *dn; /* this area has the CPU identification register and some registers used by smp boards */ sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); /* * Turn on the L2 cache. * We assume that we have a PSX memory controller iff * we have an ohare I/O controller. */ dn = of_find_node_by_name(NULL, "ohare"); if (dn) { of_node_put(dn); if (((sysctrl_regs[2] >> 24) & 0xf) >= 3) { if (sysctrl_regs[4] & 0x10) sysctrl_regs[4] |= 0x04000020; else sysctrl_regs[4] |= 0x04000000; if(has_l2cache) printk(KERN_INFO "Level 2 cache enabled\n"); } }}static void __init l2cr_init(void){ /* Checks "l2cr-value" property in the registry */ if (cpu_has_feature(CPU_FTR_L2CR)) { struct device_node *np = of_find_node_by_name(NULL, "cpus"); if (np == 0) np = of_find_node_by_type(NULL, "cpu"); if (np != 0) { const unsigned int *l2cr = of_get_property(np, "l2cr-value", NULL); if (l2cr != 0) { ppc_override_l2cr = 1; ppc_override_l2cr_value = *l2cr; _set_L2CR(0); _set_L2CR(ppc_override_l2cr_value); } of_node_put(np); } } if (ppc_override_l2cr) printk(KERN_INFO "L2CR overridden (0x%x), " "backside cache is %s\n", ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) ? "enabled" : "disabled");}#endifstatic void __init pmac_setup_arch(void){ struct device_node *cpu, *ic; const int *fp; unsigned long pvr; pvr = PVR_VER(mfspr(SPRN_PVR)); /* Set loops_per_jiffy to a half-way reasonable value, for use until calibrate_delay gets called. */ loops_per_jiffy = 50000000 / HZ; cpu = of_find_node_by_type(NULL, "cpu"); if (cpu != NULL) { fp = of_get_property(cpu, "clock-frequency", NULL); if (fp != NULL) { if (pvr >= 0x30 && pvr < 0x80) /* PPC970 etc. */ loops_per_jiffy = *fp / (3 * HZ); else if (pvr == 4 || pvr >= 8) /* 604, G3, G4 etc. */ loops_per_jiffy = *fp / HZ; else /* 601, 603, etc. */ loops_per_jiffy = *fp / (2 * HZ); } of_node_put(cpu); } /* See if newworld or oldworld */ for (ic = NULL; (ic = of_find_all_nodes(ic)) != NULL; ) if (of_get_property(ic, "interrupt-controller", NULL)) break; if (ic) { pmac_newworld = 1; of_node_put(ic); } /* Lookup PCI hosts */ pmac_pci_init();#ifdef CONFIG_PPC32 ohare_init(); l2cr_init();#endif /* CONFIG_PPC32 */#ifdef CONFIG_KGDB zs_kgdb_hook(0);#endif find_via_cuda(); find_via_pmu(); smu_init();#if defined(CONFIG_NVRAM) || defined(CONFIG_PPC64) pmac_nvram_init();#endif#ifdef CONFIG_PPC32#ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) ROOT_DEV = Root_RAM0; else#endif ROOT_DEV = DEFAULT_ROOT_DEVICE;#endif#ifdef CONFIG_SMP
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -