📄 prep_setup.c
字号:
/* * arch/ppc/platforms/setup.c * * Copyright (C) 1995 Linus Torvalds * Adapted from 'alpha' version by Gary Thomas * Modified by Cort Dougan (cort@cs.nmt.edu) * * Support for PReP (Motorola MTX/MVME) * by Troy Benjegerdes (hozer@drgw.net) *//* * bootup setup stuff.. */#include <linux/config.h>#include <linux/delay.h>#include <linux/module.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/major.h>#include <linux/interrupt.h>#include <linux/reboot.h>#include <linux/init.h>#include <linux/initrd.h>#include <linux/ioport.h>#include <linux/console.h>#include <linux/timex.h>#include <linux/pci.h>#include <linux/ide.h>#include <linux/seq_file.h>#include <linux/root_dev.h>#include <asm/sections.h>#include <asm/mmu.h>#include <asm/processor.h>#include <asm/residual.h>#include <asm/io.h>#include <asm/pgtable.h>#include <asm/cache.h>#include <asm/dma.h>#include <asm/machdep.h>#include <asm/mc146818rtc.h>#include <asm/mk48t59.h>#include <asm/prep_nvram.h>#include <asm/raven.h>#include <asm/vga.h>#include <asm/time.h>#include <asm/mpc10x.h>#include <asm/i8259.h>#include <asm/open_pic.h>#include <asm/pci-bridge.h>#include <asm/todc.h>/* prep registers for L2 */#define CACHECRBA 0x80000823 /* Cache configuration register address */#define L2CACHE_MASK 0x03 /* Mask for 2 L2 Cache bits */#define L2CACHE_512KB 0x00 /* 512KB */#define L2CACHE_256KB 0x01 /* 256KB */#define L2CACHE_1MB 0x02 /* 1MB */#define L2CACHE_NONE 0x03 /* NONE */#define L2CACHE_PARITY 0x08 /* Mask for L2 Cache Parity Protected bit */TODC_ALLOC();unsigned char ucSystemType;unsigned char ucBoardRev;unsigned char ucBoardRevMaj, ucBoardRevMin;extern unsigned char prep_nvram_read_val(int addr);extern void prep_nvram_write_val(int addr, unsigned char val);extern unsigned char rs_nvram_read_val(int addr);extern void rs_nvram_write_val(int addr, unsigned char val);extern void ibm_prep_init(void);extern void prep_find_bridges(void);int _prep_type;extern void prep_residual_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);extern void prep_sandalfoot_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);extern void prep_thinkpad_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);extern void prep_carolina_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);extern void prep_tiger1_setup_pci(char *irq_edge_mask_lo, char *irq_edge_mask_hi);#define cached_21 (((char *)(ppc_cached_irq_mask))[3])#define cached_A1 (((char *)(ppc_cached_irq_mask))[2])#ifdef CONFIG_SOUND_CS4232long ppc_cs4232_dma, ppc_cs4232_dma2;#endifextern PTE *Hash, *Hash_end;extern unsigned long Hash_size, Hash_mask;extern int probingmem;extern unsigned long loops_per_jiffy;#ifdef CONFIG_SOUND_CS4232EXPORT_SYMBOL(ppc_cs4232_dma);EXPORT_SYMBOL(ppc_cs4232_dma2);#endif/* useful ISA ports */#define PREP_SYSCTL 0x81c/* present in the IBM reference design; possibly identical in Mot boxes: */#define PREP_IBM_SIMM_ID 0x803 /* SIMM size: 32 or 8 MiB */#define PREP_IBM_SIMM_PRESENCE 0x804#define PREP_IBM_EQUIPMENT 0x80c#define PREP_IBM_L2INFO 0x80d#define PREP_IBM_PM1 0x82a /* power management register 1 */#define PREP_IBM_PLANAR 0x852 /* planar ID - identifies the motherboard */#define PREP_IBM_DISP 0x8c0 /* 4-digit LED display *//* Equipment Present Register masks: */#define PREP_IBM_EQUIPMENT_RESERVED 0x80#define PREP_IBM_EQUIPMENT_SCSIFUSE 0x40#define PREP_IBM_EQUIPMENT_L2_COPYBACK 0x08#define PREP_IBM_EQUIPMENT_L2_256 0x04#define PREP_IBM_EQUIPMENT_CPU 0x02#define PREP_IBM_EQUIPMENT_L2 0x01/* planar ID values: *//* Sandalfoot/Sandalbow (6015/7020) */#define PREP_IBM_SANDALFOOT 0xfc/* Woodfield, Thinkpad 850/860 (6042/7249) */#define PREP_IBM_THINKPAD 0xff /* planar ID unimplemented *//* PowerSeries 830/850 (6050/6070) */#define PREP_IBM_CAROLINA_IDE_0 0xf0#define PREP_IBM_CAROLINA_IDE_1 0xf1#define PREP_IBM_CAROLINA_IDE_2 0xf2#define PREP_IBM_CAROLINA_IDE_3 0xf3/* 7248-43P */#define PREP_IBM_CAROLINA_SCSI_0 0xf4#define PREP_IBM_CAROLINA_SCSI_1 0xf5#define PREP_IBM_CAROLINA_SCSI_2 0xf6#define PREP_IBM_CAROLINA_SCSI_3 0xf7 /* missing from Carolina Tech Spec *//* Tiger1 (7043-140) */#define PREP_IBM_TIGER1_133 0xd1#define PREP_IBM_TIGER1_166 0xd2#define PREP_IBM_TIGER1_180 0xd3#define PREP_IBM_TIGER1_xxx 0xd4 /* unknown, but probably exists */#define PREP_IBM_TIGER1_333 0xd5 /* missing from Tiger Tech Spec *//* setup_ibm_pci: * set Motherboard_map_name, Motherboard_map, Motherboard_routes. * return 8259 edge/level masks. */void (*setup_ibm_pci)(char *irq_lo, char *irq_hi);extern char *Motherboard_map_name; /* for use in *_cpuinfo *//* * As found in the PReP reference implementation. * Used by Thinkpad, Sandalfoot (6015/7020), and all Motorola PReP. */static void __initprep_gen_enable_l2(void){ outb(inb(PREP_SYSCTL) | 0x3, PREP_SYSCTL);}/* Used by Carolina and Tiger1 */static void __initprep_carolina_enable_l2(void){ outb(inb(PREP_SYSCTL) | 0xc0, PREP_SYSCTL);}/* cpuinfo code common to all IBM PReP */static voidprep_ibm_cpuinfo(struct seq_file *m){ unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT); seq_printf(m, "machine\t\t: PReP %s\n", Motherboard_map_name); seq_printf(m, "upgrade cpu\t: "); if (equip_reg & PREP_IBM_EQUIPMENT_CPU) { seq_printf(m, "not "); } seq_printf(m, "present\n"); /* print info about the SCSI fuse */ seq_printf(m, "scsi fuse\t: "); if (equip_reg & PREP_IBM_EQUIPMENT_SCSIFUSE) seq_printf(m, "ok"); else seq_printf(m, "bad"); seq_printf(m, "\n"); /* print info about SIMMs */ if (have_residual_data) { int i; seq_printf(m, "simms\t\t: "); for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) { if (res->Memories[i].SIMMSize != 0) seq_printf(m, "%d:%ldMiB ", i, (res->Memories[i].SIMMSize > 1024) ? res->Memories[i].SIMMSize>>20 : res->Memories[i].SIMMSize); } seq_printf(m, "\n"); }}static intprep_gen_cpuinfo(struct seq_file *m){ prep_ibm_cpuinfo(m); return 0;}static intprep_sandalfoot_cpuinfo(struct seq_file *m){ unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT); prep_ibm_cpuinfo(m); /* report amount and type of L2 cache present */ seq_printf(m, "L2 cache\t: "); if (equip_reg & PREP_IBM_EQUIPMENT_L2) { seq_printf(m, "not present"); } else { if (equip_reg & PREP_IBM_EQUIPMENT_L2_256) seq_printf(m, "256KiB"); else seq_printf(m, "unknown size"); if (equip_reg & PREP_IBM_EQUIPMENT_L2_COPYBACK) seq_printf(m, ", copy-back"); else seq_printf(m, ", write-through"); } seq_printf(m, "\n"); return 0;}static intprep_thinkpad_cpuinfo(struct seq_file *m){ unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT); char *cpubus_speed, *pci_speed; prep_ibm_cpuinfo(m); /* report amount and type of L2 cache present */ seq_printf(m, "l2 cache\t: "); if ((equip_reg & 0x1) == 0) { switch ((equip_reg & 0xc) >> 2) { case 0x0: seq_printf(m, "128KiB look-aside 2-way write-through\n"); break; case 0x1: seq_printf(m, "512KiB look-aside direct-mapped write-back\n"); break; case 0x2: seq_printf(m, "256KiB look-aside 2-way write-through\n"); break; case 0x3: seq_printf(m, "256KiB look-aside direct-mapped write-back\n"); break; } } else { seq_printf(m, "not present\n"); } /* report bus speeds because we can */ if ((equip_reg & 0x80) == 0) { switch ((equip_reg & 0x30) >> 4) { case 0x1: cpubus_speed = "50"; pci_speed = "25"; break; case 0x3: cpubus_speed = "66"; pci_speed = "33"; break; default: cpubus_speed = "unknown"; pci_speed = "unknown"; break; } } else { switch ((equip_reg & 0x30) >> 4) { case 0x1: cpubus_speed = "25"; pci_speed = "25"; break; case 0x2: cpubus_speed = "60"; pci_speed = "30"; break; case 0x3: cpubus_speed = "33"; pci_speed = "33"; break; default: cpubus_speed = "unknown"; pci_speed = "unknown"; break; } } seq_printf(m, "60x bus\t\t: %sMHz\n", cpubus_speed); seq_printf(m, "pci bus\t\t: %sMHz\n", pci_speed); return 0;}static intprep_carolina_cpuinfo(struct seq_file *m){ unsigned int equip_reg = inb(PREP_IBM_EQUIPMENT); prep_ibm_cpuinfo(m); /* report amount and type of L2 cache present */ seq_printf(m, "l2 cache\t: "); if ((equip_reg & 0x1) == 0) { unsigned int l2_reg = inb(PREP_IBM_L2INFO); /* L2 size */ if ((l2_reg & 0x60) == 0) seq_printf(m, "256KiB"); else if ((l2_reg & 0x60) == 0x20) seq_printf(m, "512KiB"); else seq_printf(m, "unknown size"); /* L2 type */ if ((l2_reg & 0x3) == 0) seq_printf(m, ", async"); else if ((l2_reg & 0x3) == 1) seq_printf(m, ", sync"); else seq_printf(m, ", unknown type"); seq_printf(m, "\n"); } else { seq_printf(m, "not present\n"); } return 0;}static intprep_tiger1_cpuinfo(struct seq_file *m){ unsigned int l2_reg = inb(PREP_IBM_L2INFO); prep_ibm_cpuinfo(m); /* report amount and type of L2 cache present */ seq_printf(m, "l2 cache\t: "); if ((l2_reg & 0xf) == 0xf) { seq_printf(m, "not present\n"); } else { if (l2_reg & 0x8) seq_printf(m, "async, "); else seq_printf(m, "sync burst, "); if (l2_reg & 0x4) seq_printf(m, "parity, "); else seq_printf(m, "no parity, "); switch (l2_reg & 0x3) { case 0x0: seq_printf(m, "256KiB\n"); break; case 0x1: seq_printf(m, "512KiB\n"); break; case 0x2: seq_printf(m, "1MiB\n"); break; default: seq_printf(m, "unknown size\n"); break; } } return 0;}/* Used by all Motorola PReP */static intprep_mot_cpuinfo(struct seq_file *m){ unsigned int cachew = *((unsigned char *)CACHECRBA); seq_printf(m, "machine\t\t: PReP %s\n", Motherboard_map_name); /* report amount and type of L2 cache present */ seq_printf(m, "l2 cache\t: "); switch (cachew & L2CACHE_MASK) { case L2CACHE_512KB: seq_printf(m, "512KiB"); break; case L2CACHE_256KB: seq_printf(m, "256KiB"); break; case L2CACHE_1MB: seq_printf(m, "1MiB"); break; case L2CACHE_NONE: seq_printf(m, "none\n"); goto no_l2; break; default: seq_printf(m, "%x\n", cachew); } seq_printf(m, ", parity %s", (cachew & L2CACHE_PARITY)? "enabled" : "disabled"); seq_printf(m, " SRAM:"); switch ( ((cachew & 0xf0) >> 4) & ~(0x3) ) { case 1: seq_printf(m, "synchronous, parity, flow-through\n"); break; case 2: seq_printf(m, "asynchronous, no parity\n"); break; case 3: seq_printf(m, "asynchronous, parity\n"); break; default:seq_printf(m, "synchronous, pipelined, no parity\n"); break; }no_l2: /* print info about SIMMs */ if (have_residual_data) { int i; seq_printf(m, "simms\t\t: "); for (i = 0; (res->ActualNumMemories) && (i < MAX_MEMS); i++) { if (res->Memories[i].SIMMSize != 0) seq_printf(m, "%d:%ldM ", i, (res->Memories[i].SIMMSize > 1024) ? res->Memories[i].SIMMSize>>20 : res->Memories[i].SIMMSize); } seq_printf(m, "\n"); } return 0;}static voidprep_restart(char *cmd){#define PREP_SP92 0x92 /* Special Port 92 */ local_irq_disable(); /* no interrupts */ /* set exception prefix high - to the prom */ _nmask_and_or_msr(0, MSR_IP); /* make sure bit 0 (reset) is a 0 */ outb( inb(PREP_SP92) & ~1L , PREP_SP92); /* signal a reset to system control port A - soft reset */ outb( inb(PREP_SP92) | 1 , PREP_SP92); while ( 1 ) ; /* not reached */#undef PREP_SP92}static voidprep_halt(void){ local_irq_disable(); /* no interrupts */ /* set exception prefix high - to the prom */ _nmask_and_or_msr(0, MSR_IP); while ( 1 ) ; /* not reached */}/* Carrera is the power manager in the Thinkpads. Unfortunately not much is * known about it, so we can't power down. */static voidprep_carrera_poweroff(void){ prep_halt();}/* * On most IBM PReP's, power management is handled by a Signetics 87c750 * behind the Utah component on the ISA bus. To access the 750 you must write * a series of nibbles to port 0x82a (decoded by the Utah). This is described * somewhat in the IBM Carolina Technical Specification. * -Hollis */static voidutah_sig87c750_setbit(unsigned int bytenum, unsigned int bitnum, int value){ /* * byte1: 0 0 0 1 0 d a5 a4 * byte2: 0 0 0 1 a3 a2 a1 a0 * * d = the bit's value, enabled or disabled * (a5 a4 a3) = the byte number, minus 20 * (a2 a1 a0) = the bit number * * example: set the 5th bit of byte 21 (21.5) * a5 a4 a3 = 001 (byte 1) * a2 a1 a0 = 101 (bit 5) * * byte1 = 0001 0100 (0x14) * byte2 = 0001 1101 (0x1d) */ unsigned char byte1=0x10, byte2=0x10; /* the 750's '20.0' is accessed as '0.0' through Utah (which adds 20) */ bytenum -= 20; byte1 |= (!!value) << 2; /* set d */ byte1 |= (bytenum >> 1) & 0x3; /* set a5, a4 */ byte2 |= (bytenum & 0x1) << 3; /* set a3 */ byte2 |= bitnum & 0x7; /* set a2, a1, a0 */ outb(byte1, PREP_IBM_PM1); /* first nibble */ mb(); udelay(100); /* important: let controller recover */ outb(byte2, PREP_IBM_PM1); /* second nibble */ mb(); udelay(100); /* important: let controller recover */}static voidprep_sig750_poweroff(void){ /* tweak the power manager found in most IBM PRePs (except Thinkpads) */ local_irq_disable(); /* set exception prefix high - to the prom */ _nmask_and_or_msr(0, MSR_IP); utah_sig87c750_setbit(21, 5, 1); /* set bit 21.5, "PMEXEC_OFF" */ while (1) ; /* not reached */}static intprep_show_percpuinfo(struct seq_file *m, int i){ /* PREP's without residual data will give incorrect values here */ seq_printf(m, "clock\t\t: "); if (have_residual_data) seq_printf(m, "%ldMHz\n", (res->VitalProductData.ProcessorHz > 1024) ? res->VitalProductData.ProcessorHz / 1000000 : res->VitalProductData.ProcessorHz); else seq_printf(m, "???\n"); return 0;}#ifdef CONFIG_SOUND_CS4232static long __init masktoint(unsigned int i){ int t = -1; while (i >> ++t) ; return (t-1);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -