📄 pmac_setup.c
字号:
/* * linux/arch/ppc/kernel/setup.c * * PowerPC version * Copyright (C) 1995-1996 Gary Thomas (gdt@linuxppc.org) * * Adapted for Power Macintosh by Paul Mackerras * Copyright (C) 1996 Paul Mackerras (paulus@cs.anu.edu.au) * * Derived from "arch/alpha/kernel/setup.c" * Copyright (C) 1995 Linus Torvalds * * 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/config.h>#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/malloc.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/blk.h>#include <linux/vt_kern.h>#include <linux/console.h>#include <linux/ide.h>#include <linux/pci.h>#include <linux/adb.h>#include <linux/cuda.h>#include <linux/pmu.h>#include <asm/init.h>#include <asm/prom.h>#include <asm/system.h>#include <asm/pgtable.h>#include <asm/bitops.h>#include <asm/io.h>#include <asm/pci-bridge.h>#include <asm/ohare.h>#include <asm/mediabay.h>#include <asm/feature.h>#include <asm/machdep.h>#include <asm/keyboard.h>#include <asm/dma.h>#include <asm/bootx.h>#include <asm/time.h>#include "local_irq.h"#include "pmac_pic.h"#undef SHOW_GATWICK_IRQSextern long pmac_time_init(void);extern unsigned long pmac_get_rtc_time(void);extern int pmac_set_rtc_time(unsigned long nowtime);extern void pmac_read_rtc_time(void);extern void pmac_calibrate_decr(void);extern void pmac_setup_pci_ptrs(void);extern int mackbd_setkeycode(unsigned int scancode, unsigned int keycode);extern int mackbd_getkeycode(unsigned int scancode);extern int mackbd_translate(unsigned char keycode, unsigned char *keycodep, char raw_mode);extern int mackbd_unexpected_up(unsigned char keycode);extern void mackbd_leds(unsigned char leds);extern void __init mackbd_init_hw(void);extern int mac_hid_kbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode);extern char mac_hid_kbd_unexpected_up(unsigned char keycode);extern void mac_hid_init_hw(void);#ifdef CONFIG_MAGIC_SYSRQextern unsigned char mac_hid_kbd_sysrq_xlate[128];extern unsigned char pckbd_sysrq_xlate[128];extern unsigned char mackbd_sysrq_xlate[128];#endif /* CONFIG_MAGIC_SYSRQ */extern int pckbd_setkeycode(unsigned int scancode, unsigned int keycode);extern int pckbd_getkeycode(unsigned int scancode);extern int pckbd_translate(unsigned char scancode, unsigned char *keycode, char raw_mode);extern char pckbd_unexpected_up(unsigned char keycode);extern int keyboard_sends_linux_keycodes;extern void pmac_nvram_update(void);extern void *pmac_pci_dev_io_base(unsigned char bus, unsigned char devfn, int physical);extern void *pmac_pci_dev_mem_base(unsigned char bus, unsigned char devfn);extern int pmac_pci_dev_root_bridge(unsigned char bus, unsigned char devfn);unsigned char drive_info;int ppc_override_l2cr = 0;int ppc_override_l2cr_value;int has_l2cache = 0;static int current_root_goodness = -1;extern char saved_command_line[];extern int pmac_newworld;#define DEFAULT_ROOT_DEVICE 0x0801 /* sda1 - slightly silly choice */extern void zs_kgdb_hook(int tty_num);static void ohare_init(void);static void init_p2pbridge(void);#ifdef CONFIG_BOOTX_TEXTvoid pmac_progress(char *s, unsigned short hex);#endifsys_ctrler_t sys_ctrler = SYS_CTRLER_UNKNOWN;__pmacintpmac_get_cpuinfo(char *buffer){ int len; struct device_node *np; char *pp; int plen; /* find motherboard type */ len = sprintf(buffer, "machine\t\t: "); np = find_devices("device-tree"); if (np != NULL) { pp = (char *) get_property(np, "model", NULL); if (pp != NULL) len += sprintf(buffer+len, "%s\n", pp); else len += sprintf(buffer+len, "PowerMac\n"); pp = (char *) get_property(np, "compatible", &plen); if (pp != NULL) { len += sprintf(buffer+len, "motherboard\t:"); while (plen > 0) { int l = strlen(pp) + 1; len += sprintf(buffer+len, " %s", pp); plen -= l; pp += l; } buffer[len++] = '\n'; } } else len += sprintf(buffer+len, "PowerMac\n"); /* find l2 cache info */ np = find_devices("l2-cache"); if (np == 0) np = find_type_devices("cache"); if (np != 0) { unsigned int *ic = (unsigned int *) get_property(np, "i-cache-size", NULL); unsigned int *dc = (unsigned int *) get_property(np, "d-cache-size", NULL); len += sprintf(buffer+len, "L2 cache\t:"); has_l2cache = 1; if (get_property(np, "cache-unified", NULL) != 0 && dc) { len += sprintf(buffer+len, " %dK unified", *dc / 1024); } else { if (ic) len += sprintf(buffer+len, " %dK instruction", *ic / 1024); if (dc) len += sprintf(buffer+len, "%s %dK data", (ic? " +": ""), *dc / 1024); } pp = get_property(np, "ram-type", NULL); if (pp) len += sprintf(buffer+len, " %s", pp); buffer[len++] = '\n'; } /* find ram info */ np = find_devices("memory"); if (np != 0) { int n; struct reg_property *reg = (struct reg_property *) get_property(np, "reg", &n); if (reg != 0) { unsigned long total = 0; for (n /= sizeof(struct reg_property); n > 0; --n) total += (reg++)->size; len += sprintf(buffer+len, "memory\t\t: %luMB\n", total >> 20); } } /* Checks "l2cr-value" property in the registry */ np = find_devices("cpus"); if (np == 0) np = find_type_devices("cpu"); if (np != 0) { unsigned int *l2cr = (unsigned int *) get_property(np, "l2cr-value", NULL); if (l2cr != 0) { len += sprintf(buffer+len, "l2cr override\t: 0x%x\n", *l2cr); } } /* Indicate newworld/oldworld */ len += sprintf(buffer+len, "pmac-generation\t: %s\n", pmac_newworld ? "NewWorld" : "OldWorld"); return len;}#ifdef CONFIG_SCSI/* Find the device number for the disk (if any) at target tgt on host adaptor host. We just need to get the prototype from sd.h */#include <linux/blkdev.h>#include "../../../drivers/scsi/scsi.h"#include "../../../drivers/scsi/sd.h"#endif/* * Dummy mksound function that does nothing. * The real one is in the dmasound driver. */__pmacstatic voidpmac_mksound(unsigned int hz, unsigned int ticks){}static volatile u32 *sysctrl_regs;void __initpmac_setup_arch(void){ struct device_node *cpu; int *fp; /* Set loops_per_sec to a half-way reasonable value, for use until calibrate_delay gets called. */ cpu = find_type_devices("cpu"); if (cpu != 0) { fp = (int *) get_property(cpu, "clock-frequency", NULL); if (fp != 0) { switch (_get_PVR() >> 16) { case 4: /* 604 */ case 8: /* G3 */ case 9: /* 604e */ case 10: /* mach V (604ev5) */ case 12: /* G4 */ case 20: /* 620 */ loops_per_sec = *fp; break; default: /* 601, 603, etc. */ loops_per_sec = *fp / 2; } } else loops_per_sec = 50000000; } /* this area has the CPU identification register and some registers used by smp boards */ sysctrl_regs = (volatile u32 *) ioremap(0xf8000000, 0x1000); __ioremap(0xffc00000, 0x400000, pgprot_val(PAGE_READONLY)); ohare_init(); pmac_find_bridges(); init_p2pbridge(); /* Checks "l2cr-value" property in the registry */ if ( (_get_PVR() >> 16) == 8 || (_get_PVR() >> 16) == 12 ) { struct device_node *np = find_devices("cpus"); if (np == 0) np = find_type_devices("cpu"); if (np != 0) { unsigned int *l2cr = (unsigned int *) 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); } } } if (ppc_override_l2cr) printk(KERN_INFO "L2CR overriden (0x%x), backside cache is %s\n", ppc_override_l2cr_value, (ppc_override_l2cr_value & 0x80000000) ? "enabled" : "disabled");#ifdef CONFIG_KGDB zs_kgdb_hook(0);#endif#ifdef CONFIG_ADB_CUDA find_via_cuda();#endif #ifdef CONFIG_ADB_PMU find_via_pmu();#endif #ifdef CONFIG_NVRAM pmac_nvram_init();#endif#ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con;#endif kd_mksound = pmac_mksound;#ifdef CONFIG_BLK_DEV_INITRD if (initrd_start) ROOT_DEV = MKDEV(RAMDISK_MAJOR, 0); else#endif ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE);}/* * Tweak the PCI-PCI bridge chip on the blue & white G3s. */static void __init init_p2pbridge(void){ struct device_node *p2pbridge; unsigned char bus, devfn; unsigned short val; /* XXX it would be better here to identify the specific PCI-PCI bridge chip we have. */ if ((p2pbridge = find_devices("pci-bridge")) == 0 || p2pbridge->parent == NULL || strcmp(p2pbridge->parent->name, "pci") != 0) return; if (pci_device_loc(p2pbridge, &bus, &devfn) < 0) return; if (ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val) < 0) { printk(KERN_ERR "init_p2pbridge: couldn't read bridge control\n"); return; } val &= ~PCI_BRIDGE_CTL_MASTER_ABORT; ppc_md.pcibios_write_config_word(bus, devfn, PCI_BRIDGE_CONTROL, val); ppc_md.pcibios_read_config_word(bus, devfn, PCI_BRIDGE_CONTROL, &val);}static void __init ohare_init(void){ /* * Turn on the L2 cache. * We assume that we have a PSX memory controller iff * we have an ohare I/O controller. */ if (find_devices("ohare") != NULL) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -