diff options
author | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@ppc970.osdl.org> | 2005-04-16 18:20:36 -0400 |
commit | 1da177e4c3f41524e886b7f1b8a0c1fc7321cac2 (patch) | |
tree | 0bba044c4ce775e45a88a51686b5d9f90697ea9d /arch/ppc/boot/simple/misc-prep.c |
Linux-2.6.12-rc2v2.6.12-rc2
Initial git repository build. I'm not bothering with the full history,
even though we have it. We can create a separate "historical" git
archive of that later if we want to, and in the meantime it's about
3.2GB when imported into git - space that would just make the early
git days unnecessarily complicated, when we don't have a lot of good
infrastructure for it.
Let it rip!
Diffstat (limited to 'arch/ppc/boot/simple/misc-prep.c')
-rw-r--r-- | arch/ppc/boot/simple/misc-prep.c | 212 |
1 files changed, 212 insertions, 0 deletions
diff --git a/arch/ppc/boot/simple/misc-prep.c b/arch/ppc/boot/simple/misc-prep.c new file mode 100644 index 000000000000..75380ac41669 --- /dev/null +++ b/arch/ppc/boot/simple/misc-prep.c | |||
@@ -0,0 +1,212 @@ | |||
1 | /* | ||
2 | * arch/ppc/boot/simple/misc-prep.c | ||
3 | * | ||
4 | * Maintainer: Tom Rini <trini@kernel.crashing.org> | ||
5 | * | ||
6 | * In the past: Gary Thomas, Cort Dougan <cort@cs.nmt.edu> | ||
7 | */ | ||
8 | |||
9 | #include <linux/config.h> | ||
10 | #include <linux/pci_ids.h> | ||
11 | #include <linux/types.h> | ||
12 | #include <asm/residual.h> | ||
13 | #include <asm/string.h> | ||
14 | #include <asm/byteorder.h> | ||
15 | #include "mpc10x.h" | ||
16 | #include "of1275.h" | ||
17 | #include "nonstdio.h" | ||
18 | |||
19 | extern int keyb_present; /* keyboard controller is present by default */ | ||
20 | RESIDUAL hold_resid_buf; | ||
21 | RESIDUAL *hold_residual = &hold_resid_buf; | ||
22 | static void *OFW_interface; /* Pointer to OF, if available. */ | ||
23 | |||
24 | #ifdef CONFIG_VGA_CONSOLE | ||
25 | char *vidmem = (char *)0xC00B8000; | ||
26 | int lines = 25, cols = 80; | ||
27 | int orig_x, orig_y = 24; | ||
28 | #endif /* CONFIG_VGA_CONSOLE */ | ||
29 | |||
30 | extern int CRT_tstc(void); | ||
31 | extern int vga_init(unsigned char *ISA_mem); | ||
32 | extern void gunzip(void *, int, unsigned char *, int *); | ||
33 | extern unsigned long serial_init(int chan, void *ignored); | ||
34 | extern void serial_fixups(void); | ||
35 | extern struct bi_record *decompress_kernel(unsigned long load_addr, | ||
36 | int num_words, unsigned long cksum); | ||
37 | extern void disable_6xx_mmu(void); | ||
38 | extern unsigned long mpc10x_get_mem_size(void); | ||
39 | |||
40 | static void | ||
41 | writel(unsigned int val, unsigned int address) | ||
42 | { | ||
43 | /* Ensure I/O operations complete */ | ||
44 | __asm__ volatile("eieio"); | ||
45 | *(unsigned int *)address = cpu_to_le32(val); | ||
46 | } | ||
47 | |||
48 | #define PCI_CFG_ADDR(dev,off) ((0x80<<24) | (dev<<8) | (off&0xfc)) | ||
49 | #define PCI_CFG_DATA(off) (MPC10X_MAPA_CNFG_DATA+(off&3)) | ||
50 | |||
51 | static void | ||
52 | pci_read_config_32(unsigned char devfn, | ||
53 | unsigned char offset, | ||
54 | unsigned int *val) | ||
55 | { | ||
56 | /* Ensure I/O operations complete */ | ||
57 | __asm__ volatile("eieio"); | ||
58 | *(unsigned int *)PCI_CFG_ADDR(devfn,offset) = | ||
59 | cpu_to_le32(MPC10X_MAPA_CNFG_ADDR); | ||
60 | /* Ensure I/O operations complete */ | ||
61 | __asm__ volatile("eieio"); | ||
62 | *val = le32_to_cpu(*(unsigned int *)PCI_CFG_DATA(offset)); | ||
63 | return; | ||
64 | } | ||
65 | |||
66 | #ifdef CONFIG_VGA_CONSOLE | ||
67 | void | ||
68 | scroll(void) | ||
69 | { | ||
70 | int i; | ||
71 | |||
72 | memcpy ( vidmem, vidmem + cols * 2, ( lines - 1 ) * cols * 2 ); | ||
73 | for ( i = ( lines - 1 ) * cols * 2; i < lines * cols * 2; i += 2 ) | ||
74 | vidmem[i] = ' '; | ||
75 | } | ||
76 | #endif /* CONFIG_VGA_CONSOLE */ | ||
77 | |||
78 | unsigned long | ||
79 | load_kernel(unsigned long load_addr, int num_words, unsigned long cksum, | ||
80 | RESIDUAL *residual, void *OFW) | ||
81 | { | ||
82 | int start_multi = 0; | ||
83 | unsigned int pci_viddid, pci_did, tulip_pci_base, tulip_base; | ||
84 | |||
85 | /* If we have Open Firmware, initialise it immediately */ | ||
86 | if (OFW) { | ||
87 | OFW_interface = OFW; | ||
88 | ofinit(OFW_interface); | ||
89 | } | ||
90 | |||
91 | board_isa_init(); | ||
92 | #if defined(CONFIG_VGA_CONSOLE) | ||
93 | vga_init((unsigned char *)0xC0000000); | ||
94 | #endif /* CONFIG_VGA_CONSOLE */ | ||
95 | |||
96 | if (residual) { | ||
97 | /* Is this Motorola PPCBug? */ | ||
98 | if ((1 & residual->VitalProductData.FirmwareSupports) && | ||
99 | (1 == residual->VitalProductData.FirmwareSupplier)) { | ||
100 | unsigned char base_mod; | ||
101 | unsigned char board_type = inb(0x801) & 0xF0; | ||
102 | |||
103 | /* | ||
104 | * Reset the onboard 21x4x Ethernet | ||
105 | * Motorola Ethernet is at IDSEL 14 (devfn 0x70) | ||
106 | */ | ||
107 | pci_read_config_32(0x70, 0x00, &pci_viddid); | ||
108 | pci_did = (pci_viddid & 0xffff0000) >> 16; | ||
109 | /* Be sure we've really found a 21x4x chip */ | ||
110 | if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_DEC) && | ||
111 | ((pci_did == PCI_DEVICE_ID_DEC_TULIP_FAST) || | ||
112 | (pci_did == PCI_DEVICE_ID_DEC_TULIP) || | ||
113 | (pci_did == PCI_DEVICE_ID_DEC_TULIP_PLUS) || | ||
114 | (pci_did == PCI_DEVICE_ID_DEC_21142))) { | ||
115 | pci_read_config_32(0x70, | ||
116 | 0x10, | ||
117 | &tulip_pci_base); | ||
118 | /* Get the physical base address */ | ||
119 | tulip_base = | ||
120 | (tulip_pci_base & ~0x03UL) + 0x80000000; | ||
121 | /* Strobe the 21x4x reset bit in CSR0 */ | ||
122 | writel(0x1, tulip_base); | ||
123 | } | ||
124 | |||
125 | /* If this is genesis 2 board then check for no | ||
126 | * keyboard controller and more than one processor. | ||
127 | */ | ||
128 | if (board_type == 0xe0) { | ||
129 | base_mod = inb(0x803); | ||
130 | /* if a MVME2300/2400 or a Sitka then no keyboard */ | ||
131 | if((base_mod == 0xFA) || (base_mod == 0xF9) || | ||
132 | (base_mod == 0xE1)) { | ||
133 | keyb_present = 0; /* no keyboard */ | ||
134 | } | ||
135 | } | ||
136 | /* If this is a multiprocessor system then | ||
137 | * park the other processor so that the | ||
138 | * kernel knows where to find them. | ||
139 | */ | ||
140 | if (residual->MaxNumCpus > 1) | ||
141 | start_multi = 1; | ||
142 | } | ||
143 | memcpy(hold_residual,residual,sizeof(RESIDUAL)); | ||
144 | } | ||
145 | |||
146 | /* Call decompress_kernel */ | ||
147 | decompress_kernel(load_addr, num_words, cksum); | ||
148 | |||
149 | if (start_multi) { | ||
150 | residual->VitalProductData.SmpIar = (unsigned long)0xc0; | ||
151 | residual->Cpus[1].CpuState = CPU_GOOD; | ||
152 | hold_residual->VitalProductData.Reserved5 = 0xdeadbeef; | ||
153 | } | ||
154 | |||
155 | /* Now go and clear out the BATs and ensure that our MSR is | ||
156 | * correct .*/ | ||
157 | disable_6xx_mmu(); | ||
158 | |||
159 | /* Make r3 be a pointer to the residual data. */ | ||
160 | return (unsigned long)hold_residual; | ||
161 | } | ||
162 | |||
163 | unsigned long | ||
164 | get_mem_size(void) | ||
165 | { | ||
166 | unsigned int pci_viddid, pci_did; | ||
167 | |||
168 | /* First, figure out what kind of host bridge we are on. If it's | ||
169 | * an MPC10x, we can ask it directly how much memory it has. | ||
170 | * Otherwise, see if the residual data has anything. This isn't | ||
171 | * the best way, but it can be the only way. If there's nothing, | ||
172 | * assume 32MB. -- Tom. | ||
173 | */ | ||
174 | /* See what our host bridge is. */ | ||
175 | pci_read_config_32(0x00, 0x00, &pci_viddid); | ||
176 | pci_did = (pci_viddid & 0xffff0000) >> 16; | ||
177 | /* See if we are on an MPC10x. */ | ||
178 | if (((pci_viddid & 0xffff) == PCI_VENDOR_ID_MOTOROLA) | ||
179 | && ((pci_did == PCI_DEVICE_ID_MOTOROLA_MPC105) | ||
180 | || (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC106) | ||
181 | || (pci_did == PCI_DEVICE_ID_MOTOROLA_MPC107))) | ||
182 | return mpc10x_get_mem_size(); | ||
183 | /* If it's not, see if we have anything in the residual data. */ | ||
184 | else if (hold_residual && hold_residual->TotalMemory) | ||
185 | return hold_residual->TotalMemory; | ||
186 | else if (OFW_interface) { | ||
187 | /* | ||
188 | * This is a 'best guess' check. We want to make sure | ||
189 | * we don't try this on a PReP box without OF | ||
190 | * -- Cort | ||
191 | */ | ||
192 | while (OFW_interface) | ||
193 | { | ||
194 | phandle dev_handle; | ||
195 | int mem_info[2]; | ||
196 | |||
197 | /* get handle to memory description */ | ||
198 | if (!(dev_handle = finddevice("/memory@0"))) | ||
199 | break; | ||
200 | |||
201 | /* get the info */ | ||
202 | if (getprop(dev_handle, "reg", mem_info, | ||
203 | sizeof(mem_info)) != 8) | ||
204 | break; | ||
205 | |||
206 | return mem_info[1]; | ||
207 | } | ||
208 | } | ||
209 | |||
210 | /* Fall back to hard-coding 32MB. */ | ||
211 | return 32*1024*1024; | ||
212 | } | ||