diff options
author | Tony Luck <tony.luck@intel.com> | 2006-06-23 16:46:23 -0400 |
---|---|---|
committer | Tony Luck <tony.luck@intel.com> | 2006-06-23 16:46:23 -0400 |
commit | 8cf60e04a131310199d5776e2f9e915f0c468899 (patch) | |
tree | 373a68e88e6737713a0a5723d552cdeefffff929 /arch/powerpc/platforms | |
parent | 1323523f505606cfd24af6122369afddefc3b09d (diff) | |
parent | 95eaa5fa8eb2c345244acd5f65b200b115ae8c65 (diff) |
Auto-update from upstream
Diffstat (limited to 'arch/powerpc/platforms')
66 files changed, 4905 insertions, 2339 deletions
diff --git a/arch/powerpc/platforms/85xx/Kconfig b/arch/powerpc/platforms/85xx/Kconfig index 06e371282f57..454fc53289ab 100644 --- a/arch/powerpc/platforms/85xx/Kconfig +++ b/arch/powerpc/platforms/85xx/Kconfig | |||
@@ -11,13 +11,20 @@ config MPC8540_ADS | |||
11 | help | 11 | help |
12 | This option enables support for the MPC 8540 ADS board | 12 | This option enables support for the MPC 8540 ADS board |
13 | 13 | ||
14 | config MPC85xx_CDS | ||
15 | bool "Freescale MPC85xx CDS" | ||
16 | select DEFAULT_UIMAGE | ||
17 | select PPC_I8259 if PCI | ||
18 | help | ||
19 | This option enables support for the MPC85xx CDS board | ||
20 | |||
14 | endchoice | 21 | endchoice |
15 | 22 | ||
16 | config MPC8540 | 23 | config MPC8540 |
17 | bool | 24 | bool |
18 | select PPC_UDBG_16550 | 25 | select PPC_UDBG_16550 |
19 | select PPC_INDIRECT_PCI | 26 | select PPC_INDIRECT_PCI |
20 | default y if MPC8540_ADS | 27 | default y if MPC8540_ADS || MPC85xx_CDS |
21 | 28 | ||
22 | config PPC_INDIRECT_PCI_BE | 29 | config PPC_INDIRECT_PCI_BE |
23 | bool | 30 | bool |
diff --git a/arch/powerpc/platforms/85xx/Makefile b/arch/powerpc/platforms/85xx/Makefile index ffc4139cb214..7615aa59c78b 100644 --- a/arch/powerpc/platforms/85xx/Makefile +++ b/arch/powerpc/platforms/85xx/Makefile | |||
@@ -3,3 +3,4 @@ | |||
3 | # | 3 | # |
4 | obj-$(CONFIG_PPC_85xx) += misc.o pci.o | 4 | obj-$(CONFIG_PPC_85xx) += misc.o pci.o |
5 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o | 5 | obj-$(CONFIG_MPC8540_ADS) += mpc85xx_ads.o |
6 | obj-$(CONFIG_MPC85xx_CDS) += mpc85xx_cds.o | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.c b/arch/powerpc/platforms/85xx/mpc85xx_cds.c new file mode 100644 index 000000000000..18e6e11f7020 --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.c | |||
@@ -0,0 +1,359 @@ | |||
1 | /* | ||
2 | * MPC85xx setup and early boot code plus other random bits. | ||
3 | * | ||
4 | * Maintained by Kumar Gala (see MAINTAINERS for contact information) | ||
5 | * | ||
6 | * Copyright 2005 Freescale Semiconductor Inc. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or modify it | ||
9 | * under the terms of the GNU General Public License as published by the | ||
10 | * Free Software Foundation; either version 2 of the License, or (at your | ||
11 | * option) any later version. | ||
12 | */ | ||
13 | |||
14 | #include <linux/config.h> | ||
15 | #include <linux/stddef.h> | ||
16 | #include <linux/kernel.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/errno.h> | ||
19 | #include <linux/reboot.h> | ||
20 | #include <linux/pci.h> | ||
21 | #include <linux/kdev_t.h> | ||
22 | #include <linux/major.h> | ||
23 | #include <linux/console.h> | ||
24 | #include <linux/delay.h> | ||
25 | #include <linux/seq_file.h> | ||
26 | #include <linux/root_dev.h> | ||
27 | #include <linux/initrd.h> | ||
28 | #include <linux/module.h> | ||
29 | #include <linux/fsl_devices.h> | ||
30 | |||
31 | #include <asm/system.h> | ||
32 | #include <asm/pgtable.h> | ||
33 | #include <asm/page.h> | ||
34 | #include <asm/atomic.h> | ||
35 | #include <asm/time.h> | ||
36 | #include <asm/io.h> | ||
37 | #include <asm/machdep.h> | ||
38 | #include <asm/ipic.h> | ||
39 | #include <asm/bootinfo.h> | ||
40 | #include <asm/pci-bridge.h> | ||
41 | #include <asm/mpc85xx.h> | ||
42 | #include <asm/irq.h> | ||
43 | #include <mm/mmu_decl.h> | ||
44 | #include <asm/prom.h> | ||
45 | #include <asm/udbg.h> | ||
46 | #include <asm/mpic.h> | ||
47 | #include <asm/i8259.h> | ||
48 | |||
49 | #include <sysdev/fsl_soc.h> | ||
50 | #include "mpc85xx.h" | ||
51 | |||
52 | #ifndef CONFIG_PCI | ||
53 | unsigned long isa_io_base = 0; | ||
54 | unsigned long isa_mem_base = 0; | ||
55 | #endif | ||
56 | |||
57 | static int cds_pci_slot = 2; | ||
58 | static volatile u8 *cadmus; | ||
59 | |||
60 | /* | ||
61 | * Internal interrupts are all Level Sensitive, and Positive Polarity | ||
62 | * | ||
63 | * Note: Likely, this table and the following function should be | ||
64 | * obtained and derived from the OF Device Tree. | ||
65 | */ | ||
66 | static u_char mpc85xx_cds_openpic_initsenses[] __initdata = { | ||
67 | MPC85XX_INTERNAL_IRQ_SENSES, | ||
68 | #if defined(CONFIG_PCI) | ||
69 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Ext 0: PCI slot 0 */ | ||
70 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 1: PCI slot 1 */ | ||
71 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 2: PCI slot 2 */ | ||
72 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 3: PCI slot 3 */ | ||
73 | #else | ||
74 | 0x0, /* External 0: */ | ||
75 | 0x0, /* External 1: */ | ||
76 | 0x0, /* External 2: */ | ||
77 | 0x0, /* External 3: */ | ||
78 | #endif | ||
79 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 5: PHY */ | ||
80 | 0x0, /* External 6: */ | ||
81 | 0x0, /* External 7: */ | ||
82 | 0x0, /* External 8: */ | ||
83 | 0x0, /* External 9: */ | ||
84 | 0x0, /* External 10: */ | ||
85 | #ifdef CONFIG_PCI | ||
86 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* Ext 11: PCI2 slot 0 */ | ||
87 | #else | ||
88 | 0x0, /* External 11: */ | ||
89 | #endif | ||
90 | }; | ||
91 | |||
92 | |||
93 | #ifdef CONFIG_PCI | ||
94 | /* | ||
95 | * interrupt routing | ||
96 | */ | ||
97 | int | ||
98 | mpc85xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | ||
99 | { | ||
100 | struct pci_controller *hose = pci_bus_to_hose(dev->bus->number); | ||
101 | |||
102 | if (!hose->index) | ||
103 | { | ||
104 | /* Handle PCI1 interrupts */ | ||
105 | char pci_irq_table[][4] = | ||
106 | /* | ||
107 | * PCI IDSEL/INTPIN->INTLINE | ||
108 | * A B C D | ||
109 | */ | ||
110 | |||
111 | /* Note IRQ assignment for slots is based on which slot the elysium is | ||
112 | * in -- in this setup elysium is in slot #2 (this PIRQA as first | ||
113 | * interrupt on slot */ | ||
114 | { | ||
115 | { 0, 1, 2, 3 }, /* 16 - PMC */ | ||
116 | { 0, 1, 2, 3 }, /* 17 P2P (Tsi320) */ | ||
117 | { 0, 1, 2, 3 }, /* 18 - Slot 1 */ | ||
118 | { 1, 2, 3, 0 }, /* 19 - Slot 2 */ | ||
119 | { 2, 3, 0, 1 }, /* 20 - Slot 3 */ | ||
120 | { 3, 0, 1, 2 }, /* 21 - Slot 4 */ | ||
121 | }; | ||
122 | |||
123 | const long min_idsel = 16, max_idsel = 21, irqs_per_slot = 4; | ||
124 | int i, j; | ||
125 | |||
126 | for (i = 0; i < 6; i++) | ||
127 | for (j = 0; j < 4; j++) | ||
128 | pci_irq_table[i][j] = | ||
129 | ((pci_irq_table[i][j] + 5 - | ||
130 | cds_pci_slot) & 0x3) + PIRQ0A; | ||
131 | |||
132 | return PCI_IRQ_TABLE_LOOKUP; | ||
133 | } else { | ||
134 | /* Handle PCI2 interrupts (if we have one) */ | ||
135 | char pci_irq_table[][4] = | ||
136 | { | ||
137 | /* | ||
138 | * We only have one slot and one interrupt | ||
139 | * going to PIRQA - PIRQD */ | ||
140 | { PIRQ1A, PIRQ1A, PIRQ1A, PIRQ1A }, /* 21 - slot 0 */ | ||
141 | }; | ||
142 | |||
143 | const long min_idsel = 21, max_idsel = 21, irqs_per_slot = 4; | ||
144 | |||
145 | return PCI_IRQ_TABLE_LOOKUP; | ||
146 | } | ||
147 | } | ||
148 | |||
149 | #define ARCADIA_HOST_BRIDGE_IDSEL 17 | ||
150 | #define ARCADIA_2ND_BRIDGE_IDSEL 3 | ||
151 | |||
152 | extern int mpc85xx_pci2_busno; | ||
153 | |||
154 | int | ||
155 | mpc85xx_exclude_device(u_char bus, u_char devfn) | ||
156 | { | ||
157 | if (bus == 0 && PCI_SLOT(devfn) == 0) | ||
158 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
159 | if (mpc85xx_pci2_busno) | ||
160 | if (bus == (mpc85xx_pci2_busno) && PCI_SLOT(devfn) == 0) | ||
161 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
162 | /* We explicitly do not go past the Tundra 320 Bridge */ | ||
163 | if ((bus == 1) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) | ||
164 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
165 | if ((bus == 0) && (PCI_SLOT(devfn) == ARCADIA_2ND_BRIDGE_IDSEL)) | ||
166 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
167 | else | ||
168 | return PCIBIOS_SUCCESSFUL; | ||
169 | } | ||
170 | |||
171 | void __init | ||
172 | mpc85xx_cds_pcibios_fixup(void) | ||
173 | { | ||
174 | struct pci_dev *dev; | ||
175 | u_char c; | ||
176 | |||
177 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | ||
178 | PCI_DEVICE_ID_VIA_82C586_1, NULL))) { | ||
179 | /* | ||
180 | * U-Boot does not set the enable bits | ||
181 | * for the IDE device. Force them on here. | ||
182 | */ | ||
183 | pci_read_config_byte(dev, 0x40, &c); | ||
184 | c |= 0x03; /* IDE: Chip Enable Bits */ | ||
185 | pci_write_config_byte(dev, 0x40, c); | ||
186 | |||
187 | /* | ||
188 | * Since only primary interface works, force the | ||
189 | * IDE function to standard primary IDE interrupt | ||
190 | * w/ 8259 offset | ||
191 | */ | ||
192 | dev->irq = 14; | ||
193 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, dev->irq); | ||
194 | pci_dev_put(dev); | ||
195 | } | ||
196 | |||
197 | /* | ||
198 | * Force legacy USB interrupt routing | ||
199 | */ | ||
200 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | ||
201 | PCI_DEVICE_ID_VIA_82C586_2, NULL))) { | ||
202 | dev->irq = 10; | ||
203 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 10); | ||
204 | pci_dev_put(dev); | ||
205 | } | ||
206 | |||
207 | if ((dev = pci_get_device(PCI_VENDOR_ID_VIA, | ||
208 | PCI_DEVICE_ID_VIA_82C586_2, dev))) { | ||
209 | dev->irq = 11; | ||
210 | pci_write_config_byte(dev, PCI_INTERRUPT_LINE, 11); | ||
211 | pci_dev_put(dev); | ||
212 | } | ||
213 | } | ||
214 | #endif /* CONFIG_PCI */ | ||
215 | |||
216 | void __init mpc85xx_cds_pic_init(void) | ||
217 | { | ||
218 | struct mpic *mpic1; | ||
219 | phys_addr_t OpenPIC_PAddr; | ||
220 | |||
221 | /* Determine the Physical Address of the OpenPIC regs */ | ||
222 | OpenPIC_PAddr = get_immrbase() + MPC85xx_OPENPIC_OFFSET; | ||
223 | |||
224 | mpic1 = mpic_alloc(OpenPIC_PAddr, | ||
225 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
226 | 4, MPC85xx_OPENPIC_IRQ_OFFSET, 0, 250, | ||
227 | mpc85xx_cds_openpic_initsenses, | ||
228 | sizeof(mpc85xx_cds_openpic_initsenses), " OpenPIC "); | ||
229 | BUG_ON(mpic1 == NULL); | ||
230 | mpic_assign_isu(mpic1, 0, OpenPIC_PAddr + 0x10200); | ||
231 | mpic_assign_isu(mpic1, 1, OpenPIC_PAddr + 0x10280); | ||
232 | mpic_assign_isu(mpic1, 2, OpenPIC_PAddr + 0x10300); | ||
233 | mpic_assign_isu(mpic1, 3, OpenPIC_PAddr + 0x10380); | ||
234 | mpic_assign_isu(mpic1, 4, OpenPIC_PAddr + 0x10400); | ||
235 | mpic_assign_isu(mpic1, 5, OpenPIC_PAddr + 0x10480); | ||
236 | mpic_assign_isu(mpic1, 6, OpenPIC_PAddr + 0x10500); | ||
237 | mpic_assign_isu(mpic1, 7, OpenPIC_PAddr + 0x10580); | ||
238 | |||
239 | /* dummy mappings to get to 48 */ | ||
240 | mpic_assign_isu(mpic1, 8, OpenPIC_PAddr + 0x10600); | ||
241 | mpic_assign_isu(mpic1, 9, OpenPIC_PAddr + 0x10680); | ||
242 | mpic_assign_isu(mpic1, 10, OpenPIC_PAddr + 0x10700); | ||
243 | mpic_assign_isu(mpic1, 11, OpenPIC_PAddr + 0x10780); | ||
244 | |||
245 | /* External ints */ | ||
246 | mpic_assign_isu(mpic1, 12, OpenPIC_PAddr + 0x10000); | ||
247 | mpic_assign_isu(mpic1, 13, OpenPIC_PAddr + 0x10080); | ||
248 | mpic_assign_isu(mpic1, 14, OpenPIC_PAddr + 0x10100); | ||
249 | |||
250 | mpic_init(mpic1); | ||
251 | |||
252 | #ifdef CONFIG_PCI | ||
253 | mpic_setup_cascade(PIRQ0A, i8259_irq_cascade, NULL); | ||
254 | |||
255 | i8259_init(0,0); | ||
256 | #endif | ||
257 | } | ||
258 | |||
259 | |||
260 | /* | ||
261 | * Setup the architecture | ||
262 | */ | ||
263 | static void __init | ||
264 | mpc85xx_cds_setup_arch(void) | ||
265 | { | ||
266 | struct device_node *cpu; | ||
267 | #ifdef CONFIG_PCI | ||
268 | struct device_node *np; | ||
269 | #endif | ||
270 | |||
271 | if (ppc_md.progress) | ||
272 | ppc_md.progress("mpc85xx_cds_setup_arch()", 0); | ||
273 | |||
274 | cpu = of_find_node_by_type(NULL, "cpu"); | ||
275 | if (cpu != 0) { | ||
276 | unsigned int *fp; | ||
277 | |||
278 | fp = (int *)get_property(cpu, "clock-frequency", NULL); | ||
279 | if (fp != 0) | ||
280 | loops_per_jiffy = *fp / HZ; | ||
281 | else | ||
282 | loops_per_jiffy = 500000000 / HZ; | ||
283 | of_node_put(cpu); | ||
284 | } | ||
285 | |||
286 | cadmus = ioremap(CADMUS_BASE, CADMUS_SIZE); | ||
287 | cds_pci_slot = ((cadmus[CM_CSR] >> 6) & 0x3) + 1; | ||
288 | |||
289 | if (ppc_md.progress) { | ||
290 | char buf[40]; | ||
291 | snprintf(buf, 40, "CDS Version = 0x%x in slot %d\n", | ||
292 | cadmus[CM_VER], cds_pci_slot); | ||
293 | ppc_md.progress(buf, 0); | ||
294 | } | ||
295 | |||
296 | #ifdef CONFIG_PCI | ||
297 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) | ||
298 | add_bridge(np); | ||
299 | |||
300 | ppc_md.pcibios_fixup = mpc85xx_cds_pcibios_fixup; | ||
301 | ppc_md.pci_swizzle = common_swizzle; | ||
302 | ppc_md.pci_map_irq = mpc85xx_map_irq; | ||
303 | ppc_md.pci_exclude_device = mpc85xx_exclude_device; | ||
304 | #endif | ||
305 | |||
306 | #ifdef CONFIG_ROOT_NFS | ||
307 | ROOT_DEV = Root_NFS; | ||
308 | #else | ||
309 | ROOT_DEV = Root_HDA1; | ||
310 | #endif | ||
311 | } | ||
312 | |||
313 | |||
314 | void | ||
315 | mpc85xx_cds_show_cpuinfo(struct seq_file *m) | ||
316 | { | ||
317 | uint pvid, svid, phid1; | ||
318 | uint memsize = total_memory; | ||
319 | |||
320 | pvid = mfspr(SPRN_PVR); | ||
321 | svid = mfspr(SPRN_SVR); | ||
322 | |||
323 | seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); | ||
324 | seq_printf(m, "Machine\t\t: MPC85xx CDS (0x%x)\n", cadmus[CM_VER]); | ||
325 | seq_printf(m, "PVR\t\t: 0x%x\n", pvid); | ||
326 | seq_printf(m, "SVR\t\t: 0x%x\n", svid); | ||
327 | |||
328 | /* Display cpu Pll setting */ | ||
329 | phid1 = mfspr(SPRN_HID1); | ||
330 | seq_printf(m, "PLL setting\t: 0x%x\n", ((phid1 >> 24) & 0x3f)); | ||
331 | |||
332 | /* Display the amount of memory */ | ||
333 | seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); | ||
334 | } | ||
335 | |||
336 | |||
337 | /* | ||
338 | * Called very early, device-tree isn't unflattened | ||
339 | */ | ||
340 | static int __init mpc85xx_cds_probe(void) | ||
341 | { | ||
342 | /* We always match for now, eventually we should look at | ||
343 | * the flat dev tree to ensure this is the board we are | ||
344 | * supposed to run on | ||
345 | */ | ||
346 | return 1; | ||
347 | } | ||
348 | |||
349 | define_machine(mpc85xx_cds) { | ||
350 | .name = "MPC85xx CDS", | ||
351 | .probe = mpc85xx_cds_probe, | ||
352 | .setup_arch = mpc85xx_cds_setup_arch, | ||
353 | .init_IRQ = mpc85xx_cds_pic_init, | ||
354 | .show_cpuinfo = mpc85xx_cds_show_cpuinfo, | ||
355 | .get_irq = mpic_get_irq, | ||
356 | .restart = mpc85xx_restart, | ||
357 | .calibrate_decr = generic_calibrate_decr, | ||
358 | .progress = udbg_progress, | ||
359 | }; | ||
diff --git a/arch/powerpc/platforms/85xx/mpc85xx_cds.h b/arch/powerpc/platforms/85xx/mpc85xx_cds.h new file mode 100644 index 000000000000..671f54ff185a --- /dev/null +++ b/arch/powerpc/platforms/85xx/mpc85xx_cds.h | |||
@@ -0,0 +1,43 @@ | |||
1 | /* | ||
2 | * arch/ppc/platforms/85xx/mpc85xx_cds_common.h | ||
3 | * | ||
4 | * MPC85xx CDS board definitions | ||
5 | * | ||
6 | * Maintainer: Kumar Gala <galak@kernel.crashing.org> | ||
7 | * | ||
8 | * Copyright 2004 Freescale Semiconductor, Inc | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or modify it | ||
11 | * under the terms of the GNU General Public License as published by the | ||
12 | * Free Software Foundation; either version 2 of the License, or (at your | ||
13 | * option) any later version. | ||
14 | * | ||
15 | */ | ||
16 | |||
17 | #ifndef __MACH_MPC85XX_CDS_H__ | ||
18 | #define __MACH_MPC85XX_CDS_H__ | ||
19 | |||
20 | /* CADMUS info */ | ||
21 | #define CADMUS_BASE (0xf8004000) | ||
22 | #define CADMUS_SIZE (256) | ||
23 | #define CM_VER (0) | ||
24 | #define CM_CSR (1) | ||
25 | #define CM_RST (2) | ||
26 | |||
27 | /* CDS NVRAM/RTC */ | ||
28 | #define CDS_RTC_ADDR (0xf8000000) | ||
29 | #define CDS_RTC_SIZE (8 * 1024) | ||
30 | |||
31 | /* PCI interrupt controller */ | ||
32 | #define PIRQ0A MPC85xx_IRQ_EXT0 | ||
33 | #define PIRQ0B MPC85xx_IRQ_EXT1 | ||
34 | #define PIRQ0C MPC85xx_IRQ_EXT2 | ||
35 | #define PIRQ0D MPC85xx_IRQ_EXT3 | ||
36 | #define PIRQ1A MPC85xx_IRQ_EXT11 | ||
37 | |||
38 | #define NR_8259_INTS 16 | ||
39 | #define CPM_IRQ_OFFSET NR_8259_INTS | ||
40 | |||
41 | #define MPC85xx_OPENPIC_IRQ_OFFSET 80 | ||
42 | |||
43 | #endif /* __MACH_MPC85XX_CDS_H__ */ | ||
diff --git a/arch/powerpc/platforms/86xx/Kconfig b/arch/powerpc/platforms/86xx/Kconfig new file mode 100644 index 000000000000..3a87863d2876 --- /dev/null +++ b/arch/powerpc/platforms/86xx/Kconfig | |||
@@ -0,0 +1,36 @@ | |||
1 | menu "Platform Support" | ||
2 | depends on PPC_86xx | ||
3 | |||
4 | choice | ||
5 | prompt "Machine Type" | ||
6 | default MPC8641_HPCN | ||
7 | |||
8 | config MPC8641_HPCN | ||
9 | bool "Freescale MPC8641 HPCN" | ||
10 | help | ||
11 | This option enables support for the MPC8641 HPCN board. | ||
12 | |||
13 | endchoice | ||
14 | |||
15 | |||
16 | config MPC8641 | ||
17 | bool | ||
18 | select PPC_INDIRECT_PCI | ||
19 | select PPC_UDBG_16550 | ||
20 | default y if MPC8641_HPCN | ||
21 | |||
22 | config MPIC | ||
23 | bool | ||
24 | default y | ||
25 | |||
26 | config PPC_INDIRECT_PCI_BE | ||
27 | bool | ||
28 | depends on PPC_86xx | ||
29 | default y | ||
30 | |||
31 | config PPC_STD_MMU | ||
32 | bool | ||
33 | depends on PPC_86xx | ||
34 | default y | ||
35 | |||
36 | endmenu | ||
diff --git a/arch/powerpc/platforms/86xx/Makefile b/arch/powerpc/platforms/86xx/Makefile new file mode 100644 index 000000000000..7be796c5d5c9 --- /dev/null +++ b/arch/powerpc/platforms/86xx/Makefile | |||
@@ -0,0 +1,10 @@ | |||
1 | # | ||
2 | # Makefile for the PowerPC 86xx linux kernel. | ||
3 | # | ||
4 | |||
5 | |||
6 | ifeq ($(CONFIG_PPC_86xx),y) | ||
7 | obj-$(CONFIG_SMP) += mpc86xx_smp.o | ||
8 | endif | ||
9 | obj-$(CONFIG_MPC8641_HPCN) += mpc86xx_hpcn.o | ||
10 | obj-$(CONFIG_PCI) += pci.o mpc86xx_pcie.o | ||
diff --git a/arch/powerpc/platforms/86xx/mpc8641_hpcn.h b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h new file mode 100644 index 000000000000..5042253758b7 --- /dev/null +++ b/arch/powerpc/platforms/86xx/mpc8641_hpcn.h | |||
@@ -0,0 +1,54 @@ | |||
1 | /* | ||
2 | * MPC8641 HPCN board definitions | ||
3 | * | ||
4 | * Copyright 2006 Freescale Semiconductor Inc. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or modify it | ||
7 | * under the terms of the GNU General Public License as published by the | ||
8 | * Free Software Foundation; either version 2 of the License, or (at your | ||
9 | * option) any later version. | ||
10 | * | ||
11 | * Author: Xianghua Xiao <x.xiao@freescale.com> | ||
12 | */ | ||
13 | |||
14 | #ifndef __MPC8641_HPCN_H__ | ||
15 | #define __MPC8641_HPCN_H__ | ||
16 | |||
17 | #include <linux/config.h> | ||
18 | #include <linux/init.h> | ||
19 | |||
20 | /* PCI interrupt controller */ | ||
21 | #define PIRQA 3 | ||
22 | #define PIRQB 4 | ||
23 | #define PIRQC 5 | ||
24 | #define PIRQD 6 | ||
25 | #define PIRQ7 7 | ||
26 | #define PIRQE 9 | ||
27 | #define PIRQF 10 | ||
28 | #define PIRQG 11 | ||
29 | #define PIRQH 12 | ||
30 | |||
31 | /* PCI-Express memory map */ | ||
32 | #define MPC86XX_PCIE_LOWER_IO 0x00000000 | ||
33 | #define MPC86XX_PCIE_UPPER_IO 0x00ffffff | ||
34 | |||
35 | #define MPC86XX_PCIE_LOWER_MEM 0x80000000 | ||
36 | #define MPC86XX_PCIE_UPPER_MEM 0x9fffffff | ||
37 | |||
38 | #define MPC86XX_PCIE_IO_BASE 0xe2000000 | ||
39 | #define MPC86XX_PCIE_MEM_OFFSET 0x00000000 | ||
40 | |||
41 | #define MPC86XX_PCIE_IO_SIZE 0x01000000 | ||
42 | |||
43 | #define PCIE1_CFG_ADDR_OFFSET (0x8000) | ||
44 | #define PCIE1_CFG_DATA_OFFSET (0x8004) | ||
45 | |||
46 | #define PCIE2_CFG_ADDR_OFFSET (0x9000) | ||
47 | #define PCIE2_CFG_DATA_OFFSET (0x9004) | ||
48 | |||
49 | #define MPC86xx_PCIE_OFFSET PCIE1_CFG_ADDR_OFFSET | ||
50 | #define MPC86xx_PCIE_SIZE (0x1000) | ||
51 | |||
52 | #define MPC86XX_RSTCR_OFFSET (0xe00b0) /* Reset Control Register */ | ||
53 | |||
54 | #endif /* __MPC8641_HPCN_H__ */ | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx.h b/arch/powerpc/platforms/86xx/mpc86xx.h new file mode 100644 index 000000000000..e3c9e4f417d3 --- /dev/null +++ b/arch/powerpc/platforms/86xx/mpc86xx.h | |||
@@ -0,0 +1,28 @@ | |||
1 | /* | ||
2 | * Copyright 2006 Freescale Semiconductor Inc. | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify it | ||
5 | * under the terms of the GNU General Public License as published by the | ||
6 | * Free Software Foundation; either version 2 of the License, or (at your | ||
7 | * option) any later version. | ||
8 | */ | ||
9 | |||
10 | #ifndef __MPC86XX_H__ | ||
11 | #define __MPC86XX_H__ | ||
12 | |||
13 | /* | ||
14 | * Declaration for the various functions exported by the | ||
15 | * mpc86xx_* files. Mostly for use by mpc86xx_setup(). | ||
16 | */ | ||
17 | |||
18 | extern int __init add_bridge(struct device_node *dev); | ||
19 | |||
20 | extern void __init setup_indirect_pcie(struct pci_controller *hose, | ||
21 | u32 cfg_addr, u32 cfg_data); | ||
22 | extern void __init setup_indirect_pcie_nomap(struct pci_controller *hose, | ||
23 | void __iomem *cfg_addr, | ||
24 | void __iomem *cfg_data); | ||
25 | |||
26 | extern void __init mpc86xx_smp_init(void); | ||
27 | |||
28 | #endif /* __MPC86XX_H__ */ | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c new file mode 100644 index 000000000000..483c21df181e --- /dev/null +++ b/arch/powerpc/platforms/86xx/mpc86xx_hpcn.c | |||
@@ -0,0 +1,326 @@ | |||
1 | /* | ||
2 | * MPC86xx HPCN board specific routines | ||
3 | * | ||
4 | * Recode: ZHANG WEI <wei.zhang@freescale.com> | ||
5 | * Initial author: Xianghua Xiao <x.xiao@freescale.com> | ||
6 | * | ||
7 | * Copyright 2006 Freescale Semiconductor Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/stddef.h> | ||
17 | #include <linux/kernel.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/kdev_t.h> | ||
20 | #include <linux/delay.h> | ||
21 | #include <linux/seq_file.h> | ||
22 | #include <linux/root_dev.h> | ||
23 | |||
24 | #include <asm/system.h> | ||
25 | #include <asm/time.h> | ||
26 | #include <asm/machdep.h> | ||
27 | #include <asm/pci-bridge.h> | ||
28 | #include <asm/mpc86xx.h> | ||
29 | #include <asm/prom.h> | ||
30 | #include <mm/mmu_decl.h> | ||
31 | #include <asm/udbg.h> | ||
32 | #include <asm/i8259.h> | ||
33 | |||
34 | #include <asm/mpic.h> | ||
35 | |||
36 | #include <sysdev/fsl_soc.h> | ||
37 | |||
38 | #include "mpc86xx.h" | ||
39 | |||
40 | #ifndef CONFIG_PCI | ||
41 | unsigned long isa_io_base = 0; | ||
42 | unsigned long isa_mem_base = 0; | ||
43 | unsigned long pci_dram_offset = 0; | ||
44 | #endif | ||
45 | |||
46 | |||
47 | /* | ||
48 | * Internal interrupts are all Level Sensitive, and Positive Polarity | ||
49 | */ | ||
50 | |||
51 | static u_char mpc86xx_hpcn_openpic_initsenses[] __initdata = { | ||
52 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 0: Reserved */ | ||
53 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 1: MCM */ | ||
54 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 2: DDR DRAM */ | ||
55 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 3: LBIU */ | ||
56 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 4: DMA 0 */ | ||
57 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 5: DMA 1 */ | ||
58 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 6: DMA 2 */ | ||
59 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 7: DMA 3 */ | ||
60 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 8: PCIE1 */ | ||
61 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 9: PCIE2 */ | ||
62 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 10: Reserved */ | ||
63 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 11: Reserved */ | ||
64 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 12: DUART2 */ | ||
65 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 13: TSEC 1 Transmit */ | ||
66 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 14: TSEC 1 Receive */ | ||
67 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 15: TSEC 3 transmit */ | ||
68 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 16: TSEC 3 receive */ | ||
69 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 17: TSEC 3 error */ | ||
70 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 18: TSEC 1 Receive/Transmit Error */ | ||
71 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 19: TSEC 2 Transmit */ | ||
72 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 20: TSEC 2 Receive */ | ||
73 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 21: TSEC 4 transmit */ | ||
74 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 22: TSEC 4 receive */ | ||
75 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 23: TSEC 4 error */ | ||
76 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 24: TSEC 2 Receive/Transmit Error */ | ||
77 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 25: Unused */ | ||
78 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 26: DUART1 */ | ||
79 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 27: I2C */ | ||
80 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 28: Performance Monitor */ | ||
81 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 29: Unused */ | ||
82 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 30: Unused */ | ||
83 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 31: Unused */ | ||
84 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 32: SRIO error/write-port unit */ | ||
85 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 33: SRIO outbound doorbell */ | ||
86 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 34: SRIO inbound doorbell */ | ||
87 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 35: Unused */ | ||
88 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 36: Unused */ | ||
89 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 37: SRIO outbound message unit 1 */ | ||
90 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 38: SRIO inbound message unit 1 */ | ||
91 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 39: SRIO outbound message unit 2 */ | ||
92 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 40: SRIO inbound message unit 2 */ | ||
93 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 41: Unused */ | ||
94 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 42: Unused */ | ||
95 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 43: Unused */ | ||
96 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 44: Unused */ | ||
97 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 45: Unused */ | ||
98 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 46: Unused */ | ||
99 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* Internal 47: Unused */ | ||
100 | 0x0, /* External 0: */ | ||
101 | 0x0, /* External 1: */ | ||
102 | 0x0, /* External 2: */ | ||
103 | 0x0, /* External 3: */ | ||
104 | 0x0, /* External 4: */ | ||
105 | 0x0, /* External 5: */ | ||
106 | 0x0, /* External 6: */ | ||
107 | 0x0, /* External 7: */ | ||
108 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 8: Pixis FPGA */ | ||
109 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_POSITIVE), /* External 9: ULI 8259 INTR Cascade */ | ||
110 | (IRQ_SENSE_LEVEL | IRQ_POLARITY_NEGATIVE), /* External 10: Quad ETH PHY */ | ||
111 | 0x0, /* External 11: */ | ||
112 | 0x0, | ||
113 | 0x0, | ||
114 | 0x0, | ||
115 | 0x0, | ||
116 | }; | ||
117 | |||
118 | |||
119 | void __init | ||
120 | mpc86xx_hpcn_init_irq(void) | ||
121 | { | ||
122 | struct mpic *mpic1; | ||
123 | phys_addr_t openpic_paddr; | ||
124 | |||
125 | /* Determine the Physical Address of the OpenPIC regs */ | ||
126 | openpic_paddr = get_immrbase() + MPC86xx_OPENPIC_OFFSET; | ||
127 | |||
128 | /* Alloc mpic structure and per isu has 16 INT entries. */ | ||
129 | mpic1 = mpic_alloc(openpic_paddr, | ||
130 | MPIC_PRIMARY | MPIC_WANTS_RESET | MPIC_BIG_ENDIAN, | ||
131 | 16, MPC86xx_OPENPIC_IRQ_OFFSET, 0, 250, | ||
132 | mpc86xx_hpcn_openpic_initsenses, | ||
133 | sizeof(mpc86xx_hpcn_openpic_initsenses), | ||
134 | " MPIC "); | ||
135 | BUG_ON(mpic1 == NULL); | ||
136 | |||
137 | /* 48 Internal Interrupts */ | ||
138 | mpic_assign_isu(mpic1, 0, openpic_paddr + 0x10200); | ||
139 | mpic_assign_isu(mpic1, 1, openpic_paddr + 0x10400); | ||
140 | mpic_assign_isu(mpic1, 2, openpic_paddr + 0x10600); | ||
141 | |||
142 | /* 16 External interrupts */ | ||
143 | mpic_assign_isu(mpic1, 3, openpic_paddr + 0x10000); | ||
144 | |||
145 | mpic_init(mpic1); | ||
146 | |||
147 | #ifdef CONFIG_PCI | ||
148 | mpic_setup_cascade(MPC86xx_IRQ_EXT9, i8259_irq_cascade, NULL); | ||
149 | i8259_init(0, I8259_OFFSET); | ||
150 | #endif | ||
151 | } | ||
152 | |||
153 | |||
154 | |||
155 | #ifdef CONFIG_PCI | ||
156 | /* | ||
157 | * interrupt routing | ||
158 | */ | ||
159 | |||
160 | int | ||
161 | mpc86xx_map_irq(struct pci_dev *dev, unsigned char idsel, unsigned char pin) | ||
162 | { | ||
163 | static char pci_irq_table[][4] = { | ||
164 | /* | ||
165 | * PCI IDSEL/INTPIN->INTLINE | ||
166 | * A B C D | ||
167 | */ | ||
168 | {PIRQA, PIRQB, PIRQC, PIRQD}, /* IDSEL 17 -- PCI Slot 1 */ | ||
169 | {PIRQB, PIRQC, PIRQD, PIRQA}, /* IDSEL 18 -- PCI Slot 2 */ | ||
170 | {0, 0, 0, 0}, /* IDSEL 19 */ | ||
171 | {0, 0, 0, 0}, /* IDSEL 20 */ | ||
172 | {0, 0, 0, 0}, /* IDSEL 21 */ | ||
173 | {0, 0, 0, 0}, /* IDSEL 22 */ | ||
174 | {0, 0, 0, 0}, /* IDSEL 23 */ | ||
175 | {0, 0, 0, 0}, /* IDSEL 24 */ | ||
176 | {0, 0, 0, 0}, /* IDSEL 25 */ | ||
177 | {PIRQD, PIRQA, PIRQB, PIRQC}, /* IDSEL 26 -- PCI Bridge*/ | ||
178 | {PIRQC, 0, 0, 0}, /* IDSEL 27 -- LAN */ | ||
179 | {PIRQE, PIRQF, PIRQH, PIRQ7}, /* IDSEL 28 -- USB 1.1 */ | ||
180 | {PIRQE, PIRQF, PIRQG, 0}, /* IDSEL 29 -- Audio & Modem */ | ||
181 | {PIRQH, 0, 0, 0}, /* IDSEL 30 -- LPC & PMU*/ | ||
182 | {PIRQD, 0, 0, 0}, /* IDSEL 31 -- ATA */ | ||
183 | }; | ||
184 | |||
185 | const long min_idsel = 17, max_idsel = 31, irqs_per_slot = 4; | ||
186 | return PCI_IRQ_TABLE_LOOKUP + I8259_OFFSET; | ||
187 | } | ||
188 | |||
189 | |||
190 | int | ||
191 | mpc86xx_exclude_device(u_char bus, u_char devfn) | ||
192 | { | ||
193 | #if !defined(CONFIG_PCI) | ||
194 | if (bus == 0 && PCI_SLOT(devfn) == 0) | ||
195 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
196 | #endif | ||
197 | |||
198 | return PCIBIOS_SUCCESSFUL; | ||
199 | } | ||
200 | #endif /* CONFIG_PCI */ | ||
201 | |||
202 | |||
203 | static void __init | ||
204 | mpc86xx_hpcn_setup_arch(void) | ||
205 | { | ||
206 | struct device_node *np; | ||
207 | |||
208 | if (ppc_md.progress) | ||
209 | ppc_md.progress("mpc86xx_hpcn_setup_arch()", 0); | ||
210 | |||
211 | np = of_find_node_by_type(NULL, "cpu"); | ||
212 | if (np != 0) { | ||
213 | unsigned int *fp; | ||
214 | |||
215 | fp = (int *)get_property(np, "clock-frequency", NULL); | ||
216 | if (fp != 0) | ||
217 | loops_per_jiffy = *fp / HZ; | ||
218 | else | ||
219 | loops_per_jiffy = 50000000 / HZ; | ||
220 | of_node_put(np); | ||
221 | } | ||
222 | |||
223 | #ifdef CONFIG_PCI | ||
224 | for (np = NULL; (np = of_find_node_by_type(np, "pci")) != NULL;) | ||
225 | add_bridge(np); | ||
226 | |||
227 | ppc_md.pci_swizzle = common_swizzle; | ||
228 | ppc_md.pci_map_irq = mpc86xx_map_irq; | ||
229 | ppc_md.pci_exclude_device = mpc86xx_exclude_device; | ||
230 | #endif | ||
231 | |||
232 | printk("MPC86xx HPCN board from Freescale Semiconductor\n"); | ||
233 | |||
234 | #ifdef CONFIG_ROOT_NFS | ||
235 | ROOT_DEV = Root_NFS; | ||
236 | #else | ||
237 | ROOT_DEV = Root_HDA1; | ||
238 | #endif | ||
239 | |||
240 | #ifdef CONFIG_SMP | ||
241 | mpc86xx_smp_init(); | ||
242 | #endif | ||
243 | } | ||
244 | |||
245 | |||
246 | void | ||
247 | mpc86xx_hpcn_show_cpuinfo(struct seq_file *m) | ||
248 | { | ||
249 | struct device_node *root; | ||
250 | uint memsize = total_memory; | ||
251 | const char *model = ""; | ||
252 | uint svid = mfspr(SPRN_SVR); | ||
253 | |||
254 | seq_printf(m, "Vendor\t\t: Freescale Semiconductor\n"); | ||
255 | |||
256 | root = of_find_node_by_path("/"); | ||
257 | if (root) | ||
258 | model = get_property(root, "model", NULL); | ||
259 | seq_printf(m, "Machine\t\t: %s\n", model); | ||
260 | of_node_put(root); | ||
261 | |||
262 | seq_printf(m, "SVR\t\t: 0x%x\n", svid); | ||
263 | seq_printf(m, "Memory\t\t: %d MB\n", memsize / (1024 * 1024)); | ||
264 | } | ||
265 | |||
266 | |||
267 | /* | ||
268 | * Called very early, device-tree isn't unflattened | ||
269 | */ | ||
270 | static int __init mpc86xx_hpcn_probe(void) | ||
271 | { | ||
272 | unsigned long root = of_get_flat_dt_root(); | ||
273 | |||
274 | if (of_flat_dt_is_compatible(root, "mpc86xx")) | ||
275 | return 1; /* Looks good */ | ||
276 | |||
277 | return 0; | ||
278 | } | ||
279 | |||
280 | |||
281 | void | ||
282 | mpc86xx_restart(char *cmd) | ||
283 | { | ||
284 | void __iomem *rstcr; | ||
285 | |||
286 | rstcr = ioremap(get_immrbase() + MPC86XX_RSTCR_OFFSET, 0x100); | ||
287 | |||
288 | local_irq_disable(); | ||
289 | |||
290 | /* Assert reset request to Reset Control Register */ | ||
291 | out_be32(rstcr, 0x2); | ||
292 | |||
293 | /* not reached */ | ||
294 | } | ||
295 | |||
296 | |||
297 | long __init | ||
298 | mpc86xx_time_init(void) | ||
299 | { | ||
300 | unsigned int temp; | ||
301 | |||
302 | /* Set the time base to zero */ | ||
303 | mtspr(SPRN_TBWL, 0); | ||
304 | mtspr(SPRN_TBWU, 0); | ||
305 | |||
306 | temp = mfspr(SPRN_HID0); | ||
307 | temp |= HID0_TBEN; | ||
308 | mtspr(SPRN_HID0, temp); | ||
309 | asm volatile("isync"); | ||
310 | |||
311 | return 0; | ||
312 | } | ||
313 | |||
314 | |||
315 | define_machine(mpc86xx_hpcn) { | ||
316 | .name = "MPC86xx HPCN", | ||
317 | .probe = mpc86xx_hpcn_probe, | ||
318 | .setup_arch = mpc86xx_hpcn_setup_arch, | ||
319 | .init_IRQ = mpc86xx_hpcn_init_irq, | ||
320 | .show_cpuinfo = mpc86xx_hpcn_show_cpuinfo, | ||
321 | .get_irq = mpic_get_irq, | ||
322 | .restart = mpc86xx_restart, | ||
323 | .time_init = mpc86xx_time_init, | ||
324 | .calibrate_decr = generic_calibrate_decr, | ||
325 | .progress = udbg_progress, | ||
326 | }; | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_pcie.c b/arch/powerpc/platforms/86xx/mpc86xx_pcie.c new file mode 100644 index 000000000000..a2f4f730213e --- /dev/null +++ b/arch/powerpc/platforms/86xx/mpc86xx_pcie.c | |||
@@ -0,0 +1,173 @@ | |||
1 | /* | ||
2 | * Support for indirect PCI bridges. | ||
3 | * | ||
4 | * Copyright (C) 1998 Gabriel Paubert. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | * | ||
11 | * "Temporary" MPC8548 Errata file - | ||
12 | * The standard indirect_pci code should work with future silicon versions. | ||
13 | */ | ||
14 | |||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/pci.h> | ||
17 | #include <linux/delay.h> | ||
18 | #include <linux/string.h> | ||
19 | #include <linux/init.h> | ||
20 | #include <linux/bootmem.h> | ||
21 | |||
22 | #include <asm/io.h> | ||
23 | #include <asm/prom.h> | ||
24 | #include <asm/pci-bridge.h> | ||
25 | #include <asm/machdep.h> | ||
26 | |||
27 | #include "mpc86xx.h" | ||
28 | |||
29 | #define PCI_CFG_OUT out_be32 | ||
30 | |||
31 | /* ERRATA PCI-Ex 14 PCIE Controller timeout */ | ||
32 | #define PCIE_FIX out_be32(hose->cfg_addr+0x4, 0x0400ffff) | ||
33 | |||
34 | |||
35 | static int | ||
36 | indirect_read_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset, | ||
37 | int len, u32 *val) | ||
38 | { | ||
39 | struct pci_controller *hose = bus->sysdata; | ||
40 | volatile void __iomem *cfg_data; | ||
41 | u32 temp; | ||
42 | |||
43 | if (ppc_md.pci_exclude_device) | ||
44 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | ||
45 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
46 | |||
47 | /* Possible artifact of CDCpp50937 needs further investigation */ | ||
48 | if (devfn != 0x0 && bus->number == 0xff) | ||
49 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
50 | |||
51 | PCIE_FIX; | ||
52 | if (bus->number == 0xff) { | ||
53 | PCI_CFG_OUT(hose->cfg_addr, | ||
54 | (0x80000000 | ((offset & 0xf00) << 16) | | ||
55 | ((bus->number - hose->bus_offset) << 16) | ||
56 | | (devfn << 8) | ((offset & 0xfc) ))); | ||
57 | } else { | ||
58 | PCI_CFG_OUT(hose->cfg_addr, | ||
59 | (0x80000001 | ((offset & 0xf00) << 16) | | ||
60 | ((bus->number - hose->bus_offset) << 16) | ||
61 | | (devfn << 8) | ((offset & 0xfc) ))); | ||
62 | } | ||
63 | |||
64 | /* | ||
65 | * Note: the caller has already checked that offset is | ||
66 | * suitably aligned and that len is 1, 2 or 4. | ||
67 | */ | ||
68 | /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */ | ||
69 | cfg_data = hose->cfg_data; | ||
70 | PCIE_FIX; | ||
71 | temp = in_le32(cfg_data); | ||
72 | switch (len) { | ||
73 | case 1: | ||
74 | *val = (temp >> (((offset & 3))*8)) & 0xff; | ||
75 | break; | ||
76 | case 2: | ||
77 | *val = (temp >> (((offset & 3))*8)) & 0xffff; | ||
78 | break; | ||
79 | default: | ||
80 | *val = temp; | ||
81 | break; | ||
82 | } | ||
83 | return PCIBIOS_SUCCESSFUL; | ||
84 | } | ||
85 | |||
86 | static int | ||
87 | indirect_write_config_pcie(struct pci_bus *bus, unsigned int devfn, int offset, | ||
88 | int len, u32 val) | ||
89 | { | ||
90 | struct pci_controller *hose = bus->sysdata; | ||
91 | volatile void __iomem *cfg_data; | ||
92 | u32 temp; | ||
93 | |||
94 | if (ppc_md.pci_exclude_device) | ||
95 | if (ppc_md.pci_exclude_device(bus->number, devfn)) | ||
96 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
97 | |||
98 | /* Possible artifact of CDCpp50937 needs further investigation */ | ||
99 | if (devfn != 0x0 && bus->number == 0xff) | ||
100 | return PCIBIOS_DEVICE_NOT_FOUND; | ||
101 | |||
102 | PCIE_FIX; | ||
103 | if (bus->number == 0xff) { | ||
104 | PCI_CFG_OUT(hose->cfg_addr, | ||
105 | (0x80000000 | ((offset & 0xf00) << 16) | | ||
106 | ((bus->number - hose->bus_offset) << 16) | ||
107 | | (devfn << 8) | ((offset & 0xfc) ))); | ||
108 | } else { | ||
109 | PCI_CFG_OUT(hose->cfg_addr, | ||
110 | (0x80000001 | ((offset & 0xf00) << 16) | | ||
111 | ((bus->number - hose->bus_offset) << 16) | ||
112 | | (devfn << 8) | ((offset & 0xfc) ))); | ||
113 | } | ||
114 | |||
115 | /* | ||
116 | * Note: the caller has already checked that offset is | ||
117 | * suitably aligned and that len is 1, 2 or 4. | ||
118 | */ | ||
119 | /* ERRATA PCI-Ex 12 - Configuration Address/Data Alignment */ | ||
120 | cfg_data = hose->cfg_data; | ||
121 | switch (len) { | ||
122 | case 1: | ||
123 | PCIE_FIX; | ||
124 | temp = in_le32(cfg_data); | ||
125 | temp = (temp & ~(0xff << ((offset & 3) * 8))) | | ||
126 | (val << ((offset & 3) * 8)); | ||
127 | PCIE_FIX; | ||
128 | out_le32(cfg_data, temp); | ||
129 | break; | ||
130 | case 2: | ||
131 | PCIE_FIX; | ||
132 | temp = in_le32(cfg_data); | ||
133 | temp = (temp & ~(0xffff << ((offset & 3) * 8))); | ||
134 | temp |= (val << ((offset & 3) * 8)) ; | ||
135 | PCIE_FIX; | ||
136 | out_le32(cfg_data, temp); | ||
137 | break; | ||
138 | default: | ||
139 | PCIE_FIX; | ||
140 | out_le32(cfg_data, val); | ||
141 | break; | ||
142 | } | ||
143 | PCIE_FIX; | ||
144 | return PCIBIOS_SUCCESSFUL; | ||
145 | } | ||
146 | |||
147 | static struct pci_ops indirect_pcie_ops = { | ||
148 | indirect_read_config_pcie, | ||
149 | indirect_write_config_pcie | ||
150 | }; | ||
151 | |||
152 | void __init | ||
153 | setup_indirect_pcie_nomap(struct pci_controller* hose, void __iomem * cfg_addr, | ||
154 | void __iomem * cfg_data) | ||
155 | { | ||
156 | hose->cfg_addr = cfg_addr; | ||
157 | hose->cfg_data = cfg_data; | ||
158 | hose->ops = &indirect_pcie_ops; | ||
159 | } | ||
160 | |||
161 | void __init | ||
162 | setup_indirect_pcie(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data) | ||
163 | { | ||
164 | unsigned long base = cfg_addr & PAGE_MASK; | ||
165 | void __iomem *mbase, *addr, *data; | ||
166 | |||
167 | mbase = ioremap(base, PAGE_SIZE); | ||
168 | addr = mbase + (cfg_addr & ~PAGE_MASK); | ||
169 | if ((cfg_data & PAGE_MASK) != base) | ||
170 | mbase = ioremap(cfg_data & PAGE_MASK, PAGE_SIZE); | ||
171 | data = mbase + (cfg_data & ~PAGE_MASK); | ||
172 | setup_indirect_pcie_nomap(hose, addr, data); | ||
173 | } | ||
diff --git a/arch/powerpc/platforms/86xx/mpc86xx_smp.c b/arch/powerpc/platforms/86xx/mpc86xx_smp.c new file mode 100644 index 000000000000..944ec4b71416 --- /dev/null +++ b/arch/powerpc/platforms/86xx/mpc86xx_smp.c | |||
@@ -0,0 +1,117 @@ | |||
1 | /* | ||
2 | * Author: Xianghua Xiao <x.xiao@freescale.com> | ||
3 | * Zhang Wei <wei.zhang@freescale.com> | ||
4 | * | ||
5 | * Copyright 2006 Freescale Semiconductor Inc. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify it | ||
8 | * under the terms of the GNU General Public License as published by the | ||
9 | * Free Software Foundation; either version 2 of the License, or (at your | ||
10 | * option) any later version. | ||
11 | */ | ||
12 | |||
13 | #include <linux/config.h> | ||
14 | #include <linux/stddef.h> | ||
15 | #include <linux/kernel.h> | ||
16 | #include <linux/init.h> | ||
17 | #include <linux/delay.h> | ||
18 | |||
19 | #include <asm/pgtable.h> | ||
20 | #include <asm/page.h> | ||
21 | #include <asm/pci-bridge.h> | ||
22 | #include <asm-powerpc/mpic.h> | ||
23 | #include <asm/mpc86xx.h> | ||
24 | #include <asm/cacheflush.h> | ||
25 | |||
26 | #include <sysdev/fsl_soc.h> | ||
27 | |||
28 | #include "mpc86xx.h" | ||
29 | |||
30 | extern void __secondary_start_mpc86xx(void); | ||
31 | extern unsigned long __secondary_hold_acknowledge; | ||
32 | |||
33 | |||
34 | static void __init | ||
35 | smp_86xx_release_core(int nr) | ||
36 | { | ||
37 | void *mcm_vaddr; | ||
38 | unsigned long vaddr, pcr; | ||
39 | |||
40 | if (nr < 0 || nr >= NR_CPUS) | ||
41 | return; | ||
42 | |||
43 | /* | ||
44 | * Startup Core #nr. | ||
45 | */ | ||
46 | mcm_vaddr = ioremap(get_immrbase() + MPC86xx_MCM_OFFSET, | ||
47 | MPC86xx_MCM_SIZE); | ||
48 | vaddr = (unsigned long)mcm_vaddr + MCM_PORT_CONFIG_OFFSET; | ||
49 | pcr = in_be32((volatile unsigned *)vaddr); | ||
50 | pcr |= 1 << (nr + 24); | ||
51 | out_be32((volatile unsigned *)vaddr, pcr); | ||
52 | } | ||
53 | |||
54 | |||
55 | static void __init | ||
56 | smp_86xx_kick_cpu(int nr) | ||
57 | { | ||
58 | unsigned int save_vector; | ||
59 | unsigned long target, flags; | ||
60 | int n = 0; | ||
61 | volatile unsigned int *vector | ||
62 | = (volatile unsigned int *)(KERNELBASE + 0x100); | ||
63 | |||
64 | if (nr < 0 || nr >= NR_CPUS) | ||
65 | return; | ||
66 | |||
67 | pr_debug("smp_86xx_kick_cpu: kick CPU #%d\n", nr); | ||
68 | |||
69 | local_irq_save(flags); | ||
70 | local_irq_disable(); | ||
71 | |||
72 | /* Save reset vector */ | ||
73 | save_vector = *vector; | ||
74 | |||
75 | /* Setup fake reset vector to call __secondary_start_mpc86xx. */ | ||
76 | target = (unsigned long) __secondary_start_mpc86xx; | ||
77 | create_branch((unsigned long)vector, target, BRANCH_SET_LINK); | ||
78 | |||
79 | /* Kick that CPU */ | ||
80 | smp_86xx_release_core(nr); | ||
81 | |||
82 | /* Wait a bit for the CPU to take the exception. */ | ||
83 | while ((__secondary_hold_acknowledge != nr) && (n++, n < 1000)) | ||
84 | mdelay(1); | ||
85 | |||
86 | /* Restore the exception vector */ | ||
87 | *vector = save_vector; | ||
88 | flush_icache_range((unsigned long) vector, (unsigned long) vector + 4); | ||
89 | |||
90 | local_irq_restore(flags); | ||
91 | |||
92 | pr_debug("wait CPU #%d for %d msecs.\n", nr, n); | ||
93 | } | ||
94 | |||
95 | |||
96 | static void __init | ||
97 | smp_86xx_setup_cpu(int cpu_nr) | ||
98 | { | ||
99 | mpic_setup_this_cpu(); | ||
100 | } | ||
101 | |||
102 | |||
103 | struct smp_ops_t smp_86xx_ops = { | ||
104 | .message_pass = smp_mpic_message_pass, | ||
105 | .probe = smp_mpic_probe, | ||
106 | .kick_cpu = smp_86xx_kick_cpu, | ||
107 | .setup_cpu = smp_86xx_setup_cpu, | ||
108 | .take_timebase = smp_generic_take_timebase, | ||
109 | .give_timebase = smp_generic_give_timebase, | ||
110 | }; | ||
111 | |||
112 | |||
113 | void __init | ||
114 | mpc86xx_smp_init(void) | ||
115 | { | ||
116 | smp_ops = &smp_86xx_ops; | ||
117 | } | ||
diff --git a/arch/powerpc/platforms/86xx/pci.c b/arch/powerpc/platforms/86xx/pci.c new file mode 100644 index 000000000000..5180df7c75bc --- /dev/null +++ b/arch/powerpc/platforms/86xx/pci.c | |||
@@ -0,0 +1,325 @@ | |||
1 | /* | ||
2 | * MPC86XX pci setup code | ||
3 | * | ||
4 | * Recode: ZHANG WEI <wei.zhang@freescale.com> | ||
5 | * Initial author: Xianghua Xiao <x.xiao@freescale.com> | ||
6 | * | ||
7 | * Copyright 2006 Freescale Semiconductor Inc. | ||
8 | * | ||
9 | * This program is free software; you can redistribute it and/or modify it | ||
10 | * under the terms of the GNU General Public License as published by the | ||
11 | * Free Software Foundation; either version 2 of the License, or (at your | ||
12 | * option) any later version. | ||
13 | */ | ||
14 | |||
15 | #include <linux/config.h> | ||
16 | #include <linux/types.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/init.h> | ||
19 | #include <linux/pci.h> | ||
20 | #include <linux/serial.h> | ||
21 | |||
22 | #include <asm/system.h> | ||
23 | #include <asm/atomic.h> | ||
24 | #include <asm/io.h> | ||
25 | #include <asm/prom.h> | ||
26 | #include <asm/immap_86xx.h> | ||
27 | #include <asm/pci-bridge.h> | ||
28 | #include <sysdev/fsl_soc.h> | ||
29 | |||
30 | #include "mpc86xx.h" | ||
31 | |||
32 | #undef DEBUG | ||
33 | |||
34 | #ifdef DEBUG | ||
35 | #define DBG(fmt, args...) printk(KERN_ERR "%s: " fmt, __FUNCTION__, ## args) | ||
36 | #else | ||
37 | #define DBG(fmt, args...) | ||
38 | #endif | ||
39 | |||
40 | struct pcie_outbound_window_regs { | ||
41 | uint pexotar; /* 0x.0 - PCI Express outbound translation address register */ | ||
42 | uint pexotear; /* 0x.4 - PCI Express outbound translation extended address register */ | ||
43 | uint pexowbar; /* 0x.8 - PCI Express outbound window base address register */ | ||
44 | char res1[4]; | ||
45 | uint pexowar; /* 0x.10 - PCI Express outbound window attributes register */ | ||
46 | char res2[12]; | ||
47 | }; | ||
48 | |||
49 | struct pcie_inbound_window_regs { | ||
50 | uint pexitar; /* 0x.0 - PCI Express inbound translation address register */ | ||
51 | char res1[4]; | ||
52 | uint pexiwbar; /* 0x.8 - PCI Express inbound window base address register */ | ||
53 | uint pexiwbear; /* 0x.c - PCI Express inbound window base extended address register */ | ||
54 | uint pexiwar; /* 0x.10 - PCI Express inbound window attributes register */ | ||
55 | char res2[12]; | ||
56 | }; | ||
57 | |||
58 | static void __init setup_pcie_atmu(struct pci_controller *hose, struct resource *rsrc) | ||
59 | { | ||
60 | volatile struct ccsr_pex *pcie; | ||
61 | volatile struct pcie_outbound_window_regs *pcieow; | ||
62 | volatile struct pcie_inbound_window_regs *pcieiw; | ||
63 | int i = 0; | ||
64 | |||
65 | DBG("PCIE memory map start 0x%x, size 0x%x\n", rsrc->start, | ||
66 | rsrc->end - rsrc->start + 1); | ||
67 | pcie = ioremap(rsrc->start, rsrc->end - rsrc->start + 1); | ||
68 | |||
69 | /* Disable all windows (except pexowar0 since its ignored) */ | ||
70 | pcie->pexowar1 = 0; | ||
71 | pcie->pexowar2 = 0; | ||
72 | pcie->pexowar3 = 0; | ||
73 | pcie->pexowar4 = 0; | ||
74 | pcie->pexiwar1 = 0; | ||
75 | pcie->pexiwar2 = 0; | ||
76 | pcie->pexiwar3 = 0; | ||
77 | |||
78 | pcieow = (struct pcie_outbound_window_regs *)&pcie->pexotar1; | ||
79 | pcieiw = (struct pcie_inbound_window_regs *)&pcie->pexitar1; | ||
80 | |||
81 | /* Setup outbound MEM window */ | ||
82 | for(i = 0; i < 3; i++) | ||
83 | if (hose->mem_resources[i].flags & IORESOURCE_MEM){ | ||
84 | DBG("PCIE MEM resource start 0x%08x, size 0x%08x.\n", | ||
85 | hose->mem_resources[i].start, | ||
86 | hose->mem_resources[i].end | ||
87 | - hose->mem_resources[i].start + 1); | ||
88 | pcieow->pexotar = (hose->mem_resources[i].start) >> 12 | ||
89 | & 0x000fffff; | ||
90 | pcieow->pexotear = 0; | ||
91 | pcieow->pexowbar = (hose->mem_resources[i].start) >> 12 | ||
92 | & 0x000fffff; | ||
93 | /* Enable, Mem R/W */ | ||
94 | pcieow->pexowar = 0x80044000 | | ||
95 | (__ilog2(hose->mem_resources[i].end | ||
96 | - hose->mem_resources[i].start + 1) | ||
97 | - 1); | ||
98 | pcieow++; | ||
99 | } | ||
100 | |||
101 | /* Setup outbound IO window */ | ||
102 | if (hose->io_resource.flags & IORESOURCE_IO){ | ||
103 | DBG("PCIE IO resource start 0x%08x, size 0x%08x, phy base 0x%08x.\n", | ||
104 | hose->io_resource.start, | ||
105 | hose->io_resource.end - hose->io_resource.start + 1, | ||
106 | hose->io_base_phys); | ||
107 | pcieow->pexotar = (hose->io_resource.start) >> 12 & 0x000fffff; | ||
108 | pcieow->pexotear = 0; | ||
109 | pcieow->pexowbar = (hose->io_base_phys) >> 12 & 0x000fffff; | ||
110 | /* Enable, IO R/W */ | ||
111 | pcieow->pexowar = 0x80088000 | (__ilog2(hose->io_resource.end | ||
112 | - hose->io_resource.start + 1) - 1); | ||
113 | } | ||
114 | |||
115 | /* Setup 2G inbound Memory Window @ 0 */ | ||
116 | pcieiw->pexitar = 0x00000000; | ||
117 | pcieiw->pexiwbar = 0x00000000; | ||
118 | /* Enable, Prefetch, Local Mem, Snoop R/W, 2G */ | ||
119 | pcieiw->pexiwar = 0xa0f5501e; | ||
120 | } | ||
121 | |||
122 | static void __init | ||
123 | mpc86xx_setup_pcie(struct pci_controller *hose, u32 pcie_offset, u32 pcie_size) | ||
124 | { | ||
125 | volatile struct ccsr_pex *pcie; | ||
126 | u16 cmd; | ||
127 | unsigned int temps; | ||
128 | |||
129 | DBG("PCIE host controller register offset 0x%08x, size 0x%08x.\n", | ||
130 | pcie_offset, pcie_size); | ||
131 | |||
132 | pcie = ioremap(pcie_offset, pcie_size); | ||
133 | |||
134 | early_read_config_word(hose, 0, 0, PCI_COMMAND, &cmd); | ||
135 | cmd |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | ||
136 | | PCI_COMMAND_IO; | ||
137 | early_write_config_word(hose, 0, 0, PCI_COMMAND, cmd); | ||
138 | |||
139 | early_write_config_byte(hose, 0, 0, PCI_LATENCY_TIMER, 0x80); | ||
140 | |||
141 | /* PCIE Bus, Fix the MPC8641D host bridge's location to bus 0xFF. */ | ||
142 | early_read_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, &temps); | ||
143 | temps = (temps & 0xff000000) | (0xff) | (0x0 << 8) | (0xfe << 16); | ||
144 | early_write_config_dword(hose, 0, 0, PCI_PRIMARY_BUS, temps); | ||
145 | } | ||
146 | |||
147 | int __init add_bridge(struct device_node *dev) | ||
148 | { | ||
149 | int len; | ||
150 | struct pci_controller *hose; | ||
151 | struct resource rsrc; | ||
152 | int *bus_range; | ||
153 | int has_address = 0; | ||
154 | int primary = 0; | ||
155 | |||
156 | DBG("Adding PCIE host bridge %s\n", dev->full_name); | ||
157 | |||
158 | /* Fetch host bridge registers address */ | ||
159 | has_address = (of_address_to_resource(dev, 0, &rsrc) == 0); | ||
160 | |||
161 | /* Get bus range if any */ | ||
162 | bus_range = (int *) get_property(dev, "bus-range", &len); | ||
163 | if (bus_range == NULL || len < 2 * sizeof(int)) | ||
164 | printk(KERN_WARNING "Can't get bus-range for %s, assume" | ||
165 | " bus 0\n", dev->full_name); | ||
166 | |||
167 | hose = pcibios_alloc_controller(); | ||
168 | if (!hose) | ||
169 | return -ENOMEM; | ||
170 | hose->arch_data = dev; | ||
171 | hose->set_cfg_type = 1; | ||
172 | |||
173 | /* last_busno = 0xfe cause by MPC8641 PCIE bug */ | ||
174 | hose->first_busno = bus_range ? bus_range[0] : 0x0; | ||
175 | hose->last_busno = bus_range ? bus_range[1] : 0xfe; | ||
176 | |||
177 | setup_indirect_pcie(hose, rsrc.start, rsrc.start + 0x4); | ||
178 | |||
179 | /* Setup the PCIE host controller. */ | ||
180 | mpc86xx_setup_pcie(hose, rsrc.start, rsrc.end - rsrc.start + 1); | ||
181 | |||
182 | if ((rsrc.start & 0xfffff) == 0x8000) | ||
183 | primary = 1; | ||
184 | |||
185 | printk(KERN_INFO "Found MPC86xx PCIE host bridge at 0x%08lx. " | ||
186 | "Firmware bus number: %d->%d\n", | ||
187 | rsrc.start, hose->first_busno, hose->last_busno); | ||
188 | |||
189 | DBG(" ->Hose at 0x%p, cfg_addr=0x%p,cfg_data=0x%p\n", | ||
190 | hose, hose->cfg_addr, hose->cfg_data); | ||
191 | |||
192 | /* Interpret the "ranges" property */ | ||
193 | /* This also maps the I/O region and sets isa_io/mem_base */ | ||
194 | pci_process_bridge_OF_ranges(hose, dev, primary); | ||
195 | |||
196 | /* Setup PEX window registers */ | ||
197 | setup_pcie_atmu(hose, &rsrc); | ||
198 | |||
199 | return 0; | ||
200 | } | ||
201 | |||
202 | static void __devinit quirk_ali1575(struct pci_dev *dev) | ||
203 | { | ||
204 | unsigned short temp; | ||
205 | |||
206 | /* | ||
207 | * ALI1575 interrupts route table setup: | ||
208 | * | ||
209 | * IRQ pin IRQ# | ||
210 | * PIRQA ---- 3 | ||
211 | * PIRQB ---- 4 | ||
212 | * PIRQC ---- 5 | ||
213 | * PIRQD ---- 6 | ||
214 | * PIRQE ---- 9 | ||
215 | * PIRQF ---- 10 | ||
216 | * PIRQG ---- 11 | ||
217 | * PIRQH ---- 12 | ||
218 | * | ||
219 | * interrupts for PCI slot0 -- PIRQA / PIRQB / PIRQC / PIRQD | ||
220 | * PCI slot1 -- PIRQB / PIRQC / PIRQD / PIRQA | ||
221 | */ | ||
222 | pci_write_config_dword(dev, 0x48, 0xb9317542); | ||
223 | |||
224 | /* USB 1.1 OHCI controller 1, interrupt: PIRQE */ | ||
225 | pci_write_config_byte(dev, 0x86, 0x0c); | ||
226 | |||
227 | /* USB 1.1 OHCI controller 2, interrupt: PIRQF */ | ||
228 | pci_write_config_byte(dev, 0x87, 0x0d); | ||
229 | |||
230 | /* USB 1.1 OHCI controller 3, interrupt: PIRQH */ | ||
231 | pci_write_config_byte(dev, 0x88, 0x0f); | ||
232 | |||
233 | /* USB 2.0 controller, interrupt: PIRQ7 */ | ||
234 | pci_write_config_byte(dev, 0x74, 0x06); | ||
235 | |||
236 | /* Audio controller, interrupt: PIRQE */ | ||
237 | pci_write_config_byte(dev, 0x8a, 0x0c); | ||
238 | |||
239 | /* Modem controller, interrupt: PIRQF */ | ||
240 | pci_write_config_byte(dev, 0x8b, 0x0d); | ||
241 | |||
242 | /* HD audio controller, interrupt: PIRQG */ | ||
243 | pci_write_config_byte(dev, 0x8c, 0x0e); | ||
244 | |||
245 | /* Serial ATA interrupt: PIRQD */ | ||
246 | pci_write_config_byte(dev, 0x8d, 0x0b); | ||
247 | |||
248 | /* SMB interrupt: PIRQH */ | ||
249 | pci_write_config_byte(dev, 0x8e, 0x0f); | ||
250 | |||
251 | /* PMU ACPI SCI interrupt: PIRQH */ | ||
252 | pci_write_config_byte(dev, 0x8f, 0x0f); | ||
253 | |||
254 | /* Primary PATA IDE IRQ: 14 | ||
255 | * Secondary PATA IDE IRQ: 15 | ||
256 | */ | ||
257 | pci_write_config_byte(dev, 0x44, 0x3d); | ||
258 | pci_write_config_byte(dev, 0x75, 0x0f); | ||
259 | |||
260 | /* Set IRQ14 and IRQ15 to legacy IRQs */ | ||
261 | pci_read_config_word(dev, 0x46, &temp); | ||
262 | temp |= 0xc000; | ||
263 | pci_write_config_word(dev, 0x46, temp); | ||
264 | |||
265 | /* Set i8259 interrupt trigger | ||
266 | * IRQ 3: Level | ||
267 | * IRQ 4: Level | ||
268 | * IRQ 5: Level | ||
269 | * IRQ 6: Level | ||
270 | * IRQ 7: Level | ||
271 | * IRQ 9: Level | ||
272 | * IRQ 10: Level | ||
273 | * IRQ 11: Level | ||
274 | * IRQ 12: Level | ||
275 | * IRQ 14: Edge | ||
276 | * IRQ 15: Edge | ||
277 | */ | ||
278 | outb(0xfa, 0x4d0); | ||
279 | outb(0x1e, 0x4d1); | ||
280 | } | ||
281 | |||
282 | static void __devinit quirk_uli5288(struct pci_dev *dev) | ||
283 | { | ||
284 | unsigned char c; | ||
285 | |||
286 | pci_read_config_byte(dev,0x83,&c); | ||
287 | c |= 0x80; | ||
288 | pci_write_config_byte(dev, 0x83, c); | ||
289 | |||
290 | pci_write_config_byte(dev, 0x09, 0x01); | ||
291 | pci_write_config_byte(dev, 0x0a, 0x06); | ||
292 | |||
293 | pci_read_config_byte(dev,0x83,&c); | ||
294 | c &= 0x7f; | ||
295 | pci_write_config_byte(dev, 0x83, c); | ||
296 | |||
297 | pci_read_config_byte(dev,0x84,&c); | ||
298 | c |= 0x01; | ||
299 | pci_write_config_byte(dev, 0x84, c); | ||
300 | } | ||
301 | |||
302 | static void __devinit quirk_uli5229(struct pci_dev *dev) | ||
303 | { | ||
304 | unsigned short temp; | ||
305 | pci_write_config_word(dev, 0x04, 0x0405); | ||
306 | pci_read_config_word(dev, 0x4a, &temp); | ||
307 | temp |= 0x1000; | ||
308 | pci_write_config_word(dev, 0x4a, temp); | ||
309 | } | ||
310 | |||
311 | static void __devinit early_uli5249(struct pci_dev *dev) | ||
312 | { | ||
313 | unsigned char temp; | ||
314 | pci_write_config_word(dev, 0x04, 0x0007); | ||
315 | pci_read_config_byte(dev, 0x7c, &temp); | ||
316 | pci_write_config_byte(dev, 0x7c, 0x80); | ||
317 | pci_write_config_byte(dev, 0x09, 0x01); | ||
318 | pci_write_config_byte(dev, 0x7c, temp); | ||
319 | dev->class |= 0x1; | ||
320 | } | ||
321 | |||
322 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x1575, quirk_ali1575); | ||
323 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5288, quirk_uli5288); | ||
324 | DECLARE_PCI_FIXUP_HEADER(PCI_VENDOR_ID_AL, 0x5229, quirk_uli5229); | ||
325 | DECLARE_PCI_FIXUP_EARLY(PCI_VENDOR_ID_AL, 0x5249, early_uli5249); | ||
diff --git a/arch/powerpc/platforms/Makefile b/arch/powerpc/platforms/Makefile index c4f6b0d2d140..292863694562 100644 --- a/arch/powerpc/platforms/Makefile +++ b/arch/powerpc/platforms/Makefile | |||
@@ -9,6 +9,7 @@ obj-$(CONFIG_PPC_CHRP) += chrp/ | |||
9 | obj-$(CONFIG_4xx) += 4xx/ | 9 | obj-$(CONFIG_4xx) += 4xx/ |
10 | obj-$(CONFIG_PPC_83xx) += 83xx/ | 10 | obj-$(CONFIG_PPC_83xx) += 83xx/ |
11 | obj-$(CONFIG_PPC_85xx) += 85xx/ | 11 | obj-$(CONFIG_PPC_85xx) += 85xx/ |
12 | obj-$(CONFIG_PPC_86xx) += 86xx/ | ||
12 | obj-$(CONFIG_PPC_PSERIES) += pseries/ | 13 | obj-$(CONFIG_PPC_PSERIES) += pseries/ |
13 | obj-$(CONFIG_PPC_ISERIES) += iseries/ | 14 | obj-$(CONFIG_PPC_ISERIES) += iseries/ |
14 | obj-$(CONFIG_PPC_MAPLE) += maple/ | 15 | obj-$(CONFIG_PPC_MAPLE) += maple/ |
diff --git a/arch/powerpc/platforms/cell/Kconfig b/arch/powerpc/platforms/cell/Kconfig index 6a02d51086c8..352bbbacde9a 100644 --- a/arch/powerpc/platforms/cell/Kconfig +++ b/arch/powerpc/platforms/cell/Kconfig | |||
@@ -5,15 +5,24 @@ config SPU_FS | |||
5 | tristate "SPU file system" | 5 | tristate "SPU file system" |
6 | default m | 6 | default m |
7 | depends on PPC_CELL | 7 | depends on PPC_CELL |
8 | select SPU_BASE | ||
8 | help | 9 | help |
9 | The SPU file system is used to access Synergistic Processing | 10 | The SPU file system is used to access Synergistic Processing |
10 | Units on machines implementing the Broadband Processor | 11 | Units on machines implementing the Broadband Processor |
11 | Architecture. | 12 | Architecture. |
12 | 13 | ||
14 | config SPU_BASE | ||
15 | bool | ||
16 | default n | ||
17 | |||
13 | config SPUFS_MMAP | 18 | config SPUFS_MMAP |
14 | bool | 19 | bool |
15 | depends on SPU_FS && SPARSEMEM | 20 | depends on SPU_FS && SPARSEMEM |
16 | select MEMORY_HOTPLUG | 21 | select MEMORY_HOTPLUG |
17 | default y | 22 | default y |
18 | 23 | ||
24 | config CBE_RAS | ||
25 | bool "RAS features for bare metal Cell BE" | ||
26 | default y | ||
27 | |||
19 | endmenu | 28 | endmenu |
diff --git a/arch/powerpc/platforms/cell/Makefile b/arch/powerpc/platforms/cell/Makefile index e570bad06394..c89cdd67383b 100644 --- a/arch/powerpc/platforms/cell/Makefile +++ b/arch/powerpc/platforms/cell/Makefile | |||
@@ -1,16 +1,15 @@ | |||
1 | obj-y += interrupt.o iommu.o setup.o spider-pic.o | 1 | obj-$(CONFIG_PPC_CELL_NATIVE) += interrupt.o iommu.o setup.o \ |
2 | obj-y += pervasive.o | 2 | cbe_regs.o spider-pic.o pervasive.o |
3 | obj-$(CONFIG_CBE_RAS) += ras.o | ||
3 | 4 | ||
4 | obj-$(CONFIG_SMP) += smp.o | 5 | ifeq ($(CONFIG_SMP),y) |
5 | obj-$(CONFIG_SPU_FS) += spu-base.o spufs/ | 6 | obj-$(CONFIG_PPC_CELL_NATIVE) += smp.o |
6 | 7 | endif | |
7 | spu-base-y += spu_base.o spu_priv1.o | ||
8 | 8 | ||
9 | # needed only when building loadable spufs.ko | 9 | # needed only when building loadable spufs.ko |
10 | spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o | 10 | spufs-modular-$(CONFIG_SPU_FS) += spu_syscalls.o |
11 | obj-y += $(spufs-modular-m) | 11 | spu-priv1-$(CONFIG_PPC_CELL_NATIVE) += spu_priv1_mmio.o |
12 | |||
13 | # always needed in kernel | ||
14 | spufs-builtin-$(CONFIG_SPU_FS) += spu_callbacks.o | ||
15 | obj-y += $(spufs-builtin-y) $(spufs-builtin-m) | ||
16 | 12 | ||
13 | obj-$(CONFIG_SPU_BASE) += spu_callbacks.o spu_base.o \ | ||
14 | $(spufs-modular-m) \ | ||
15 | $(spu-priv1-y) spufs/ | ||
diff --git a/arch/powerpc/platforms/cell/cbe_regs.c b/arch/powerpc/platforms/cell/cbe_regs.c new file mode 100644 index 000000000000..2dfde61c8412 --- /dev/null +++ b/arch/powerpc/platforms/cell/cbe_regs.c | |||
@@ -0,0 +1,128 @@ | |||
1 | /* | ||
2 | * cbe_regs.c | ||
3 | * | ||
4 | * Accessor routines for the various MMIO register blocks of the CBE | ||
5 | * | ||
6 | * (c) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. | ||
7 | */ | ||
8 | |||
9 | |||
10 | #include <linux/config.h> | ||
11 | #include <linux/percpu.h> | ||
12 | #include <linux/types.h> | ||
13 | |||
14 | #include <asm/io.h> | ||
15 | #include <asm/pgtable.h> | ||
16 | #include <asm/prom.h> | ||
17 | #include <asm/ptrace.h> | ||
18 | |||
19 | #include "cbe_regs.h" | ||
20 | |||
21 | #define MAX_CBE 2 | ||
22 | |||
23 | /* | ||
24 | * Current implementation uses "cpu" nodes. We build our own mapping | ||
25 | * array of cpu numbers to cpu nodes locally for now to allow interrupt | ||
26 | * time code to have a fast path rather than call of_get_cpu_node(). If | ||
27 | * we implement cpu hotplug, we'll have to install an appropriate norifier | ||
28 | * in order to release references to the cpu going away | ||
29 | */ | ||
30 | static struct cbe_regs_map | ||
31 | { | ||
32 | struct device_node *cpu_node; | ||
33 | struct cbe_pmd_regs __iomem *pmd_regs; | ||
34 | struct cbe_iic_regs __iomem *iic_regs; | ||
35 | } cbe_regs_maps[MAX_CBE]; | ||
36 | static int cbe_regs_map_count; | ||
37 | |||
38 | static struct cbe_thread_map | ||
39 | { | ||
40 | struct device_node *cpu_node; | ||
41 | struct cbe_regs_map *regs; | ||
42 | } cbe_thread_map[NR_CPUS]; | ||
43 | |||
44 | static struct cbe_regs_map *cbe_find_map(struct device_node *np) | ||
45 | { | ||
46 | int i; | ||
47 | |||
48 | for (i = 0; i < cbe_regs_map_count; i++) | ||
49 | if (cbe_regs_maps[i].cpu_node == np) | ||
50 | return &cbe_regs_maps[i]; | ||
51 | return NULL; | ||
52 | } | ||
53 | |||
54 | struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np) | ||
55 | { | ||
56 | struct cbe_regs_map *map = cbe_find_map(np); | ||
57 | if (map == NULL) | ||
58 | return NULL; | ||
59 | return map->pmd_regs; | ||
60 | } | ||
61 | |||
62 | struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu) | ||
63 | { | ||
64 | struct cbe_regs_map *map = cbe_thread_map[cpu].regs; | ||
65 | if (map == NULL) | ||
66 | return NULL; | ||
67 | return map->pmd_regs; | ||
68 | } | ||
69 | |||
70 | |||
71 | struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np) | ||
72 | { | ||
73 | struct cbe_regs_map *map = cbe_find_map(np); | ||
74 | if (map == NULL) | ||
75 | return NULL; | ||
76 | return map->iic_regs; | ||
77 | } | ||
78 | struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu) | ||
79 | { | ||
80 | struct cbe_regs_map *map = cbe_thread_map[cpu].regs; | ||
81 | if (map == NULL) | ||
82 | return NULL; | ||
83 | return map->iic_regs; | ||
84 | } | ||
85 | |||
86 | void __init cbe_regs_init(void) | ||
87 | { | ||
88 | int i; | ||
89 | struct device_node *cpu; | ||
90 | |||
91 | /* Build local fast map of CPUs */ | ||
92 | for_each_cpu(i) | ||
93 | cbe_thread_map[i].cpu_node = of_get_cpu_node(i, NULL); | ||
94 | |||
95 | /* Find maps for each device tree CPU */ | ||
96 | for_each_node_by_type(cpu, "cpu") { | ||
97 | struct cbe_regs_map *map = &cbe_regs_maps[cbe_regs_map_count++]; | ||
98 | |||
99 | /* That hack must die die die ! */ | ||
100 | struct address_prop { | ||
101 | unsigned long address; | ||
102 | unsigned int len; | ||
103 | } __attribute__((packed)) *prop; | ||
104 | |||
105 | |||
106 | if (cbe_regs_map_count > MAX_CBE) { | ||
107 | printk(KERN_ERR "cbe_regs: More BE chips than supported" | ||
108 | "!\n"); | ||
109 | cbe_regs_map_count--; | ||
110 | return; | ||
111 | } | ||
112 | map->cpu_node = cpu; | ||
113 | for_each_cpu(i) | ||
114 | if (cbe_thread_map[i].cpu_node == cpu) | ||
115 | cbe_thread_map[i].regs = map; | ||
116 | |||
117 | prop = (struct address_prop *)get_property(cpu, "pervasive", | ||
118 | NULL); | ||
119 | if (prop != NULL) | ||
120 | map->pmd_regs = ioremap(prop->address, prop->len); | ||
121 | |||
122 | prop = (struct address_prop *)get_property(cpu, "iic", | ||
123 | NULL); | ||
124 | if (prop != NULL) | ||
125 | map->iic_regs = ioremap(prop->address, prop->len); | ||
126 | } | ||
127 | } | ||
128 | |||
diff --git a/arch/powerpc/platforms/cell/cbe_regs.h b/arch/powerpc/platforms/cell/cbe_regs.h new file mode 100644 index 000000000000..e76e4a6af5bc --- /dev/null +++ b/arch/powerpc/platforms/cell/cbe_regs.h | |||
@@ -0,0 +1,129 @@ | |||
1 | /* | ||
2 | * cbe_regs.h | ||
3 | * | ||
4 | * This file is intended to hold the various register definitions for CBE | ||
5 | * on-chip system devices (memory controller, IO controller, etc...) | ||
6 | * | ||
7 | * (c) 2006 Benjamin Herrenschmidt <benh@kernel.crashing.org>, IBM Corp. | ||
8 | */ | ||
9 | |||
10 | #ifndef CBE_REGS_H | ||
11 | #define CBE_REGS_H | ||
12 | |||
13 | /* | ||
14 | * | ||
15 | * Some HID register definitions | ||
16 | * | ||
17 | */ | ||
18 | |||
19 | /* CBE specific HID0 bits */ | ||
20 | #define HID0_CBE_THERM_WAKEUP 0x0000020000000000ul | ||
21 | #define HID0_CBE_SYSERR_WAKEUP 0x0000008000000000ul | ||
22 | #define HID0_CBE_THERM_INT_EN 0x0000000400000000ul | ||
23 | #define HID0_CBE_SYSERR_INT_EN 0x0000000200000000ul | ||
24 | |||
25 | |||
26 | /* | ||
27 | * | ||
28 | * Pervasive unit register definitions | ||
29 | * | ||
30 | */ | ||
31 | |||
32 | struct cbe_pmd_regs { | ||
33 | u8 pad_0x0000_0x0800[0x0800 - 0x0000]; /* 0x0000 */ | ||
34 | |||
35 | /* Thermal Sensor Registers */ | ||
36 | u64 ts_ctsr1; /* 0x0800 */ | ||
37 | u64 ts_ctsr2; /* 0x0808 */ | ||
38 | u64 ts_mtsr1; /* 0x0810 */ | ||
39 | u64 ts_mtsr2; /* 0x0818 */ | ||
40 | u64 ts_itr1; /* 0x0820 */ | ||
41 | u64 ts_itr2; /* 0x0828 */ | ||
42 | u64 ts_gitr; /* 0x0830 */ | ||
43 | u64 ts_isr; /* 0x0838 */ | ||
44 | u64 ts_imr; /* 0x0840 */ | ||
45 | u64 tm_cr1; /* 0x0848 */ | ||
46 | u64 tm_cr2; /* 0x0850 */ | ||
47 | u64 tm_simr; /* 0x0858 */ | ||
48 | u64 tm_tpr; /* 0x0860 */ | ||
49 | u64 tm_str1; /* 0x0868 */ | ||
50 | u64 tm_str2; /* 0x0870 */ | ||
51 | u64 tm_tsr; /* 0x0878 */ | ||
52 | |||
53 | /* Power Management */ | ||
54 | u64 pm_control; /* 0x0880 */ | ||
55 | #define CBE_PMD_PAUSE_ZERO_CONTROL 0x10000 | ||
56 | u64 pm_status; /* 0x0888 */ | ||
57 | |||
58 | /* Time Base Register */ | ||
59 | u64 tbr; /* 0x0890 */ | ||
60 | |||
61 | u8 pad_0x0898_0x0c00 [0x0c00 - 0x0898]; /* 0x0898 */ | ||
62 | |||
63 | /* Fault Isolation Registers */ | ||
64 | u64 checkstop_fir; /* 0x0c00 */ | ||
65 | u64 recoverable_fir; | ||
66 | u64 spec_att_mchk_fir; | ||
67 | u64 fir_mode_reg; | ||
68 | u64 fir_enable_mask; | ||
69 | |||
70 | u8 pad_0x0c28_0x1000 [0x1000 - 0x0c28]; /* 0x0c28 */ | ||
71 | }; | ||
72 | |||
73 | extern struct cbe_pmd_regs __iomem *cbe_get_pmd_regs(struct device_node *np); | ||
74 | extern struct cbe_pmd_regs __iomem *cbe_get_cpu_pmd_regs(int cpu); | ||
75 | |||
76 | /* | ||
77 | * | ||
78 | * IIC unit register definitions | ||
79 | * | ||
80 | */ | ||
81 | |||
82 | struct cbe_iic_pending_bits { | ||
83 | u32 data; | ||
84 | u8 flags; | ||
85 | u8 class; | ||
86 | u8 source; | ||
87 | u8 prio; | ||
88 | }; | ||
89 | |||
90 | #define CBE_IIC_IRQ_VALID 0x80 | ||
91 | #define CBE_IIC_IRQ_IPI 0x40 | ||
92 | |||
93 | struct cbe_iic_thread_regs { | ||
94 | struct cbe_iic_pending_bits pending; | ||
95 | struct cbe_iic_pending_bits pending_destr; | ||
96 | u64 generate; | ||
97 | u64 prio; | ||
98 | }; | ||
99 | |||
100 | struct cbe_iic_regs { | ||
101 | u8 pad_0x0000_0x0400[0x0400 - 0x0000]; /* 0x0000 */ | ||
102 | |||
103 | /* IIC interrupt registers */ | ||
104 | struct cbe_iic_thread_regs thread[2]; /* 0x0400 */ | ||
105 | u64 iic_ir; /* 0x0440 */ | ||
106 | u64 iic_is; /* 0x0448 */ | ||
107 | |||
108 | u8 pad_0x0450_0x0500[0x0500 - 0x0450]; /* 0x0450 */ | ||
109 | |||
110 | /* IOC FIR */ | ||
111 | u64 ioc_fir_reset; /* 0x0500 */ | ||
112 | u64 ioc_fir_set; | ||
113 | u64 ioc_checkstop_enable; | ||
114 | u64 ioc_fir_error_mask; | ||
115 | u64 ioc_syserr_enable; | ||
116 | u64 ioc_fir; | ||
117 | |||
118 | u8 pad_0x0530_0x1000[0x1000 - 0x0530]; /* 0x0530 */ | ||
119 | }; | ||
120 | |||
121 | extern struct cbe_iic_regs __iomem *cbe_get_iic_regs(struct device_node *np); | ||
122 | extern struct cbe_iic_regs __iomem *cbe_get_cpu_iic_regs(int cpu); | ||
123 | |||
124 | |||
125 | /* Init this module early */ | ||
126 | extern void cbe_regs_init(void); | ||
127 | |||
128 | |||
129 | #endif /* CBE_REGS_H */ | ||
diff --git a/arch/powerpc/platforms/cell/interrupt.c b/arch/powerpc/platforms/cell/interrupt.c index 978be1c30c1b..f4e2d8805c9e 100644 --- a/arch/powerpc/platforms/cell/interrupt.c +++ b/arch/powerpc/platforms/cell/interrupt.c | |||
@@ -33,29 +33,10 @@ | |||
33 | #include <asm/ptrace.h> | 33 | #include <asm/ptrace.h> |
34 | 34 | ||
35 | #include "interrupt.h" | 35 | #include "interrupt.h" |
36 | 36 | #include "cbe_regs.h" | |
37 | struct iic_pending_bits { | ||
38 | u32 data; | ||
39 | u8 flags; | ||
40 | u8 class; | ||
41 | u8 source; | ||
42 | u8 prio; | ||
43 | }; | ||
44 | |||
45 | enum iic_pending_flags { | ||
46 | IIC_VALID = 0x80, | ||
47 | IIC_IPI = 0x40, | ||
48 | }; | ||
49 | |||
50 | struct iic_regs { | ||
51 | struct iic_pending_bits pending; | ||
52 | struct iic_pending_bits pending_destr; | ||
53 | u64 generate; | ||
54 | u64 prio; | ||
55 | }; | ||
56 | 37 | ||
57 | struct iic { | 38 | struct iic { |
58 | struct iic_regs __iomem *regs; | 39 | struct cbe_iic_thread_regs __iomem *regs; |
59 | u8 target_id; | 40 | u8 target_id; |
60 | }; | 41 | }; |
61 | 42 | ||
@@ -115,7 +96,7 @@ static struct hw_interrupt_type iic_pic = { | |||
115 | .end = iic_end, | 96 | .end = iic_end, |
116 | }; | 97 | }; |
117 | 98 | ||
118 | static int iic_external_get_irq(struct iic_pending_bits pending) | 99 | static int iic_external_get_irq(struct cbe_iic_pending_bits pending) |
119 | { | 100 | { |
120 | int irq; | 101 | int irq; |
121 | unsigned char node, unit; | 102 | unsigned char node, unit; |
@@ -136,8 +117,7 @@ static int iic_external_get_irq(struct iic_pending_bits pending) | |||
136 | * One of these units can be connected | 117 | * One of these units can be connected |
137 | * to an external interrupt controller. | 118 | * to an external interrupt controller. |
138 | */ | 119 | */ |
139 | if (pending.prio > 0x3f || | 120 | if (pending.class != 2) |
140 | pending.class != 2) | ||
141 | break; | 121 | break; |
142 | irq = IIC_EXT_OFFSET | 122 | irq = IIC_EXT_OFFSET |
143 | + spider_get_irq(node) | 123 | + spider_get_irq(node) |
@@ -168,15 +148,15 @@ int iic_get_irq(struct pt_regs *regs) | |||
168 | { | 148 | { |
169 | struct iic *iic; | 149 | struct iic *iic; |
170 | int irq; | 150 | int irq; |
171 | struct iic_pending_bits pending; | 151 | struct cbe_iic_pending_bits pending; |
172 | 152 | ||
173 | iic = &__get_cpu_var(iic); | 153 | iic = &__get_cpu_var(iic); |
174 | *(unsigned long *) &pending = | 154 | *(unsigned long *) &pending = |
175 | in_be64((unsigned long __iomem *) &iic->regs->pending_destr); | 155 | in_be64((unsigned long __iomem *) &iic->regs->pending_destr); |
176 | 156 | ||
177 | irq = -1; | 157 | irq = -1; |
178 | if (pending.flags & IIC_VALID) { | 158 | if (pending.flags & CBE_IIC_IRQ_VALID) { |
179 | if (pending.flags & IIC_IPI) { | 159 | if (pending.flags & CBE_IIC_IRQ_IPI) { |
180 | irq = IIC_IPI_OFFSET + (pending.prio >> 4); | 160 | irq = IIC_IPI_OFFSET + (pending.prio >> 4); |
181 | /* | 161 | /* |
182 | if (irq > 0x80) | 162 | if (irq > 0x80) |
@@ -226,7 +206,7 @@ static int setup_iic_hardcoded(void) | |||
226 | regs += 0x20; | 206 | regs += 0x20; |
227 | 207 | ||
228 | printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs); | 208 | printk(KERN_INFO "IIC for CPU %d at %lx\n", cpu, regs); |
229 | iic->regs = ioremap(regs, sizeof(struct iic_regs)); | 209 | iic->regs = ioremap(regs, sizeof(struct cbe_iic_thread_regs)); |
230 | iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); | 210 | iic->target_id = (nodeid << 4) + ((cpu & 1) ? 0xf : 0xe); |
231 | } | 211 | } |
232 | 212 | ||
@@ -267,12 +247,12 @@ static int setup_iic(void) | |||
267 | } | 247 | } |
268 | 248 | ||
269 | iic = &per_cpu(iic, np[0]); | 249 | iic = &per_cpu(iic, np[0]); |
270 | iic->regs = ioremap(regs[0], sizeof(struct iic_regs)); | 250 | iic->regs = ioremap(regs[0], sizeof(struct cbe_iic_thread_regs)); |
271 | iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe); | 251 | iic->target_id = ((np[0] & 2) << 3) + ((np[0] & 1) ? 0xf : 0xe); |
272 | printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs); | 252 | printk("IIC for CPU %d at %lx mapped to %p\n", np[0], regs[0], iic->regs); |
273 | 253 | ||
274 | iic = &per_cpu(iic, np[1]); | 254 | iic = &per_cpu(iic, np[1]); |
275 | iic->regs = ioremap(regs[2], sizeof(struct iic_regs)); | 255 | iic->regs = ioremap(regs[2], sizeof(struct cbe_iic_thread_regs)); |
276 | iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe); | 256 | iic->target_id = ((np[1] & 2) << 3) + ((np[1] & 1) ? 0xf : 0xe); |
277 | printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs); | 257 | printk("IIC for CPU %d at %lx mapped to %p\n", np[1], regs[2], iic->regs); |
278 | 258 | ||
diff --git a/arch/powerpc/platforms/cell/iommu.c b/arch/powerpc/platforms/cell/iommu.c index a49ceb799a8e..a35004e14c69 100644 --- a/arch/powerpc/platforms/cell/iommu.c +++ b/arch/powerpc/platforms/cell/iommu.c | |||
@@ -473,6 +473,16 @@ static int cell_dma_supported(struct device *dev, u64 mask) | |||
473 | return mask < 0x100000000ull; | 473 | return mask < 0x100000000ull; |
474 | } | 474 | } |
475 | 475 | ||
476 | static struct dma_mapping_ops cell_iommu_ops = { | ||
477 | .alloc_coherent = cell_alloc_coherent, | ||
478 | .free_coherent = cell_free_coherent, | ||
479 | .map_single = cell_map_single, | ||
480 | .unmap_single = cell_unmap_single, | ||
481 | .map_sg = cell_map_sg, | ||
482 | .unmap_sg = cell_unmap_sg, | ||
483 | .dma_supported = cell_dma_supported, | ||
484 | }; | ||
485 | |||
476 | void cell_init_iommu(void) | 486 | void cell_init_iommu(void) |
477 | { | 487 | { |
478 | int setup_bus = 0; | 488 | int setup_bus = 0; |
@@ -498,11 +508,5 @@ void cell_init_iommu(void) | |||
498 | } | 508 | } |
499 | } | 509 | } |
500 | 510 | ||
501 | pci_dma_ops.alloc_coherent = cell_alloc_coherent; | 511 | pci_dma_ops = cell_iommu_ops; |
502 | pci_dma_ops.free_coherent = cell_free_coherent; | ||
503 | pci_dma_ops.map_single = cell_map_single; | ||
504 | pci_dma_ops.unmap_single = cell_unmap_single; | ||
505 | pci_dma_ops.map_sg = cell_map_sg; | ||
506 | pci_dma_ops.unmap_sg = cell_unmap_sg; | ||
507 | pci_dma_ops.dma_supported = cell_dma_supported; | ||
508 | } | 512 | } |
diff --git a/arch/powerpc/platforms/cell/pervasive.c b/arch/powerpc/platforms/cell/pervasive.c index 7eed8c624517..695ac4e1617e 100644 --- a/arch/powerpc/platforms/cell/pervasive.c +++ b/arch/powerpc/platforms/cell/pervasive.c | |||
@@ -37,36 +37,28 @@ | |||
37 | #include <asm/reg.h> | 37 | #include <asm/reg.h> |
38 | 38 | ||
39 | #include "pervasive.h" | 39 | #include "pervasive.h" |
40 | #include "cbe_regs.h" | ||
40 | 41 | ||
41 | static DEFINE_SPINLOCK(cbe_pervasive_lock); | 42 | static DEFINE_SPINLOCK(cbe_pervasive_lock); |
42 | struct cbe_pervasive { | ||
43 | struct pmd_regs __iomem *regs; | ||
44 | unsigned int thread; | ||
45 | }; | ||
46 | |||
47 | /* can't use per_cpu from setup_arch */ | ||
48 | static struct cbe_pervasive cbe_pervasive[NR_CPUS]; | ||
49 | 43 | ||
50 | static void __init cbe_enable_pause_zero(void) | 44 | static void __init cbe_enable_pause_zero(void) |
51 | { | 45 | { |
52 | unsigned long thread_switch_control; | 46 | unsigned long thread_switch_control; |
53 | unsigned long temp_register; | 47 | unsigned long temp_register; |
54 | struct cbe_pervasive *p; | 48 | struct cbe_pmd_regs __iomem *pregs; |
55 | int thread; | ||
56 | 49 | ||
57 | spin_lock_irq(&cbe_pervasive_lock); | 50 | spin_lock_irq(&cbe_pervasive_lock); |
58 | p = &cbe_pervasive[smp_processor_id()]; | 51 | pregs = cbe_get_cpu_pmd_regs(smp_processor_id()); |
59 | 52 | if (pregs == NULL) | |
60 | if (!cbe_pervasive->regs) | ||
61 | goto out; | 53 | goto out; |
62 | 54 | ||
63 | pr_debug("Power Management: CPU %d\n", smp_processor_id()); | 55 | pr_debug("Power Management: CPU %d\n", smp_processor_id()); |
64 | 56 | ||
65 | /* Enable Pause(0) control bit */ | 57 | /* Enable Pause(0) control bit */ |
66 | temp_register = in_be64(&p->regs->pm_control); | 58 | temp_register = in_be64(&pregs->pm_control); |
67 | 59 | ||
68 | out_be64(&p->regs->pm_control, | 60 | out_be64(&pregs->pm_control, |
69 | temp_register|PMD_PAUSE_ZERO_CONTROL); | 61 | temp_register | CBE_PMD_PAUSE_ZERO_CONTROL); |
70 | 62 | ||
71 | /* Enable DEC and EE interrupt request */ | 63 | /* Enable DEC and EE interrupt request */ |
72 | thread_switch_control = mfspr(SPRN_TSC_CELL); | 64 | thread_switch_control = mfspr(SPRN_TSC_CELL); |
@@ -75,25 +67,16 @@ static void __init cbe_enable_pause_zero(void) | |||
75 | switch ((mfspr(SPRN_CTRLF) & CTRL_CT)) { | 67 | switch ((mfspr(SPRN_CTRLF) & CTRL_CT)) { |
76 | case CTRL_CT0: | 68 | case CTRL_CT0: |
77 | thread_switch_control |= TSC_CELL_DEC_ENABLE_0; | 69 | thread_switch_control |= TSC_CELL_DEC_ENABLE_0; |
78 | thread = 0; | ||
79 | break; | 70 | break; |
80 | case CTRL_CT1: | 71 | case CTRL_CT1: |
81 | thread_switch_control |= TSC_CELL_DEC_ENABLE_1; | 72 | thread_switch_control |= TSC_CELL_DEC_ENABLE_1; |
82 | thread = 1; | ||
83 | break; | 73 | break; |
84 | default: | 74 | default: |
85 | printk(KERN_WARNING "%s: unknown configuration\n", | 75 | printk(KERN_WARNING "%s: unknown configuration\n", |
86 | __FUNCTION__); | 76 | __FUNCTION__); |
87 | thread = -1; | ||
88 | break; | 77 | break; |
89 | } | 78 | } |
90 | 79 | ||
91 | if (p->thread != thread) | ||
92 | printk(KERN_WARNING "%s: device tree inconsistant, " | ||
93 | "cpu %i: %d/%d\n", __FUNCTION__, | ||
94 | smp_processor_id(), | ||
95 | p->thread, thread); | ||
96 | |||
97 | mtspr(SPRN_TSC_CELL, thread_switch_control); | 80 | mtspr(SPRN_TSC_CELL, thread_switch_control); |
98 | 81 | ||
99 | out: | 82 | out: |
@@ -104,6 +87,11 @@ static void cbe_idle(void) | |||
104 | { | 87 | { |
105 | unsigned long ctrl; | 88 | unsigned long ctrl; |
106 | 89 | ||
90 | /* Why do we do that on every idle ? Couldn't that be done once for | ||
91 | * all or do we lose the state some way ? Also, the pm_control | ||
92 | * register setting, that can't be set once at boot ? We really want | ||
93 | * to move that away in order to implement a simple powersave | ||
94 | */ | ||
107 | cbe_enable_pause_zero(); | 95 | cbe_enable_pause_zero(); |
108 | 96 | ||
109 | while (1) { | 97 | while (1) { |
@@ -152,8 +140,15 @@ static int cbe_system_reset_exception(struct pt_regs *regs) | |||
152 | timer_interrupt(regs); | 140 | timer_interrupt(regs); |
153 | break; | 141 | break; |
154 | case SRR1_WAKEMT: | 142 | case SRR1_WAKEMT: |
155 | /* no action required */ | ||
156 | break; | 143 | break; |
144 | #ifdef CONFIG_CBE_RAS | ||
145 | case SRR1_WAKESYSERR: | ||
146 | cbe_system_error_exception(regs); | ||
147 | break; | ||
148 | case SRR1_WAKETHERM: | ||
149 | cbe_thermal_exception(regs); | ||
150 | break; | ||
151 | #endif /* CONFIG_CBE_RAS */ | ||
157 | default: | 152 | default: |
158 | /* do system reset */ | 153 | /* do system reset */ |
159 | return 0; | 154 | return 0; |
@@ -162,68 +157,11 @@ static int cbe_system_reset_exception(struct pt_regs *regs) | |||
162 | return 1; | 157 | return 1; |
163 | } | 158 | } |
164 | 159 | ||
165 | static int __init cbe_find_pmd_mmio(int cpu, struct cbe_pervasive *p) | 160 | void __init cbe_pervasive_init(void) |
166 | { | ||
167 | struct device_node *node; | ||
168 | unsigned int *int_servers; | ||
169 | char *addr; | ||
170 | unsigned long real_address; | ||
171 | unsigned int size; | ||
172 | |||
173 | struct pmd_regs __iomem *pmd_mmio_area; | ||
174 | int hardid, thread; | ||
175 | int proplen; | ||
176 | |||
177 | pmd_mmio_area = NULL; | ||
178 | hardid = get_hard_smp_processor_id(cpu); | ||
179 | for (node = NULL; (node = of_find_node_by_type(node, "cpu"));) { | ||
180 | int_servers = (void *) get_property(node, | ||
181 | "ibm,ppc-interrupt-server#s", &proplen); | ||
182 | if (!int_servers) { | ||
183 | printk(KERN_WARNING "%s misses " | ||
184 | "ibm,ppc-interrupt-server#s property", | ||
185 | node->full_name); | ||
186 | continue; | ||
187 | } | ||
188 | for (thread = 0; thread < proplen / sizeof (int); thread++) { | ||
189 | if (hardid == int_servers[thread]) { | ||
190 | addr = get_property(node, "pervasive", NULL); | ||
191 | goto found; | ||
192 | } | ||
193 | } | ||
194 | } | ||
195 | |||
196 | printk(KERN_WARNING "%s: CPU %d not found\n", __FUNCTION__, cpu); | ||
197 | return -EINVAL; | ||
198 | |||
199 | found: | ||
200 | real_address = *(unsigned long*) addr; | ||
201 | addr += sizeof (unsigned long); | ||
202 | size = *(unsigned int*) addr; | ||
203 | |||
204 | pr_debug("pervasive area for CPU %d at %lx, size %x\n", | ||
205 | cpu, real_address, size); | ||
206 | p->regs = ioremap(real_address, size); | ||
207 | p->thread = thread; | ||
208 | return 0; | ||
209 | } | ||
210 | |||
211 | void __init cell_pervasive_init(void) | ||
212 | { | 161 | { |
213 | struct cbe_pervasive *p; | ||
214 | int cpu; | ||
215 | int ret; | ||
216 | |||
217 | if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) | 162 | if (!cpu_has_feature(CPU_FTR_PAUSE_ZERO)) |
218 | return; | 163 | return; |
219 | 164 | ||
220 | for_each_possible_cpu(cpu) { | ||
221 | p = &cbe_pervasive[cpu]; | ||
222 | ret = cbe_find_pmd_mmio(cpu, p); | ||
223 | if (ret) | ||
224 | return; | ||
225 | } | ||
226 | |||
227 | ppc_md.idle_loop = cbe_idle; | 165 | ppc_md.idle_loop = cbe_idle; |
228 | ppc_md.system_reset_exception = cbe_system_reset_exception; | 166 | ppc_md.system_reset_exception = cbe_system_reset_exception; |
229 | } | 167 | } |
diff --git a/arch/powerpc/platforms/cell/pervasive.h b/arch/powerpc/platforms/cell/pervasive.h index da1fb85ca3e8..7b50947f8044 100644 --- a/arch/powerpc/platforms/cell/pervasive.h +++ b/arch/powerpc/platforms/cell/pervasive.h | |||
@@ -25,38 +25,9 @@ | |||
25 | #ifndef PERVASIVE_H | 25 | #ifndef PERVASIVE_H |
26 | #define PERVASIVE_H | 26 | #define PERVASIVE_H |
27 | 27 | ||
28 | struct pmd_regs { | 28 | extern void cbe_pervasive_init(void); |
29 | u8 pad_0x0000_0x0800[0x0800 - 0x0000]; /* 0x0000 */ | 29 | extern void cbe_system_error_exception(struct pt_regs *regs); |
30 | 30 | extern void cbe_maintenance_exception(struct pt_regs *regs); | |
31 | /* Thermal Sensor Registers */ | 31 | extern void cbe_thermal_exception(struct pt_regs *regs); |
32 | u64 ts_ctsr1; /* 0x0800 */ | ||
33 | u64 ts_ctsr2; /* 0x0808 */ | ||
34 | u64 ts_mtsr1; /* 0x0810 */ | ||
35 | u64 ts_mtsr2; /* 0x0818 */ | ||
36 | u64 ts_itr1; /* 0x0820 */ | ||
37 | u64 ts_itr2; /* 0x0828 */ | ||
38 | u64 ts_gitr; /* 0x0830 */ | ||
39 | u64 ts_isr; /* 0x0838 */ | ||
40 | u64 ts_imr; /* 0x0840 */ | ||
41 | u64 tm_cr1; /* 0x0848 */ | ||
42 | u64 tm_cr2; /* 0x0850 */ | ||
43 | u64 tm_simr; /* 0x0858 */ | ||
44 | u64 tm_tpr; /* 0x0860 */ | ||
45 | u64 tm_str1; /* 0x0868 */ | ||
46 | u64 tm_str2; /* 0x0870 */ | ||
47 | u64 tm_tsr; /* 0x0878 */ | ||
48 | |||
49 | /* Power Management */ | ||
50 | u64 pm_control; /* 0x0880 */ | ||
51 | #define PMD_PAUSE_ZERO_CONTROL 0x10000 | ||
52 | u64 pm_status; /* 0x0888 */ | ||
53 | |||
54 | /* Time Base Register */ | ||
55 | u64 tbr; /* 0x0890 */ | ||
56 | |||
57 | u8 pad_0x0898_0x1000 [0x1000 - 0x0898]; /* 0x0898 */ | ||
58 | }; | ||
59 | |||
60 | void __init cell_pervasive_init(void); | ||
61 | 32 | ||
62 | #endif | 33 | #endif |
diff --git a/arch/powerpc/platforms/cell/ras.c b/arch/powerpc/platforms/cell/ras.c new file mode 100644 index 000000000000..033ad6e2827b --- /dev/null +++ b/arch/powerpc/platforms/cell/ras.c | |||
@@ -0,0 +1,112 @@ | |||
1 | #define DEBUG | ||
2 | |||
3 | #include <linux/config.h> | ||
4 | #include <linux/types.h> | ||
5 | #include <linux/kernel.h> | ||
6 | #include <linux/smp.h> | ||
7 | |||
8 | #include <asm/reg.h> | ||
9 | #include <asm/io.h> | ||
10 | #include <asm/prom.h> | ||
11 | #include <asm/machdep.h> | ||
12 | |||
13 | #include "ras.h" | ||
14 | #include "cbe_regs.h" | ||
15 | |||
16 | |||
17 | static void dump_fir(int cpu) | ||
18 | { | ||
19 | struct cbe_pmd_regs __iomem *pregs = cbe_get_cpu_pmd_regs(cpu); | ||
20 | struct cbe_iic_regs __iomem *iregs = cbe_get_cpu_iic_regs(cpu); | ||
21 | |||
22 | if (pregs == NULL) | ||
23 | return; | ||
24 | |||
25 | /* Todo: do some nicer parsing of bits and based on them go down | ||
26 | * to other sub-units FIRs and not only IIC | ||
27 | */ | ||
28 | printk(KERN_ERR "Global Checkstop FIR : 0x%016lx\n", | ||
29 | in_be64(&pregs->checkstop_fir)); | ||
30 | printk(KERN_ERR "Global Recoverable FIR : 0x%016lx\n", | ||
31 | in_be64(&pregs->checkstop_fir)); | ||
32 | printk(KERN_ERR "Global MachineCheck FIR : 0x%016lx\n", | ||
33 | in_be64(&pregs->spec_att_mchk_fir)); | ||
34 | |||
35 | if (iregs == NULL) | ||
36 | return; | ||
37 | printk(KERN_ERR "IOC FIR : 0x%016lx\n", | ||
38 | in_be64(&iregs->ioc_fir)); | ||
39 | |||
40 | } | ||
41 | |||
42 | void cbe_system_error_exception(struct pt_regs *regs) | ||
43 | { | ||
44 | int cpu = smp_processor_id(); | ||
45 | |||
46 | printk(KERN_ERR "System Error Interrupt on CPU %d !\n", cpu); | ||
47 | dump_fir(cpu); | ||
48 | dump_stack(); | ||
49 | } | ||
50 | |||
51 | void cbe_maintenance_exception(struct pt_regs *regs) | ||
52 | { | ||
53 | int cpu = smp_processor_id(); | ||
54 | |||
55 | /* | ||
56 | * Nothing implemented for the maintenance interrupt at this point | ||
57 | */ | ||
58 | |||
59 | printk(KERN_ERR "Unhandled Maintenance interrupt on CPU %d !\n", cpu); | ||
60 | dump_stack(); | ||
61 | } | ||
62 | |||
63 | void cbe_thermal_exception(struct pt_regs *regs) | ||
64 | { | ||
65 | int cpu = smp_processor_id(); | ||
66 | |||
67 | /* | ||
68 | * Nothing implemented for the thermal interrupt at this point | ||
69 | */ | ||
70 | |||
71 | printk(KERN_ERR "Unhandled Thermal interrupt on CPU %d !\n", cpu); | ||
72 | dump_stack(); | ||
73 | } | ||
74 | |||
75 | static int cbe_machine_check_handler(struct pt_regs *regs) | ||
76 | { | ||
77 | int cpu = smp_processor_id(); | ||
78 | |||
79 | printk(KERN_ERR "Machine Check Interrupt on CPU %d !\n", cpu); | ||
80 | dump_fir(cpu); | ||
81 | |||
82 | /* No recovery from this code now, lets continue */ | ||
83 | return 0; | ||
84 | } | ||
85 | |||
86 | void __init cbe_ras_init(void) | ||
87 | { | ||
88 | unsigned long hid0; | ||
89 | |||
90 | /* | ||
91 | * Enable System Error & thermal interrupts and wakeup conditions | ||
92 | */ | ||
93 | |||
94 | hid0 = mfspr(SPRN_HID0); | ||
95 | hid0 |= HID0_CBE_THERM_INT_EN | HID0_CBE_THERM_WAKEUP | | ||
96 | HID0_CBE_SYSERR_INT_EN | HID0_CBE_SYSERR_WAKEUP; | ||
97 | mtspr(SPRN_HID0, hid0); | ||
98 | mb(); | ||
99 | |||
100 | /* | ||
101 | * Install machine check handler. Leave setting of precise mode to | ||
102 | * what the firmware did for now | ||
103 | */ | ||
104 | ppc_md.machine_check_exception = cbe_machine_check_handler; | ||
105 | mb(); | ||
106 | |||
107 | /* | ||
108 | * For now, we assume that IOC_FIR is already set to forward some | ||
109 | * error conditions to the System Error handler. If that is not true | ||
110 | * then it will have to be fixed up here. | ||
111 | */ | ||
112 | } | ||
diff --git a/arch/powerpc/platforms/cell/ras.h b/arch/powerpc/platforms/cell/ras.h new file mode 100644 index 000000000000..eb7ee54c82a0 --- /dev/null +++ b/arch/powerpc/platforms/cell/ras.h | |||
@@ -0,0 +1,9 @@ | |||
1 | #ifndef RAS_H | ||
2 | #define RAS_H | ||
3 | |||
4 | extern void cbe_system_error_exception(struct pt_regs *regs); | ||
5 | extern void cbe_maintenance_exception(struct pt_regs *regs); | ||
6 | extern void cbe_thermal_exception(struct pt_regs *regs); | ||
7 | extern void cbe_ras_init(void); | ||
8 | |||
9 | #endif /* RAS_H */ | ||
diff --git a/arch/powerpc/platforms/cell/setup.c b/arch/powerpc/platforms/cell/setup.c index fd3e5609e3e0..3d1831d331e5 100644 --- a/arch/powerpc/platforms/cell/setup.c +++ b/arch/powerpc/platforms/cell/setup.c | |||
@@ -49,10 +49,13 @@ | |||
49 | #include <asm/ppc-pci.h> | 49 | #include <asm/ppc-pci.h> |
50 | #include <asm/irq.h> | 50 | #include <asm/irq.h> |
51 | #include <asm/spu.h> | 51 | #include <asm/spu.h> |
52 | #include <asm/spu_priv1.h> | ||
52 | 53 | ||
53 | #include "interrupt.h" | 54 | #include "interrupt.h" |
54 | #include "iommu.h" | 55 | #include "iommu.h" |
56 | #include "cbe_regs.h" | ||
55 | #include "pervasive.h" | 57 | #include "pervasive.h" |
58 | #include "ras.h" | ||
56 | 59 | ||
57 | #ifdef DEBUG | 60 | #ifdef DEBUG |
58 | #define DBG(fmt...) udbg_printf(fmt) | 61 | #define DBG(fmt...) udbg_printf(fmt) |
@@ -81,6 +84,15 @@ static void __init cell_setup_arch(void) | |||
81 | { | 84 | { |
82 | ppc_md.init_IRQ = iic_init_IRQ; | 85 | ppc_md.init_IRQ = iic_init_IRQ; |
83 | ppc_md.get_irq = iic_get_irq; | 86 | ppc_md.get_irq = iic_get_irq; |
87 | #ifdef CONFIG_SPU_BASE | ||
88 | spu_priv1_ops = &spu_priv1_mmio_ops; | ||
89 | #endif | ||
90 | |||
91 | cbe_regs_init(); | ||
92 | |||
93 | #ifdef CONFIG_CBE_RAS | ||
94 | cbe_ras_init(); | ||
95 | #endif | ||
84 | 96 | ||
85 | #ifdef CONFIG_SMP | 97 | #ifdef CONFIG_SMP |
86 | smp_init_cell(); | 98 | smp_init_cell(); |
@@ -98,7 +110,7 @@ static void __init cell_setup_arch(void) | |||
98 | init_pci_config_tokens(); | 110 | init_pci_config_tokens(); |
99 | find_and_init_phbs(); | 111 | find_and_init_phbs(); |
100 | spider_init_IRQ(); | 112 | spider_init_IRQ(); |
101 | cell_pervasive_init(); | 113 | cbe_pervasive_init(); |
102 | #ifdef CONFIG_DUMMY_CONSOLE | 114 | #ifdef CONFIG_DUMMY_CONSOLE |
103 | conswitchp = &dummy_con; | 115 | conswitchp = &dummy_con; |
104 | #endif | 116 | #endif |
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index ad141fe8d52d..db82f503ba2c 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -34,10 +34,15 @@ | |||
34 | #include <asm/prom.h> | 34 | #include <asm/prom.h> |
35 | #include <linux/mutex.h> | 35 | #include <linux/mutex.h> |
36 | #include <asm/spu.h> | 36 | #include <asm/spu.h> |
37 | #include <asm/spu_priv1.h> | ||
37 | #include <asm/mmu_context.h> | 38 | #include <asm/mmu_context.h> |
38 | 39 | ||
39 | #include "interrupt.h" | 40 | #include "interrupt.h" |
40 | 41 | ||
42 | const struct spu_priv1_ops *spu_priv1_ops; | ||
43 | |||
44 | EXPORT_SYMBOL_GPL(spu_priv1_ops); | ||
45 | |||
41 | static int __spu_trap_invalid_dma(struct spu *spu) | 46 | static int __spu_trap_invalid_dma(struct spu *spu) |
42 | { | 47 | { |
43 | pr_debug("%s\n", __FUNCTION__); | 48 | pr_debug("%s\n", __FUNCTION__); |
@@ -71,7 +76,7 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) | |||
71 | { | 76 | { |
72 | struct spu_priv2 __iomem *priv2 = spu->priv2; | 77 | struct spu_priv2 __iomem *priv2 = spu->priv2; |
73 | struct mm_struct *mm = spu->mm; | 78 | struct mm_struct *mm = spu->mm; |
74 | u64 esid, vsid; | 79 | u64 esid, vsid, llp; |
75 | 80 | ||
76 | pr_debug("%s\n", __FUNCTION__); | 81 | pr_debug("%s\n", __FUNCTION__); |
77 | 82 | ||
@@ -91,9 +96,14 @@ static int __spu_trap_data_seg(struct spu *spu, unsigned long ea) | |||
91 | } | 96 | } |
92 | 97 | ||
93 | esid = (ea & ESID_MASK) | SLB_ESID_V; | 98 | esid = (ea & ESID_MASK) | SLB_ESID_V; |
94 | vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | SLB_VSID_USER; | 99 | #ifdef CONFIG_HUGETLB_PAGE |
95 | if (in_hugepage_area(mm->context, ea)) | 100 | if (in_hugepage_area(mm->context, ea)) |
96 | vsid |= SLB_VSID_L; | 101 | llp = mmu_psize_defs[mmu_huge_psize].sllp; |
102 | else | ||
103 | #endif | ||
104 | llp = mmu_psize_defs[mmu_virtual_psize].sllp; | ||
105 | vsid = (get_vsid(mm->context.id, ea) << SLB_VSID_SHIFT) | | ||
106 | SLB_VSID_USER | llp; | ||
97 | 107 | ||
98 | out_be64(&priv2->slb_index_W, spu->slb_replace); | 108 | out_be64(&priv2->slb_index_W, spu->slb_replace); |
99 | out_be64(&priv2->slb_vsid_RW, vsid); | 109 | out_be64(&priv2->slb_vsid_RW, vsid); |
@@ -130,57 +140,7 @@ static int __spu_trap_data_map(struct spu *spu, unsigned long ea, u64 dsisr) | |||
130 | spu->dar = ea; | 140 | spu->dar = ea; |
131 | spu->dsisr = dsisr; | 141 | spu->dsisr = dsisr; |
132 | mb(); | 142 | mb(); |
133 | if (spu->stop_callback) | 143 | spu->stop_callback(spu); |
134 | spu->stop_callback(spu); | ||
135 | return 0; | ||
136 | } | ||
137 | |||
138 | static int __spu_trap_mailbox(struct spu *spu) | ||
139 | { | ||
140 | if (spu->ibox_callback) | ||
141 | spu->ibox_callback(spu); | ||
142 | |||
143 | /* atomically disable SPU mailbox interrupts */ | ||
144 | spin_lock(&spu->register_lock); | ||
145 | spu_int_mask_and(spu, 2, ~0x1); | ||
146 | spin_unlock(&spu->register_lock); | ||
147 | return 0; | ||
148 | } | ||
149 | |||
150 | static int __spu_trap_stop(struct spu *spu) | ||
151 | { | ||
152 | pr_debug("%s\n", __FUNCTION__); | ||
153 | spu->stop_code = in_be32(&spu->problem->spu_status_R); | ||
154 | if (spu->stop_callback) | ||
155 | spu->stop_callback(spu); | ||
156 | return 0; | ||
157 | } | ||
158 | |||
159 | static int __spu_trap_halt(struct spu *spu) | ||
160 | { | ||
161 | pr_debug("%s\n", __FUNCTION__); | ||
162 | spu->stop_code = in_be32(&spu->problem->spu_status_R); | ||
163 | if (spu->stop_callback) | ||
164 | spu->stop_callback(spu); | ||
165 | return 0; | ||
166 | } | ||
167 | |||
168 | static int __spu_trap_tag_group(struct spu *spu) | ||
169 | { | ||
170 | pr_debug("%s\n", __FUNCTION__); | ||
171 | spu->mfc_callback(spu); | ||
172 | return 0; | ||
173 | } | ||
174 | |||
175 | static int __spu_trap_spubox(struct spu *spu) | ||
176 | { | ||
177 | if (spu->wbox_callback) | ||
178 | spu->wbox_callback(spu); | ||
179 | |||
180 | /* atomically disable SPU mailbox interrupts */ | ||
181 | spin_lock(&spu->register_lock); | ||
182 | spu_int_mask_and(spu, 2, ~0x10); | ||
183 | spin_unlock(&spu->register_lock); | ||
184 | return 0; | 144 | return 0; |
185 | } | 145 | } |
186 | 146 | ||
@@ -191,8 +151,7 @@ spu_irq_class_0(int irq, void *data, struct pt_regs *regs) | |||
191 | 151 | ||
192 | spu = data; | 152 | spu = data; |
193 | spu->class_0_pending = 1; | 153 | spu->class_0_pending = 1; |
194 | if (spu->stop_callback) | 154 | spu->stop_callback(spu); |
195 | spu->stop_callback(spu); | ||
196 | 155 | ||
197 | return IRQ_HANDLED; | 156 | return IRQ_HANDLED; |
198 | } | 157 | } |
@@ -270,29 +229,38 @@ spu_irq_class_2(int irq, void *data, struct pt_regs *regs) | |||
270 | unsigned long mask; | 229 | unsigned long mask; |
271 | 230 | ||
272 | spu = data; | 231 | spu = data; |
232 | spin_lock(&spu->register_lock); | ||
273 | stat = spu_int_stat_get(spu, 2); | 233 | stat = spu_int_stat_get(spu, 2); |
274 | mask = spu_int_mask_get(spu, 2); | 234 | mask = spu_int_mask_get(spu, 2); |
235 | /* ignore interrupts we're not waiting for */ | ||
236 | stat &= mask; | ||
237 | /* | ||
238 | * mailbox interrupts (0x1 and 0x10) are level triggered. | ||
239 | * mask them now before acknowledging. | ||
240 | */ | ||
241 | if (stat & 0x11) | ||
242 | spu_int_mask_and(spu, 2, ~(stat & 0x11)); | ||
243 | /* acknowledge all interrupts before the callbacks */ | ||
244 | spu_int_stat_clear(spu, 2, stat); | ||
245 | spin_unlock(&spu->register_lock); | ||
275 | 246 | ||
276 | pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); | 247 | pr_debug("class 2 interrupt %d, %lx, %lx\n", irq, stat, mask); |
277 | 248 | ||
278 | stat &= mask; | ||
279 | |||
280 | if (stat & 1) /* PPC core mailbox */ | 249 | if (stat & 1) /* PPC core mailbox */ |
281 | __spu_trap_mailbox(spu); | 250 | spu->ibox_callback(spu); |
282 | 251 | ||
283 | if (stat & 2) /* SPU stop-and-signal */ | 252 | if (stat & 2) /* SPU stop-and-signal */ |
284 | __spu_trap_stop(spu); | 253 | spu->stop_callback(spu); |
285 | 254 | ||
286 | if (stat & 4) /* SPU halted */ | 255 | if (stat & 4) /* SPU halted */ |
287 | __spu_trap_halt(spu); | 256 | spu->stop_callback(spu); |
288 | 257 | ||
289 | if (stat & 8) /* DMA tag group complete */ | 258 | if (stat & 8) /* DMA tag group complete */ |
290 | __spu_trap_tag_group(spu); | 259 | spu->mfc_callback(spu); |
291 | 260 | ||
292 | if (stat & 0x10) /* SPU mailbox threshold */ | 261 | if (stat & 0x10) /* SPU mailbox threshold */ |
293 | __spu_trap_spubox(spu); | 262 | spu->wbox_callback(spu); |
294 | 263 | ||
295 | spu_int_stat_clear(spu, 2, stat); | ||
296 | return stat ? IRQ_HANDLED : IRQ_NONE; | 264 | return stat ? IRQ_HANDLED : IRQ_NONE; |
297 | } | 265 | } |
298 | 266 | ||
@@ -512,14 +480,6 @@ int spu_irq_class_1_bottom(struct spu *spu) | |||
512 | return ret; | 480 | return ret; |
513 | } | 481 | } |
514 | 482 | ||
515 | void spu_irq_setaffinity(struct spu *spu, int cpu) | ||
516 | { | ||
517 | u64 target = iic_get_target_id(cpu); | ||
518 | u64 route = target << 48 | target << 32 | target << 16; | ||
519 | spu_int_route_set(spu, route); | ||
520 | } | ||
521 | EXPORT_SYMBOL_GPL(spu_irq_setaffinity); | ||
522 | |||
523 | static int __init find_spu_node_id(struct device_node *spe) | 483 | static int __init find_spu_node_id(struct device_node *spe) |
524 | { | 484 | { |
525 | unsigned int *id; | 485 | unsigned int *id; |
@@ -649,6 +609,46 @@ out: | |||
649 | return ret; | 609 | return ret; |
650 | } | 610 | } |
651 | 611 | ||
612 | struct sysdev_class spu_sysdev_class = { | ||
613 | set_kset_name("spu") | ||
614 | }; | ||
615 | |||
616 | static ssize_t spu_show_isrc(struct sys_device *sysdev, char *buf) | ||
617 | { | ||
618 | struct spu *spu = container_of(sysdev, struct spu, sysdev); | ||
619 | return sprintf(buf, "%d\n", spu->isrc); | ||
620 | |||
621 | } | ||
622 | static SYSDEV_ATTR(isrc, 0400, spu_show_isrc, NULL); | ||
623 | |||
624 | extern int attach_sysdev_to_node(struct sys_device *dev, int nid); | ||
625 | |||
626 | static int spu_create_sysdev(struct spu *spu) | ||
627 | { | ||
628 | int ret; | ||
629 | |||
630 | spu->sysdev.id = spu->number; | ||
631 | spu->sysdev.cls = &spu_sysdev_class; | ||
632 | ret = sysdev_register(&spu->sysdev); | ||
633 | if (ret) { | ||
634 | printk(KERN_ERR "Can't register SPU %d with sysfs\n", | ||
635 | spu->number); | ||
636 | return ret; | ||
637 | } | ||
638 | |||
639 | sysdev_create_file(&spu->sysdev, &attr_isrc); | ||
640 | sysfs_add_device_to_node(&spu->sysdev, spu->nid); | ||
641 | |||
642 | return 0; | ||
643 | } | ||
644 | |||
645 | static void spu_destroy_sysdev(struct spu *spu) | ||
646 | { | ||
647 | sysdev_remove_file(&spu->sysdev, &attr_isrc); | ||
648 | sysfs_remove_device_from_node(&spu->sysdev, spu->nid); | ||
649 | sysdev_unregister(&spu->sysdev); | ||
650 | } | ||
651 | |||
652 | static int __init create_spu(struct device_node *spe) | 652 | static int __init create_spu(struct device_node *spe) |
653 | { | 653 | { |
654 | struct spu *spu; | 654 | struct spu *spu; |
@@ -656,7 +656,7 @@ static int __init create_spu(struct device_node *spe) | |||
656 | static int number; | 656 | static int number; |
657 | 657 | ||
658 | ret = -ENOMEM; | 658 | ret = -ENOMEM; |
659 | spu = kmalloc(sizeof (*spu), GFP_KERNEL); | 659 | spu = kzalloc(sizeof (*spu), GFP_KERNEL); |
660 | if (!spu) | 660 | if (!spu) |
661 | goto out; | 661 | goto out; |
662 | 662 | ||
@@ -668,33 +668,20 @@ static int __init create_spu(struct device_node *spe) | |||
668 | spu->nid = of_node_to_nid(spe); | 668 | spu->nid = of_node_to_nid(spe); |
669 | if (spu->nid == -1) | 669 | if (spu->nid == -1) |
670 | spu->nid = 0; | 670 | spu->nid = 0; |
671 | |||
672 | spu->stop_code = 0; | ||
673 | spu->slb_replace = 0; | ||
674 | spu->mm = NULL; | ||
675 | spu->ctx = NULL; | ||
676 | spu->rq = NULL; | ||
677 | spu->pid = 0; | ||
678 | spu->class_0_pending = 0; | ||
679 | spu->flags = 0UL; | ||
680 | spu->dar = 0UL; | ||
681 | spu->dsisr = 0UL; | ||
682 | spin_lock_init(&spu->register_lock); | 671 | spin_lock_init(&spu->register_lock); |
683 | |||
684 | spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1)); | 672 | spu_mfc_sdr_set(spu, mfspr(SPRN_SDR1)); |
685 | spu_mfc_sr1_set(spu, 0x33); | 673 | spu_mfc_sr1_set(spu, 0x33); |
686 | |||
687 | spu->ibox_callback = NULL; | ||
688 | spu->wbox_callback = NULL; | ||
689 | spu->stop_callback = NULL; | ||
690 | spu->mfc_callback = NULL; | ||
691 | |||
692 | mutex_lock(&spu_mutex); | 674 | mutex_lock(&spu_mutex); |
675 | |||
693 | spu->number = number++; | 676 | spu->number = number++; |
694 | ret = spu_request_irqs(spu); | 677 | ret = spu_request_irqs(spu); |
695 | if (ret) | 678 | if (ret) |
696 | goto out_unmap; | 679 | goto out_unmap; |
697 | 680 | ||
681 | ret = spu_create_sysdev(spu); | ||
682 | if (ret) | ||
683 | goto out_free_irqs; | ||
684 | |||
698 | list_add(&spu->list, &spu_list); | 685 | list_add(&spu->list, &spu_list); |
699 | mutex_unlock(&spu_mutex); | 686 | mutex_unlock(&spu_mutex); |
700 | 687 | ||
@@ -703,6 +690,9 @@ static int __init create_spu(struct device_node *spe) | |||
703 | spu->problem, spu->priv1, spu->priv2, spu->number); | 690 | spu->problem, spu->priv1, spu->priv2, spu->number); |
704 | goto out; | 691 | goto out; |
705 | 692 | ||
693 | out_free_irqs: | ||
694 | spu_free_irqs(spu); | ||
695 | |||
706 | out_unmap: | 696 | out_unmap: |
707 | mutex_unlock(&spu_mutex); | 697 | mutex_unlock(&spu_mutex); |
708 | spu_unmap(spu); | 698 | spu_unmap(spu); |
@@ -716,6 +706,7 @@ static void destroy_spu(struct spu *spu) | |||
716 | { | 706 | { |
717 | list_del_init(&spu->list); | 707 | list_del_init(&spu->list); |
718 | 708 | ||
709 | spu_destroy_sysdev(spu); | ||
719 | spu_free_irqs(spu); | 710 | spu_free_irqs(spu); |
720 | spu_unmap(spu); | 711 | spu_unmap(spu); |
721 | kfree(spu); | 712 | kfree(spu); |
@@ -728,6 +719,7 @@ static void cleanup_spu_base(void) | |||
728 | list_for_each_entry_safe(spu, tmp, &spu_list, list) | 719 | list_for_each_entry_safe(spu, tmp, &spu_list, list) |
729 | destroy_spu(spu); | 720 | destroy_spu(spu); |
730 | mutex_unlock(&spu_mutex); | 721 | mutex_unlock(&spu_mutex); |
722 | sysdev_class_unregister(&spu_sysdev_class); | ||
731 | } | 723 | } |
732 | module_exit(cleanup_spu_base); | 724 | module_exit(cleanup_spu_base); |
733 | 725 | ||
@@ -736,6 +728,11 @@ static int __init init_spu_base(void) | |||
736 | struct device_node *node; | 728 | struct device_node *node; |
737 | int ret; | 729 | int ret; |
738 | 730 | ||
731 | /* create sysdev class for spus */ | ||
732 | ret = sysdev_class_register(&spu_sysdev_class); | ||
733 | if (ret) | ||
734 | return ret; | ||
735 | |||
739 | ret = -ENODEV; | 736 | ret = -ENODEV; |
740 | for (node = of_find_node_by_type(NULL, "spe"); | 737 | for (node = of_find_node_by_type(NULL, "spe"); |
741 | node; node = of_find_node_by_type(node, "spe")) { | 738 | node; node = of_find_node_by_type(node, "spe")) { |
diff --git a/arch/powerpc/platforms/cell/spu_callbacks.c b/arch/powerpc/platforms/cell/spu_callbacks.c index b47fcc5ddb78..47ec3be3edcd 100644 --- a/arch/powerpc/platforms/cell/spu_callbacks.c +++ b/arch/powerpc/platforms/cell/spu_callbacks.c | |||
@@ -34,307 +34,19 @@ | |||
34 | */ | 34 | */ |
35 | 35 | ||
36 | void *spu_syscall_table[] = { | 36 | void *spu_syscall_table[] = { |
37 | [__NR_restart_syscall] sys_ni_syscall, /* sys_restart_syscall */ | 37 | #define SYSCALL(func) sys_ni_syscall, |
38 | [__NR_exit] sys_ni_syscall, /* sys_exit */ | 38 | #define COMPAT_SYS(func) sys_ni_syscall, |
39 | [__NR_fork] sys_ni_syscall, /* ppc_fork */ | 39 | #define PPC_SYS(func) sys_ni_syscall, |
40 | [__NR_read] sys_read, | 40 | #define OLDSYS(func) sys_ni_syscall, |
41 | [__NR_write] sys_write, | 41 | #define SYS32ONLY(func) sys_ni_syscall, |
42 | [__NR_open] sys_open, | 42 | #define SYSX(f, f3264, f32) sys_ni_syscall, |
43 | [__NR_close] sys_close, | 43 | |
44 | [__NR_waitpid] sys_waitpid, | 44 | #define SYSCALL_SPU(func) sys_##func, |
45 | [__NR_creat] sys_creat, | 45 | #define COMPAT_SYS_SPU(func) sys_##func, |
46 | [__NR_link] sys_link, | 46 | #define PPC_SYS_SPU(func) ppc_##func, |
47 | [__NR_unlink] sys_unlink, | 47 | #define SYSX_SPU(f, f3264, f32) f, |
48 | [__NR_execve] sys_ni_syscall, /* sys_execve */ | 48 | |
49 | [__NR_chdir] sys_chdir, | 49 | #include <asm/systbl.h> |
50 | [__NR_time] sys_time, | ||
51 | [__NR_mknod] sys_mknod, | ||
52 | [__NR_chmod] sys_chmod, | ||
53 | [__NR_lchown] sys_lchown, | ||
54 | [__NR_break] sys_ni_syscall, | ||
55 | [__NR_oldstat] sys_ni_syscall, | ||
56 | [__NR_lseek] sys_lseek, | ||
57 | [__NR_getpid] sys_getpid, | ||
58 | [__NR_mount] sys_ni_syscall, /* sys_mount */ | ||
59 | [__NR_umount] sys_ni_syscall, | ||
60 | [__NR_setuid] sys_setuid, | ||
61 | [__NR_getuid] sys_getuid, | ||
62 | [__NR_stime] sys_stime, | ||
63 | [__NR_ptrace] sys_ni_syscall, /* sys_ptrace */ | ||
64 | [__NR_alarm] sys_alarm, | ||
65 | [__NR_oldfstat] sys_ni_syscall, | ||
66 | [__NR_pause] sys_ni_syscall, /* sys_pause */ | ||
67 | [__NR_utime] sys_ni_syscall, /* sys_utime */ | ||
68 | [__NR_stty] sys_ni_syscall, | ||
69 | [__NR_gtty] sys_ni_syscall, | ||
70 | [__NR_access] sys_access, | ||
71 | [__NR_nice] sys_nice, | ||
72 | [__NR_ftime] sys_ni_syscall, | ||
73 | [__NR_sync] sys_sync, | ||
74 | [__NR_kill] sys_kill, | ||
75 | [__NR_rename] sys_rename, | ||
76 | [__NR_mkdir] sys_mkdir, | ||
77 | [__NR_rmdir] sys_rmdir, | ||
78 | [__NR_dup] sys_dup, | ||
79 | [__NR_pipe] sys_pipe, | ||
80 | [__NR_times] sys_times, | ||
81 | [__NR_prof] sys_ni_syscall, | ||
82 | [__NR_brk] sys_brk, | ||
83 | [__NR_setgid] sys_setgid, | ||
84 | [__NR_getgid] sys_getgid, | ||
85 | [__NR_signal] sys_ni_syscall, /* sys_signal */ | ||
86 | [__NR_geteuid] sys_geteuid, | ||
87 | [__NR_getegid] sys_getegid, | ||
88 | [__NR_acct] sys_ni_syscall, /* sys_acct */ | ||
89 | [__NR_umount2] sys_ni_syscall, /* sys_umount */ | ||
90 | [__NR_lock] sys_ni_syscall, | ||
91 | [__NR_ioctl] sys_ioctl, | ||
92 | [__NR_fcntl] sys_fcntl, | ||
93 | [__NR_mpx] sys_ni_syscall, | ||
94 | [__NR_setpgid] sys_setpgid, | ||
95 | [__NR_ulimit] sys_ni_syscall, | ||
96 | [__NR_oldolduname] sys_ni_syscall, | ||
97 | [__NR_umask] sys_umask, | ||
98 | [__NR_chroot] sys_chroot, | ||
99 | [__NR_ustat] sys_ni_syscall, /* sys_ustat */ | ||
100 | [__NR_dup2] sys_dup2, | ||
101 | [__NR_getppid] sys_getppid, | ||
102 | [__NR_getpgrp] sys_getpgrp, | ||
103 | [__NR_setsid] sys_setsid, | ||
104 | [__NR_sigaction] sys_ni_syscall, | ||
105 | [__NR_sgetmask] sys_sgetmask, | ||
106 | [__NR_ssetmask] sys_ssetmask, | ||
107 | [__NR_setreuid] sys_setreuid, | ||
108 | [__NR_setregid] sys_setregid, | ||
109 | [__NR_sigsuspend] sys_ni_syscall, | ||
110 | [__NR_sigpending] sys_ni_syscall, | ||
111 | [__NR_sethostname] sys_sethostname, | ||
112 | [__NR_setrlimit] sys_setrlimit, | ||
113 | [__NR_getrlimit] sys_ni_syscall, | ||
114 | [__NR_getrusage] sys_getrusage, | ||
115 | [__NR_gettimeofday] sys_gettimeofday, | ||
116 | [__NR_settimeofday] sys_settimeofday, | ||
117 | [__NR_getgroups] sys_getgroups, | ||
118 | [__NR_setgroups] sys_setgroups, | ||
119 | [__NR_select] sys_ni_syscall, | ||
120 | [__NR_symlink] sys_symlink, | ||
121 | [__NR_oldlstat] sys_ni_syscall, | ||
122 | [__NR_readlink] sys_readlink, | ||
123 | [__NR_uselib] sys_ni_syscall, /* sys_uselib */ | ||
124 | [__NR_swapon] sys_ni_syscall, /* sys_swapon */ | ||
125 | [__NR_reboot] sys_ni_syscall, /* sys_reboot */ | ||
126 | [__NR_readdir] sys_ni_syscall, | ||
127 | [__NR_mmap] sys_mmap, | ||
128 | [__NR_munmap] sys_munmap, | ||
129 | [__NR_truncate] sys_truncate, | ||
130 | [__NR_ftruncate] sys_ftruncate, | ||
131 | [__NR_fchmod] sys_fchmod, | ||
132 | [__NR_fchown] sys_fchown, | ||
133 | [__NR_getpriority] sys_getpriority, | ||
134 | [__NR_setpriority] sys_setpriority, | ||
135 | [__NR_profil] sys_ni_syscall, | ||
136 | [__NR_statfs] sys_ni_syscall, /* sys_statfs */ | ||
137 | [__NR_fstatfs] sys_ni_syscall, /* sys_fstatfs */ | ||
138 | [__NR_ioperm] sys_ni_syscall, | ||
139 | [__NR_socketcall] sys_socketcall, | ||
140 | [__NR_syslog] sys_syslog, | ||
141 | [__NR_setitimer] sys_setitimer, | ||
142 | [__NR_getitimer] sys_getitimer, | ||
143 | [__NR_stat] sys_newstat, | ||
144 | [__NR_lstat] sys_newlstat, | ||
145 | [__NR_fstat] sys_newfstat, | ||
146 | [__NR_olduname] sys_ni_syscall, | ||
147 | [__NR_iopl] sys_ni_syscall, | ||
148 | [__NR_vhangup] sys_vhangup, | ||
149 | [__NR_idle] sys_ni_syscall, | ||
150 | [__NR_vm86] sys_ni_syscall, | ||
151 | [__NR_wait4] sys_wait4, | ||
152 | [__NR_swapoff] sys_ni_syscall, /* sys_swapoff */ | ||
153 | [__NR_sysinfo] sys_sysinfo, | ||
154 | [__NR_ipc] sys_ni_syscall, /* sys_ipc */ | ||
155 | [__NR_fsync] sys_fsync, | ||
156 | [__NR_sigreturn] sys_ni_syscall, | ||
157 | [__NR_clone] sys_ni_syscall, /* ppc_clone */ | ||
158 | [__NR_setdomainname] sys_setdomainname, | ||
159 | [__NR_uname] ppc_newuname, | ||
160 | [__NR_modify_ldt] sys_ni_syscall, | ||
161 | [__NR_adjtimex] sys_adjtimex, | ||
162 | [__NR_mprotect] sys_mprotect, | ||
163 | [__NR_sigprocmask] sys_ni_syscall, | ||
164 | [__NR_create_module] sys_ni_syscall, | ||
165 | [__NR_init_module] sys_ni_syscall, /* sys_init_module */ | ||
166 | [__NR_delete_module] sys_ni_syscall, /* sys_delete_module */ | ||
167 | [__NR_get_kernel_syms] sys_ni_syscall, | ||
168 | [__NR_quotactl] sys_ni_syscall, /* sys_quotactl */ | ||
169 | [__NR_getpgid] sys_getpgid, | ||
170 | [__NR_fchdir] sys_fchdir, | ||
171 | [__NR_bdflush] sys_bdflush, | ||
172 | [__NR_sysfs] sys_ni_syscall, /* sys_sysfs */ | ||
173 | [__NR_personality] ppc64_personality, | ||
174 | [__NR_afs_syscall] sys_ni_syscall, | ||
175 | [__NR_setfsuid] sys_setfsuid, | ||
176 | [__NR_setfsgid] sys_setfsgid, | ||
177 | [__NR__llseek] sys_llseek, | ||
178 | [__NR_getdents] sys_getdents, | ||
179 | [__NR__newselect] sys_select, | ||
180 | [__NR_flock] sys_flock, | ||
181 | [__NR_msync] sys_msync, | ||
182 | [__NR_readv] sys_readv, | ||
183 | [__NR_writev] sys_writev, | ||
184 | [__NR_getsid] sys_getsid, | ||
185 | [__NR_fdatasync] sys_fdatasync, | ||
186 | [__NR__sysctl] sys_ni_syscall, /* sys_sysctl */ | ||
187 | [__NR_mlock] sys_mlock, | ||
188 | [__NR_munlock] sys_munlock, | ||
189 | [__NR_mlockall] sys_mlockall, | ||
190 | [__NR_munlockall] sys_munlockall, | ||
191 | [__NR_sched_setparam] sys_sched_setparam, | ||
192 | [__NR_sched_getparam] sys_sched_getparam, | ||
193 | [__NR_sched_setscheduler] sys_sched_setscheduler, | ||
194 | [__NR_sched_getscheduler] sys_sched_getscheduler, | ||
195 | [__NR_sched_yield] sys_sched_yield, | ||
196 | [__NR_sched_get_priority_max] sys_sched_get_priority_max, | ||
197 | [__NR_sched_get_priority_min] sys_sched_get_priority_min, | ||
198 | [__NR_sched_rr_get_interval] sys_sched_rr_get_interval, | ||
199 | [__NR_nanosleep] sys_nanosleep, | ||
200 | [__NR_mremap] sys_mremap, | ||
201 | [__NR_setresuid] sys_setresuid, | ||
202 | [__NR_getresuid] sys_getresuid, | ||
203 | [__NR_query_module] sys_ni_syscall, | ||
204 | [__NR_poll] sys_poll, | ||
205 | [__NR_nfsservctl] sys_ni_syscall, /* sys_nfsservctl */ | ||
206 | [__NR_setresgid] sys_setresgid, | ||
207 | [__NR_getresgid] sys_getresgid, | ||
208 | [__NR_prctl] sys_prctl, | ||
209 | [__NR_rt_sigreturn] sys_ni_syscall, /* ppc64_rt_sigreturn */ | ||
210 | [__NR_rt_sigaction] sys_ni_syscall, /* sys_rt_sigaction */ | ||
211 | [__NR_rt_sigprocmask] sys_ni_syscall, /* sys_rt_sigprocmask */ | ||
212 | [__NR_rt_sigpending] sys_ni_syscall, /* sys_rt_sigpending */ | ||
213 | [__NR_rt_sigtimedwait] sys_ni_syscall, /* sys_rt_sigtimedwait */ | ||
214 | [__NR_rt_sigqueueinfo] sys_ni_syscall, /* sys_rt_sigqueueinfo */ | ||
215 | [__NR_rt_sigsuspend] sys_ni_syscall, /* sys_rt_sigsuspend */ | ||
216 | [__NR_pread64] sys_pread64, | ||
217 | [__NR_pwrite64] sys_pwrite64, | ||
218 | [__NR_chown] sys_chown, | ||
219 | [__NR_getcwd] sys_getcwd, | ||
220 | [__NR_capget] sys_capget, | ||
221 | [__NR_capset] sys_capset, | ||
222 | [__NR_sigaltstack] sys_ni_syscall, /* sys_sigaltstack */ | ||
223 | [__NR_sendfile] sys_sendfile64, | ||
224 | [__NR_getpmsg] sys_ni_syscall, | ||
225 | [__NR_putpmsg] sys_ni_syscall, | ||
226 | [__NR_vfork] sys_ni_syscall, /* ppc_vfork */ | ||
227 | [__NR_ugetrlimit] sys_getrlimit, | ||
228 | [__NR_readahead] sys_readahead, | ||
229 | [192] sys_ni_syscall, | ||
230 | [193] sys_ni_syscall, | ||
231 | [194] sys_ni_syscall, | ||
232 | [195] sys_ni_syscall, | ||
233 | [196] sys_ni_syscall, | ||
234 | [197] sys_ni_syscall, | ||
235 | [__NR_pciconfig_read] sys_ni_syscall, /* sys_pciconfig_read */ | ||
236 | [__NR_pciconfig_write] sys_ni_syscall, /* sys_pciconfig_write */ | ||
237 | [__NR_pciconfig_iobase] sys_ni_syscall, /* sys_pciconfig_iobase */ | ||
238 | [__NR_multiplexer] sys_ni_syscall, | ||
239 | [__NR_getdents64] sys_getdents64, | ||
240 | [__NR_pivot_root] sys_pivot_root, | ||
241 | [204] sys_ni_syscall, | ||
242 | [__NR_madvise] sys_madvise, | ||
243 | [__NR_mincore] sys_mincore, | ||
244 | [__NR_gettid] sys_gettid, | ||
245 | [__NR_tkill] sys_tkill, | ||
246 | [__NR_setxattr] sys_setxattr, | ||
247 | [__NR_lsetxattr] sys_lsetxattr, | ||
248 | [__NR_fsetxattr] sys_fsetxattr, | ||
249 | [__NR_getxattr] sys_getxattr, | ||
250 | [__NR_lgetxattr] sys_lgetxattr, | ||
251 | [__NR_fgetxattr] sys_fgetxattr, | ||
252 | [__NR_listxattr] sys_listxattr, | ||
253 | [__NR_llistxattr] sys_llistxattr, | ||
254 | [__NR_flistxattr] sys_flistxattr, | ||
255 | [__NR_removexattr] sys_removexattr, | ||
256 | [__NR_lremovexattr] sys_lremovexattr, | ||
257 | [__NR_fremovexattr] sys_fremovexattr, | ||
258 | [__NR_futex] sys_futex, | ||
259 | [__NR_sched_setaffinity] sys_sched_setaffinity, | ||
260 | [__NR_sched_getaffinity] sys_sched_getaffinity, | ||
261 | [224] sys_ni_syscall, | ||
262 | [__NR_tuxcall] sys_ni_syscall, | ||
263 | [226] sys_ni_syscall, | ||
264 | [__NR_io_setup] sys_io_setup, | ||
265 | [__NR_io_destroy] sys_io_destroy, | ||
266 | [__NR_io_getevents] sys_io_getevents, | ||
267 | [__NR_io_submit] sys_io_submit, | ||
268 | [__NR_io_cancel] sys_io_cancel, | ||
269 | [__NR_set_tid_address] sys_ni_syscall, /* sys_set_tid_address */ | ||
270 | [__NR_fadvise64] sys_fadvise64, | ||
271 | [__NR_exit_group] sys_ni_syscall, /* sys_exit_group */ | ||
272 | [__NR_lookup_dcookie] sys_ni_syscall, /* sys_lookup_dcookie */ | ||
273 | [__NR_epoll_create] sys_epoll_create, | ||
274 | [__NR_epoll_ctl] sys_epoll_ctl, | ||
275 | [__NR_epoll_wait] sys_epoll_wait, | ||
276 | [__NR_remap_file_pages] sys_remap_file_pages, | ||
277 | [__NR_timer_create] sys_timer_create, | ||
278 | [__NR_timer_settime] sys_timer_settime, | ||
279 | [__NR_timer_gettime] sys_timer_gettime, | ||
280 | [__NR_timer_getoverrun] sys_timer_getoverrun, | ||
281 | [__NR_timer_delete] sys_timer_delete, | ||
282 | [__NR_clock_settime] sys_clock_settime, | ||
283 | [__NR_clock_gettime] sys_clock_gettime, | ||
284 | [__NR_clock_getres] sys_clock_getres, | ||
285 | [__NR_clock_nanosleep] sys_clock_nanosleep, | ||
286 | [__NR_swapcontext] sys_ni_syscall, /* ppc64_swapcontext */ | ||
287 | [__NR_tgkill] sys_tgkill, | ||
288 | [__NR_utimes] sys_utimes, | ||
289 | [__NR_statfs64] sys_statfs64, | ||
290 | [__NR_fstatfs64] sys_fstatfs64, | ||
291 | [254] sys_ni_syscall, | ||
292 | [__NR_rtas] ppc_rtas, | ||
293 | [256] sys_ni_syscall, | ||
294 | [257] sys_ni_syscall, | ||
295 | [258] sys_ni_syscall, | ||
296 | [__NR_mbind] sys_ni_syscall, /* sys_mbind */ | ||
297 | [__NR_get_mempolicy] sys_ni_syscall, /* sys_get_mempolicy */ | ||
298 | [__NR_set_mempolicy] sys_ni_syscall, /* sys_set_mempolicy */ | ||
299 | [__NR_mq_open] sys_ni_syscall, /* sys_mq_open */ | ||
300 | [__NR_mq_unlink] sys_ni_syscall, /* sys_mq_unlink */ | ||
301 | [__NR_mq_timedsend] sys_ni_syscall, /* sys_mq_timedsend */ | ||
302 | [__NR_mq_timedreceive] sys_ni_syscall, /* sys_mq_timedreceive */ | ||
303 | [__NR_mq_notify] sys_ni_syscall, /* sys_mq_notify */ | ||
304 | [__NR_mq_getsetattr] sys_ni_syscall, /* sys_mq_getsetattr */ | ||
305 | [__NR_kexec_load] sys_ni_syscall, /* sys_kexec_load */ | ||
306 | [__NR_add_key] sys_ni_syscall, /* sys_add_key */ | ||
307 | [__NR_request_key] sys_ni_syscall, /* sys_request_key */ | ||
308 | [__NR_keyctl] sys_ni_syscall, /* sys_keyctl */ | ||
309 | [__NR_waitid] sys_ni_syscall, /* sys_waitid */ | ||
310 | [__NR_ioprio_set] sys_ni_syscall, /* sys_ioprio_set */ | ||
311 | [__NR_ioprio_get] sys_ni_syscall, /* sys_ioprio_get */ | ||
312 | [__NR_inotify_init] sys_ni_syscall, /* sys_inotify_init */ | ||
313 | [__NR_inotify_add_watch] sys_ni_syscall, /* sys_inotify_add_watch */ | ||
314 | [__NR_inotify_rm_watch] sys_ni_syscall, /* sys_inotify_rm_watch */ | ||
315 | [__NR_spu_run] sys_ni_syscall, /* sys_spu_run */ | ||
316 | [__NR_spu_create] sys_ni_syscall, /* sys_spu_create */ | ||
317 | [__NR_pselect6] sys_ni_syscall, /* sys_pselect */ | ||
318 | [__NR_ppoll] sys_ni_syscall, /* sys_ppoll */ | ||
319 | [__NR_unshare] sys_unshare, | ||
320 | [__NR_splice] sys_splice, | ||
321 | [__NR_tee] sys_tee, | ||
322 | [__NR_vmsplice] sys_vmsplice, | ||
323 | [__NR_openat] sys_openat, | ||
324 | [__NR_mkdirat] sys_mkdirat, | ||
325 | [__NR_mknodat] sys_mknodat, | ||
326 | [__NR_fchownat] sys_fchownat, | ||
327 | [__NR_futimesat] sys_futimesat, | ||
328 | [__NR_newfstatat] sys_newfstatat, | ||
329 | [__NR_unlinkat] sys_unlinkat, | ||
330 | [__NR_renameat] sys_renameat, | ||
331 | [__NR_linkat] sys_linkat, | ||
332 | [__NR_symlinkat] sys_symlinkat, | ||
333 | [__NR_readlinkat] sys_readlinkat, | ||
334 | [__NR_fchmodat] sys_fchmodat, | ||
335 | [__NR_faccessat] sys_faccessat, | ||
336 | [__NR_get_robust_list] sys_get_robust_list, | ||
337 | [__NR_set_robust_list] sys_set_robust_list, | ||
338 | }; | 50 | }; |
339 | 51 | ||
340 | long spu_sys_callback(struct spu_syscall_block *s) | 52 | long spu_sys_callback(struct spu_syscall_block *s) |
diff --git a/arch/powerpc/platforms/cell/spu_priv1.c b/arch/powerpc/platforms/cell/spu_priv1.c deleted file mode 100644 index b2656421c7b5..000000000000 --- a/arch/powerpc/platforms/cell/spu_priv1.c +++ /dev/null | |||
@@ -1,133 +0,0 @@ | |||
1 | /* | ||
2 | * access to SPU privileged registers | ||
3 | */ | ||
4 | #include <linux/module.h> | ||
5 | |||
6 | #include <asm/io.h> | ||
7 | #include <asm/spu.h> | ||
8 | |||
9 | void spu_int_mask_and(struct spu *spu, int class, u64 mask) | ||
10 | { | ||
11 | u64 old_mask; | ||
12 | |||
13 | old_mask = in_be64(&spu->priv1->int_mask_RW[class]); | ||
14 | out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); | ||
15 | } | ||
16 | EXPORT_SYMBOL_GPL(spu_int_mask_and); | ||
17 | |||
18 | void spu_int_mask_or(struct spu *spu, int class, u64 mask) | ||
19 | { | ||
20 | u64 old_mask; | ||
21 | |||
22 | old_mask = in_be64(&spu->priv1->int_mask_RW[class]); | ||
23 | out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); | ||
24 | } | ||
25 | EXPORT_SYMBOL_GPL(spu_int_mask_or); | ||
26 | |||
27 | void spu_int_mask_set(struct spu *spu, int class, u64 mask) | ||
28 | { | ||
29 | out_be64(&spu->priv1->int_mask_RW[class], mask); | ||
30 | } | ||
31 | EXPORT_SYMBOL_GPL(spu_int_mask_set); | ||
32 | |||
33 | u64 spu_int_mask_get(struct spu *spu, int class) | ||
34 | { | ||
35 | return in_be64(&spu->priv1->int_mask_RW[class]); | ||
36 | } | ||
37 | EXPORT_SYMBOL_GPL(spu_int_mask_get); | ||
38 | |||
39 | void spu_int_stat_clear(struct spu *spu, int class, u64 stat) | ||
40 | { | ||
41 | out_be64(&spu->priv1->int_stat_RW[class], stat); | ||
42 | } | ||
43 | EXPORT_SYMBOL_GPL(spu_int_stat_clear); | ||
44 | |||
45 | u64 spu_int_stat_get(struct spu *spu, int class) | ||
46 | { | ||
47 | return in_be64(&spu->priv1->int_stat_RW[class]); | ||
48 | } | ||
49 | EXPORT_SYMBOL_GPL(spu_int_stat_get); | ||
50 | |||
51 | void spu_int_route_set(struct spu *spu, u64 route) | ||
52 | { | ||
53 | out_be64(&spu->priv1->int_route_RW, route); | ||
54 | } | ||
55 | EXPORT_SYMBOL_GPL(spu_int_route_set); | ||
56 | |||
57 | u64 spu_mfc_dar_get(struct spu *spu) | ||
58 | { | ||
59 | return in_be64(&spu->priv1->mfc_dar_RW); | ||
60 | } | ||
61 | EXPORT_SYMBOL_GPL(spu_mfc_dar_get); | ||
62 | |||
63 | u64 spu_mfc_dsisr_get(struct spu *spu) | ||
64 | { | ||
65 | return in_be64(&spu->priv1->mfc_dsisr_RW); | ||
66 | } | ||
67 | EXPORT_SYMBOL_GPL(spu_mfc_dsisr_get); | ||
68 | |||
69 | void spu_mfc_dsisr_set(struct spu *spu, u64 dsisr) | ||
70 | { | ||
71 | out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); | ||
72 | } | ||
73 | EXPORT_SYMBOL_GPL(spu_mfc_dsisr_set); | ||
74 | |||
75 | void spu_mfc_sdr_set(struct spu *spu, u64 sdr) | ||
76 | { | ||
77 | out_be64(&spu->priv1->mfc_sdr_RW, sdr); | ||
78 | } | ||
79 | EXPORT_SYMBOL_GPL(spu_mfc_sdr_set); | ||
80 | |||
81 | void spu_mfc_sr1_set(struct spu *spu, u64 sr1) | ||
82 | { | ||
83 | out_be64(&spu->priv1->mfc_sr1_RW, sr1); | ||
84 | } | ||
85 | EXPORT_SYMBOL_GPL(spu_mfc_sr1_set); | ||
86 | |||
87 | u64 spu_mfc_sr1_get(struct spu *spu) | ||
88 | { | ||
89 | return in_be64(&spu->priv1->mfc_sr1_RW); | ||
90 | } | ||
91 | EXPORT_SYMBOL_GPL(spu_mfc_sr1_get); | ||
92 | |||
93 | void spu_mfc_tclass_id_set(struct spu *spu, u64 tclass_id) | ||
94 | { | ||
95 | out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); | ||
96 | } | ||
97 | EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_set); | ||
98 | |||
99 | u64 spu_mfc_tclass_id_get(struct spu *spu) | ||
100 | { | ||
101 | return in_be64(&spu->priv1->mfc_tclass_id_RW); | ||
102 | } | ||
103 | EXPORT_SYMBOL_GPL(spu_mfc_tclass_id_get); | ||
104 | |||
105 | void spu_tlb_invalidate(struct spu *spu) | ||
106 | { | ||
107 | out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); | ||
108 | } | ||
109 | EXPORT_SYMBOL_GPL(spu_tlb_invalidate); | ||
110 | |||
111 | void spu_resource_allocation_groupID_set(struct spu *spu, u64 id) | ||
112 | { | ||
113 | out_be64(&spu->priv1->resource_allocation_groupID_RW, id); | ||
114 | } | ||
115 | EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_set); | ||
116 | |||
117 | u64 spu_resource_allocation_groupID_get(struct spu *spu) | ||
118 | { | ||
119 | return in_be64(&spu->priv1->resource_allocation_groupID_RW); | ||
120 | } | ||
121 | EXPORT_SYMBOL_GPL(spu_resource_allocation_groupID_get); | ||
122 | |||
123 | void spu_resource_allocation_enable_set(struct spu *spu, u64 enable) | ||
124 | { | ||
125 | out_be64(&spu->priv1->resource_allocation_enable_RW, enable); | ||
126 | } | ||
127 | EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_set); | ||
128 | |||
129 | u64 spu_resource_allocation_enable_get(struct spu *spu) | ||
130 | { | ||
131 | return in_be64(&spu->priv1->resource_allocation_enable_RW); | ||
132 | } | ||
133 | EXPORT_SYMBOL_GPL(spu_resource_allocation_enable_get); | ||
diff --git a/arch/powerpc/platforms/cell/spu_priv1_mmio.c b/arch/powerpc/platforms/cell/spu_priv1_mmio.c new file mode 100644 index 000000000000..71b69f0a1a48 --- /dev/null +++ b/arch/powerpc/platforms/cell/spu_priv1_mmio.c | |||
@@ -0,0 +1,159 @@ | |||
1 | /* | ||
2 | * spu hypervisor abstraction for direct hardware access. | ||
3 | * | ||
4 | * (C) Copyright IBM Deutschland Entwicklung GmbH 2005 | ||
5 | * Copyright 2006 Sony Corp. | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; version 2 of the License. | ||
10 | * | ||
11 | * This program is distributed in the hope that it will be useful, | ||
12 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
13 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
14 | * GNU General Public License for more details. | ||
15 | * | ||
16 | * You should have received a copy of the GNU General Public License | ||
17 | * along with this program; if not, write to the Free Software | ||
18 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | ||
19 | */ | ||
20 | |||
21 | #include <linux/module.h> | ||
22 | |||
23 | #include <asm/io.h> | ||
24 | #include <asm/spu.h> | ||
25 | #include <asm/spu_priv1.h> | ||
26 | |||
27 | #include "interrupt.h" | ||
28 | |||
29 | static void int_mask_and(struct spu *spu, int class, u64 mask) | ||
30 | { | ||
31 | u64 old_mask; | ||
32 | |||
33 | old_mask = in_be64(&spu->priv1->int_mask_RW[class]); | ||
34 | out_be64(&spu->priv1->int_mask_RW[class], old_mask & mask); | ||
35 | } | ||
36 | |||
37 | static void int_mask_or(struct spu *spu, int class, u64 mask) | ||
38 | { | ||
39 | u64 old_mask; | ||
40 | |||
41 | old_mask = in_be64(&spu->priv1->int_mask_RW[class]); | ||
42 | out_be64(&spu->priv1->int_mask_RW[class], old_mask | mask); | ||
43 | } | ||
44 | |||
45 | static void int_mask_set(struct spu *spu, int class, u64 mask) | ||
46 | { | ||
47 | out_be64(&spu->priv1->int_mask_RW[class], mask); | ||
48 | } | ||
49 | |||
50 | static u64 int_mask_get(struct spu *spu, int class) | ||
51 | { | ||
52 | return in_be64(&spu->priv1->int_mask_RW[class]); | ||
53 | } | ||
54 | |||
55 | static void int_stat_clear(struct spu *spu, int class, u64 stat) | ||
56 | { | ||
57 | out_be64(&spu->priv1->int_stat_RW[class], stat); | ||
58 | } | ||
59 | |||
60 | static u64 int_stat_get(struct spu *spu, int class) | ||
61 | { | ||
62 | return in_be64(&spu->priv1->int_stat_RW[class]); | ||
63 | } | ||
64 | |||
65 | static void cpu_affinity_set(struct spu *spu, int cpu) | ||
66 | { | ||
67 | u64 target = iic_get_target_id(cpu); | ||
68 | u64 route = target << 48 | target << 32 | target << 16; | ||
69 | out_be64(&spu->priv1->int_route_RW, route); | ||
70 | } | ||
71 | |||
72 | static u64 mfc_dar_get(struct spu *spu) | ||
73 | { | ||
74 | return in_be64(&spu->priv1->mfc_dar_RW); | ||
75 | } | ||
76 | |||
77 | static u64 mfc_dsisr_get(struct spu *spu) | ||
78 | { | ||
79 | return in_be64(&spu->priv1->mfc_dsisr_RW); | ||
80 | } | ||
81 | |||
82 | static void mfc_dsisr_set(struct spu *spu, u64 dsisr) | ||
83 | { | ||
84 | out_be64(&spu->priv1->mfc_dsisr_RW, dsisr); | ||
85 | } | ||
86 | |||
87 | static void mfc_sdr_set(struct spu *spu, u64 sdr) | ||
88 | { | ||
89 | out_be64(&spu->priv1->mfc_sdr_RW, sdr); | ||
90 | } | ||
91 | |||
92 | static void mfc_sr1_set(struct spu *spu, u64 sr1) | ||
93 | { | ||
94 | out_be64(&spu->priv1->mfc_sr1_RW, sr1); | ||
95 | } | ||
96 | |||
97 | static u64 mfc_sr1_get(struct spu *spu) | ||
98 | { | ||
99 | return in_be64(&spu->priv1->mfc_sr1_RW); | ||
100 | } | ||
101 | |||
102 | static void mfc_tclass_id_set(struct spu *spu, u64 tclass_id) | ||
103 | { | ||
104 | out_be64(&spu->priv1->mfc_tclass_id_RW, tclass_id); | ||
105 | } | ||
106 | |||
107 | static u64 mfc_tclass_id_get(struct spu *spu) | ||
108 | { | ||
109 | return in_be64(&spu->priv1->mfc_tclass_id_RW); | ||
110 | } | ||
111 | |||
112 | static void tlb_invalidate(struct spu *spu) | ||
113 | { | ||
114 | out_be64(&spu->priv1->tlb_invalidate_entry_W, 0ul); | ||
115 | } | ||
116 | |||
117 | static void resource_allocation_groupID_set(struct spu *spu, u64 id) | ||
118 | { | ||
119 | out_be64(&spu->priv1->resource_allocation_groupID_RW, id); | ||
120 | } | ||
121 | |||
122 | static u64 resource_allocation_groupID_get(struct spu *spu) | ||
123 | { | ||
124 | return in_be64(&spu->priv1->resource_allocation_groupID_RW); | ||
125 | } | ||
126 | |||
127 | static void resource_allocation_enable_set(struct spu *spu, u64 enable) | ||
128 | { | ||
129 | out_be64(&spu->priv1->resource_allocation_enable_RW, enable); | ||
130 | } | ||
131 | |||
132 | static u64 resource_allocation_enable_get(struct spu *spu) | ||
133 | { | ||
134 | return in_be64(&spu->priv1->resource_allocation_enable_RW); | ||
135 | } | ||
136 | |||
137 | const struct spu_priv1_ops spu_priv1_mmio_ops = | ||
138 | { | ||
139 | .int_mask_and = int_mask_and, | ||
140 | .int_mask_or = int_mask_or, | ||
141 | .int_mask_set = int_mask_set, | ||
142 | .int_mask_get = int_mask_get, | ||
143 | .int_stat_clear = int_stat_clear, | ||
144 | .int_stat_get = int_stat_get, | ||
145 | .cpu_affinity_set = cpu_affinity_set, | ||
146 | .mfc_dar_get = mfc_dar_get, | ||
147 | .mfc_dsisr_get = mfc_dsisr_get, | ||
148 | .mfc_dsisr_set = mfc_dsisr_set, | ||
149 | .mfc_sdr_set = mfc_sdr_set, | ||
150 | .mfc_sr1_set = mfc_sr1_set, | ||
151 | .mfc_sr1_get = mfc_sr1_get, | ||
152 | .mfc_tclass_id_set = mfc_tclass_id_set, | ||
153 | .mfc_tclass_id_get = mfc_tclass_id_get, | ||
154 | .tlb_invalidate = tlb_invalidate, | ||
155 | .resource_allocation_groupID_set = resource_allocation_groupID_set, | ||
156 | .resource_allocation_groupID_get = resource_allocation_groupID_get, | ||
157 | .resource_allocation_enable_set = resource_allocation_enable_set, | ||
158 | .resource_allocation_enable_get = resource_allocation_enable_get, | ||
159 | }; | ||
diff --git a/arch/powerpc/platforms/cell/spufs/Makefile b/arch/powerpc/platforms/cell/spufs/Makefile index a7cddf40e3d9..bb5dc634272c 100644 --- a/arch/powerpc/platforms/cell/spufs/Makefile +++ b/arch/powerpc/platforms/cell/spufs/Makefile | |||
@@ -1,5 +1,7 @@ | |||
1 | obj-y += switch.o | ||
2 | |||
1 | obj-$(CONFIG_SPU_FS) += spufs.o | 3 | obj-$(CONFIG_SPU_FS) += spufs.o |
2 | spufs-y += inode.o file.o context.o switch.o syscalls.o | 4 | spufs-y += inode.o file.o context.o syscalls.o |
3 | spufs-y += sched.o backing_ops.o hw_ops.o run.o | 5 | spufs-y += sched.o backing_ops.o hw_ops.o run.o |
4 | 6 | ||
5 | # Rules to build switch.o with the help of SPU tool chain | 7 | # Rules to build switch.o with the help of SPU tool chain |
@@ -8,11 +10,14 @@ SPU_CC := $(SPU_CROSS)gcc | |||
8 | SPU_AS := $(SPU_CROSS)gcc | 10 | SPU_AS := $(SPU_CROSS)gcc |
9 | SPU_LD := $(SPU_CROSS)ld | 11 | SPU_LD := $(SPU_CROSS)ld |
10 | SPU_OBJCOPY := $(SPU_CROSS)objcopy | 12 | SPU_OBJCOPY := $(SPU_CROSS)objcopy |
11 | SPU_CFLAGS := -O2 -Wall -I$(srctree)/include -I$(objtree)/include2 | 13 | SPU_CFLAGS := -O2 -Wall -I$(srctree)/include \ |
12 | SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include -I$(objtree)/include2 | 14 | -I$(objtree)/include2 -D__KERNEL__ |
15 | SPU_AFLAGS := -c -D__ASSEMBLY__ -I$(srctree)/include \ | ||
16 | -I$(objtree)/include2 -D__KERNEL__ | ||
13 | SPU_LDFLAGS := -N -Ttext=0x0 | 17 | SPU_LDFLAGS := -N -Ttext=0x0 |
14 | 18 | ||
15 | $(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h | 19 | $(obj)/switch.o: $(obj)/spu_save_dump.h $(obj)/spu_restore_dump.h |
20 | clean-files := spu_save_dump.h spu_restore_dump.h | ||
16 | 21 | ||
17 | # Compile SPU files | 22 | # Compile SPU files |
18 | cmd_spu_cc = $(SPU_CC) $(SPU_CFLAGS) -c -o $@ $< | 23 | cmd_spu_cc = $(SPU_CC) $(SPU_CFLAGS) -c -o $@ $< |
@@ -45,7 +50,8 @@ cmd_hexdump = ( \ | |||
45 | echo " * Hex-dump auto generated from $*.c." ; \ | 50 | echo " * Hex-dump auto generated from $*.c." ; \ |
46 | echo " * Do not edit!" ; \ | 51 | echo " * Do not edit!" ; \ |
47 | echo " */" ; \ | 52 | echo " */" ; \ |
48 | echo "static unsigned int $*_code[] __page_aligned = {" ; \ | 53 | echo "static unsigned int $*_code[] " \ |
54 | "__attribute__((__aligned__(128))) = {" ; \ | ||
49 | hexdump -v -e '"0x" 4/1 "%02x" "," "\n"' $< ; \ | 55 | hexdump -v -e '"0x" 4/1 "%02x" "," "\n"' $< ; \ |
50 | echo "};" ; \ | 56 | echo "};" ; \ |
51 | ) > $@ | 57 | ) > $@ |
diff --git a/arch/powerpc/platforms/cell/spufs/context.c b/arch/powerpc/platforms/cell/spufs/context.c index 8bb33abfad17..36439c5e9f2d 100644 --- a/arch/powerpc/platforms/cell/spufs/context.c +++ b/arch/powerpc/platforms/cell/spufs/context.c | |||
@@ -30,7 +30,7 @@ | |||
30 | struct spu_context *alloc_spu_context(void) | 30 | struct spu_context *alloc_spu_context(void) |
31 | { | 31 | { |
32 | struct spu_context *ctx; | 32 | struct spu_context *ctx; |
33 | ctx = kmalloc(sizeof *ctx, GFP_KERNEL); | 33 | ctx = kzalloc(sizeof *ctx, GFP_KERNEL); |
34 | if (!ctx) | 34 | if (!ctx) |
35 | goto out; | 35 | goto out; |
36 | /* Binding to physical processor deferred | 36 | /* Binding to physical processor deferred |
@@ -48,17 +48,7 @@ struct spu_context *alloc_spu_context(void) | |||
48 | init_waitqueue_head(&ctx->wbox_wq); | 48 | init_waitqueue_head(&ctx->wbox_wq); |
49 | init_waitqueue_head(&ctx->stop_wq); | 49 | init_waitqueue_head(&ctx->stop_wq); |
50 | init_waitqueue_head(&ctx->mfc_wq); | 50 | init_waitqueue_head(&ctx->mfc_wq); |
51 | ctx->ibox_fasync = NULL; | ||
52 | ctx->wbox_fasync = NULL; | ||
53 | ctx->mfc_fasync = NULL; | ||
54 | ctx->mfc = NULL; | ||
55 | ctx->tagwait = 0; | ||
56 | ctx->state = SPU_STATE_SAVED; | 51 | ctx->state = SPU_STATE_SAVED; |
57 | ctx->local_store = NULL; | ||
58 | ctx->cntl = NULL; | ||
59 | ctx->signal1 = NULL; | ||
60 | ctx->signal2 = NULL; | ||
61 | ctx->spu = NULL; | ||
62 | ctx->ops = &spu_backing_ops; | 52 | ctx->ops = &spu_backing_ops; |
63 | ctx->owner = get_task_mm(current); | 53 | ctx->owner = get_task_mm(current); |
64 | goto out; | 54 | goto out; |
diff --git a/arch/powerpc/platforms/cell/spufs/file.c b/arch/powerpc/platforms/cell/spufs/file.c index 366185e92667..80c02660e617 100644 --- a/arch/powerpc/platforms/cell/spufs/file.c +++ b/arch/powerpc/platforms/cell/spufs/file.c | |||
@@ -825,6 +825,55 @@ DEFINE_SIMPLE_ATTRIBUTE(spufs_signal2_type, spufs_signal2_type_get, | |||
825 | spufs_signal2_type_set, "%llu"); | 825 | spufs_signal2_type_set, "%llu"); |
826 | 826 | ||
827 | #ifdef CONFIG_SPUFS_MMAP | 827 | #ifdef CONFIG_SPUFS_MMAP |
828 | static struct page *spufs_mss_mmap_nopage(struct vm_area_struct *vma, | ||
829 | unsigned long address, int *type) | ||
830 | { | ||
831 | return spufs_ps_nopage(vma, address, type, 0x0000); | ||
832 | } | ||
833 | |||
834 | static struct vm_operations_struct spufs_mss_mmap_vmops = { | ||
835 | .nopage = spufs_mss_mmap_nopage, | ||
836 | }; | ||
837 | |||
838 | /* | ||
839 | * mmap support for problem state MFC DMA area [0x0000 - 0x0fff]. | ||
840 | * Mapping this area requires that the application have CAP_SYS_RAWIO, | ||
841 | * as these registers require special care when read/writing. | ||
842 | */ | ||
843 | static int spufs_mss_mmap(struct file *file, struct vm_area_struct *vma) | ||
844 | { | ||
845 | if (!(vma->vm_flags & VM_SHARED)) | ||
846 | return -EINVAL; | ||
847 | |||
848 | if (!capable(CAP_SYS_RAWIO)) | ||
849 | return -EPERM; | ||
850 | |||
851 | vma->vm_flags |= VM_RESERVED; | ||
852 | vma->vm_page_prot = __pgprot(pgprot_val(vma->vm_page_prot) | ||
853 | | _PAGE_NO_CACHE); | ||
854 | |||
855 | vma->vm_ops = &spufs_mss_mmap_vmops; | ||
856 | return 0; | ||
857 | } | ||
858 | #endif | ||
859 | |||
860 | static int spufs_mss_open(struct inode *inode, struct file *file) | ||
861 | { | ||
862 | struct spufs_inode_info *i = SPUFS_I(inode); | ||
863 | |||
864 | file->private_data = i->i_ctx; | ||
865 | return nonseekable_open(inode, file); | ||
866 | } | ||
867 | |||
868 | static struct file_operations spufs_mss_fops = { | ||
869 | .open = spufs_mss_open, | ||
870 | #ifdef CONFIG_SPUFS_MMAP | ||
871 | .mmap = spufs_mss_mmap, | ||
872 | #endif | ||
873 | }; | ||
874 | |||
875 | |||
876 | #ifdef CONFIG_SPUFS_MMAP | ||
828 | static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, | 877 | static struct page *spufs_mfc_mmap_nopage(struct vm_area_struct *vma, |
829 | unsigned long address, int *type) | 878 | unsigned long address, int *type) |
830 | { | 879 | { |
@@ -1279,6 +1328,22 @@ static u64 spufs_srr0_get(void *data) | |||
1279 | DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, | 1328 | DEFINE_SIMPLE_ATTRIBUTE(spufs_srr0_ops, spufs_srr0_get, spufs_srr0_set, |
1280 | "%llx\n") | 1329 | "%llx\n") |
1281 | 1330 | ||
1331 | static u64 spufs_id_get(void *data) | ||
1332 | { | ||
1333 | struct spu_context *ctx = data; | ||
1334 | u64 num; | ||
1335 | |||
1336 | spu_acquire(ctx); | ||
1337 | if (ctx->state == SPU_STATE_RUNNABLE) | ||
1338 | num = ctx->spu->number; | ||
1339 | else | ||
1340 | num = (unsigned int)-1; | ||
1341 | spu_release(ctx); | ||
1342 | |||
1343 | return num; | ||
1344 | } | ||
1345 | DEFINE_SIMPLE_ATTRIBUTE(spufs_id_ops, spufs_id_get, 0, "0x%llx\n") | ||
1346 | |||
1282 | struct tree_descr spufs_dir_contents[] = { | 1347 | struct tree_descr spufs_dir_contents[] = { |
1283 | { "mem", &spufs_mem_fops, 0666, }, | 1348 | { "mem", &spufs_mem_fops, 0666, }, |
1284 | { "regs", &spufs_regs_fops, 0666, }, | 1349 | { "regs", &spufs_regs_fops, 0666, }, |
@@ -1292,6 +1357,7 @@ struct tree_descr spufs_dir_contents[] = { | |||
1292 | { "signal2", &spufs_signal2_fops, 0666, }, | 1357 | { "signal2", &spufs_signal2_fops, 0666, }, |
1293 | { "signal1_type", &spufs_signal1_type, 0666, }, | 1358 | { "signal1_type", &spufs_signal1_type, 0666, }, |
1294 | { "signal2_type", &spufs_signal2_type, 0666, }, | 1359 | { "signal2_type", &spufs_signal2_type, 0666, }, |
1360 | { "mss", &spufs_mss_fops, 0666, }, | ||
1295 | { "mfc", &spufs_mfc_fops, 0666, }, | 1361 | { "mfc", &spufs_mfc_fops, 0666, }, |
1296 | { "cntl", &spufs_cntl_fops, 0666, }, | 1362 | { "cntl", &spufs_cntl_fops, 0666, }, |
1297 | { "npc", &spufs_npc_ops, 0666, }, | 1363 | { "npc", &spufs_npc_ops, 0666, }, |
@@ -1301,5 +1367,6 @@ struct tree_descr spufs_dir_contents[] = { | |||
1301 | { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, | 1367 | { "spu_tag_mask", &spufs_spu_tag_mask_ops, 0666, }, |
1302 | { "event_mask", &spufs_event_mask_ops, 0666, }, | 1368 | { "event_mask", &spufs_event_mask_ops, 0666, }, |
1303 | { "srr0", &spufs_srr0_ops, 0666, }, | 1369 | { "srr0", &spufs_srr0_ops, 0666, }, |
1370 | { "phys-id", &spufs_id_ops, 0666, }, | ||
1304 | {}, | 1371 | {}, |
1305 | }; | 1372 | }; |
diff --git a/arch/powerpc/platforms/cell/spufs/hw_ops.c b/arch/powerpc/platforms/cell/spufs/hw_ops.c index a13a8b5a014d..ede2cac46b6d 100644 --- a/arch/powerpc/platforms/cell/spufs/hw_ops.c +++ b/arch/powerpc/platforms/cell/spufs/hw_ops.c | |||
@@ -32,6 +32,7 @@ | |||
32 | 32 | ||
33 | #include <asm/io.h> | 33 | #include <asm/io.h> |
34 | #include <asm/spu.h> | 34 | #include <asm/spu.h> |
35 | #include <asm/spu_priv1.h> | ||
35 | #include <asm/spu_csa.h> | 36 | #include <asm/spu_csa.h> |
36 | #include <asm/mmu_context.h> | 37 | #include <asm/mmu_context.h> |
37 | #include "spufs.h" | 38 | #include "spufs.h" |
diff --git a/arch/powerpc/platforms/cell/spufs/inode.c b/arch/powerpc/platforms/cell/spufs/inode.c index d9554199afa7..7b4572805db9 100644 --- a/arch/powerpc/platforms/cell/spufs/inode.c +++ b/arch/powerpc/platforms/cell/spufs/inode.c | |||
@@ -157,20 +157,12 @@ static void spufs_prune_dir(struct dentry *dir) | |||
157 | mutex_unlock(&dir->d_inode->i_mutex); | 157 | mutex_unlock(&dir->d_inode->i_mutex); |
158 | } | 158 | } |
159 | 159 | ||
160 | /* Caller must hold root->i_mutex */ | ||
160 | static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) | 161 | static int spufs_rmdir(struct inode *root, struct dentry *dir_dentry) |
161 | { | 162 | { |
162 | struct spu_context *ctx; | ||
163 | |||
164 | /* remove all entries */ | 163 | /* remove all entries */ |
165 | mutex_lock(&root->i_mutex); | ||
166 | spufs_prune_dir(dir_dentry); | 164 | spufs_prune_dir(dir_dentry); |
167 | mutex_unlock(&root->i_mutex); | ||
168 | |||
169 | /* We have to give up the mm_struct */ | ||
170 | ctx = SPUFS_I(dir_dentry->d_inode)->i_ctx; | ||
171 | spu_forget(ctx); | ||
172 | 165 | ||
173 | /* XXX Do we need to hold i_mutex here ? */ | ||
174 | return simple_rmdir(root, dir_dentry); | 166 | return simple_rmdir(root, dir_dentry); |
175 | } | 167 | } |
176 | 168 | ||
@@ -199,16 +191,23 @@ out: | |||
199 | 191 | ||
200 | static int spufs_dir_close(struct inode *inode, struct file *file) | 192 | static int spufs_dir_close(struct inode *inode, struct file *file) |
201 | { | 193 | { |
194 | struct spu_context *ctx; | ||
202 | struct inode *dir; | 195 | struct inode *dir; |
203 | struct dentry *dentry; | 196 | struct dentry *dentry; |
204 | int ret; | 197 | int ret; |
205 | 198 | ||
206 | dentry = file->f_dentry; | 199 | dentry = file->f_dentry; |
207 | dir = dentry->d_parent->d_inode; | 200 | dir = dentry->d_parent->d_inode; |
201 | ctx = SPUFS_I(dentry->d_inode)->i_ctx; | ||
208 | 202 | ||
203 | mutex_lock(&dir->i_mutex); | ||
209 | ret = spufs_rmdir(dir, dentry); | 204 | ret = spufs_rmdir(dir, dentry); |
205 | mutex_unlock(&dir->i_mutex); | ||
210 | WARN_ON(ret); | 206 | WARN_ON(ret); |
211 | 207 | ||
208 | /* We have to give up the mm_struct */ | ||
209 | spu_forget(ctx); | ||
210 | |||
212 | return dcache_dir_close(inode, file); | 211 | return dcache_dir_close(inode, file); |
213 | } | 212 | } |
214 | 213 | ||
@@ -305,6 +304,10 @@ long spufs_create_thread(struct nameidata *nd, | |||
305 | nd->dentry != nd->dentry->d_sb->s_root) | 304 | nd->dentry != nd->dentry->d_sb->s_root) |
306 | goto out; | 305 | goto out; |
307 | 306 | ||
307 | /* all flags are reserved */ | ||
308 | if (flags) | ||
309 | goto out; | ||
310 | |||
308 | dentry = lookup_create(nd, 1); | 311 | dentry = lookup_create(nd, 1); |
309 | ret = PTR_ERR(dentry); | 312 | ret = PTR_ERR(dentry); |
310 | if (IS_ERR(dentry)) | 313 | if (IS_ERR(dentry)) |
@@ -324,8 +327,13 @@ long spufs_create_thread(struct nameidata *nd, | |||
324 | * in error path of *_open(). | 327 | * in error path of *_open(). |
325 | */ | 328 | */ |
326 | ret = spufs_context_open(dget(dentry), mntget(nd->mnt)); | 329 | ret = spufs_context_open(dget(dentry), mntget(nd->mnt)); |
327 | if (ret < 0) | 330 | if (ret < 0) { |
328 | spufs_rmdir(nd->dentry->d_inode, dentry); | 331 | WARN_ON(spufs_rmdir(nd->dentry->d_inode, dentry)); |
332 | mutex_unlock(&nd->dentry->d_inode->i_mutex); | ||
333 | spu_forget(SPUFS_I(dentry->d_inode)->i_ctx); | ||
334 | dput(dentry); | ||
335 | goto out; | ||
336 | } | ||
329 | 337 | ||
330 | out_dput: | 338 | out_dput: |
331 | dput(dentry); | 339 | dput(dentry); |
@@ -428,11 +436,11 @@ spufs_fill_super(struct super_block *sb, void *data, int silent) | |||
428 | return spufs_create_root(sb, data); | 436 | return spufs_create_root(sb, data); |
429 | } | 437 | } |
430 | 438 | ||
431 | static struct super_block * | 439 | static int |
432 | spufs_get_sb(struct file_system_type *fstype, int flags, | 440 | spufs_get_sb(struct file_system_type *fstype, int flags, |
433 | const char *name, void *data) | 441 | const char *name, void *data, struct vfsmount *mnt) |
434 | { | 442 | { |
435 | return get_sb_single(fstype, flags, data, spufs_fill_super); | 443 | return get_sb_single(fstype, flags, data, spufs_fill_super, mnt); |
436 | } | 444 | } |
437 | 445 | ||
438 | static struct file_system_type spufs_type = { | 446 | static struct file_system_type spufs_type = { |
diff --git a/arch/powerpc/platforms/cell/spufs/sched.c b/arch/powerpc/platforms/cell/spufs/sched.c index bf652cd77000..3dcc5d8d66b9 100644 --- a/arch/powerpc/platforms/cell/spufs/sched.c +++ b/arch/powerpc/platforms/cell/spufs/sched.c | |||
@@ -43,6 +43,7 @@ | |||
43 | #include <asm/mmu_context.h> | 43 | #include <asm/mmu_context.h> |
44 | #include <asm/spu.h> | 44 | #include <asm/spu.h> |
45 | #include <asm/spu_csa.h> | 45 | #include <asm/spu_csa.h> |
46 | #include <asm/spu_priv1.h> | ||
46 | #include "spufs.h" | 47 | #include "spufs.h" |
47 | 48 | ||
48 | #define SPU_MIN_TIMESLICE (100 * HZ / 1000) | 49 | #define SPU_MIN_TIMESLICE (100 * HZ / 1000) |
@@ -363,7 +364,7 @@ int spu_activate(struct spu_context *ctx, u64 flags) | |||
363 | * We're likely to wait for interrupts on the same | 364 | * We're likely to wait for interrupts on the same |
364 | * CPU that we are now on, so send them here. | 365 | * CPU that we are now on, so send them here. |
365 | */ | 366 | */ |
366 | spu_irq_setaffinity(spu, raw_smp_processor_id()); | 367 | spu_cpu_affinity_set(spu, raw_smp_processor_id()); |
367 | put_active_spu(spu); | 368 | put_active_spu(spu); |
368 | return 0; | 369 | return 0; |
369 | } | 370 | } |
diff --git a/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped b/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped index 1b2355ff7036..15183d209b58 100644 --- a/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped +++ b/arch/powerpc/platforms/cell/spufs/spu_restore_dump.h_shipped | |||
@@ -3,229 +3,901 @@ | |||
3 | * Hex-dump auto generated from spu_restore.c. | 3 | * Hex-dump auto generated from spu_restore.c. |
4 | * Do not edit! | 4 | * Do not edit! |
5 | */ | 5 | */ |
6 | static unsigned int spu_restore_code[] __page_aligned = { | 6 | static unsigned int spu_restore_code[] __attribute__((__aligned__(128))) = { |
7 | 0x40800000, 0x409ff801, 0x24000080, 0x24fd8081, | 7 | 0x40800000, |
8 | 0x1cd80081, 0x33001180, 0x42030003, 0x33800284, | 8 | 0x409ff801, |
9 | 0x1c010204, 0x40200000, 0x40200000, 0x40200000, | 9 | 0x24000080, |
10 | 0x34000190, 0x34004191, 0x34008192, 0x3400c193, | 10 | 0x24fd8081, |
11 | 0x141fc205, 0x23fffd84, 0x1c100183, 0x217ffa85, | 11 | 0x1cd80081, |
12 | 0x3080a000, 0x3080a201, 0x3080a402, 0x3080a603, | 12 | 0x33001180, |
13 | 0x3080a804, 0x3080aa05, 0x3080ac06, 0x3080ae07, | 13 | 0x42030003, |
14 | 0x3080b008, 0x3080b209, 0x3080b40a, 0x3080b60b, | 14 | 0x33800284, |
15 | 0x3080b80c, 0x3080ba0d, 0x3080bc0e, 0x3080be0f, | 15 | 0x1c010204, |
16 | 0x00003ffc, 0x00000000, 0x00000000, 0x00000000, | 16 | 0x40200000, |
17 | 0x01a00182, 0x3ec00083, 0xb0a14103, 0x01a00204, | 17 | 0x40200000, |
18 | 0x3ec10082, 0x4202800e, 0x04000703, 0xb0a14202, | 18 | 0x40200000, |
19 | 0x21a00803, 0x3fbf028d, 0x3f20068d, 0x3fbe0682, | 19 | 0x34000190, |
20 | 0x3fe30102, 0x21a00882, 0x3f82028f, 0x3fe3078f, | 20 | 0x34004191, |
21 | 0x3fbf0784, 0x3f200204, 0x3fbe0204, 0x3fe30204, | 21 | 0x34008192, |
22 | 0x04000203, 0x21a00903, 0x40848002, 0x21a00982, | 22 | 0x3400c193, |
23 | 0x40800003, 0x21a00a03, 0x40802002, 0x21a00a82, | 23 | 0x141fc205, |
24 | 0x21a00083, 0x40800082, 0x21a00b02, 0x10002818, | 24 | 0x23fffd84, |
25 | 0x40a80002, 0x32800007, 0x4207000c, 0x18008208, | 25 | 0x1c100183, |
26 | 0x40a0000b, 0x4080020a, 0x40800709, 0x00200000, | 26 | 0x217ffa85, |
27 | 0x42070002, 0x3ac30384, 0x1cffc489, 0x00200000, | 27 | 0x3080a000, |
28 | 0x18008383, 0x38830382, 0x4cffc486, 0x3ac28185, | 28 | 0x3080a201, |
29 | 0xb0408584, 0x28830382, 0x1c020387, 0x38828182, | 29 | 0x3080a402, |
30 | 0xb0408405, 0x1802c408, 0x28828182, 0x217ff886, | 30 | 0x3080a603, |
31 | 0x04000583, 0x21a00803, 0x3fbe0682, 0x3fe30102, | 31 | 0x3080a804, |
32 | 0x04000106, 0x21a00886, 0x04000603, 0x21a00903, | 32 | 0x3080aa05, |
33 | 0x40803c02, 0x21a00982, 0x40800003, 0x04000184, | 33 | 0x3080ac06, |
34 | 0x21a00a04, 0x40802202, 0x21a00a82, 0x42028005, | 34 | 0x3080ae07, |
35 | 0x34208702, 0x21002282, 0x21a00804, 0x21a00886, | 35 | 0x3080b008, |
36 | 0x3fbf0782, 0x3f200102, 0x3fbe0102, 0x3fe30102, | 36 | 0x3080b209, |
37 | 0x21a00902, 0x40804003, 0x21a00983, 0x21a00a04, | 37 | 0x3080b40a, |
38 | 0x40805a02, 0x21a00a82, 0x40800083, 0x21a00b83, | 38 | 0x3080b60b, |
39 | 0x01a00c02, 0x01a00d83, 0x3420c282, 0x21a00e02, | 39 | 0x3080b80c, |
40 | 0x34210283, 0x21a00f03, 0x34200284, 0x77400200, | 40 | 0x3080ba0d, |
41 | 0x3421c282, 0x21a00702, 0x34218283, 0x21a00083, | 41 | 0x3080bc0e, |
42 | 0x34214282, 0x21a00b02, 0x4200480c, 0x00200000, | 42 | 0x3080be0f, |
43 | 0x1c010286, 0x34220284, 0x34220302, 0x0f608203, | 43 | 0x00003ffc, |
44 | 0x5c024204, 0x3b81810b, 0x42013c02, 0x00200000, | 44 | 0x00000000, |
45 | 0x18008185, 0x38808183, 0x3b814182, 0x21004e84, | 45 | 0x00000000, |
46 | 0x4020007f, 0x35000100, 0x000004e0, 0x000002a0, | 46 | 0x00000000, |
47 | 0x000002e8, 0x00000428, 0x00000360, 0x000002e8, | 47 | 0x01a00182, |
48 | 0x000004a0, 0x00000468, 0x000003c8, 0x00000360, | 48 | 0x3ec00083, |
49 | 0x409ffe02, 0x30801203, 0x40800204, 0x3ec40085, | 49 | 0xb0a14103, |
50 | 0x10009c09, 0x3ac10606, 0xb060c105, 0x4020007f, | 50 | 0x01a00204, |
51 | 0x4020007f, 0x20801203, 0x38810602, 0xb0408586, | 51 | 0x3ec10082, |
52 | 0x28810602, 0x32004180, 0x34204702, 0x21a00382, | 52 | 0x4202800e, |
53 | 0x4020007f, 0x327fdc80, 0x409ffe02, 0x30801203, | 53 | 0x04000703, |
54 | 0x40800204, 0x3ec40087, 0x40800405, 0x00200000, | 54 | 0xb0a14202, |
55 | 0x40800606, 0x3ac10608, 0x3ac14609, 0x3ac1860a, | 55 | 0x21a00803, |
56 | 0xb060c107, 0x20801203, 0x41004003, 0x38810602, | 56 | 0x3fbf028d, |
57 | 0x4020007f, 0xb0408188, 0x4020007f, 0x28810602, | 57 | 0x3f20068d, |
58 | 0x41201002, 0x38814603, 0x10009c09, 0xb060c109, | 58 | 0x3fbe0682, |
59 | 0x4020007f, 0x28814603, 0x41193f83, 0x38818602, | 59 | 0x3fe30102, |
60 | 0x60ffc003, 0xb040818a, 0x28818602, 0x32003080, | 60 | 0x21a00882, |
61 | 0x409ffe02, 0x30801203, 0x40800204, 0x3ec40087, | 61 | 0x3f82028f, |
62 | 0x41201008, 0x10009c14, 0x40800405, 0x3ac10609, | 62 | 0x3fe3078f, |
63 | 0x40800606, 0x3ac1460a, 0xb060c107, 0x3ac1860b, | 63 | 0x3fbf0784, |
64 | 0x20801203, 0x38810602, 0xb0408409, 0x28810602, | 64 | 0x3f200204, |
65 | 0x38814603, 0xb060c40a, 0x4020007f, 0x28814603, | 65 | 0x3fbe0204, |
66 | 0x41193f83, 0x38818602, 0x60ffc003, 0xb040818b, | 66 | 0x3fe30204, |
67 | 0x28818602, 0x32002380, 0x409ffe02, 0x30801204, | 67 | 0x04000203, |
68 | 0x40800205, 0x3ec40083, 0x40800406, 0x3ac14607, | 68 | 0x21a00903, |
69 | 0x3ac18608, 0xb0810103, 0x41004002, 0x20801204, | 69 | 0x40848002, |
70 | 0x4020007f, 0x38814603, 0x10009c0b, 0xb060c107, | 70 | 0x21a00982, |
71 | 0x4020007f, 0x4020007f, 0x28814603, 0x38818602, | 71 | 0x40800003, |
72 | 0x4020007f, 0x4020007f, 0xb0408588, 0x28818602, | 72 | 0x21a00a03, |
73 | 0x4020007f, 0x32001780, 0x409ffe02, 0x1000640e, | 73 | 0x40802002, |
74 | 0x40800204, 0x30801203, 0x40800405, 0x3ec40087, | 74 | 0x21a00a82, |
75 | 0x40800606, 0x3ac10608, 0x3ac14609, 0x3ac1860a, | 75 | 0x21a00083, |
76 | 0xb060c107, 0x20801203, 0x413d8003, 0x38810602, | 76 | 0x40800082, |
77 | 0x4020007f, 0x327fd780, 0x409ffe02, 0x10007f0c, | 77 | 0x21a00b02, |
78 | 0x40800205, 0x30801204, 0x40800406, 0x3ec40083, | 78 | 0x10002818, |
79 | 0x3ac14607, 0x3ac18608, 0xb0810103, 0x413d8002, | 79 | 0x42a00002, |
80 | 0x20801204, 0x38814603, 0x4020007f, 0x327feb80, | 80 | 0x32800007, |
81 | 0x409ffe02, 0x30801203, 0x40800204, 0x3ec40087, | 81 | 0x4207000c, |
82 | 0x40800405, 0x1000650a, 0x40800606, 0x3ac10608, | 82 | 0x18008208, |
83 | 0x3ac14609, 0x3ac1860a, 0xb060c107, 0x20801203, | 83 | 0x40a0000b, |
84 | 0x38810602, 0xb0408588, 0x4020007f, 0x327fc980, | 84 | 0x4080020a, |
85 | 0x00400000, 0x40800003, 0x4020007f, 0x35000000, | 85 | 0x40800709, |
86 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 86 | 0x00200000, |
87 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 87 | 0x42070002, |
88 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 88 | 0x3ac30384, |
89 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 89 | 0x1cffc489, |
90 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 90 | 0x00200000, |
91 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 91 | 0x18008383, |
92 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 92 | 0x38830382, |
93 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 93 | 0x4cffc486, |
94 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 94 | 0x3ac28185, |
95 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 95 | 0xb0408584, |
96 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 96 | 0x28830382, |
97 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 97 | 0x1c020387, |
98 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 98 | 0x38828182, |
99 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 99 | 0xb0408405, |
100 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 100 | 0x1802c408, |
101 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 101 | 0x28828182, |
102 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 102 | 0x217ff886, |
103 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 103 | 0x04000583, |
104 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 104 | 0x21a00803, |
105 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 105 | 0x3fbe0682, |
106 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 106 | 0x3fe30102, |
107 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 107 | 0x04000106, |
108 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 108 | 0x21a00886, |
109 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 109 | 0x04000603, |
110 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 110 | 0x21a00903, |
111 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 111 | 0x40803c02, |
112 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 112 | 0x21a00982, |
113 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 113 | 0x40800003, |
114 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 114 | 0x04000184, |
115 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 115 | 0x21a00a04, |
116 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 116 | 0x40802202, |
117 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 117 | 0x21a00a82, |
118 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 118 | 0x42028005, |
119 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 119 | 0x34208702, |
120 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 120 | 0x21002282, |
121 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 121 | 0x21a00804, |
122 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 122 | 0x21a00886, |
123 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 123 | 0x3fbf0782, |
124 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 124 | 0x3f200102, |
125 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 125 | 0x3fbe0102, |
126 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 126 | 0x3fe30102, |
127 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 127 | 0x21a00902, |
128 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 128 | 0x40804003, |
129 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 129 | 0x21a00983, |
130 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 130 | 0x21a00a04, |
131 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 131 | 0x40805a02, |
132 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 132 | 0x21a00a82, |
133 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 133 | 0x40800083, |
134 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 134 | 0x21a00b83, |
135 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 135 | 0x01a00c02, |
136 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 136 | 0x01a00d83, |
137 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 137 | 0x3420c282, |
138 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 138 | 0x21a00e02, |
139 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 139 | 0x34210283, |
140 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 140 | 0x21a00f03, |
141 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 141 | 0x34200284, |
142 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 142 | 0x77400200, |
143 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 143 | 0x3421c282, |
144 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 144 | 0x21a00702, |
145 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 145 | 0x34218283, |
146 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 146 | 0x21a00083, |
147 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 147 | 0x34214282, |
148 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 148 | 0x21a00b02, |
149 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 149 | 0x4200480c, |
150 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 150 | 0x00200000, |
151 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 151 | 0x1c010286, |
152 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 152 | 0x34220284, |
153 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 153 | 0x34220302, |
154 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 154 | 0x0f608203, |
155 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 155 | 0x5c024204, |
156 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 156 | 0x3b81810b, |
157 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 157 | 0x42013c02, |
158 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 158 | 0x00200000, |
159 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 159 | 0x18008185, |
160 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 160 | 0x38808183, |
161 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 161 | 0x3b814182, |
162 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 162 | 0x21004e84, |
163 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 163 | 0x4020007f, |
164 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 164 | 0x35000100, |
165 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 165 | 0x000004e0, |
166 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 166 | 0x000002a0, |
167 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 167 | 0x000002e8, |
168 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 168 | 0x00000428, |
169 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 169 | 0x00000360, |
170 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 170 | 0x000002e8, |
171 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 171 | 0x000004a0, |
172 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 172 | 0x00000468, |
173 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 173 | 0x000003c8, |
174 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 174 | 0x00000360, |
175 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 175 | 0x409ffe02, |
176 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 176 | 0x30801203, |
177 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 177 | 0x40800204, |
178 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 178 | 0x3ec40085, |
179 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 179 | 0x10009c09, |
180 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 180 | 0x3ac10606, |
181 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 181 | 0xb060c105, |
182 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 182 | 0x4020007f, |
183 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 183 | 0x4020007f, |
184 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 184 | 0x20801203, |
185 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 185 | 0x38810602, |
186 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 186 | 0xb0408586, |
187 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 187 | 0x28810602, |
188 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 188 | 0x32004180, |
189 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 189 | 0x34204702, |
190 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 190 | 0x21a00382, |
191 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 191 | 0x4020007f, |
192 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 192 | 0x327fdc80, |
193 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 193 | 0x409ffe02, |
194 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 194 | 0x30801203, |
195 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 195 | 0x40800204, |
196 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 196 | 0x3ec40087, |
197 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 197 | 0x40800405, |
198 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 198 | 0x00200000, |
199 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 199 | 0x40800606, |
200 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 200 | 0x3ac10608, |
201 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 201 | 0x3ac14609, |
202 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 202 | 0x3ac1860a, |
203 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 203 | 0xb060c107, |
204 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 204 | 0x20801203, |
205 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 205 | 0x41004003, |
206 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 206 | 0x38810602, |
207 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 207 | 0x4020007f, |
208 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 208 | 0xb0408188, |
209 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 209 | 0x4020007f, |
210 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 210 | 0x28810602, |
211 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 211 | 0x41201002, |
212 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 212 | 0x38814603, |
213 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 213 | 0x10009c09, |
214 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 214 | 0xb060c109, |
215 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 215 | 0x4020007f, |
216 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 216 | 0x28814603, |
217 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 217 | 0x41193f83, |
218 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 218 | 0x38818602, |
219 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 219 | 0x60ffc003, |
220 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 220 | 0xb040818a, |
221 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 221 | 0x28818602, |
222 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 222 | 0x32003080, |
223 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 223 | 0x409ffe02, |
224 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 224 | 0x30801203, |
225 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 225 | 0x40800204, |
226 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 226 | 0x3ec40087, |
227 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 227 | 0x41201008, |
228 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 228 | 0x10009c14, |
229 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 229 | 0x40800405, |
230 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 230 | 0x3ac10609, |
231 | 0x40800606, | ||
232 | 0x3ac1460a, | ||
233 | 0xb060c107, | ||
234 | 0x3ac1860b, | ||
235 | 0x20801203, | ||
236 | 0x38810602, | ||
237 | 0xb0408409, | ||
238 | 0x28810602, | ||
239 | 0x38814603, | ||
240 | 0xb060c40a, | ||
241 | 0x4020007f, | ||
242 | 0x28814603, | ||
243 | 0x41193f83, | ||
244 | 0x38818602, | ||
245 | 0x60ffc003, | ||
246 | 0xb040818b, | ||
247 | 0x28818602, | ||
248 | 0x32002380, | ||
249 | 0x409ffe02, | ||
250 | 0x30801204, | ||
251 | 0x40800205, | ||
252 | 0x3ec40083, | ||
253 | 0x40800406, | ||
254 | 0x3ac14607, | ||
255 | 0x3ac18608, | ||
256 | 0xb0810103, | ||
257 | 0x41004002, | ||
258 | 0x20801204, | ||
259 | 0x4020007f, | ||
260 | 0x38814603, | ||
261 | 0x10009c0b, | ||
262 | 0xb060c107, | ||
263 | 0x4020007f, | ||
264 | 0x4020007f, | ||
265 | 0x28814603, | ||
266 | 0x38818602, | ||
267 | 0x4020007f, | ||
268 | 0x4020007f, | ||
269 | 0xb0408588, | ||
270 | 0x28818602, | ||
271 | 0x4020007f, | ||
272 | 0x32001780, | ||
273 | 0x409ffe02, | ||
274 | 0x1000640e, | ||
275 | 0x40800204, | ||
276 | 0x30801203, | ||
277 | 0x40800405, | ||
278 | 0x3ec40087, | ||
279 | 0x40800606, | ||
280 | 0x3ac10608, | ||
281 | 0x3ac14609, | ||
282 | 0x3ac1860a, | ||
283 | 0xb060c107, | ||
284 | 0x20801203, | ||
285 | 0x413d8003, | ||
286 | 0x38810602, | ||
287 | 0x4020007f, | ||
288 | 0x327fd780, | ||
289 | 0x409ffe02, | ||
290 | 0x10007f0c, | ||
291 | 0x40800205, | ||
292 | 0x30801204, | ||
293 | 0x40800406, | ||
294 | 0x3ec40083, | ||
295 | 0x3ac14607, | ||
296 | 0x3ac18608, | ||
297 | 0xb0810103, | ||
298 | 0x413d8002, | ||
299 | 0x20801204, | ||
300 | 0x38814603, | ||
301 | 0x4020007f, | ||
302 | 0x327feb80, | ||
303 | 0x409ffe02, | ||
304 | 0x30801203, | ||
305 | 0x40800204, | ||
306 | 0x3ec40087, | ||
307 | 0x40800405, | ||
308 | 0x1000650a, | ||
309 | 0x40800606, | ||
310 | 0x3ac10608, | ||
311 | 0x3ac14609, | ||
312 | 0x3ac1860a, | ||
313 | 0xb060c107, | ||
314 | 0x20801203, | ||
315 | 0x38810602, | ||
316 | 0xb0408588, | ||
317 | 0x4020007f, | ||
318 | 0x327fc980, | ||
319 | 0x00400000, | ||
320 | 0x40800003, | ||
321 | 0x4020007f, | ||
322 | 0x35000000, | ||
323 | 0x00000000, | ||
324 | 0x00000000, | ||
325 | 0x00000000, | ||
326 | 0x00000000, | ||
327 | 0x00000000, | ||
328 | 0x00000000, | ||
329 | 0x00000000, | ||
330 | 0x00000000, | ||
331 | 0x00000000, | ||
332 | 0x00000000, | ||
333 | 0x00000000, | ||
334 | 0x00000000, | ||
335 | 0x00000000, | ||
336 | 0x00000000, | ||
337 | 0x00000000, | ||
338 | 0x00000000, | ||
339 | 0x00000000, | ||
340 | 0x00000000, | ||
341 | 0x00000000, | ||
342 | 0x00000000, | ||
343 | 0x00000000, | ||
344 | 0x00000000, | ||
345 | 0x00000000, | ||
346 | 0x00000000, | ||
347 | 0x00000000, | ||
348 | 0x00000000, | ||
349 | 0x00000000, | ||
350 | 0x00000000, | ||
351 | 0x00000000, | ||
352 | 0x00000000, | ||
353 | 0x00000000, | ||
354 | 0x00000000, | ||
355 | 0x00000000, | ||
356 | 0x00000000, | ||
357 | 0x00000000, | ||
358 | 0x00000000, | ||
359 | 0x00000000, | ||
360 | 0x00000000, | ||
361 | 0x00000000, | ||
362 | 0x00000000, | ||
363 | 0x00000000, | ||
364 | 0x00000000, | ||
365 | 0x00000000, | ||
366 | 0x00000000, | ||
367 | 0x00000000, | ||
368 | 0x00000000, | ||
369 | 0x00000000, | ||
370 | 0x00000000, | ||
371 | 0x00000000, | ||
372 | 0x00000000, | ||
373 | 0x00000000, | ||
374 | 0x00000000, | ||
375 | 0x00000000, | ||
376 | 0x00000000, | ||
377 | 0x00000000, | ||
378 | 0x00000000, | ||
379 | 0x00000000, | ||
380 | 0x00000000, | ||
381 | 0x00000000, | ||
382 | 0x00000000, | ||
383 | 0x00000000, | ||
384 | 0x00000000, | ||
385 | 0x00000000, | ||
386 | 0x00000000, | ||
387 | 0x00000000, | ||
388 | 0x00000000, | ||
389 | 0x00000000, | ||
390 | 0x00000000, | ||
391 | 0x00000000, | ||
392 | 0x00000000, | ||
393 | 0x00000000, | ||
394 | 0x00000000, | ||
395 | 0x00000000, | ||
396 | 0x00000000, | ||
397 | 0x00000000, | ||
398 | 0x00000000, | ||
399 | 0x00000000, | ||
400 | 0x00000000, | ||
401 | 0x00000000, | ||
402 | 0x00000000, | ||
403 | 0x00000000, | ||
404 | 0x00000000, | ||
405 | 0x00000000, | ||
406 | 0x00000000, | ||
407 | 0x00000000, | ||
408 | 0x00000000, | ||
409 | 0x00000000, | ||
410 | 0x00000000, | ||
411 | 0x00000000, | ||
412 | 0x00000000, | ||
413 | 0x00000000, | ||
414 | 0x00000000, | ||
415 | 0x00000000, | ||
416 | 0x00000000, | ||
417 | 0x00000000, | ||
418 | 0x00000000, | ||
419 | 0x00000000, | ||
420 | 0x00000000, | ||
421 | 0x00000000, | ||
422 | 0x00000000, | ||
423 | 0x00000000, | ||
424 | 0x00000000, | ||
425 | 0x00000000, | ||
426 | 0x00000000, | ||
427 | 0x00000000, | ||
428 | 0x00000000, | ||
429 | 0x00000000, | ||
430 | 0x00000000, | ||
431 | 0x00000000, | ||
432 | 0x00000000, | ||
433 | 0x00000000, | ||
434 | 0x00000000, | ||
435 | 0x00000000, | ||
436 | 0x00000000, | ||
437 | 0x00000000, | ||
438 | 0x00000000, | ||
439 | 0x00000000, | ||
440 | 0x00000000, | ||
441 | 0x00000000, | ||
442 | 0x00000000, | ||
443 | 0x00000000, | ||
444 | 0x00000000, | ||
445 | 0x00000000, | ||
446 | 0x00000000, | ||
447 | 0x00000000, | ||
448 | 0x00000000, | ||
449 | 0x00000000, | ||
450 | 0x00000000, | ||
451 | 0x00000000, | ||
452 | 0x00000000, | ||
453 | 0x00000000, | ||
454 | 0x00000000, | ||
455 | 0x00000000, | ||
456 | 0x00000000, | ||
457 | 0x00000000, | ||
458 | 0x00000000, | ||
459 | 0x00000000, | ||
460 | 0x00000000, | ||
461 | 0x00000000, | ||
462 | 0x00000000, | ||
463 | 0x00000000, | ||
464 | 0x00000000, | ||
465 | 0x00000000, | ||
466 | 0x00000000, | ||
467 | 0x00000000, | ||
468 | 0x00000000, | ||
469 | 0x00000000, | ||
470 | 0x00000000, | ||
471 | 0x00000000, | ||
472 | 0x00000000, | ||
473 | 0x00000000, | ||
474 | 0x00000000, | ||
475 | 0x00000000, | ||
476 | 0x00000000, | ||
477 | 0x00000000, | ||
478 | 0x00000000, | ||
479 | 0x00000000, | ||
480 | 0x00000000, | ||
481 | 0x00000000, | ||
482 | 0x00000000, | ||
483 | 0x00000000, | ||
484 | 0x00000000, | ||
485 | 0x00000000, | ||
486 | 0x00000000, | ||
487 | 0x00000000, | ||
488 | 0x00000000, | ||
489 | 0x00000000, | ||
490 | 0x00000000, | ||
491 | 0x00000000, | ||
492 | 0x00000000, | ||
493 | 0x00000000, | ||
494 | 0x00000000, | ||
495 | 0x00000000, | ||
496 | 0x00000000, | ||
497 | 0x00000000, | ||
498 | 0x00000000, | ||
499 | 0x00000000, | ||
500 | 0x00000000, | ||
501 | 0x00000000, | ||
502 | 0x00000000, | ||
503 | 0x00000000, | ||
504 | 0x00000000, | ||
505 | 0x00000000, | ||
506 | 0x00000000, | ||
507 | 0x00000000, | ||
508 | 0x00000000, | ||
509 | 0x00000000, | ||
510 | 0x00000000, | ||
511 | 0x00000000, | ||
512 | 0x00000000, | ||
513 | 0x00000000, | ||
514 | 0x00000000, | ||
515 | 0x00000000, | ||
516 | 0x00000000, | ||
517 | 0x00000000, | ||
518 | 0x00000000, | ||
519 | 0x00000000, | ||
520 | 0x00000000, | ||
521 | 0x00000000, | ||
522 | 0x00000000, | ||
523 | 0x00000000, | ||
524 | 0x00000000, | ||
525 | 0x00000000, | ||
526 | 0x00000000, | ||
527 | 0x00000000, | ||
528 | 0x00000000, | ||
529 | 0x00000000, | ||
530 | 0x00000000, | ||
531 | 0x00000000, | ||
532 | 0x00000000, | ||
533 | 0x00000000, | ||
534 | 0x00000000, | ||
535 | 0x00000000, | ||
536 | 0x00000000, | ||
537 | 0x00000000, | ||
538 | 0x00000000, | ||
539 | 0x00000000, | ||
540 | 0x00000000, | ||
541 | 0x00000000, | ||
542 | 0x00000000, | ||
543 | 0x00000000, | ||
544 | 0x00000000, | ||
545 | 0x00000000, | ||
546 | 0x00000000, | ||
547 | 0x00000000, | ||
548 | 0x00000000, | ||
549 | 0x00000000, | ||
550 | 0x00000000, | ||
551 | 0x00000000, | ||
552 | 0x00000000, | ||
553 | 0x00000000, | ||
554 | 0x00000000, | ||
555 | 0x00000000, | ||
556 | 0x00000000, | ||
557 | 0x00000000, | ||
558 | 0x00000000, | ||
559 | 0x00000000, | ||
560 | 0x00000000, | ||
561 | 0x00000000, | ||
562 | 0x00000000, | ||
563 | 0x00000000, | ||
564 | 0x00000000, | ||
565 | 0x00000000, | ||
566 | 0x00000000, | ||
567 | 0x00000000, | ||
568 | 0x00000000, | ||
569 | 0x00000000, | ||
570 | 0x00000000, | ||
571 | 0x00000000, | ||
572 | 0x00000000, | ||
573 | 0x00000000, | ||
574 | 0x00000000, | ||
575 | 0x00000000, | ||
576 | 0x00000000, | ||
577 | 0x00000000, | ||
578 | 0x00000000, | ||
579 | 0x00000000, | ||
580 | 0x00000000, | ||
581 | 0x00000000, | ||
582 | 0x00000000, | ||
583 | 0x00000000, | ||
584 | 0x00000000, | ||
585 | 0x00000000, | ||
586 | 0x00000000, | ||
587 | 0x00000000, | ||
588 | 0x00000000, | ||
589 | 0x00000000, | ||
590 | 0x00000000, | ||
591 | 0x00000000, | ||
592 | 0x00000000, | ||
593 | 0x00000000, | ||
594 | 0x00000000, | ||
595 | 0x00000000, | ||
596 | 0x00000000, | ||
597 | 0x00000000, | ||
598 | 0x00000000, | ||
599 | 0x00000000, | ||
600 | 0x00000000, | ||
601 | 0x00000000, | ||
602 | 0x00000000, | ||
603 | 0x00000000, | ||
604 | 0x00000000, | ||
605 | 0x00000000, | ||
606 | 0x00000000, | ||
607 | 0x00000000, | ||
608 | 0x00000000, | ||
609 | 0x00000000, | ||
610 | 0x00000000, | ||
611 | 0x00000000, | ||
612 | 0x00000000, | ||
613 | 0x00000000, | ||
614 | 0x00000000, | ||
615 | 0x00000000, | ||
616 | 0x00000000, | ||
617 | 0x00000000, | ||
618 | 0x00000000, | ||
619 | 0x00000000, | ||
620 | 0x00000000, | ||
621 | 0x00000000, | ||
622 | 0x00000000, | ||
623 | 0x00000000, | ||
624 | 0x00000000, | ||
625 | 0x00000000, | ||
626 | 0x00000000, | ||
627 | 0x00000000, | ||
628 | 0x00000000, | ||
629 | 0x00000000, | ||
630 | 0x00000000, | ||
631 | 0x00000000, | ||
632 | 0x00000000, | ||
633 | 0x00000000, | ||
634 | 0x00000000, | ||
635 | 0x00000000, | ||
636 | 0x00000000, | ||
637 | 0x00000000, | ||
638 | 0x00000000, | ||
639 | 0x00000000, | ||
640 | 0x00000000, | ||
641 | 0x00000000, | ||
642 | 0x00000000, | ||
643 | 0x00000000, | ||
644 | 0x00000000, | ||
645 | 0x00000000, | ||
646 | 0x00000000, | ||
647 | 0x00000000, | ||
648 | 0x00000000, | ||
649 | 0x00000000, | ||
650 | 0x00000000, | ||
651 | 0x00000000, | ||
652 | 0x00000000, | ||
653 | 0x00000000, | ||
654 | 0x00000000, | ||
655 | 0x00000000, | ||
656 | 0x00000000, | ||
657 | 0x00000000, | ||
658 | 0x00000000, | ||
659 | 0x00000000, | ||
660 | 0x00000000, | ||
661 | 0x00000000, | ||
662 | 0x00000000, | ||
663 | 0x00000000, | ||
664 | 0x00000000, | ||
665 | 0x00000000, | ||
666 | 0x00000000, | ||
667 | 0x00000000, | ||
668 | 0x00000000, | ||
669 | 0x00000000, | ||
670 | 0x00000000, | ||
671 | 0x00000000, | ||
672 | 0x00000000, | ||
673 | 0x00000000, | ||
674 | 0x00000000, | ||
675 | 0x00000000, | ||
676 | 0x00000000, | ||
677 | 0x00000000, | ||
678 | 0x00000000, | ||
679 | 0x00000000, | ||
680 | 0x00000000, | ||
681 | 0x00000000, | ||
682 | 0x00000000, | ||
683 | 0x00000000, | ||
684 | 0x00000000, | ||
685 | 0x00000000, | ||
686 | 0x00000000, | ||
687 | 0x00000000, | ||
688 | 0x00000000, | ||
689 | 0x00000000, | ||
690 | 0x00000000, | ||
691 | 0x00000000, | ||
692 | 0x00000000, | ||
693 | 0x00000000, | ||
694 | 0x00000000, | ||
695 | 0x00000000, | ||
696 | 0x00000000, | ||
697 | 0x00000000, | ||
698 | 0x00000000, | ||
699 | 0x00000000, | ||
700 | 0x00000000, | ||
701 | 0x00000000, | ||
702 | 0x00000000, | ||
703 | 0x00000000, | ||
704 | 0x00000000, | ||
705 | 0x00000000, | ||
706 | 0x00000000, | ||
707 | 0x00000000, | ||
708 | 0x00000000, | ||
709 | 0x00000000, | ||
710 | 0x00000000, | ||
711 | 0x00000000, | ||
712 | 0x00000000, | ||
713 | 0x00000000, | ||
714 | 0x00000000, | ||
715 | 0x00000000, | ||
716 | 0x00000000, | ||
717 | 0x00000000, | ||
718 | 0x00000000, | ||
719 | 0x00000000, | ||
720 | 0x00000000, | ||
721 | 0x00000000, | ||
722 | 0x00000000, | ||
723 | 0x00000000, | ||
724 | 0x00000000, | ||
725 | 0x00000000, | ||
726 | 0x00000000, | ||
727 | 0x00000000, | ||
728 | 0x00000000, | ||
729 | 0x00000000, | ||
730 | 0x00000000, | ||
731 | 0x00000000, | ||
732 | 0x00000000, | ||
733 | 0x00000000, | ||
734 | 0x00000000, | ||
735 | 0x00000000, | ||
736 | 0x00000000, | ||
737 | 0x00000000, | ||
738 | 0x00000000, | ||
739 | 0x00000000, | ||
740 | 0x00000000, | ||
741 | 0x00000000, | ||
742 | 0x00000000, | ||
743 | 0x00000000, | ||
744 | 0x00000000, | ||
745 | 0x00000000, | ||
746 | 0x00000000, | ||
747 | 0x00000000, | ||
748 | 0x00000000, | ||
749 | 0x00000000, | ||
750 | 0x00000000, | ||
751 | 0x00000000, | ||
752 | 0x00000000, | ||
753 | 0x00000000, | ||
754 | 0x00000000, | ||
755 | 0x00000000, | ||
756 | 0x00000000, | ||
757 | 0x00000000, | ||
758 | 0x00000000, | ||
759 | 0x00000000, | ||
760 | 0x00000000, | ||
761 | 0x00000000, | ||
762 | 0x00000000, | ||
763 | 0x00000000, | ||
764 | 0x00000000, | ||
765 | 0x00000000, | ||
766 | 0x00000000, | ||
767 | 0x00000000, | ||
768 | 0x00000000, | ||
769 | 0x00000000, | ||
770 | 0x00000000, | ||
771 | 0x00000000, | ||
772 | 0x00000000, | ||
773 | 0x00000000, | ||
774 | 0x00000000, | ||
775 | 0x00000000, | ||
776 | 0x00000000, | ||
777 | 0x00000000, | ||
778 | 0x00000000, | ||
779 | 0x00000000, | ||
780 | 0x00000000, | ||
781 | 0x00000000, | ||
782 | 0x00000000, | ||
783 | 0x00000000, | ||
784 | 0x00000000, | ||
785 | 0x00000000, | ||
786 | 0x00000000, | ||
787 | 0x00000000, | ||
788 | 0x00000000, | ||
789 | 0x00000000, | ||
790 | 0x00000000, | ||
791 | 0x00000000, | ||
792 | 0x00000000, | ||
793 | 0x00000000, | ||
794 | 0x00000000, | ||
795 | 0x00000000, | ||
796 | 0x00000000, | ||
797 | 0x00000000, | ||
798 | 0x00000000, | ||
799 | 0x00000000, | ||
800 | 0x00000000, | ||
801 | 0x00000000, | ||
802 | 0x00000000, | ||
803 | 0x00000000, | ||
804 | 0x00000000, | ||
805 | 0x00000000, | ||
806 | 0x00000000, | ||
807 | 0x00000000, | ||
808 | 0x00000000, | ||
809 | 0x00000000, | ||
810 | 0x00000000, | ||
811 | 0x00000000, | ||
812 | 0x00000000, | ||
813 | 0x00000000, | ||
814 | 0x00000000, | ||
815 | 0x00000000, | ||
816 | 0x00000000, | ||
817 | 0x00000000, | ||
818 | 0x00000000, | ||
819 | 0x00000000, | ||
820 | 0x00000000, | ||
821 | 0x00000000, | ||
822 | 0x00000000, | ||
823 | 0x00000000, | ||
824 | 0x00000000, | ||
825 | 0x00000000, | ||
826 | 0x00000000, | ||
827 | 0x00000000, | ||
828 | 0x00000000, | ||
829 | 0x00000000, | ||
830 | 0x00000000, | ||
831 | 0x00000000, | ||
832 | 0x00000000, | ||
833 | 0x00000000, | ||
834 | 0x00000000, | ||
835 | 0x00000000, | ||
836 | 0x00000000, | ||
837 | 0x00000000, | ||
838 | 0x00000000, | ||
839 | 0x00000000, | ||
840 | 0x00000000, | ||
841 | 0x00000000, | ||
842 | 0x00000000, | ||
843 | 0x00000000, | ||
844 | 0x00000000, | ||
845 | 0x00000000, | ||
846 | 0x00000000, | ||
847 | 0x00000000, | ||
848 | 0x00000000, | ||
849 | 0x00000000, | ||
850 | 0x00000000, | ||
851 | 0x00000000, | ||
852 | 0x00000000, | ||
853 | 0x00000000, | ||
854 | 0x00000000, | ||
855 | 0x00000000, | ||
856 | 0x00000000, | ||
857 | 0x00000000, | ||
858 | 0x00000000, | ||
859 | 0x00000000, | ||
860 | 0x00000000, | ||
861 | 0x00000000, | ||
862 | 0x00000000, | ||
863 | 0x00000000, | ||
864 | 0x00000000, | ||
865 | 0x00000000, | ||
866 | 0x00000000, | ||
867 | 0x00000000, | ||
868 | 0x00000000, | ||
869 | 0x00000000, | ||
870 | 0x00000000, | ||
871 | 0x00000000, | ||
872 | 0x00000000, | ||
873 | 0x00000000, | ||
874 | 0x00000000, | ||
875 | 0x00000000, | ||
876 | 0x00000000, | ||
877 | 0x00000000, | ||
878 | 0x00000000, | ||
879 | 0x00000000, | ||
880 | 0x00000000, | ||
881 | 0x00000000, | ||
882 | 0x00000000, | ||
883 | 0x00000000, | ||
884 | 0x00000000, | ||
885 | 0x00000000, | ||
886 | 0x00000000, | ||
887 | 0x00000000, | ||
888 | 0x00000000, | ||
889 | 0x00000000, | ||
890 | 0x00000000, | ||
891 | 0x00000000, | ||
892 | 0x00000000, | ||
893 | 0x00000000, | ||
894 | 0x00000000, | ||
895 | 0x00000000, | ||
896 | 0x00000000, | ||
897 | 0x00000000, | ||
898 | 0x00000000, | ||
899 | 0x00000000, | ||
900 | 0x00000000, | ||
901 | 0x00000000, | ||
902 | 0x00000000, | ||
231 | }; | 903 | }; |
diff --git a/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped b/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped index 39e54003f1df..b9f81ac8a632 100644 --- a/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped +++ b/arch/powerpc/platforms/cell/spufs/spu_save_dump.h_shipped | |||
@@ -3,189 +3,741 @@ | |||
3 | * Hex-dump auto generated from spu_save.c. | 3 | * Hex-dump auto generated from spu_save.c. |
4 | * Do not edit! | 4 | * Do not edit! |
5 | */ | 5 | */ |
6 | static unsigned int spu_save_code[] __page_aligned = { | 6 | static unsigned int spu_save_code[] __attribute__((__aligned__(128))) = { |
7 | 0x20805000, 0x20805201, 0x20805402, 0x20805603, | 7 | 0x20805000, |
8 | 0x20805804, 0x20805a05, 0x20805c06, 0x20805e07, | 8 | 0x20805201, |
9 | 0x20806008, 0x20806209, 0x2080640a, 0x2080660b, | 9 | 0x20805402, |
10 | 0x2080680c, 0x20806a0d, 0x20806c0e, 0x20806e0f, | 10 | 0x20805603, |
11 | 0x4201c003, 0x33800184, 0x1c010204, 0x40200000, | 11 | 0x20805804, |
12 | 0x24000190, 0x24004191, 0x24008192, 0x2400c193, | 12 | 0x20805a05, |
13 | 0x141fc205, 0x23fffd84, 0x1c100183, 0x217ffb85, | 13 | 0x20805c06, |
14 | 0x40800000, 0x409ff801, 0x24000080, 0x24fd8081, | 14 | 0x20805e07, |
15 | 0x1cd80081, 0x33000180, 0x00000000, 0x00000000, | 15 | 0x20806008, |
16 | 0x01a00182, 0x3ec00083, 0xb1c38103, 0x01a00204, | 16 | 0x20806209, |
17 | 0x3ec10082, 0x4201400d, 0xb1c38202, 0x01a00583, | 17 | 0x2080640a, |
18 | 0x34218682, 0x3ed80684, 0xb0408184, 0x24218682, | 18 | 0x2080660b, |
19 | 0x01a00603, 0x00200000, 0x34214682, 0x3ed40684, | 19 | 0x2080680c, |
20 | 0xb0408184, 0x40800003, 0x24214682, 0x21a00083, | 20 | 0x20806a0d, |
21 | 0x40800082, 0x21a00b02, 0x4020007f, 0x1000251e, | 21 | 0x20806c0e, |
22 | 0x40a80002, 0x32800008, 0x4205c00c, 0x00200000, | 22 | 0x20806e0f, |
23 | 0x40a0000b, 0x3f82070f, 0x4080020a, 0x40800709, | 23 | 0x4201c003, |
24 | 0x3fe3078f, 0x3fbf0783, 0x3f200183, 0x3fbe0183, | 24 | 0x33800184, |
25 | 0x3fe30187, 0x18008387, 0x4205c002, 0x3ac30404, | 25 | 0x1c010204, |
26 | 0x1cffc489, 0x00200000, 0x18008403, 0x38830402, | 26 | 0x40200000, |
27 | 0x4cffc486, 0x3ac28185, 0xb0408584, 0x28830402, | 27 | 0x24000190, |
28 | 0x1c020408, 0x38828182, 0xb0408385, 0x1802c387, | 28 | 0x24004191, |
29 | 0x28828182, 0x217ff886, 0x04000582, 0x32800007, | 29 | 0x24008192, |
30 | 0x21a00802, 0x3fbf0705, 0x3f200285, 0x3fbe0285, | 30 | 0x2400c193, |
31 | 0x3fe30285, 0x21a00885, 0x04000603, 0x21a00903, | 31 | 0x141fc205, |
32 | 0x40803c02, 0x21a00982, 0x04000386, 0x21a00a06, | 32 | 0x23fffd84, |
33 | 0x40801202, 0x21a00a82, 0x73000003, 0x24200683, | 33 | 0x1c100183, |
34 | 0x01a00404, 0x00200000, 0x34204682, 0x3ec40683, | 34 | 0x217ffb85, |
35 | 0xb0408203, 0x24204682, 0x01a00783, 0x00200000, | 35 | 0x40800000, |
36 | 0x3421c682, 0x3edc0684, 0xb0408184, 0x2421c682, | 36 | 0x409ff801, |
37 | 0x21a00806, 0x21a00885, 0x3fbf0784, 0x3f200204, | 37 | 0x24000080, |
38 | 0x3fbe0204, 0x3fe30204, 0x21a00904, 0x40804002, | 38 | 0x24fd8081, |
39 | 0x21a00982, 0x21a00a06, 0x40805a02, 0x21a00a82, | 39 | 0x1cd80081, |
40 | 0x04000683, 0x21a00803, 0x21a00885, 0x21a00904, | 40 | 0x33000180, |
41 | 0x40848002, 0x21a00982, 0x21a00a06, 0x40801002, | 41 | 0x00000000, |
42 | 0x21a00a82, 0x21a00a06, 0x40806602, 0x00200000, | 42 | 0x00000000, |
43 | 0x35800009, 0x21a00a82, 0x40800083, 0x21a00b83, | 43 | 0x01a00182, |
44 | 0x01a00c02, 0x01a00d83, 0x00003ffb, 0x40800003, | 44 | 0x3ec00083, |
45 | 0x4020007f, 0x35000000, 0x00000000, 0x00000000, | 45 | 0xb1c38103, |
46 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 46 | 0x01a00204, |
47 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 47 | 0x3ec10082, |
48 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 48 | 0x4201400d, |
49 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 49 | 0xb1c38202, |
50 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 50 | 0x01a00583, |
51 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 51 | 0x34218682, |
52 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 52 | 0x3ed80684, |
53 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 53 | 0xb0408184, |
54 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 54 | 0x24218682, |
55 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 55 | 0x01a00603, |
56 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 56 | 0x00200000, |
57 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 57 | 0x34214682, |
58 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 58 | 0x3ed40684, |
59 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 59 | 0xb0408184, |
60 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 60 | 0x40800003, |
61 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 61 | 0x24214682, |
62 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 62 | 0x21a00083, |
63 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 63 | 0x40800082, |
64 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 64 | 0x21a00b02, |
65 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 65 | 0x4020007f, |
66 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 66 | 0x1000251e, |
67 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 67 | 0x42a00002, |
68 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 68 | 0x32800008, |
69 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 69 | 0x4205c00c, |
70 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 70 | 0x00200000, |
71 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 71 | 0x40a0000b, |
72 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 72 | 0x3f82070f, |
73 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 73 | 0x4080020a, |
74 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 74 | 0x40800709, |
75 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 75 | 0x3fe3078f, |
76 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 76 | 0x3fbf0783, |
77 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 77 | 0x3f200183, |
78 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 78 | 0x3fbe0183, |
79 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 79 | 0x3fe30187, |
80 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 80 | 0x18008387, |
81 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 81 | 0x4205c002, |
82 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 82 | 0x3ac30404, |
83 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 83 | 0x1cffc489, |
84 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 84 | 0x00200000, |
85 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 85 | 0x18008403, |
86 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 86 | 0x38830402, |
87 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 87 | 0x4cffc486, |
88 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 88 | 0x3ac28185, |
89 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 89 | 0xb0408584, |
90 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 90 | 0x28830402, |
91 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 91 | 0x1c020408, |
92 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 92 | 0x38828182, |
93 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 93 | 0xb0408385, |
94 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 94 | 0x1802c387, |
95 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 95 | 0x28828182, |
96 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 96 | 0x217ff886, |
97 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 97 | 0x04000582, |
98 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 98 | 0x32800007, |
99 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 99 | 0x21a00802, |
100 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 100 | 0x3fbf0705, |
101 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 101 | 0x3f200285, |
102 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 102 | 0x3fbe0285, |
103 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 103 | 0x3fe30285, |
104 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 104 | 0x21a00885, |
105 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 105 | 0x04000603, |
106 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 106 | 0x21a00903, |
107 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 107 | 0x40803c02, |
108 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 108 | 0x21a00982, |
109 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 109 | 0x04000386, |
110 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 110 | 0x21a00a06, |
111 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 111 | 0x40801202, |
112 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 112 | 0x21a00a82, |
113 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 113 | 0x73000003, |
114 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 114 | 0x24200683, |
115 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 115 | 0x01a00404, |
116 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 116 | 0x00200000, |
117 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 117 | 0x34204682, |
118 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 118 | 0x3ec40683, |
119 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 119 | 0xb0408203, |
120 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 120 | 0x24204682, |
121 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 121 | 0x01a00783, |
122 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 122 | 0x00200000, |
123 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 123 | 0x3421c682, |
124 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 124 | 0x3edc0684, |
125 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 125 | 0xb0408184, |
126 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 126 | 0x2421c682, |
127 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 127 | 0x21a00806, |
128 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 128 | 0x21a00885, |
129 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 129 | 0x3fbf0784, |
130 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 130 | 0x3f200204, |
131 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 131 | 0x3fbe0204, |
132 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 132 | 0x3fe30204, |
133 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 133 | 0x21a00904, |
134 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 134 | 0x40804002, |
135 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 135 | 0x21a00982, |
136 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 136 | 0x21a00a06, |
137 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 137 | 0x40805a02, |
138 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 138 | 0x21a00a82, |
139 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 139 | 0x04000683, |
140 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 140 | 0x21a00803, |
141 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 141 | 0x21a00885, |
142 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 142 | 0x21a00904, |
143 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 143 | 0x40848002, |
144 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 144 | 0x21a00982, |
145 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 145 | 0x21a00a06, |
146 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 146 | 0x40801002, |
147 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 147 | 0x21a00a82, |
148 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 148 | 0x21a00a06, |
149 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 149 | 0x40806602, |
150 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 150 | 0x00200000, |
151 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 151 | 0x35800009, |
152 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 152 | 0x21a00a82, |
153 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 153 | 0x40800083, |
154 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 154 | 0x21a00b83, |
155 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 155 | 0x01a00c02, |
156 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 156 | 0x01a00d83, |
157 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 157 | 0x00003ffb, |
158 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 158 | 0x40800003, |
159 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 159 | 0x4020007f, |
160 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 160 | 0x35000000, |
161 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 161 | 0x00000000, |
162 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 162 | 0x00000000, |
163 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 163 | 0x00000000, |
164 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 164 | 0x00000000, |
165 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 165 | 0x00000000, |
166 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 166 | 0x00000000, |
167 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 167 | 0x00000000, |
168 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 168 | 0x00000000, |
169 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 169 | 0x00000000, |
170 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 170 | 0x00000000, |
171 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 171 | 0x00000000, |
172 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 172 | 0x00000000, |
173 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 173 | 0x00000000, |
174 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 174 | 0x00000000, |
175 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 175 | 0x00000000, |
176 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 176 | 0x00000000, |
177 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 177 | 0x00000000, |
178 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 178 | 0x00000000, |
179 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 179 | 0x00000000, |
180 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 180 | 0x00000000, |
181 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 181 | 0x00000000, |
182 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 182 | 0x00000000, |
183 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 183 | 0x00000000, |
184 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 184 | 0x00000000, |
185 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 185 | 0x00000000, |
186 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 186 | 0x00000000, |
187 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 187 | 0x00000000, |
188 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 188 | 0x00000000, |
189 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 189 | 0x00000000, |
190 | 0x00000000, 0x00000000, 0x00000000, 0x00000000, | 190 | 0x00000000, |
191 | 0x00000000, | ||
192 | 0x00000000, | ||
193 | 0x00000000, | ||
194 | 0x00000000, | ||
195 | 0x00000000, | ||
196 | 0x00000000, | ||
197 | 0x00000000, | ||
198 | 0x00000000, | ||
199 | 0x00000000, | ||
200 | 0x00000000, | ||
201 | 0x00000000, | ||
202 | 0x00000000, | ||
203 | 0x00000000, | ||
204 | 0x00000000, | ||
205 | 0x00000000, | ||
206 | 0x00000000, | ||
207 | 0x00000000, | ||
208 | 0x00000000, | ||
209 | 0x00000000, | ||
210 | 0x00000000, | ||
211 | 0x00000000, | ||
212 | 0x00000000, | ||
213 | 0x00000000, | ||
214 | 0x00000000, | ||
215 | 0x00000000, | ||
216 | 0x00000000, | ||
217 | 0x00000000, | ||
218 | 0x00000000, | ||
219 | 0x00000000, | ||
220 | 0x00000000, | ||
221 | 0x00000000, | ||
222 | 0x00000000, | ||
223 | 0x00000000, | ||
224 | 0x00000000, | ||
225 | 0x00000000, | ||
226 | 0x00000000, | ||
227 | 0x00000000, | ||
228 | 0x00000000, | ||
229 | 0x00000000, | ||
230 | 0x00000000, | ||
231 | 0x00000000, | ||
232 | 0x00000000, | ||
233 | 0x00000000, | ||
234 | 0x00000000, | ||
235 | 0x00000000, | ||
236 | 0x00000000, | ||
237 | 0x00000000, | ||
238 | 0x00000000, | ||
239 | 0x00000000, | ||
240 | 0x00000000, | ||
241 | 0x00000000, | ||
242 | 0x00000000, | ||
243 | 0x00000000, | ||
244 | 0x00000000, | ||
245 | 0x00000000, | ||
246 | 0x00000000, | ||
247 | 0x00000000, | ||
248 | 0x00000000, | ||
249 | 0x00000000, | ||
250 | 0x00000000, | ||
251 | 0x00000000, | ||
252 | 0x00000000, | ||
253 | 0x00000000, | ||
254 | 0x00000000, | ||
255 | 0x00000000, | ||
256 | 0x00000000, | ||
257 | 0x00000000, | ||
258 | 0x00000000, | ||
259 | 0x00000000, | ||
260 | 0x00000000, | ||
261 | 0x00000000, | ||
262 | 0x00000000, | ||
263 | 0x00000000, | ||
264 | 0x00000000, | ||
265 | 0x00000000, | ||
266 | 0x00000000, | ||
267 | 0x00000000, | ||
268 | 0x00000000, | ||
269 | 0x00000000, | ||
270 | 0x00000000, | ||
271 | 0x00000000, | ||
272 | 0x00000000, | ||
273 | 0x00000000, | ||
274 | 0x00000000, | ||
275 | 0x00000000, | ||
276 | 0x00000000, | ||
277 | 0x00000000, | ||
278 | 0x00000000, | ||
279 | 0x00000000, | ||
280 | 0x00000000, | ||
281 | 0x00000000, | ||
282 | 0x00000000, | ||
283 | 0x00000000, | ||
284 | 0x00000000, | ||
285 | 0x00000000, | ||
286 | 0x00000000, | ||
287 | 0x00000000, | ||
288 | 0x00000000, | ||
289 | 0x00000000, | ||
290 | 0x00000000, | ||
291 | 0x00000000, | ||
292 | 0x00000000, | ||
293 | 0x00000000, | ||
294 | 0x00000000, | ||
295 | 0x00000000, | ||
296 | 0x00000000, | ||
297 | 0x00000000, | ||
298 | 0x00000000, | ||
299 | 0x00000000, | ||
300 | 0x00000000, | ||
301 | 0x00000000, | ||
302 | 0x00000000, | ||
303 | 0x00000000, | ||
304 | 0x00000000, | ||
305 | 0x00000000, | ||
306 | 0x00000000, | ||
307 | 0x00000000, | ||
308 | 0x00000000, | ||
309 | 0x00000000, | ||
310 | 0x00000000, | ||
311 | 0x00000000, | ||
312 | 0x00000000, | ||
313 | 0x00000000, | ||
314 | 0x00000000, | ||
315 | 0x00000000, | ||
316 | 0x00000000, | ||
317 | 0x00000000, | ||
318 | 0x00000000, | ||
319 | 0x00000000, | ||
320 | 0x00000000, | ||
321 | 0x00000000, | ||
322 | 0x00000000, | ||
323 | 0x00000000, | ||
324 | 0x00000000, | ||
325 | 0x00000000, | ||
326 | 0x00000000, | ||
327 | 0x00000000, | ||
328 | 0x00000000, | ||
329 | 0x00000000, | ||
330 | 0x00000000, | ||
331 | 0x00000000, | ||
332 | 0x00000000, | ||
333 | 0x00000000, | ||
334 | 0x00000000, | ||
335 | 0x00000000, | ||
336 | 0x00000000, | ||
337 | 0x00000000, | ||
338 | 0x00000000, | ||
339 | 0x00000000, | ||
340 | 0x00000000, | ||
341 | 0x00000000, | ||
342 | 0x00000000, | ||
343 | 0x00000000, | ||
344 | 0x00000000, | ||
345 | 0x00000000, | ||
346 | 0x00000000, | ||
347 | 0x00000000, | ||
348 | 0x00000000, | ||
349 | 0x00000000, | ||
350 | 0x00000000, | ||
351 | 0x00000000, | ||
352 | 0x00000000, | ||
353 | 0x00000000, | ||
354 | 0x00000000, | ||
355 | 0x00000000, | ||
356 | 0x00000000, | ||
357 | 0x00000000, | ||
358 | 0x00000000, | ||
359 | 0x00000000, | ||
360 | 0x00000000, | ||
361 | 0x00000000, | ||
362 | 0x00000000, | ||
363 | 0x00000000, | ||
364 | 0x00000000, | ||
365 | 0x00000000, | ||
366 | 0x00000000, | ||
367 | 0x00000000, | ||
368 | 0x00000000, | ||
369 | 0x00000000, | ||
370 | 0x00000000, | ||
371 | 0x00000000, | ||
372 | 0x00000000, | ||
373 | 0x00000000, | ||
374 | 0x00000000, | ||
375 | 0x00000000, | ||
376 | 0x00000000, | ||
377 | 0x00000000, | ||
378 | 0x00000000, | ||
379 | 0x00000000, | ||
380 | 0x00000000, | ||
381 | 0x00000000, | ||
382 | 0x00000000, | ||
383 | 0x00000000, | ||
384 | 0x00000000, | ||
385 | 0x00000000, | ||
386 | 0x00000000, | ||
387 | 0x00000000, | ||
388 | 0x00000000, | ||
389 | 0x00000000, | ||
390 | 0x00000000, | ||
391 | 0x00000000, | ||
392 | 0x00000000, | ||
393 | 0x00000000, | ||
394 | 0x00000000, | ||
395 | 0x00000000, | ||
396 | 0x00000000, | ||
397 | 0x00000000, | ||
398 | 0x00000000, | ||
399 | 0x00000000, | ||
400 | 0x00000000, | ||
401 | 0x00000000, | ||
402 | 0x00000000, | ||
403 | 0x00000000, | ||
404 | 0x00000000, | ||
405 | 0x00000000, | ||
406 | 0x00000000, | ||
407 | 0x00000000, | ||
408 | 0x00000000, | ||
409 | 0x00000000, | ||
410 | 0x00000000, | ||
411 | 0x00000000, | ||
412 | 0x00000000, | ||
413 | 0x00000000, | ||
414 | 0x00000000, | ||
415 | 0x00000000, | ||
416 | 0x00000000, | ||
417 | 0x00000000, | ||
418 | 0x00000000, | ||
419 | 0x00000000, | ||
420 | 0x00000000, | ||
421 | 0x00000000, | ||
422 | 0x00000000, | ||
423 | 0x00000000, | ||
424 | 0x00000000, | ||
425 | 0x00000000, | ||
426 | 0x00000000, | ||
427 | 0x00000000, | ||
428 | 0x00000000, | ||
429 | 0x00000000, | ||
430 | 0x00000000, | ||
431 | 0x00000000, | ||
432 | 0x00000000, | ||
433 | 0x00000000, | ||
434 | 0x00000000, | ||
435 | 0x00000000, | ||
436 | 0x00000000, | ||
437 | 0x00000000, | ||
438 | 0x00000000, | ||
439 | 0x00000000, | ||
440 | 0x00000000, | ||
441 | 0x00000000, | ||
442 | 0x00000000, | ||
443 | 0x00000000, | ||
444 | 0x00000000, | ||
445 | 0x00000000, | ||
446 | 0x00000000, | ||
447 | 0x00000000, | ||
448 | 0x00000000, | ||
449 | 0x00000000, | ||
450 | 0x00000000, | ||
451 | 0x00000000, | ||
452 | 0x00000000, | ||
453 | 0x00000000, | ||
454 | 0x00000000, | ||
455 | 0x00000000, | ||
456 | 0x00000000, | ||
457 | 0x00000000, | ||
458 | 0x00000000, | ||
459 | 0x00000000, | ||
460 | 0x00000000, | ||
461 | 0x00000000, | ||
462 | 0x00000000, | ||
463 | 0x00000000, | ||
464 | 0x00000000, | ||
465 | 0x00000000, | ||
466 | 0x00000000, | ||
467 | 0x00000000, | ||
468 | 0x00000000, | ||
469 | 0x00000000, | ||
470 | 0x00000000, | ||
471 | 0x00000000, | ||
472 | 0x00000000, | ||
473 | 0x00000000, | ||
474 | 0x00000000, | ||
475 | 0x00000000, | ||
476 | 0x00000000, | ||
477 | 0x00000000, | ||
478 | 0x00000000, | ||
479 | 0x00000000, | ||
480 | 0x00000000, | ||
481 | 0x00000000, | ||
482 | 0x00000000, | ||
483 | 0x00000000, | ||
484 | 0x00000000, | ||
485 | 0x00000000, | ||
486 | 0x00000000, | ||
487 | 0x00000000, | ||
488 | 0x00000000, | ||
489 | 0x00000000, | ||
490 | 0x00000000, | ||
491 | 0x00000000, | ||
492 | 0x00000000, | ||
493 | 0x00000000, | ||
494 | 0x00000000, | ||
495 | 0x00000000, | ||
496 | 0x00000000, | ||
497 | 0x00000000, | ||
498 | 0x00000000, | ||
499 | 0x00000000, | ||
500 | 0x00000000, | ||
501 | 0x00000000, | ||
502 | 0x00000000, | ||
503 | 0x00000000, | ||
504 | 0x00000000, | ||
505 | 0x00000000, | ||
506 | 0x00000000, | ||
507 | 0x00000000, | ||
508 | 0x00000000, | ||
509 | 0x00000000, | ||
510 | 0x00000000, | ||
511 | 0x00000000, | ||
512 | 0x00000000, | ||
513 | 0x00000000, | ||
514 | 0x00000000, | ||
515 | 0x00000000, | ||
516 | 0x00000000, | ||
517 | 0x00000000, | ||
518 | 0x00000000, | ||
519 | 0x00000000, | ||
520 | 0x00000000, | ||
521 | 0x00000000, | ||
522 | 0x00000000, | ||
523 | 0x00000000, | ||
524 | 0x00000000, | ||
525 | 0x00000000, | ||
526 | 0x00000000, | ||
527 | 0x00000000, | ||
528 | 0x00000000, | ||
529 | 0x00000000, | ||
530 | 0x00000000, | ||
531 | 0x00000000, | ||
532 | 0x00000000, | ||
533 | 0x00000000, | ||
534 | 0x00000000, | ||
535 | 0x00000000, | ||
536 | 0x00000000, | ||
537 | 0x00000000, | ||
538 | 0x00000000, | ||
539 | 0x00000000, | ||
540 | 0x00000000, | ||
541 | 0x00000000, | ||
542 | 0x00000000, | ||
543 | 0x00000000, | ||
544 | 0x00000000, | ||
545 | 0x00000000, | ||
546 | 0x00000000, | ||
547 | 0x00000000, | ||
548 | 0x00000000, | ||
549 | 0x00000000, | ||
550 | 0x00000000, | ||
551 | 0x00000000, | ||
552 | 0x00000000, | ||
553 | 0x00000000, | ||
554 | 0x00000000, | ||
555 | 0x00000000, | ||
556 | 0x00000000, | ||
557 | 0x00000000, | ||
558 | 0x00000000, | ||
559 | 0x00000000, | ||
560 | 0x00000000, | ||
561 | 0x00000000, | ||
562 | 0x00000000, | ||
563 | 0x00000000, | ||
564 | 0x00000000, | ||
565 | 0x00000000, | ||
566 | 0x00000000, | ||
567 | 0x00000000, | ||
568 | 0x00000000, | ||
569 | 0x00000000, | ||
570 | 0x00000000, | ||
571 | 0x00000000, | ||
572 | 0x00000000, | ||
573 | 0x00000000, | ||
574 | 0x00000000, | ||
575 | 0x00000000, | ||
576 | 0x00000000, | ||
577 | 0x00000000, | ||
578 | 0x00000000, | ||
579 | 0x00000000, | ||
580 | 0x00000000, | ||
581 | 0x00000000, | ||
582 | 0x00000000, | ||
583 | 0x00000000, | ||
584 | 0x00000000, | ||
585 | 0x00000000, | ||
586 | 0x00000000, | ||
587 | 0x00000000, | ||
588 | 0x00000000, | ||
589 | 0x00000000, | ||
590 | 0x00000000, | ||
591 | 0x00000000, | ||
592 | 0x00000000, | ||
593 | 0x00000000, | ||
594 | 0x00000000, | ||
595 | 0x00000000, | ||
596 | 0x00000000, | ||
597 | 0x00000000, | ||
598 | 0x00000000, | ||
599 | 0x00000000, | ||
600 | 0x00000000, | ||
601 | 0x00000000, | ||
602 | 0x00000000, | ||
603 | 0x00000000, | ||
604 | 0x00000000, | ||
605 | 0x00000000, | ||
606 | 0x00000000, | ||
607 | 0x00000000, | ||
608 | 0x00000000, | ||
609 | 0x00000000, | ||
610 | 0x00000000, | ||
611 | 0x00000000, | ||
612 | 0x00000000, | ||
613 | 0x00000000, | ||
614 | 0x00000000, | ||
615 | 0x00000000, | ||
616 | 0x00000000, | ||
617 | 0x00000000, | ||
618 | 0x00000000, | ||
619 | 0x00000000, | ||
620 | 0x00000000, | ||
621 | 0x00000000, | ||
622 | 0x00000000, | ||
623 | 0x00000000, | ||
624 | 0x00000000, | ||
625 | 0x00000000, | ||
626 | 0x00000000, | ||
627 | 0x00000000, | ||
628 | 0x00000000, | ||
629 | 0x00000000, | ||
630 | 0x00000000, | ||
631 | 0x00000000, | ||
632 | 0x00000000, | ||
633 | 0x00000000, | ||
634 | 0x00000000, | ||
635 | 0x00000000, | ||
636 | 0x00000000, | ||
637 | 0x00000000, | ||
638 | 0x00000000, | ||
639 | 0x00000000, | ||
640 | 0x00000000, | ||
641 | 0x00000000, | ||
642 | 0x00000000, | ||
643 | 0x00000000, | ||
644 | 0x00000000, | ||
645 | 0x00000000, | ||
646 | 0x00000000, | ||
647 | 0x00000000, | ||
648 | 0x00000000, | ||
649 | 0x00000000, | ||
650 | 0x00000000, | ||
651 | 0x00000000, | ||
652 | 0x00000000, | ||
653 | 0x00000000, | ||
654 | 0x00000000, | ||
655 | 0x00000000, | ||
656 | 0x00000000, | ||
657 | 0x00000000, | ||
658 | 0x00000000, | ||
659 | 0x00000000, | ||
660 | 0x00000000, | ||
661 | 0x00000000, | ||
662 | 0x00000000, | ||
663 | 0x00000000, | ||
664 | 0x00000000, | ||
665 | 0x00000000, | ||
666 | 0x00000000, | ||
667 | 0x00000000, | ||
668 | 0x00000000, | ||
669 | 0x00000000, | ||
670 | 0x00000000, | ||
671 | 0x00000000, | ||
672 | 0x00000000, | ||
673 | 0x00000000, | ||
674 | 0x00000000, | ||
675 | 0x00000000, | ||
676 | 0x00000000, | ||
677 | 0x00000000, | ||
678 | 0x00000000, | ||
679 | 0x00000000, | ||
680 | 0x00000000, | ||
681 | 0x00000000, | ||
682 | 0x00000000, | ||
683 | 0x00000000, | ||
684 | 0x00000000, | ||
685 | 0x00000000, | ||
686 | 0x00000000, | ||
687 | 0x00000000, | ||
688 | 0x00000000, | ||
689 | 0x00000000, | ||
690 | 0x00000000, | ||
691 | 0x00000000, | ||
692 | 0x00000000, | ||
693 | 0x00000000, | ||
694 | 0x00000000, | ||
695 | 0x00000000, | ||
696 | 0x00000000, | ||
697 | 0x00000000, | ||
698 | 0x00000000, | ||
699 | 0x00000000, | ||
700 | 0x00000000, | ||
701 | 0x00000000, | ||
702 | 0x00000000, | ||
703 | 0x00000000, | ||
704 | 0x00000000, | ||
705 | 0x00000000, | ||
706 | 0x00000000, | ||
707 | 0x00000000, | ||
708 | 0x00000000, | ||
709 | 0x00000000, | ||
710 | 0x00000000, | ||
711 | 0x00000000, | ||
712 | 0x00000000, | ||
713 | 0x00000000, | ||
714 | 0x00000000, | ||
715 | 0x00000000, | ||
716 | 0x00000000, | ||
717 | 0x00000000, | ||
718 | 0x00000000, | ||
719 | 0x00000000, | ||
720 | 0x00000000, | ||
721 | 0x00000000, | ||
722 | 0x00000000, | ||
723 | 0x00000000, | ||
724 | 0x00000000, | ||
725 | 0x00000000, | ||
726 | 0x00000000, | ||
727 | 0x00000000, | ||
728 | 0x00000000, | ||
729 | 0x00000000, | ||
730 | 0x00000000, | ||
731 | 0x00000000, | ||
732 | 0x00000000, | ||
733 | 0x00000000, | ||
734 | 0x00000000, | ||
735 | 0x00000000, | ||
736 | 0x00000000, | ||
737 | 0x00000000, | ||
738 | 0x00000000, | ||
739 | 0x00000000, | ||
740 | 0x00000000, | ||
741 | 0x00000000, | ||
742 | 0x00000000, | ||
191 | }; | 743 | }; |
diff --git a/arch/powerpc/platforms/cell/spufs/switch.c b/arch/powerpc/platforms/cell/spufs/switch.c index 1726bfe38ee0..b30e55dab832 100644 --- a/arch/powerpc/platforms/cell/spufs/switch.c +++ b/arch/powerpc/platforms/cell/spufs/switch.c | |||
@@ -46,6 +46,7 @@ | |||
46 | 46 | ||
47 | #include <asm/io.h> | 47 | #include <asm/io.h> |
48 | #include <asm/spu.h> | 48 | #include <asm/spu.h> |
49 | #include <asm/spu_priv1.h> | ||
49 | #include <asm/spu_csa.h> | 50 | #include <asm/spu_csa.h> |
50 | #include <asm/mmu_context.h> | 51 | #include <asm/mmu_context.h> |
51 | 52 | ||
@@ -622,12 +623,17 @@ static inline void save_ppuint_mb(struct spu_state *csa, struct spu *spu) | |||
622 | static inline void save_ch_part1(struct spu_state *csa, struct spu *spu) | 623 | static inline void save_ch_part1(struct spu_state *csa, struct spu *spu) |
623 | { | 624 | { |
624 | struct spu_priv2 __iomem *priv2 = spu->priv2; | 625 | struct spu_priv2 __iomem *priv2 = spu->priv2; |
625 | u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; | 626 | u64 idx, ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; |
626 | int i; | 627 | int i; |
627 | 628 | ||
628 | /* Save, Step 42: | 629 | /* Save, Step 42: |
629 | * Save the following CH: [0,1,3,4,24,25,27] | ||
630 | */ | 630 | */ |
631 | |||
632 | /* Save CH 1, without channel count */ | ||
633 | out_be64(&priv2->spu_chnlcntptr_RW, 1); | ||
634 | csa->spu_chnldata_RW[1] = in_be64(&priv2->spu_chnldata_RW); | ||
635 | |||
636 | /* Save the following CH: [0,3,4,24,25,27] */ | ||
631 | for (i = 0; i < 7; i++) { | 637 | for (i = 0; i < 7; i++) { |
632 | idx = ch_indices[i]; | 638 | idx = ch_indices[i]; |
633 | out_be64(&priv2->spu_chnlcntptr_RW, idx); | 639 | out_be64(&priv2->spu_chnlcntptr_RW, idx); |
@@ -718,13 +724,15 @@ static inline void invalidate_slbs(struct spu_state *csa, struct spu *spu) | |||
718 | 724 | ||
719 | static inline void get_kernel_slb(u64 ea, u64 slb[2]) | 725 | static inline void get_kernel_slb(u64 ea, u64 slb[2]) |
720 | { | 726 | { |
721 | slb[0] = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | SLB_VSID_KERNEL; | 727 | u64 llp; |
722 | slb[1] = (ea & ESID_MASK) | SLB_ESID_V; | ||
723 | 728 | ||
724 | /* Large pages are used for kernel text/data, but not vmalloc. */ | 729 | if (REGION_ID(ea) == KERNEL_REGION_ID) |
725 | if (cpu_has_feature(CPU_FTR_16M_PAGE) | 730 | llp = mmu_psize_defs[mmu_linear_psize].sllp; |
726 | && REGION_ID(ea) == KERNEL_REGION_ID) | 731 | else |
727 | slb[0] |= SLB_VSID_L; | 732 | llp = mmu_psize_defs[mmu_virtual_psize].sllp; |
733 | slb[0] = (get_kernel_vsid(ea) << SLB_VSID_SHIFT) | | ||
734 | SLB_VSID_KERNEL | llp; | ||
735 | slb[1] = (ea & ESID_MASK) | SLB_ESID_V; | ||
728 | } | 736 | } |
729 | 737 | ||
730 | static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe) | 738 | static inline void load_mfc_slb(struct spu *spu, u64 slb[2], int slbe) |
@@ -1103,13 +1111,18 @@ static inline void clear_spu_status(struct spu_state *csa, struct spu *spu) | |||
1103 | static inline void reset_ch_part1(struct spu_state *csa, struct spu *spu) | 1111 | static inline void reset_ch_part1(struct spu_state *csa, struct spu *spu) |
1104 | { | 1112 | { |
1105 | struct spu_priv2 __iomem *priv2 = spu->priv2; | 1113 | struct spu_priv2 __iomem *priv2 = spu->priv2; |
1106 | u64 ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; | 1114 | u64 ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; |
1107 | u64 idx; | 1115 | u64 idx; |
1108 | int i; | 1116 | int i; |
1109 | 1117 | ||
1110 | /* Restore, Step 20: | 1118 | /* Restore, Step 20: |
1111 | * Reset the following CH: [0,1,3,4,24,25,27] | ||
1112 | */ | 1119 | */ |
1120 | |||
1121 | /* Reset CH 1 */ | ||
1122 | out_be64(&priv2->spu_chnlcntptr_RW, 1); | ||
1123 | out_be64(&priv2->spu_chnldata_RW, 0UL); | ||
1124 | |||
1125 | /* Reset the following CH: [0,3,4,24,25,27] */ | ||
1113 | for (i = 0; i < 7; i++) { | 1126 | for (i = 0; i < 7; i++) { |
1114 | idx = ch_indices[i]; | 1127 | idx = ch_indices[i]; |
1115 | out_be64(&priv2->spu_chnlcntptr_RW, idx); | 1128 | out_be64(&priv2->spu_chnlcntptr_RW, idx); |
@@ -1570,12 +1583,17 @@ static inline void restore_decr_wrapped(struct spu_state *csa, struct spu *spu) | |||
1570 | static inline void restore_ch_part1(struct spu_state *csa, struct spu *spu) | 1583 | static inline void restore_ch_part1(struct spu_state *csa, struct spu *spu) |
1571 | { | 1584 | { |
1572 | struct spu_priv2 __iomem *priv2 = spu->priv2; | 1585 | struct spu_priv2 __iomem *priv2 = spu->priv2; |
1573 | u64 idx, ch_indices[7] = { 0UL, 1UL, 3UL, 4UL, 24UL, 25UL, 27UL }; | 1586 | u64 idx, ch_indices[7] = { 0UL, 3UL, 4UL, 24UL, 25UL, 27UL }; |
1574 | int i; | 1587 | int i; |
1575 | 1588 | ||
1576 | /* Restore, Step 59: | 1589 | /* Restore, Step 59: |
1577 | * Restore the following CH: [0,1,3,4,24,25,27] | ||
1578 | */ | 1590 | */ |
1591 | |||
1592 | /* Restore CH 1 without count */ | ||
1593 | out_be64(&priv2->spu_chnlcntptr_RW, 1); | ||
1594 | out_be64(&priv2->spu_chnldata_RW, csa->spu_chnldata_RW[1]); | ||
1595 | |||
1596 | /* Restore the following CH: [0,3,4,24,25,27] */ | ||
1579 | for (i = 0; i < 7; i++) { | 1597 | for (i = 0; i < 7; i++) { |
1580 | idx = ch_indices[i]; | 1598 | idx = ch_indices[i]; |
1581 | out_be64(&priv2->spu_chnlcntptr_RW, idx); | 1599 | out_be64(&priv2->spu_chnlcntptr_RW, idx); |
@@ -2074,6 +2092,7 @@ int spu_save(struct spu_state *prev, struct spu *spu) | |||
2074 | } | 2092 | } |
2075 | return rc; | 2093 | return rc; |
2076 | } | 2094 | } |
2095 | EXPORT_SYMBOL_GPL(spu_save); | ||
2077 | 2096 | ||
2078 | /** | 2097 | /** |
2079 | * spu_restore - SPU context restore, with harvest and locking. | 2098 | * spu_restore - SPU context restore, with harvest and locking. |
@@ -2090,7 +2109,6 @@ int spu_restore(struct spu_state *new, struct spu *spu) | |||
2090 | 2109 | ||
2091 | acquire_spu_lock(spu); | 2110 | acquire_spu_lock(spu); |
2092 | harvest(NULL, spu); | 2111 | harvest(NULL, spu); |
2093 | spu->stop_code = 0; | ||
2094 | spu->dar = 0; | 2112 | spu->dar = 0; |
2095 | spu->dsisr = 0; | 2113 | spu->dsisr = 0; |
2096 | spu->slb_replace = 0; | 2114 | spu->slb_replace = 0; |
@@ -2103,6 +2121,7 @@ int spu_restore(struct spu_state *new, struct spu *spu) | |||
2103 | } | 2121 | } |
2104 | return rc; | 2122 | return rc; |
2105 | } | 2123 | } |
2124 | EXPORT_SYMBOL_GPL(spu_restore); | ||
2106 | 2125 | ||
2107 | /** | 2126 | /** |
2108 | * spu_harvest - SPU harvest (reset) operation | 2127 | * spu_harvest - SPU harvest (reset) operation |
@@ -2125,6 +2144,7 @@ static void init_prob(struct spu_state *csa) | |||
2125 | csa->spu_chnlcnt_RW[28] = 1; | 2144 | csa->spu_chnlcnt_RW[28] = 1; |
2126 | csa->spu_chnlcnt_RW[30] = 1; | 2145 | csa->spu_chnlcnt_RW[30] = 1; |
2127 | csa->prob.spu_runcntl_RW = SPU_RUNCNTL_STOP; | 2146 | csa->prob.spu_runcntl_RW = SPU_RUNCNTL_STOP; |
2147 | csa->prob.mb_stat_R = 0x000400; | ||
2128 | } | 2148 | } |
2129 | 2149 | ||
2130 | static void init_priv1(struct spu_state *csa) | 2150 | static void init_priv1(struct spu_state *csa) |
@@ -2193,6 +2213,7 @@ void spu_init_csa(struct spu_state *csa) | |||
2193 | init_priv1(csa); | 2213 | init_priv1(csa); |
2194 | init_priv2(csa); | 2214 | init_priv2(csa); |
2195 | } | 2215 | } |
2216 | EXPORT_SYMBOL_GPL(spu_init_csa); | ||
2196 | 2217 | ||
2197 | void spu_fini_csa(struct spu_state *csa) | 2218 | void spu_fini_csa(struct spu_state *csa) |
2198 | { | 2219 | { |
@@ -2203,3 +2224,4 @@ void spu_fini_csa(struct spu_state *csa) | |||
2203 | 2224 | ||
2204 | vfree(csa->lscsa); | 2225 | vfree(csa->lscsa); |
2205 | } | 2226 | } |
2227 | EXPORT_SYMBOL_GPL(spu_fini_csa); | ||
diff --git a/arch/powerpc/platforms/iseries/Makefile b/arch/powerpc/platforms/iseries/Makefile index ce8c0b943fa0..dee4eb4d8bec 100644 --- a/arch/powerpc/platforms/iseries/Makefile +++ b/arch/powerpc/platforms/iseries/Makefile | |||
@@ -1,9 +1,11 @@ | |||
1 | EXTRA_CFLAGS += -mno-minimal-toc | 1 | EXTRA_CFLAGS += -mno-minimal-toc |
2 | 2 | ||
3 | obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o mf.o lpevents.o \ | 3 | obj-y += hvlog.o hvlpconfig.o lpardata.o setup.o dt_mod.o mf.o lpevents.o \ |
4 | hvcall.o proc.o htab.o iommu.o misc.o irq.o | 4 | hvcall.o proc.o htab.o iommu.o misc.o irq.o |
5 | obj-$(CONFIG_PCI) += pci.o vpdinfo.o | 5 | obj-$(CONFIG_PCI) += pci.o vpdinfo.o |
6 | obj-$(CONFIG_IBMVIO) += vio.o | ||
7 | obj-$(CONFIG_SMP) += smp.o | 6 | obj-$(CONFIG_SMP) += smp.o |
8 | obj-$(CONFIG_VIOPATH) += viopath.o | 7 | obj-$(CONFIG_VIOPATH) += viopath.o |
9 | obj-$(CONFIG_MODULES) += ksyms.o | 8 | obj-$(CONFIG_MODULES) += ksyms.o |
9 | |||
10 | $(obj)/dt_mod.o: $(obj)/dt.o | ||
11 | @$(OBJCOPY) --rename-section .rodata.str1.8=.dt_strings $(obj)/dt.o $(obj)/dt_mod.o | ||
diff --git a/arch/powerpc/platforms/iseries/call_pci.h b/arch/powerpc/platforms/iseries/call_pci.h index 59d4e0ad5cf3..dbdf69850ed9 100644 --- a/arch/powerpc/platforms/iseries/call_pci.h +++ b/arch/powerpc/platforms/iseries/call_pci.h | |||
@@ -145,6 +145,25 @@ static inline u64 HvCallPci_configLoad16(u16 busNumber, u8 subBusNumber, | |||
145 | return retVal.rc; | 145 | return retVal.rc; |
146 | } | 146 | } |
147 | 147 | ||
148 | static inline u64 HvCallPci_configLoad32(u16 busNumber, u8 subBusNumber, | ||
149 | u8 deviceId, u32 offset, u32 *value) | ||
150 | { | ||
151 | struct HvCallPci_DsaAddr dsa; | ||
152 | struct HvCallPci_LoadReturn retVal; | ||
153 | |||
154 | *((u64*)&dsa) = 0; | ||
155 | |||
156 | dsa.busNumber = busNumber; | ||
157 | dsa.subBusNumber = subBusNumber; | ||
158 | dsa.deviceId = deviceId; | ||
159 | |||
160 | HvCall3Ret16(HvCallPciConfigLoad32, &retVal, *(u64 *)&dsa, offset, 0); | ||
161 | |||
162 | *value = retVal.value; | ||
163 | |||
164 | return retVal.rc; | ||
165 | } | ||
166 | |||
148 | static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, | 167 | static inline u64 HvCallPci_configStore8(u16 busNumber, u8 subBusNumber, |
149 | u8 deviceId, u32 offset, u8 value) | 168 | u8 deviceId, u32 offset, u8 value) |
150 | { | 169 | { |
diff --git a/arch/powerpc/platforms/iseries/dt.c b/arch/powerpc/platforms/iseries/dt.c new file mode 100644 index 000000000000..d3444aabe76e --- /dev/null +++ b/arch/powerpc/platforms/iseries/dt.c | |||
@@ -0,0 +1,615 @@ | |||
1 | /* | ||
2 | * Copyright (c) 2005-2006 Michael Ellerman, IBM Corporation | ||
3 | * | ||
4 | * Description: | ||
5 | * This file contains all the routines to build a flattened device | ||
6 | * tree for a legacy iSeries machine. | ||
7 | * | ||
8 | * This program is free software; you can redistribute it and/or | ||
9 | * modify it under the terms of the GNU General Public License | ||
10 | * as published by the Free Software Foundation; either version | ||
11 | * 2 of the License, or (at your option) any later version. | ||
12 | */ | ||
13 | |||
14 | #undef DEBUG | ||
15 | |||
16 | #include <linux/types.h> | ||
17 | #include <linux/init.h> | ||
18 | #include <linux/pci.h> | ||
19 | #include <linux/pci_regs.h> | ||
20 | #include <linux/pci_ids.h> | ||
21 | #include <linux/threads.h> | ||
22 | #include <linux/bitops.h> | ||
23 | #include <linux/string.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/if_ether.h> /* ETH_ALEN */ | ||
26 | |||
27 | #include <asm/machdep.h> | ||
28 | #include <asm/prom.h> | ||
29 | #include <asm/lppaca.h> | ||
30 | #include <asm/cputable.h> | ||
31 | #include <asm/abs_addr.h> | ||
32 | #include <asm/system.h> | ||
33 | #include <asm/iseries/hv_types.h> | ||
34 | #include <asm/iseries/hv_lp_config.h> | ||
35 | #include <asm/iseries/hv_call_xm.h> | ||
36 | #include <asm/iseries/it_exp_vpd_panel.h> | ||
37 | #include <asm/udbg.h> | ||
38 | |||
39 | #include "processor_vpd.h" | ||
40 | #include "call_hpt.h" | ||
41 | #include "call_pci.h" | ||
42 | #include "pci.h" | ||
43 | |||
44 | #ifdef DEBUG | ||
45 | #define DBG(fmt...) udbg_printf(fmt) | ||
46 | #else | ||
47 | #define DBG(fmt...) | ||
48 | #endif | ||
49 | |||
50 | /* | ||
51 | * These are created by the linker script at the start and end | ||
52 | * of the section containing all the strings from this file. | ||
53 | */ | ||
54 | extern char __dt_strings_start[]; | ||
55 | extern char __dt_strings_end[]; | ||
56 | |||
57 | struct iseries_flat_dt { | ||
58 | struct boot_param_header header; | ||
59 | u64 reserve_map[2]; | ||
60 | }; | ||
61 | |||
62 | static void * __initdata dt_data; | ||
63 | |||
64 | /* | ||
65 | * Putting these strings here keeps them out of the section | ||
66 | * that we rename to .dt_strings using objcopy and capture | ||
67 | * for the strings blob of the flattened device tree. | ||
68 | */ | ||
69 | static char __initdata device_type_cpu[] = "cpu"; | ||
70 | static char __initdata device_type_memory[] = "memory"; | ||
71 | static char __initdata device_type_serial[] = "serial"; | ||
72 | static char __initdata device_type_network[] = "network"; | ||
73 | static char __initdata device_type_block[] = "block"; | ||
74 | static char __initdata device_type_byte[] = "byte"; | ||
75 | static char __initdata device_type_pci[] = "pci"; | ||
76 | static char __initdata device_type_vdevice[] = "vdevice"; | ||
77 | static char __initdata device_type_vscsi[] = "vscsi"; | ||
78 | |||
79 | static struct iseries_flat_dt * __init dt_init(void) | ||
80 | { | ||
81 | struct iseries_flat_dt *dt; | ||
82 | unsigned long str_len; | ||
83 | |||
84 | str_len = __dt_strings_end - __dt_strings_start; | ||
85 | dt = (struct iseries_flat_dt *)ALIGN(klimit, 8); | ||
86 | dt->header.off_mem_rsvmap = | ||
87 | offsetof(struct iseries_flat_dt, reserve_map); | ||
88 | dt->header.off_dt_strings = ALIGN(sizeof(*dt), 8); | ||
89 | dt->header.off_dt_struct = dt->header.off_dt_strings | ||
90 | + ALIGN(str_len, 8); | ||
91 | dt_data = (void *)((unsigned long)dt + dt->header.off_dt_struct); | ||
92 | dt->header.dt_strings_size = str_len; | ||
93 | |||
94 | /* There is no notion of hardware cpu id on iSeries */ | ||
95 | dt->header.boot_cpuid_phys = smp_processor_id(); | ||
96 | |||
97 | memcpy((char *)dt + dt->header.off_dt_strings, __dt_strings_start, | ||
98 | str_len); | ||
99 | |||
100 | dt->header.magic = OF_DT_HEADER; | ||
101 | dt->header.version = 0x10; | ||
102 | dt->header.last_comp_version = 0x10; | ||
103 | |||
104 | dt->reserve_map[0] = 0; | ||
105 | dt->reserve_map[1] = 0; | ||
106 | |||
107 | return dt; | ||
108 | } | ||
109 | |||
110 | static void __init dt_push_u32(struct iseries_flat_dt *dt, u32 value) | ||
111 | { | ||
112 | *((u32 *)dt_data) = value; | ||
113 | dt_data += sizeof(u32); | ||
114 | } | ||
115 | |||
116 | #ifdef notyet | ||
117 | static void __init dt_push_u64(struct iseries_flat_dt *dt, u64 value) | ||
118 | { | ||
119 | *((u64 *)dt_data) = value; | ||
120 | dt_data += sizeof(u64); | ||
121 | } | ||
122 | #endif | ||
123 | |||
124 | static void __init dt_push_bytes(struct iseries_flat_dt *dt, const char *data, | ||
125 | int len) | ||
126 | { | ||
127 | memcpy(dt_data, data, len); | ||
128 | dt_data += ALIGN(len, 4); | ||
129 | } | ||
130 | |||
131 | static void __init dt_start_node(struct iseries_flat_dt *dt, const char *name) | ||
132 | { | ||
133 | dt_push_u32(dt, OF_DT_BEGIN_NODE); | ||
134 | dt_push_bytes(dt, name, strlen(name) + 1); | ||
135 | } | ||
136 | |||
137 | #define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE) | ||
138 | |||
139 | static void __init dt_prop(struct iseries_flat_dt *dt, const char *name, | ||
140 | const void *data, int len) | ||
141 | { | ||
142 | unsigned long offset; | ||
143 | |||
144 | dt_push_u32(dt, OF_DT_PROP); | ||
145 | |||
146 | /* Length of the data */ | ||
147 | dt_push_u32(dt, len); | ||
148 | |||
149 | offset = name - __dt_strings_start; | ||
150 | |||
151 | /* The offset of the properties name in the string blob. */ | ||
152 | dt_push_u32(dt, (u32)offset); | ||
153 | |||
154 | /* The actual data. */ | ||
155 | dt_push_bytes(dt, data, len); | ||
156 | } | ||
157 | |||
158 | static void __init dt_prop_str(struct iseries_flat_dt *dt, const char *name, | ||
159 | const char *data) | ||
160 | { | ||
161 | dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */ | ||
162 | } | ||
163 | |||
164 | static void __init dt_prop_u32(struct iseries_flat_dt *dt, const char *name, | ||
165 | u32 data) | ||
166 | { | ||
167 | dt_prop(dt, name, &data, sizeof(u32)); | ||
168 | } | ||
169 | |||
170 | #ifdef notyet | ||
171 | static void __init dt_prop_u64(struct iseries_flat_dt *dt, const char *name, | ||
172 | u64 data) | ||
173 | { | ||
174 | dt_prop(dt, name, &data, sizeof(u64)); | ||
175 | } | ||
176 | #endif | ||
177 | |||
178 | static void __init dt_prop_u64_list(struct iseries_flat_dt *dt, | ||
179 | const char *name, u64 *data, int n) | ||
180 | { | ||
181 | dt_prop(dt, name, data, sizeof(u64) * n); | ||
182 | } | ||
183 | |||
184 | static void __init dt_prop_u32_list(struct iseries_flat_dt *dt, | ||
185 | const char *name, u32 *data, int n) | ||
186 | { | ||
187 | dt_prop(dt, name, data, sizeof(u32) * n); | ||
188 | } | ||
189 | |||
190 | #ifdef notyet | ||
191 | static void __init dt_prop_empty(struct iseries_flat_dt *dt, const char *name) | ||
192 | { | ||
193 | dt_prop(dt, name, NULL, 0); | ||
194 | } | ||
195 | #endif | ||
196 | |||
197 | static void __init dt_cpus(struct iseries_flat_dt *dt) | ||
198 | { | ||
199 | unsigned char buf[32]; | ||
200 | unsigned char *p; | ||
201 | unsigned int i, index; | ||
202 | struct IoHriProcessorVpd *d; | ||
203 | u32 pft_size[2]; | ||
204 | |||
205 | /* yuck */ | ||
206 | snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name); | ||
207 | p = strchr(buf, ' '); | ||
208 | if (!p) p = buf + strlen(buf); | ||
209 | |||
210 | dt_start_node(dt, "cpus"); | ||
211 | dt_prop_u32(dt, "#address-cells", 1); | ||
212 | dt_prop_u32(dt, "#size-cells", 0); | ||
213 | |||
214 | pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA */ | ||
215 | pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); | ||
216 | |||
217 | for (i = 0; i < NR_CPUS; i++) { | ||
218 | if (lppaca[i].dyn_proc_status >= 2) | ||
219 | continue; | ||
220 | |||
221 | snprintf(p, 32 - (p - buf), "@%d", i); | ||
222 | dt_start_node(dt, buf); | ||
223 | |||
224 | dt_prop_str(dt, "device_type", device_type_cpu); | ||
225 | |||
226 | index = lppaca[i].dyn_hv_phys_proc_index; | ||
227 | d = &xIoHriProcessorVpd[index]; | ||
228 | |||
229 | dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); | ||
230 | dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize); | ||
231 | |||
232 | dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024); | ||
233 | dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize); | ||
234 | |||
235 | /* magic conversions to Hz copied from old code */ | ||
236 | dt_prop_u32(dt, "clock-frequency", | ||
237 | ((1UL << 34) * 1000000) / d->xProcFreq); | ||
238 | dt_prop_u32(dt, "timebase-frequency", | ||
239 | ((1UL << 32) * 1000000) / d->xTimeBaseFreq); | ||
240 | |||
241 | dt_prop_u32(dt, "reg", i); | ||
242 | |||
243 | dt_prop_u32_list(dt, "ibm,pft-size", pft_size, 2); | ||
244 | |||
245 | dt_end_node(dt); | ||
246 | } | ||
247 | |||
248 | dt_end_node(dt); | ||
249 | } | ||
250 | |||
251 | static void __init dt_model(struct iseries_flat_dt *dt) | ||
252 | { | ||
253 | char buf[16] = "IBM,"; | ||
254 | |||
255 | /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ | ||
256 | strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); | ||
257 | strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); | ||
258 | buf[11] = '\0'; | ||
259 | dt_prop_str(dt, "system-id", buf); | ||
260 | |||
261 | /* "IBM," + machineType[0:4] */ | ||
262 | strne2a(buf + 4, xItExtVpdPanel.machineType, 4); | ||
263 | buf[8] = '\0'; | ||
264 | dt_prop_str(dt, "model", buf); | ||
265 | |||
266 | dt_prop_str(dt, "compatible", "IBM,iSeries"); | ||
267 | } | ||
268 | |||
269 | static void __init dt_do_vdevice(struct iseries_flat_dt *dt, | ||
270 | const char *name, u32 reg, int unit, | ||
271 | const char *type, const char *compat, int end) | ||
272 | { | ||
273 | char buf[32]; | ||
274 | |||
275 | snprintf(buf, 32, "%s@%08x", name, reg + ((unit >= 0) ? unit : 0)); | ||
276 | dt_start_node(dt, buf); | ||
277 | dt_prop_str(dt, "device_type", type); | ||
278 | if (compat) | ||
279 | dt_prop_str(dt, "compatible", compat); | ||
280 | dt_prop_u32(dt, "reg", reg + ((unit >= 0) ? unit : 0)); | ||
281 | if (unit >= 0) | ||
282 | dt_prop_u32(dt, "linux,unit_address", unit); | ||
283 | if (end) | ||
284 | dt_end_node(dt); | ||
285 | } | ||
286 | |||
287 | static void __init dt_vdevices(struct iseries_flat_dt *dt) | ||
288 | { | ||
289 | u32 reg = 0; | ||
290 | HvLpIndexMap vlan_map; | ||
291 | int i; | ||
292 | |||
293 | dt_start_node(dt, "vdevice"); | ||
294 | dt_prop_str(dt, "device_type", device_type_vdevice); | ||
295 | dt_prop_str(dt, "compatible", "IBM,iSeries-vdevice"); | ||
296 | dt_prop_u32(dt, "#address-cells", 1); | ||
297 | dt_prop_u32(dt, "#size-cells", 0); | ||
298 | |||
299 | dt_do_vdevice(dt, "vty", reg, -1, device_type_serial, NULL, 1); | ||
300 | reg++; | ||
301 | |||
302 | dt_do_vdevice(dt, "v-scsi", reg, -1, device_type_vscsi, | ||
303 | "IBM,v-scsi", 1); | ||
304 | reg++; | ||
305 | |||
306 | vlan_map = HvLpConfig_getVirtualLanIndexMap(); | ||
307 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) { | ||
308 | unsigned char mac_addr[ETH_ALEN]; | ||
309 | |||
310 | if ((vlan_map & (0x8000 >> i)) == 0) | ||
311 | continue; | ||
312 | dt_do_vdevice(dt, "l-lan", reg, i, device_type_network, | ||
313 | "IBM,iSeries-l-lan", 0); | ||
314 | mac_addr[0] = 0x02; | ||
315 | mac_addr[1] = 0x01; | ||
316 | mac_addr[2] = 0xff; | ||
317 | mac_addr[3] = i; | ||
318 | mac_addr[4] = 0xff; | ||
319 | mac_addr[5] = HvLpConfig_getLpIndex_outline(); | ||
320 | dt_prop(dt, "local-mac-address", (char *)mac_addr, ETH_ALEN); | ||
321 | dt_prop(dt, "mac-address", (char *)mac_addr, ETH_ALEN); | ||
322 | dt_prop_u32(dt, "max-frame-size", 9000); | ||
323 | dt_prop_u32(dt, "address-bits", 48); | ||
324 | |||
325 | dt_end_node(dt); | ||
326 | } | ||
327 | reg += HVMAXARCHITECTEDVIRTUALLANS; | ||
328 | |||
329 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) | ||
330 | dt_do_vdevice(dt, "viodasd", reg, i, device_type_block, | ||
331 | "IBM,iSeries-viodasd", 1); | ||
332 | reg += HVMAXARCHITECTEDVIRTUALDISKS; | ||
333 | |||
334 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) | ||
335 | dt_do_vdevice(dt, "viocd", reg, i, device_type_block, | ||
336 | "IBM,iSeries-viocd", 1); | ||
337 | reg += HVMAXARCHITECTEDVIRTUALCDROMS; | ||
338 | |||
339 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) | ||
340 | dt_do_vdevice(dt, "viotape", reg, i, device_type_byte, | ||
341 | "IBM,iSeries-viotape", 1); | ||
342 | |||
343 | dt_end_node(dt); | ||
344 | } | ||
345 | |||
346 | struct pci_class_name { | ||
347 | u16 code; | ||
348 | const char *name; | ||
349 | const char *type; | ||
350 | }; | ||
351 | |||
352 | static struct pci_class_name __initdata pci_class_name[] = { | ||
353 | { PCI_CLASS_NETWORK_ETHERNET, "ethernet", device_type_network }, | ||
354 | }; | ||
355 | |||
356 | static struct pci_class_name * __init dt_find_pci_class_name(u16 class_code) | ||
357 | { | ||
358 | struct pci_class_name *cp; | ||
359 | |||
360 | for (cp = pci_class_name; | ||
361 | cp < &pci_class_name[ARRAY_SIZE(pci_class_name)]; cp++) | ||
362 | if (cp->code == class_code) | ||
363 | return cp; | ||
364 | return NULL; | ||
365 | } | ||
366 | |||
367 | /* | ||
368 | * This assumes that the node slot is always on the primary bus! | ||
369 | */ | ||
370 | static void __init scan_bridge_slot(struct iseries_flat_dt *dt, | ||
371 | HvBusNumber bus, struct HvCallPci_BridgeInfo *bridge_info) | ||
372 | { | ||
373 | HvSubBusNumber sub_bus = bridge_info->subBusNumber; | ||
374 | u16 vendor_id; | ||
375 | u16 device_id; | ||
376 | u32 class_id; | ||
377 | int err; | ||
378 | char buf[32]; | ||
379 | u32 reg[5]; | ||
380 | int id_sel = ISERIES_GET_DEVICE_FROM_SUBBUS(sub_bus); | ||
381 | int function = ISERIES_GET_FUNCTION_FROM_SUBBUS(sub_bus); | ||
382 | HvAgentId eads_id_sel = ISERIES_PCI_AGENTID(id_sel, function); | ||
383 | u8 devfn; | ||
384 | struct pci_class_name *cp; | ||
385 | |||
386 | /* | ||
387 | * Connect all functions of any device found. | ||
388 | */ | ||
389 | for (id_sel = 1; id_sel <= bridge_info->maxAgents; id_sel++) { | ||
390 | for (function = 0; function < 8; function++) { | ||
391 | HvAgentId agent_id = ISERIES_PCI_AGENTID(id_sel, | ||
392 | function); | ||
393 | err = HvCallXm_connectBusUnit(bus, sub_bus, | ||
394 | agent_id, 0); | ||
395 | if (err) { | ||
396 | if (err != 0x302) | ||
397 | DBG("connectBusUnit(%x, %x, %x) %x\n", | ||
398 | bus, sub_bus, agent_id, err); | ||
399 | continue; | ||
400 | } | ||
401 | |||
402 | err = HvCallPci_configLoad16(bus, sub_bus, agent_id, | ||
403 | PCI_VENDOR_ID, &vendor_id); | ||
404 | if (err) { | ||
405 | DBG("ReadVendor(%x, %x, %x) %x\n", | ||
406 | bus, sub_bus, agent_id, err); | ||
407 | continue; | ||
408 | } | ||
409 | err = HvCallPci_configLoad16(bus, sub_bus, agent_id, | ||
410 | PCI_DEVICE_ID, &device_id); | ||
411 | if (err) { | ||
412 | DBG("ReadDevice(%x, %x, %x) %x\n", | ||
413 | bus, sub_bus, agent_id, err); | ||
414 | continue; | ||
415 | } | ||
416 | err = HvCallPci_configLoad32(bus, sub_bus, agent_id, | ||
417 | PCI_CLASS_REVISION , &class_id); | ||
418 | if (err) { | ||
419 | DBG("ReadClass(%x, %x, %x) %x\n", | ||
420 | bus, sub_bus, agent_id, err); | ||
421 | continue; | ||
422 | } | ||
423 | |||
424 | devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(eads_id_sel), | ||
425 | function); | ||
426 | cp = dt_find_pci_class_name(class_id >> 16); | ||
427 | if (cp && cp->name) | ||
428 | strncpy(buf, cp->name, sizeof(buf) - 1); | ||
429 | else | ||
430 | snprintf(buf, sizeof(buf), "pci%x,%x", | ||
431 | vendor_id, device_id); | ||
432 | buf[sizeof(buf) - 1] = '\0'; | ||
433 | snprintf(buf + strlen(buf), sizeof(buf) - strlen(buf), | ||
434 | "@%x", PCI_SLOT(devfn)); | ||
435 | buf[sizeof(buf) - 1] = '\0'; | ||
436 | if (function != 0) | ||
437 | snprintf(buf + strlen(buf), | ||
438 | sizeof(buf) - strlen(buf), | ||
439 | ",%x", function); | ||
440 | dt_start_node(dt, buf); | ||
441 | reg[0] = (bus << 16) | (devfn << 8); | ||
442 | reg[1] = 0; | ||
443 | reg[2] = 0; | ||
444 | reg[3] = 0; | ||
445 | reg[4] = 0; | ||
446 | dt_prop_u32_list(dt, "reg", reg, 5); | ||
447 | if (cp && (cp->type || cp->name)) | ||
448 | dt_prop_str(dt, "device_type", | ||
449 | cp->type ? cp->type : cp->name); | ||
450 | dt_prop_u32(dt, "vendor-id", vendor_id); | ||
451 | dt_prop_u32(dt, "device-id", device_id); | ||
452 | dt_prop_u32(dt, "class-code", class_id >> 8); | ||
453 | dt_prop_u32(dt, "revision-id", class_id & 0xff); | ||
454 | dt_prop_u32(dt, "linux,subbus", sub_bus); | ||
455 | dt_prop_u32(dt, "linux,agent-id", agent_id); | ||
456 | dt_prop_u32(dt, "linux,logical-slot-number", | ||
457 | bridge_info->logicalSlotNumber); | ||
458 | dt_end_node(dt); | ||
459 | |||
460 | } | ||
461 | } | ||
462 | } | ||
463 | |||
464 | static void __init scan_bridge(struct iseries_flat_dt *dt, HvBusNumber bus, | ||
465 | HvSubBusNumber sub_bus, int id_sel) | ||
466 | { | ||
467 | struct HvCallPci_BridgeInfo bridge_info; | ||
468 | HvAgentId agent_id; | ||
469 | int function; | ||
470 | int ret; | ||
471 | |||
472 | /* Note: hvSubBus and irq is always be 0 at this level! */ | ||
473 | for (function = 0; function < 8; ++function) { | ||
474 | agent_id = ISERIES_PCI_AGENTID(id_sel, function); | ||
475 | ret = HvCallXm_connectBusUnit(bus, sub_bus, agent_id, 0); | ||
476 | if (ret != 0) { | ||
477 | if (ret != 0xb) | ||
478 | DBG("connectBusUnit(%x, %x, %x) %x\n", | ||
479 | bus, sub_bus, agent_id, ret); | ||
480 | continue; | ||
481 | } | ||
482 | DBG("found device at bus %d idsel %d func %d (AgentId %x)\n", | ||
483 | bus, id_sel, function, agent_id); | ||
484 | ret = HvCallPci_getBusUnitInfo(bus, sub_bus, agent_id, | ||
485 | iseries_hv_addr(&bridge_info), | ||
486 | sizeof(struct HvCallPci_BridgeInfo)); | ||
487 | if (ret != 0) | ||
488 | continue; | ||
489 | DBG("bridge info: type %x subbus %x " | ||
490 | "maxAgents %x maxsubbus %x logslot %x\n", | ||
491 | bridge_info.busUnitInfo.deviceType, | ||
492 | bridge_info.subBusNumber, | ||
493 | bridge_info.maxAgents, | ||
494 | bridge_info.maxSubBusNumber, | ||
495 | bridge_info.logicalSlotNumber); | ||
496 | if (bridge_info.busUnitInfo.deviceType == | ||
497 | HvCallPci_BridgeDevice) | ||
498 | scan_bridge_slot(dt, bus, &bridge_info); | ||
499 | else | ||
500 | DBG("PCI: Invalid Bridge Configuration(0x%02X)", | ||
501 | bridge_info.busUnitInfo.deviceType); | ||
502 | } | ||
503 | } | ||
504 | |||
505 | static void __init scan_phb(struct iseries_flat_dt *dt, HvBusNumber bus) | ||
506 | { | ||
507 | struct HvCallPci_DeviceInfo dev_info; | ||
508 | const HvSubBusNumber sub_bus = 0; /* EADs is always 0. */ | ||
509 | int err; | ||
510 | int id_sel; | ||
511 | const int max_agents = 8; | ||
512 | |||
513 | /* | ||
514 | * Probe for EADs Bridges | ||
515 | */ | ||
516 | for (id_sel = 1; id_sel < max_agents; ++id_sel) { | ||
517 | err = HvCallPci_getDeviceInfo(bus, sub_bus, id_sel, | ||
518 | iseries_hv_addr(&dev_info), | ||
519 | sizeof(struct HvCallPci_DeviceInfo)); | ||
520 | if (err) { | ||
521 | if (err != 0x302) | ||
522 | DBG("getDeviceInfo(%x, %x, %x) %x\n", | ||
523 | bus, sub_bus, id_sel, err); | ||
524 | continue; | ||
525 | } | ||
526 | if (dev_info.deviceType != HvCallPci_NodeDevice) { | ||
527 | DBG("PCI: Invalid System Configuration" | ||
528 | "(0x%02X) for bus 0x%02x id 0x%02x.\n", | ||
529 | dev_info.deviceType, bus, id_sel); | ||
530 | continue; | ||
531 | } | ||
532 | scan_bridge(dt, bus, sub_bus, id_sel); | ||
533 | } | ||
534 | } | ||
535 | |||
536 | static void __init dt_pci_devices(struct iseries_flat_dt *dt) | ||
537 | { | ||
538 | HvBusNumber bus; | ||
539 | char buf[32]; | ||
540 | u32 buses[2]; | ||
541 | int phb_num = 0; | ||
542 | |||
543 | /* Check all possible buses. */ | ||
544 | for (bus = 0; bus < 256; bus++) { | ||
545 | int err = HvCallXm_testBus(bus); | ||
546 | |||
547 | if (err) { | ||
548 | /* | ||
549 | * Check for Unexpected Return code, a clue that | ||
550 | * something has gone wrong. | ||
551 | */ | ||
552 | if (err != 0x0301) | ||
553 | DBG("Unexpected Return on Probe(0x%02X) " | ||
554 | "0x%04X\n", bus, err); | ||
555 | continue; | ||
556 | } | ||
557 | DBG("bus %d appears to exist\n", bus); | ||
558 | snprintf(buf, 32, "pci@%d", phb_num); | ||
559 | dt_start_node(dt, buf); | ||
560 | dt_prop_str(dt, "device_type", device_type_pci); | ||
561 | dt_prop_str(dt, "compatible", "IBM,iSeries-Logical-PHB"); | ||
562 | dt_prop_u32(dt, "#address-cells", 3); | ||
563 | dt_prop_u32(dt, "#size-cells", 2); | ||
564 | buses[0] = buses[1] = bus; | ||
565 | dt_prop_u32_list(dt, "bus-range", buses, 2); | ||
566 | scan_phb(dt, bus); | ||
567 | dt_end_node(dt); | ||
568 | phb_num++; | ||
569 | } | ||
570 | } | ||
571 | |||
572 | static void dt_finish(struct iseries_flat_dt *dt) | ||
573 | { | ||
574 | dt_push_u32(dt, OF_DT_END); | ||
575 | dt->header.totalsize = (unsigned long)dt_data - (unsigned long)dt; | ||
576 | klimit = ALIGN((unsigned long)dt_data, 8); | ||
577 | } | ||
578 | |||
579 | void * __init build_flat_dt(unsigned long phys_mem_size) | ||
580 | { | ||
581 | struct iseries_flat_dt *iseries_dt; | ||
582 | u64 tmp[2]; | ||
583 | |||
584 | iseries_dt = dt_init(); | ||
585 | |||
586 | dt_start_node(iseries_dt, ""); | ||
587 | |||
588 | dt_prop_u32(iseries_dt, "#address-cells", 2); | ||
589 | dt_prop_u32(iseries_dt, "#size-cells", 2); | ||
590 | dt_model(iseries_dt); | ||
591 | |||
592 | /* /memory */ | ||
593 | dt_start_node(iseries_dt, "memory@0"); | ||
594 | dt_prop_str(iseries_dt, "device_type", device_type_memory); | ||
595 | tmp[0] = 0; | ||
596 | tmp[1] = phys_mem_size; | ||
597 | dt_prop_u64_list(iseries_dt, "reg", tmp, 2); | ||
598 | dt_end_node(iseries_dt); | ||
599 | |||
600 | /* /chosen */ | ||
601 | dt_start_node(iseries_dt, "chosen"); | ||
602 | dt_prop_str(iseries_dt, "bootargs", cmd_line); | ||
603 | dt_end_node(iseries_dt); | ||
604 | |||
605 | dt_cpus(iseries_dt); | ||
606 | |||
607 | dt_vdevices(iseries_dt); | ||
608 | dt_pci_devices(iseries_dt); | ||
609 | |||
610 | dt_end_node(iseries_dt); | ||
611 | |||
612 | dt_finish(iseries_dt); | ||
613 | |||
614 | return iseries_dt; | ||
615 | } | ||
diff --git a/arch/powerpc/platforms/iseries/iommu.c b/arch/powerpc/platforms/iseries/iommu.c index bea0b703f409..e3bd2015f2c9 100644 --- a/arch/powerpc/platforms/iseries/iommu.c +++ b/arch/powerpc/platforms/iseries/iommu.c | |||
@@ -4,6 +4,7 @@ | |||
4 | * Rewrite, cleanup: | 4 | * Rewrite, cleanup: |
5 | * | 5 | * |
6 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation | 6 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation |
7 | * Copyright (C) 2006 Olof Johansson <olof@lixom.net> | ||
7 | * | 8 | * |
8 | * Dynamic DMA mapping support, iSeries-specific parts. | 9 | * Dynamic DMA mapping support, iSeries-specific parts. |
9 | * | 10 | * |
@@ -31,42 +32,37 @@ | |||
31 | #include <asm/tce.h> | 32 | #include <asm/tce.h> |
32 | #include <asm/machdep.h> | 33 | #include <asm/machdep.h> |
33 | #include <asm/abs_addr.h> | 34 | #include <asm/abs_addr.h> |
35 | #include <asm/prom.h> | ||
34 | #include <asm/pci-bridge.h> | 36 | #include <asm/pci-bridge.h> |
35 | #include <asm/iseries/hv_call_xm.h> | 37 | #include <asm/iseries/hv_call_xm.h> |
36 | 38 | #include <asm/iseries/iommu.h> | |
37 | #include "iommu.h" | ||
38 | |||
39 | extern struct list_head iSeries_Global_Device_List; | ||
40 | |||
41 | 39 | ||
42 | static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, | 40 | static void tce_build_iSeries(struct iommu_table *tbl, long index, long npages, |
43 | unsigned long uaddr, enum dma_data_direction direction) | 41 | unsigned long uaddr, enum dma_data_direction direction) |
44 | { | 42 | { |
45 | u64 rc; | 43 | u64 rc; |
46 | union tce_entry tce; | 44 | u64 tce, rpn; |
47 | 45 | ||
48 | index <<= TCE_PAGE_FACTOR; | 46 | index <<= TCE_PAGE_FACTOR; |
49 | npages <<= TCE_PAGE_FACTOR; | 47 | npages <<= TCE_PAGE_FACTOR; |
50 | 48 | ||
51 | while (npages--) { | 49 | while (npages--) { |
52 | tce.te_word = 0; | 50 | rpn = virt_to_abs(uaddr) >> TCE_SHIFT; |
53 | tce.te_bits.tb_rpn = virt_to_abs(uaddr) >> TCE_SHIFT; | 51 | tce = (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; |
54 | 52 | ||
55 | if (tbl->it_type == TCE_VB) { | 53 | if (tbl->it_type == TCE_VB) { |
56 | /* Virtual Bus */ | 54 | /* Virtual Bus */ |
57 | tce.te_bits.tb_valid = 1; | 55 | tce |= TCE_VALID|TCE_ALLIO; |
58 | tce.te_bits.tb_allio = 1; | ||
59 | if (direction != DMA_TO_DEVICE) | 56 | if (direction != DMA_TO_DEVICE) |
60 | tce.te_bits.tb_rdwr = 1; | 57 | tce |= TCE_VB_WRITE; |
61 | } else { | 58 | } else { |
62 | /* PCI Bus */ | 59 | /* PCI Bus */ |
63 | tce.te_bits.tb_rdwr = 1; /* Read allowed */ | 60 | tce |= TCE_PCI_READ; /* Read allowed */ |
64 | if (direction != DMA_TO_DEVICE) | 61 | if (direction != DMA_TO_DEVICE) |
65 | tce.te_bits.tb_pciwr = 1; | 62 | tce |= TCE_PCI_WRITE; |
66 | } | 63 | } |
67 | 64 | ||
68 | rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, | 65 | rc = HvCallXm_setTce((u64)tbl->it_index, (u64)index, tce); |
69 | tce.te_word); | ||
70 | if (rc) | 66 | if (rc) |
71 | panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", | 67 | panic("PCI_DMA: HvCallXm_setTce failed, Rc: 0x%lx\n", |
72 | rc); | 68 | rc); |
@@ -124,7 +120,7 @@ void iommu_table_getparms_iSeries(unsigned long busno, | |||
124 | 120 | ||
125 | /* itc_size is in pages worth of table, it_size is in # of entries */ | 121 | /* itc_size is in pages worth of table, it_size is in # of entries */ |
126 | tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / | 122 | tbl->it_size = ((parms->itc_size * TCE_PAGE_SIZE) / |
127 | sizeof(union tce_entry)) >> TCE_PAGE_FACTOR; | 123 | TCE_ENTRY_SIZE) >> TCE_PAGE_FACTOR; |
128 | tbl->it_busno = parms->itc_busno; | 124 | tbl->it_busno = parms->itc_busno; |
129 | tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; | 125 | tbl->it_offset = parms->itc_offset >> TCE_PAGE_FACTOR; |
130 | tbl->it_index = parms->itc_index; | 126 | tbl->it_index = parms->itc_index; |
@@ -142,10 +138,15 @@ void iommu_table_getparms_iSeries(unsigned long busno, | |||
142 | */ | 138 | */ |
143 | static struct iommu_table *iommu_table_find(struct iommu_table * tbl) | 139 | static struct iommu_table *iommu_table_find(struct iommu_table * tbl) |
144 | { | 140 | { |
145 | struct pci_dn *pdn; | 141 | struct device_node *node; |
146 | 142 | ||
147 | list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) { | 143 | for (node = NULL; (node = of_find_all_nodes(node)); ) { |
148 | struct iommu_table *it = pdn->iommu_table; | 144 | struct pci_dn *pdn = PCI_DN(node); |
145 | struct iommu_table *it; | ||
146 | |||
147 | if (pdn == NULL) | ||
148 | continue; | ||
149 | it = pdn->iommu_table; | ||
149 | if ((it != NULL) && | 150 | if ((it != NULL) && |
150 | (it->it_type == TCE_PCI) && | 151 | (it->it_type == TCE_PCI) && |
151 | (it->it_offset == tbl->it_offset) && | 152 | (it->it_offset == tbl->it_offset) && |
@@ -161,15 +162,18 @@ void iommu_devnode_init_iSeries(struct device_node *dn) | |||
161 | { | 162 | { |
162 | struct iommu_table *tbl; | 163 | struct iommu_table *tbl; |
163 | struct pci_dn *pdn = PCI_DN(dn); | 164 | struct pci_dn *pdn = PCI_DN(dn); |
165 | u32 *lsn = (u32 *)get_property(dn, "linux,logical-slot-number", NULL); | ||
166 | |||
167 | BUG_ON(lsn == NULL); | ||
164 | 168 | ||
165 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 169 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); |
166 | 170 | ||
167 | iommu_table_getparms_iSeries(pdn->busno, pdn->LogicalSlot, 0, tbl); | 171 | iommu_table_getparms_iSeries(pdn->busno, *lsn, 0, tbl); |
168 | 172 | ||
169 | /* Look for existing tce table */ | 173 | /* Look for existing tce table */ |
170 | pdn->iommu_table = iommu_table_find(tbl); | 174 | pdn->iommu_table = iommu_table_find(tbl); |
171 | if (pdn->iommu_table == NULL) | 175 | if (pdn->iommu_table == NULL) |
172 | pdn->iommu_table = iommu_init_table(tbl); | 176 | pdn->iommu_table = iommu_init_table(tbl, -1); |
173 | else | 177 | else |
174 | kfree(tbl); | 178 | kfree(tbl); |
175 | } | 179 | } |
diff --git a/arch/powerpc/platforms/iseries/iommu.h b/arch/powerpc/platforms/iseries/iommu.h deleted file mode 100644 index cb5658fbe657..000000000000 --- a/arch/powerpc/platforms/iseries/iommu.h +++ /dev/null | |||
@@ -1,35 +0,0 @@ | |||
1 | #ifndef _PLATFORMS_ISERIES_IOMMU_H | ||
2 | #define _PLATFORMS_ISERIES_IOMMU_H | ||
3 | |||
4 | /* | ||
5 | * Copyright (C) 2005 Stephen Rothwell, IBM Corporation | ||
6 | * | ||
7 | * This program is free software; you can redistribute it and/or modify | ||
8 | * it under the terms of the GNU General Public License as published by | ||
9 | * the Free Software Foundation; either version 2 of the License, or | ||
10 | * (at your option) any later version. | ||
11 | * | ||
12 | * This program is distributed in the hope that it will be useful, | ||
13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
15 | * GNU General Public License for more details. | ||
16 | * | ||
17 | * You should have received a copy of the GNU General Public License | ||
18 | * along with this program; if not, write to the: | ||
19 | * Free Software Foundation, Inc., | ||
20 | * 59 Temple Place, Suite 330, | ||
21 | * Boston, MA 02111-1307 USA | ||
22 | */ | ||
23 | |||
24 | struct device_node; | ||
25 | struct iommu_table; | ||
26 | |||
27 | /* Creates table for an individual device node */ | ||
28 | extern void iommu_devnode_init_iSeries(struct device_node *dn); | ||
29 | |||
30 | /* Get table parameters from HV */ | ||
31 | extern void iommu_table_getparms_iSeries(unsigned long busno, | ||
32 | unsigned char slotno, unsigned char virtbus, | ||
33 | struct iommu_table *tbl); | ||
34 | |||
35 | #endif /* _PLATFORMS_ISERIES_IOMMU_H */ | ||
diff --git a/arch/powerpc/platforms/iseries/irq.c b/arch/powerpc/platforms/iseries/irq.c index be3fbfc24e6c..62bbbcf5ded3 100644 --- a/arch/powerpc/platforms/iseries/irq.c +++ b/arch/powerpc/platforms/iseries/irq.c | |||
@@ -42,6 +42,7 @@ | |||
42 | #include <asm/iseries/it_lp_queue.h> | 42 | #include <asm/iseries/it_lp_queue.h> |
43 | 43 | ||
44 | #include "irq.h" | 44 | #include "irq.h" |
45 | #include "pci.h" | ||
45 | #include "call_pci.h" | 46 | #include "call_pci.h" |
46 | 47 | ||
47 | #if defined(CONFIG_SMP) | 48 | #if defined(CONFIG_SMP) |
@@ -312,12 +313,12 @@ static hw_irq_controller iSeries_IRQ_handler = { | |||
312 | * Note that sub_bus is always 0 (at the moment at least). | 313 | * Note that sub_bus is always 0 (at the moment at least). |
313 | */ | 314 | */ |
314 | int __init iSeries_allocate_IRQ(HvBusNumber bus, | 315 | int __init iSeries_allocate_IRQ(HvBusNumber bus, |
315 | HvSubBusNumber sub_bus, HvAgentId dev_id) | 316 | HvSubBusNumber sub_bus, u32 bsubbus) |
316 | { | 317 | { |
317 | int virtirq; | 318 | int virtirq; |
318 | unsigned int realirq; | 319 | unsigned int realirq; |
319 | u8 idsel = (dev_id >> 4); | 320 | u8 idsel = ISERIES_GET_DEVICE_FROM_SUBBUS(bsubbus); |
320 | u8 function = dev_id & 7; | 321 | u8 function = ISERIES_GET_FUNCTION_FROM_SUBBUS(bsubbus); |
321 | 322 | ||
322 | realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3) | 323 | realirq = (((((sub_bus << 8) + (bus - 1)) << 3) + (idsel - 1)) << 3) |
323 | + function; | 324 | + function; |
diff --git a/arch/powerpc/platforms/iseries/irq.h b/arch/powerpc/platforms/iseries/irq.h index b9c801ba5a47..188aa808abd7 100644 --- a/arch/powerpc/platforms/iseries/irq.h +++ b/arch/powerpc/platforms/iseries/irq.h | |||
@@ -2,7 +2,7 @@ | |||
2 | #define _ISERIES_IRQ_H | 2 | #define _ISERIES_IRQ_H |
3 | 3 | ||
4 | extern void iSeries_init_IRQ(void); | 4 | extern void iSeries_init_IRQ(void); |
5 | extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, HvAgentId); | 5 | extern int iSeries_allocate_IRQ(HvBusNumber, HvSubBusNumber, u32); |
6 | extern void iSeries_activate_IRQs(void); | 6 | extern void iSeries_activate_IRQs(void); |
7 | extern int iSeries_get_irq(struct pt_regs *); | 7 | extern int iSeries_get_irq(struct pt_regs *); |
8 | 8 | ||
diff --git a/arch/powerpc/platforms/iseries/mf.c b/arch/powerpc/platforms/iseries/mf.c index d771b8ee857d..1a2c2a50f922 100644 --- a/arch/powerpc/platforms/iseries/mf.c +++ b/arch/powerpc/platforms/iseries/mf.c | |||
@@ -45,7 +45,6 @@ | |||
45 | 45 | ||
46 | #include "setup.h" | 46 | #include "setup.h" |
47 | 47 | ||
48 | extern int piranha_simulator; | ||
49 | static int mf_initialized; | 48 | static int mf_initialized; |
50 | 49 | ||
51 | /* | 50 | /* |
@@ -658,7 +657,7 @@ static void mf_clear_src(void) | |||
658 | 657 | ||
659 | void __init mf_display_progress(u16 value) | 658 | void __init mf_display_progress(u16 value) |
660 | { | 659 | { |
661 | if (piranha_simulator || !mf_initialized) | 660 | if (!mf_initialized) |
662 | return; | 661 | return; |
663 | 662 | ||
664 | if (0xFFFF == value) | 663 | if (0xFFFF == value) |
@@ -1295,9 +1294,6 @@ __initcall(mf_proc_init); | |||
1295 | */ | 1294 | */ |
1296 | void iSeries_get_rtc_time(struct rtc_time *rtc_tm) | 1295 | void iSeries_get_rtc_time(struct rtc_time *rtc_tm) |
1297 | { | 1296 | { |
1298 | if (piranha_simulator) | ||
1299 | return; | ||
1300 | |||
1301 | mf_get_rtc(rtc_tm); | 1297 | mf_get_rtc(rtc_tm); |
1302 | rtc_tm->tm_mon--; | 1298 | rtc_tm->tm_mon--; |
1303 | } | 1299 | } |
@@ -1316,9 +1312,6 @@ unsigned long iSeries_get_boot_time(void) | |||
1316 | { | 1312 | { |
1317 | struct rtc_time tm; | 1313 | struct rtc_time tm; |
1318 | 1314 | ||
1319 | if (piranha_simulator) | ||
1320 | return 0; | ||
1321 | |||
1322 | mf_get_boot_rtc(&tm); | 1315 | mf_get_boot_rtc(&tm); |
1323 | return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday, | 1316 | return mktime(tm.tm_year + 1900, tm.tm_mon, tm.tm_mday, |
1324 | tm.tm_hour, tm.tm_min, tm.tm_sec); | 1317 | tm.tm_hour, tm.tm_min, tm.tm_sec); |
diff --git a/arch/powerpc/platforms/iseries/pci.c b/arch/powerpc/platforms/iseries/pci.c index a19833b880e4..35bcc98111f5 100644 --- a/arch/powerpc/platforms/iseries/pci.c +++ b/arch/powerpc/platforms/iseries/pci.c | |||
@@ -37,36 +37,18 @@ | |||
37 | 37 | ||
38 | #include <asm/iseries/hv_call_xm.h> | 38 | #include <asm/iseries/hv_call_xm.h> |
39 | #include <asm/iseries/mf.h> | 39 | #include <asm/iseries/mf.h> |
40 | #include <asm/iseries/iommu.h> | ||
40 | 41 | ||
41 | #include <asm/ppc-pci.h> | 42 | #include <asm/ppc-pci.h> |
42 | 43 | ||
43 | #include "irq.h" | 44 | #include "irq.h" |
44 | #include "pci.h" | 45 | #include "pci.h" |
45 | #include "call_pci.h" | 46 | #include "call_pci.h" |
46 | #include "iommu.h" | ||
47 | |||
48 | extern unsigned long io_page_mask; | ||
49 | 47 | ||
50 | /* | 48 | /* |
51 | * Forward declares of prototypes. | 49 | * Forward declares of prototypes. |
52 | */ | 50 | */ |
53 | static struct device_node *find_Device_Node(int bus, int devfn); | 51 | static struct device_node *find_Device_Node(int bus, int devfn); |
54 | static void scan_PHB_slots(struct pci_controller *Phb); | ||
55 | static void scan_EADS_bridge(HvBusNumber Bus, HvSubBusNumber SubBus, int IdSel); | ||
56 | static int scan_bridge_slot(HvBusNumber Bus, struct HvCallPci_BridgeInfo *Info); | ||
57 | |||
58 | LIST_HEAD(iSeries_Global_Device_List); | ||
59 | |||
60 | static int DeviceCount; | ||
61 | |||
62 | /* Counters and control flags. */ | ||
63 | static long Pci_Io_Read_Count; | ||
64 | static long Pci_Io_Write_Count; | ||
65 | #if 0 | ||
66 | static long Pci_Cfg_Read_Count; | ||
67 | static long Pci_Cfg_Write_Count; | ||
68 | #endif | ||
69 | static long Pci_Error_Count; | ||
70 | 52 | ||
71 | static int Pci_Retry_Max = 3; /* Only retry 3 times */ | 53 | static int Pci_Retry_Max = 3; /* Only retry 3 times */ |
72 | static int Pci_Error_Flag = 1; /* Set Retry Error on. */ | 54 | static int Pci_Error_Flag = 1; /* Set Retry Error on. */ |
@@ -81,41 +63,19 @@ static struct pci_ops iSeries_pci_ops; | |||
81 | #define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL | 63 | #define IOMM_TABLE_ENTRY_SIZE 0x0000000000400000UL |
82 | #define BASE_IO_MEMORY 0xE000000000000000UL | 64 | #define BASE_IO_MEMORY 0xE000000000000000UL |
83 | 65 | ||
84 | static unsigned long max_io_memory = 0xE000000000000000UL; | 66 | static unsigned long max_io_memory = BASE_IO_MEMORY; |
85 | static long current_iomm_table_entry; | 67 | static long current_iomm_table_entry; |
86 | 68 | ||
87 | /* | 69 | /* |
88 | * Lookup Tables. | 70 | * Lookup Tables. |
89 | */ | 71 | */ |
90 | static struct device_node **iomm_table; | 72 | static struct device_node *iomm_table[IOMM_TABLE_MAX_ENTRIES]; |
91 | static u8 *iobar_table; | 73 | static u8 iobar_table[IOMM_TABLE_MAX_ENTRIES]; |
92 | 74 | ||
93 | /* | 75 | static const char pci_io_text[] = "iSeries PCI I/O"; |
94 | * Static and Global variables | ||
95 | */ | ||
96 | static char *pci_io_text = "iSeries PCI I/O"; | ||
97 | static DEFINE_SPINLOCK(iomm_table_lock); | 76 | static DEFINE_SPINLOCK(iomm_table_lock); |
98 | 77 | ||
99 | /* | 78 | /* |
100 | * iomm_table_initialize | ||
101 | * | ||
102 | * Allocates and initalizes the Address Translation Table and Bar | ||
103 | * Tables to get them ready for use. Must be called before any | ||
104 | * I/O space is handed out to the device BARs. | ||
105 | */ | ||
106 | static void iomm_table_initialize(void) | ||
107 | { | ||
108 | spin_lock(&iomm_table_lock); | ||
109 | iomm_table = kmalloc(sizeof(*iomm_table) * IOMM_TABLE_MAX_ENTRIES, | ||
110 | GFP_KERNEL); | ||
111 | iobar_table = kmalloc(sizeof(*iobar_table) * IOMM_TABLE_MAX_ENTRIES, | ||
112 | GFP_KERNEL); | ||
113 | spin_unlock(&iomm_table_lock); | ||
114 | if ((iomm_table == NULL) || (iobar_table == NULL)) | ||
115 | panic("PCI: I/O tables allocation failed.\n"); | ||
116 | } | ||
117 | |||
118 | /* | ||
119 | * iomm_table_allocate_entry | 79 | * iomm_table_allocate_entry |
120 | * | 80 | * |
121 | * Adds pci_dev entry in address translation table | 81 | * Adds pci_dev entry in address translation table |
@@ -142,9 +102,8 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) | |||
142 | */ | 102 | */ |
143 | spin_lock(&iomm_table_lock); | 103 | spin_lock(&iomm_table_lock); |
144 | bar_res->name = pci_io_text; | 104 | bar_res->name = pci_io_text; |
145 | bar_res->start = | 105 | bar_res->start = BASE_IO_MEMORY + |
146 | IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry; | 106 | IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry; |
147 | bar_res->start += BASE_IO_MEMORY; | ||
148 | bar_res->end = bar_res->start + bar_size - 1; | 107 | bar_res->end = bar_res->start + bar_size - 1; |
149 | /* | 108 | /* |
150 | * Allocate the number of table entries needed for BAR. | 109 | * Allocate the number of table entries needed for BAR. |
@@ -156,7 +115,7 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) | |||
156 | ++current_iomm_table_entry; | 115 | ++current_iomm_table_entry; |
157 | } | 116 | } |
158 | max_io_memory = BASE_IO_MEMORY + | 117 | max_io_memory = BASE_IO_MEMORY + |
159 | (IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry); | 118 | IOMM_TABLE_ENTRY_SIZE * current_iomm_table_entry; |
160 | spin_unlock(&iomm_table_lock); | 119 | spin_unlock(&iomm_table_lock); |
161 | } | 120 | } |
162 | 121 | ||
@@ -173,13 +132,10 @@ static void iomm_table_allocate_entry(struct pci_dev *dev, int bar_num) | |||
173 | */ | 132 | */ |
174 | static void allocate_device_bars(struct pci_dev *dev) | 133 | static void allocate_device_bars(struct pci_dev *dev) |
175 | { | 134 | { |
176 | struct resource *bar_res; | ||
177 | int bar_num; | 135 | int bar_num; |
178 | 136 | ||
179 | for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) { | 137 | for (bar_num = 0; bar_num <= PCI_ROM_RESOURCE; ++bar_num) |
180 | bar_res = &dev->resource[bar_num]; | ||
181 | iomm_table_allocate_entry(dev, bar_num); | 138 | iomm_table_allocate_entry(dev, bar_num); |
182 | } | ||
183 | } | 139 | } |
184 | 140 | ||
185 | /* | 141 | /* |
@@ -199,34 +155,7 @@ static void pci_Log_Error(char *Error_Text, int Bus, int SubBus, | |||
199 | } | 155 | } |
200 | 156 | ||
201 | /* | 157 | /* |
202 | * build_device_node(u16 Bus, int SubBus, u8 DevFn) | 158 | * iSeries_pcibios_init |
203 | */ | ||
204 | static struct device_node *build_device_node(HvBusNumber Bus, | ||
205 | HvSubBusNumber SubBus, int AgentId, int Function) | ||
206 | { | ||
207 | struct device_node *node; | ||
208 | struct pci_dn *pdn; | ||
209 | |||
210 | node = kmalloc(sizeof(struct device_node), GFP_KERNEL); | ||
211 | if (node == NULL) | ||
212 | return NULL; | ||
213 | memset(node, 0, sizeof(struct device_node)); | ||
214 | pdn = kzalloc(sizeof(*pdn), GFP_KERNEL); | ||
215 | if (pdn == NULL) { | ||
216 | kfree(node); | ||
217 | return NULL; | ||
218 | } | ||
219 | node->data = pdn; | ||
220 | pdn->node = node; | ||
221 | list_add_tail(&pdn->Device_List, &iSeries_Global_Device_List); | ||
222 | pdn->busno = Bus; | ||
223 | pdn->bussubno = SubBus; | ||
224 | pdn->devfn = PCI_DEVFN(ISERIES_ENCODE_DEVICE(AgentId), Function); | ||
225 | return node; | ||
226 | } | ||
227 | |||
228 | /* | ||
229 | * unsigned long __init find_and_init_phbs(void) | ||
230 | * | 159 | * |
231 | * Description: | 160 | * Description: |
232 | * This function checks for all possible system PCI host bridges that connect | 161 | * This function checks for all possible system PCI host bridges that connect |
@@ -234,50 +163,42 @@ static struct device_node *build_device_node(HvBusNumber Bus, | |||
234 | * ownership status. A pci_controller is built for any bus which is partially | 163 | * ownership status. A pci_controller is built for any bus which is partially |
235 | * owned or fully owned by this guest partition. | 164 | * owned or fully owned by this guest partition. |
236 | */ | 165 | */ |
237 | unsigned long __init find_and_init_phbs(void) | 166 | void iSeries_pcibios_init(void) |
238 | { | 167 | { |
239 | struct pci_controller *phb; | 168 | struct pci_controller *phb; |
240 | HvBusNumber bus; | 169 | struct device_node *root = of_find_node_by_path("/"); |
241 | 170 | struct device_node *node = NULL; | |
242 | /* Check all possible buses. */ | ||
243 | for (bus = 0; bus < 256; bus++) { | ||
244 | int ret = HvCallXm_testBus(bus); | ||
245 | if (ret == 0) { | ||
246 | printk("bus %d appears to exist\n", bus); | ||
247 | 171 | ||
248 | phb = pcibios_alloc_controller(NULL); | 172 | if (root == NULL) { |
249 | if (phb == NULL) | 173 | printk(KERN_CRIT "iSeries_pcibios_init: can't find root " |
250 | return -ENOMEM; | 174 | "of device tree\n"); |
251 | 175 | return; | |
252 | phb->pci_mem_offset = phb->local_number = bus; | 176 | } |
253 | phb->first_busno = bus; | 177 | while ((node = of_get_next_child(root, node)) != NULL) { |
254 | phb->last_busno = bus; | 178 | HvBusNumber bus; |
255 | phb->ops = &iSeries_pci_ops; | 179 | u32 *busp; |
256 | 180 | ||
257 | /* Find and connect the devices. */ | 181 | if ((node->type == NULL) || (strcmp(node->type, "pci") != 0)) |
258 | scan_PHB_slots(phb); | 182 | continue; |
259 | } | 183 | |
260 | /* | 184 | busp = (u32 *)get_property(node, "bus-range", NULL); |
261 | * Check for Unexpected Return code, a clue that something | 185 | if (busp == NULL) |
262 | * has gone wrong. | 186 | continue; |
263 | */ | 187 | bus = *busp; |
264 | else if (ret != 0x0301) | 188 | printk("bus %d appears to exist\n", bus); |
265 | printk(KERN_ERR "Unexpected Return on Probe(0x%04X): 0x%04X", | 189 | phb = pcibios_alloc_controller(node); |
266 | bus, ret); | 190 | if (phb == NULL) |
191 | continue; | ||
192 | |||
193 | phb->pci_mem_offset = phb->local_number = bus; | ||
194 | phb->first_busno = bus; | ||
195 | phb->last_busno = bus; | ||
196 | phb->ops = &iSeries_pci_ops; | ||
267 | } | 197 | } |
268 | return 0; | ||
269 | } | ||
270 | 198 | ||
271 | /* | 199 | of_node_put(root); |
272 | * iSeries_pcibios_init | 200 | |
273 | * | 201 | pci_devs_phb_init(); |
274 | * Chance to initialize and structures or variable before PCI Bus walk. | ||
275 | */ | ||
276 | void iSeries_pcibios_init(void) | ||
277 | { | ||
278 | iomm_table_initialize(); | ||
279 | find_and_init_phbs(); | ||
280 | io_page_mask = -1; | ||
281 | } | 202 | } |
282 | 203 | ||
283 | /* | 204 | /* |
@@ -299,6 +220,34 @@ void __init iSeries_pci_final_fixup(void) | |||
299 | pdev->bus->number, pdev->devfn, node); | 220 | pdev->bus->number, pdev->devfn, node); |
300 | 221 | ||
301 | if (node != NULL) { | 222 | if (node != NULL) { |
223 | struct pci_dn *pdn = PCI_DN(node); | ||
224 | u32 *agent; | ||
225 | |||
226 | agent = (u32 *)get_property(node, "linux,agent-id", | ||
227 | NULL); | ||
228 | if ((pdn != NULL) && (agent != NULL)) { | ||
229 | u8 irq = iSeries_allocate_IRQ(pdn->busno, 0, | ||
230 | pdn->bussubno); | ||
231 | int err; | ||
232 | |||
233 | err = HvCallXm_connectBusUnit(pdn->busno, pdn->bussubno, | ||
234 | *agent, irq); | ||
235 | if (err) | ||
236 | pci_Log_Error("Connect Bus Unit", | ||
237 | pdn->busno, pdn->bussubno, *agent, err); | ||
238 | else { | ||
239 | err = HvCallPci_configStore8(pdn->busno, pdn->bussubno, | ||
240 | *agent, | ||
241 | PCI_INTERRUPT_LINE, | ||
242 | irq); | ||
243 | if (err) | ||
244 | pci_Log_Error("PciCfgStore Irq Failed!", | ||
245 | pdn->busno, pdn->bussubno, *agent, err); | ||
246 | } | ||
247 | if (!err) | ||
248 | pdev->irq = irq; | ||
249 | } | ||
250 | |||
302 | ++DeviceCount; | 251 | ++DeviceCount; |
303 | pdev->sysdata = (void *)node; | 252 | pdev->sysdata = (void *)node; |
304 | PCI_DN(node)->pcidev = pdev; | 253 | PCI_DN(node)->pcidev = pdev; |
@@ -308,7 +257,6 @@ void __init iSeries_pci_final_fixup(void) | |||
308 | } else | 257 | } else |
309 | printk("PCI: Device Tree not found for 0x%016lX\n", | 258 | printk("PCI: Device Tree not found for 0x%016lX\n", |
310 | (unsigned long)pdev); | 259 | (unsigned long)pdev); |
311 | pdev->irq = PCI_DN(node)->Irq; | ||
312 | } | 260 | } |
313 | iSeries_activate_IRQs(); | 261 | iSeries_activate_IRQs(); |
314 | mf_display_src(0xC9000200); | 262 | mf_display_src(0xC9000200); |
@@ -323,148 +271,6 @@ void pcibios_fixup_resources(struct pci_dev *pdev) | |||
323 | } | 271 | } |
324 | 272 | ||
325 | /* | 273 | /* |
326 | * Loop through each node function to find usable EADs bridges. | ||
327 | */ | ||
328 | static void scan_PHB_slots(struct pci_controller *Phb) | ||
329 | { | ||
330 | struct HvCallPci_DeviceInfo *DevInfo; | ||
331 | HvBusNumber bus = Phb->local_number; /* System Bus */ | ||
332 | const HvSubBusNumber SubBus = 0; /* EADs is always 0. */ | ||
333 | int HvRc = 0; | ||
334 | int IdSel; | ||
335 | const int MaxAgents = 8; | ||
336 | |||
337 | DevInfo = (struct HvCallPci_DeviceInfo*) | ||
338 | kmalloc(sizeof(struct HvCallPci_DeviceInfo), GFP_KERNEL); | ||
339 | if (DevInfo == NULL) | ||
340 | return; | ||
341 | |||
342 | /* | ||
343 | * Probe for EADs Bridges | ||
344 | */ | ||
345 | for (IdSel = 1; IdSel < MaxAgents; ++IdSel) { | ||
346 | HvRc = HvCallPci_getDeviceInfo(bus, SubBus, IdSel, | ||
347 | iseries_hv_addr(DevInfo), | ||
348 | sizeof(struct HvCallPci_DeviceInfo)); | ||
349 | if (HvRc == 0) { | ||
350 | if (DevInfo->deviceType == HvCallPci_NodeDevice) | ||
351 | scan_EADS_bridge(bus, SubBus, IdSel); | ||
352 | else | ||
353 | printk("PCI: Invalid System Configuration(0x%02X)" | ||
354 | " for bus 0x%02x id 0x%02x.\n", | ||
355 | DevInfo->deviceType, bus, IdSel); | ||
356 | } | ||
357 | else | ||
358 | pci_Log_Error("getDeviceInfo", bus, SubBus, IdSel, HvRc); | ||
359 | } | ||
360 | kfree(DevInfo); | ||
361 | } | ||
362 | |||
363 | static void scan_EADS_bridge(HvBusNumber bus, HvSubBusNumber SubBus, | ||
364 | int IdSel) | ||
365 | { | ||
366 | struct HvCallPci_BridgeInfo *BridgeInfo; | ||
367 | HvAgentId AgentId; | ||
368 | int Function; | ||
369 | int HvRc; | ||
370 | |||
371 | BridgeInfo = (struct HvCallPci_BridgeInfo *) | ||
372 | kmalloc(sizeof(struct HvCallPci_BridgeInfo), GFP_KERNEL); | ||
373 | if (BridgeInfo == NULL) | ||
374 | return; | ||
375 | |||
376 | /* Note: hvSubBus and irq is always be 0 at this level! */ | ||
377 | for (Function = 0; Function < 8; ++Function) { | ||
378 | AgentId = ISERIES_PCI_AGENTID(IdSel, Function); | ||
379 | HvRc = HvCallXm_connectBusUnit(bus, SubBus, AgentId, 0); | ||
380 | if (HvRc == 0) { | ||
381 | printk("found device at bus %d idsel %d func %d (AgentId %x)\n", | ||
382 | bus, IdSel, Function, AgentId); | ||
383 | /* Connect EADs: 0x18.00.12 = 0x00 */ | ||
384 | HvRc = HvCallPci_getBusUnitInfo(bus, SubBus, AgentId, | ||
385 | iseries_hv_addr(BridgeInfo), | ||
386 | sizeof(struct HvCallPci_BridgeInfo)); | ||
387 | if (HvRc == 0) { | ||
388 | printk("bridge info: type %x subbus %x maxAgents %x maxsubbus %x logslot %x\n", | ||
389 | BridgeInfo->busUnitInfo.deviceType, | ||
390 | BridgeInfo->subBusNumber, | ||
391 | BridgeInfo->maxAgents, | ||
392 | BridgeInfo->maxSubBusNumber, | ||
393 | BridgeInfo->logicalSlotNumber); | ||
394 | if (BridgeInfo->busUnitInfo.deviceType == | ||
395 | HvCallPci_BridgeDevice) { | ||
396 | /* Scan_Bridge_Slot...: 0x18.00.12 */ | ||
397 | scan_bridge_slot(bus, BridgeInfo); | ||
398 | } else | ||
399 | printk("PCI: Invalid Bridge Configuration(0x%02X)", | ||
400 | BridgeInfo->busUnitInfo.deviceType); | ||
401 | } | ||
402 | } else if (HvRc != 0x000B) | ||
403 | pci_Log_Error("EADs Connect", | ||
404 | bus, SubBus, AgentId, HvRc); | ||
405 | } | ||
406 | kfree(BridgeInfo); | ||
407 | } | ||
408 | |||
409 | /* | ||
410 | * This assumes that the node slot is always on the primary bus! | ||
411 | */ | ||
412 | static int scan_bridge_slot(HvBusNumber Bus, | ||
413 | struct HvCallPci_BridgeInfo *BridgeInfo) | ||
414 | { | ||
415 | struct device_node *node; | ||
416 | HvSubBusNumber SubBus = BridgeInfo->subBusNumber; | ||
417 | u16 VendorId = 0; | ||
418 | int HvRc = 0; | ||
419 | u8 Irq = 0; | ||
420 | int IdSel = ISERIES_GET_DEVICE_FROM_SUBBUS(SubBus); | ||
421 | int Function = ISERIES_GET_FUNCTION_FROM_SUBBUS(SubBus); | ||
422 | HvAgentId EADsIdSel = ISERIES_PCI_AGENTID(IdSel, Function); | ||
423 | |||
424 | /* iSeries_allocate_IRQ.: 0x18.00.12(0xA3) */ | ||
425 | Irq = iSeries_allocate_IRQ(Bus, 0, EADsIdSel); | ||
426 | |||
427 | /* | ||
428 | * Connect all functions of any device found. | ||
429 | */ | ||
430 | for (IdSel = 1; IdSel <= BridgeInfo->maxAgents; ++IdSel) { | ||
431 | for (Function = 0; Function < 8; ++Function) { | ||
432 | HvAgentId AgentId = ISERIES_PCI_AGENTID(IdSel, Function); | ||
433 | HvRc = HvCallXm_connectBusUnit(Bus, SubBus, | ||
434 | AgentId, Irq); | ||
435 | if (HvRc != 0) { | ||
436 | pci_Log_Error("Connect Bus Unit", | ||
437 | Bus, SubBus, AgentId, HvRc); | ||
438 | continue; | ||
439 | } | ||
440 | |||
441 | HvRc = HvCallPci_configLoad16(Bus, SubBus, AgentId, | ||
442 | PCI_VENDOR_ID, &VendorId); | ||
443 | if (HvRc != 0) { | ||
444 | pci_Log_Error("Read Vendor", | ||
445 | Bus, SubBus, AgentId, HvRc); | ||
446 | continue; | ||
447 | } | ||
448 | printk("read vendor ID: %x\n", VendorId); | ||
449 | |||
450 | /* FoundDevice: 0x18.28.10 = 0x12AE */ | ||
451 | HvRc = HvCallPci_configStore8(Bus, SubBus, AgentId, | ||
452 | PCI_INTERRUPT_LINE, Irq); | ||
453 | if (HvRc != 0) | ||
454 | pci_Log_Error("PciCfgStore Irq Failed!", | ||
455 | Bus, SubBus, AgentId, HvRc); | ||
456 | |||
457 | ++DeviceCount; | ||
458 | node = build_device_node(Bus, SubBus, EADsIdSel, Function); | ||
459 | PCI_DN(node)->Irq = Irq; | ||
460 | PCI_DN(node)->LogicalSlot = BridgeInfo->logicalSlotNumber; | ||
461 | |||
462 | } /* for (Function = 0; Function < 8; ++Function) */ | ||
463 | } /* for (IdSel = 1; IdSel <= MaxAgents; ++IdSel) */ | ||
464 | return HvRc; | ||
465 | } | ||
466 | |||
467 | /* | ||
468 | * I/0 Memory copy MUST use mmio commands on iSeries | 274 | * I/0 Memory copy MUST use mmio commands on iSeries |
469 | * To do; For performance, include the hv call directly | 275 | * To do; For performance, include the hv call directly |
470 | */ | 276 | */ |
@@ -509,11 +315,13 @@ EXPORT_SYMBOL(iSeries_memcpy_fromio); | |||
509 | */ | 315 | */ |
510 | static struct device_node *find_Device_Node(int bus, int devfn) | 316 | static struct device_node *find_Device_Node(int bus, int devfn) |
511 | { | 317 | { |
512 | struct pci_dn *pdn; | 318 | struct device_node *node; |
319 | |||
320 | for (node = NULL; (node = of_find_all_nodes(node)); ) { | ||
321 | struct pci_dn *pdn = PCI_DN(node); | ||
513 | 322 | ||
514 | list_for_each_entry(pdn, &iSeries_Global_Device_List, Device_List) { | 323 | if (pdn && (bus == pdn->busno) && (devfn == pdn->devfn)) |
515 | if ((bus == pdn->busno) && (devfn == pdn->devfn)) | 324 | return node; |
516 | return pdn->node; | ||
517 | } | 325 | } |
518 | return NULL; | 326 | return NULL; |
519 | } | 327 | } |
@@ -625,7 +433,6 @@ static int CheckReturnCode(char *TextHdr, struct device_node *DevNode, | |||
625 | if (ret != 0) { | 433 | if (ret != 0) { |
626 | struct pci_dn *pdn = PCI_DN(DevNode); | 434 | struct pci_dn *pdn = PCI_DN(DevNode); |
627 | 435 | ||
628 | ++Pci_Error_Count; | ||
629 | (*retry)++; | 436 | (*retry)++; |
630 | printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", | 437 | printk("PCI: %s: Device 0x%04X:%02X I/O Error(%2d): 0x%04X\n", |
631 | TextHdr, pdn->busno, pdn->devfn, | 438 | TextHdr, pdn->busno, pdn->devfn, |
@@ -707,7 +514,6 @@ u8 iSeries_Read_Byte(const volatile void __iomem *IoAddress) | |||
707 | return 0xff; | 514 | return 0xff; |
708 | } | 515 | } |
709 | do { | 516 | do { |
710 | ++Pci_Io_Read_Count; | ||
711 | HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); | 517 | HvCall3Ret16(HvCallPciBarLoad8, &ret, dsa, BarOffset, 0); |
712 | } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); | 518 | } while (CheckReturnCode("RDB", DevNode, &retry, ret.rc) != 0); |
713 | 519 | ||
@@ -737,7 +543,6 @@ u16 iSeries_Read_Word(const volatile void __iomem *IoAddress) | |||
737 | return 0xffff; | 543 | return 0xffff; |
738 | } | 544 | } |
739 | do { | 545 | do { |
740 | ++Pci_Io_Read_Count; | ||
741 | HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, | 546 | HvCall3Ret16(HvCallPciBarLoad16, &ret, dsa, |
742 | BarOffset, 0); | 547 | BarOffset, 0); |
743 | } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); | 548 | } while (CheckReturnCode("RDW", DevNode, &retry, ret.rc) != 0); |
@@ -768,7 +573,6 @@ u32 iSeries_Read_Long(const volatile void __iomem *IoAddress) | |||
768 | return 0xffffffff; | 573 | return 0xffffffff; |
769 | } | 574 | } |
770 | do { | 575 | do { |
771 | ++Pci_Io_Read_Count; | ||
772 | HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, | 576 | HvCall3Ret16(HvCallPciBarLoad32, &ret, dsa, |
773 | BarOffset, 0); | 577 | BarOffset, 0); |
774 | } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); | 578 | } while (CheckReturnCode("RDL", DevNode, &retry, ret.rc) != 0); |
@@ -806,7 +610,6 @@ void iSeries_Write_Byte(u8 data, volatile void __iomem *IoAddress) | |||
806 | return; | 610 | return; |
807 | } | 611 | } |
808 | do { | 612 | do { |
809 | ++Pci_Io_Write_Count; | ||
810 | rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); | 613 | rc = HvCall4(HvCallPciBarStore8, dsa, BarOffset, data, 0); |
811 | } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); | 614 | } while (CheckReturnCode("WWB", DevNode, &retry, rc) != 0); |
812 | } | 615 | } |
@@ -834,7 +637,6 @@ void iSeries_Write_Word(u16 data, volatile void __iomem *IoAddress) | |||
834 | return; | 637 | return; |
835 | } | 638 | } |
836 | do { | 639 | do { |
837 | ++Pci_Io_Write_Count; | ||
838 | rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); | 640 | rc = HvCall4(HvCallPciBarStore16, dsa, BarOffset, swab16(data), 0); |
839 | } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); | 641 | } while (CheckReturnCode("WWW", DevNode, &retry, rc) != 0); |
840 | } | 642 | } |
@@ -862,7 +664,6 @@ void iSeries_Write_Long(u32 data, volatile void __iomem *IoAddress) | |||
862 | return; | 664 | return; |
863 | } | 665 | } |
864 | do { | 666 | do { |
865 | ++Pci_Io_Write_Count; | ||
866 | rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); | 667 | rc = HvCall4(HvCallPciBarStore32, dsa, BarOffset, swab32(data), 0); |
867 | } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); | 668 | } while (CheckReturnCode("WWL", DevNode, &retry, rc) != 0); |
868 | } | 669 | } |
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c index a6fd9bedb074..617c724c4590 100644 --- a/arch/powerpc/platforms/iseries/setup.c +++ b/arch/powerpc/platforms/iseries/setup.c | |||
@@ -50,7 +50,6 @@ | |||
50 | #include <asm/iseries/hv_call_xm.h> | 50 | #include <asm/iseries/hv_call_xm.h> |
51 | #include <asm/iseries/it_lp_queue.h> | 51 | #include <asm/iseries/it_lp_queue.h> |
52 | #include <asm/iseries/mf.h> | 52 | #include <asm/iseries/mf.h> |
53 | #include <asm/iseries/it_exp_vpd_panel.h> | ||
54 | #include <asm/iseries/hv_lp_event.h> | 53 | #include <asm/iseries/hv_lp_event.h> |
55 | #include <asm/iseries/lpar_map.h> | 54 | #include <asm/iseries/lpar_map.h> |
56 | #include <asm/udbg.h> | 55 | #include <asm/udbg.h> |
@@ -81,9 +80,6 @@ extern void iSeries_pci_final_fixup(void); | |||
81 | static void iSeries_pci_final_fixup(void) { } | 80 | static void iSeries_pci_final_fixup(void) { } |
82 | #endif | 81 | #endif |
83 | 82 | ||
84 | /* Global Variables */ | ||
85 | int piranha_simulator; | ||
86 | |||
87 | extern int rd_size; /* Defined in drivers/block/rd.c */ | 83 | extern int rd_size; /* Defined in drivers/block/rd.c */ |
88 | extern unsigned long embedded_sysmap_start; | 84 | extern unsigned long embedded_sysmap_start; |
89 | extern unsigned long embedded_sysmap_end; | 85 | extern unsigned long embedded_sysmap_end; |
@@ -91,8 +87,6 @@ extern unsigned long embedded_sysmap_end; | |||
91 | extern unsigned long iSeries_recal_tb; | 87 | extern unsigned long iSeries_recal_tb; |
92 | extern unsigned long iSeries_recal_titan; | 88 | extern unsigned long iSeries_recal_titan; |
93 | 89 | ||
94 | static unsigned long cmd_mem_limit; | ||
95 | |||
96 | struct MemoryBlock { | 90 | struct MemoryBlock { |
97 | unsigned long absStart; | 91 | unsigned long absStart; |
98 | unsigned long absEnd; | 92 | unsigned long absEnd; |
@@ -340,8 +334,6 @@ static void __init iSeries_init_early(void) | |||
340 | #ifdef CONFIG_SMP | 334 | #ifdef CONFIG_SMP |
341 | smp_init_iSeries(); | 335 | smp_init_iSeries(); |
342 | #endif | 336 | #endif |
343 | if (itLpNaca.xPirEnvironMode == 0) | ||
344 | piranha_simulator = 1; | ||
345 | 337 | ||
346 | /* Associate Lp Event Queue 0 with processor 0 */ | 338 | /* Associate Lp Event Queue 0 with processor 0 */ |
347 | HvCallEvent_setLpEventQueueInterruptProc(0, 0); | 339 | HvCallEvent_setLpEventQueueInterruptProc(0, 0); |
@@ -536,10 +528,10 @@ static void __init iSeries_setup_arch(void) | |||
536 | { | 528 | { |
537 | if (get_lppaca()->shared_proc) { | 529 | if (get_lppaca()->shared_proc) { |
538 | ppc_md.idle_loop = iseries_shared_idle; | 530 | ppc_md.idle_loop = iseries_shared_idle; |
539 | printk(KERN_INFO "Using shared processor idle loop\n"); | 531 | printk(KERN_DEBUG "Using shared processor idle loop\n"); |
540 | } else { | 532 | } else { |
541 | ppc_md.idle_loop = iseries_dedicated_idle; | 533 | ppc_md.idle_loop = iseries_dedicated_idle; |
542 | printk(KERN_INFO "Using dedicated idle loop\n"); | 534 | printk(KERN_DEBUG "Using dedicated idle loop\n"); |
543 | } | 535 | } |
544 | 536 | ||
545 | /* Setup the Lp Event Queue */ | 537 | /* Setup the Lp Event Queue */ |
@@ -714,243 +706,6 @@ define_machine(iseries) { | |||
714 | /* XXX Implement enable_pmcs for iSeries */ | 706 | /* XXX Implement enable_pmcs for iSeries */ |
715 | }; | 707 | }; |
716 | 708 | ||
717 | struct blob { | ||
718 | unsigned char data[PAGE_SIZE]; | ||
719 | unsigned long next; | ||
720 | }; | ||
721 | |||
722 | struct iseries_flat_dt { | ||
723 | struct boot_param_header header; | ||
724 | u64 reserve_map[2]; | ||
725 | struct blob dt; | ||
726 | struct blob strings; | ||
727 | }; | ||
728 | |||
729 | struct iseries_flat_dt iseries_dt; | ||
730 | |||
731 | void dt_init(struct iseries_flat_dt *dt) | ||
732 | { | ||
733 | dt->header.off_mem_rsvmap = | ||
734 | offsetof(struct iseries_flat_dt, reserve_map); | ||
735 | dt->header.off_dt_struct = offsetof(struct iseries_flat_dt, dt); | ||
736 | dt->header.off_dt_strings = offsetof(struct iseries_flat_dt, strings); | ||
737 | dt->header.totalsize = sizeof(struct iseries_flat_dt); | ||
738 | dt->header.dt_strings_size = sizeof(struct blob); | ||
739 | |||
740 | /* There is no notion of hardware cpu id on iSeries */ | ||
741 | dt->header.boot_cpuid_phys = smp_processor_id(); | ||
742 | |||
743 | dt->dt.next = (unsigned long)&dt->dt.data; | ||
744 | dt->strings.next = (unsigned long)&dt->strings.data; | ||
745 | |||
746 | dt->header.magic = OF_DT_HEADER; | ||
747 | dt->header.version = 0x10; | ||
748 | dt->header.last_comp_version = 0x10; | ||
749 | |||
750 | dt->reserve_map[0] = 0; | ||
751 | dt->reserve_map[1] = 0; | ||
752 | } | ||
753 | |||
754 | void dt_check_blob(struct blob *b) | ||
755 | { | ||
756 | if (b->next >= (unsigned long)&b->next) { | ||
757 | DBG("Ran out of space in flat device tree blob!\n"); | ||
758 | BUG(); | ||
759 | } | ||
760 | } | ||
761 | |||
762 | void dt_push_u32(struct iseries_flat_dt *dt, u32 value) | ||
763 | { | ||
764 | *((u32*)dt->dt.next) = value; | ||
765 | dt->dt.next += sizeof(u32); | ||
766 | |||
767 | dt_check_blob(&dt->dt); | ||
768 | } | ||
769 | |||
770 | void dt_push_u64(struct iseries_flat_dt *dt, u64 value) | ||
771 | { | ||
772 | *((u64*)dt->dt.next) = value; | ||
773 | dt->dt.next += sizeof(u64); | ||
774 | |||
775 | dt_check_blob(&dt->dt); | ||
776 | } | ||
777 | |||
778 | unsigned long dt_push_bytes(struct blob *blob, char *data, int len) | ||
779 | { | ||
780 | unsigned long start = blob->next - (unsigned long)blob->data; | ||
781 | |||
782 | memcpy((char *)blob->next, data, len); | ||
783 | blob->next = _ALIGN(blob->next + len, 4); | ||
784 | |||
785 | dt_check_blob(blob); | ||
786 | |||
787 | return start; | ||
788 | } | ||
789 | |||
790 | void dt_start_node(struct iseries_flat_dt *dt, char *name) | ||
791 | { | ||
792 | dt_push_u32(dt, OF_DT_BEGIN_NODE); | ||
793 | dt_push_bytes(&dt->dt, name, strlen(name) + 1); | ||
794 | } | ||
795 | |||
796 | #define dt_end_node(dt) dt_push_u32(dt, OF_DT_END_NODE) | ||
797 | |||
798 | void dt_prop(struct iseries_flat_dt *dt, char *name, char *data, int len) | ||
799 | { | ||
800 | unsigned long offset; | ||
801 | |||
802 | dt_push_u32(dt, OF_DT_PROP); | ||
803 | |||
804 | /* Length of the data */ | ||
805 | dt_push_u32(dt, len); | ||
806 | |||
807 | /* Put the property name in the string blob. */ | ||
808 | offset = dt_push_bytes(&dt->strings, name, strlen(name) + 1); | ||
809 | |||
810 | /* The offset of the properties name in the string blob. */ | ||
811 | dt_push_u32(dt, (u32)offset); | ||
812 | |||
813 | /* The actual data. */ | ||
814 | dt_push_bytes(&dt->dt, data, len); | ||
815 | } | ||
816 | |||
817 | void dt_prop_str(struct iseries_flat_dt *dt, char *name, char *data) | ||
818 | { | ||
819 | dt_prop(dt, name, data, strlen(data) + 1); /* + 1 for NULL */ | ||
820 | } | ||
821 | |||
822 | void dt_prop_u32(struct iseries_flat_dt *dt, char *name, u32 data) | ||
823 | { | ||
824 | dt_prop(dt, name, (char *)&data, sizeof(u32)); | ||
825 | } | ||
826 | |||
827 | void dt_prop_u64(struct iseries_flat_dt *dt, char *name, u64 data) | ||
828 | { | ||
829 | dt_prop(dt, name, (char *)&data, sizeof(u64)); | ||
830 | } | ||
831 | |||
832 | void dt_prop_u64_list(struct iseries_flat_dt *dt, char *name, u64 *data, int n) | ||
833 | { | ||
834 | dt_prop(dt, name, (char *)data, sizeof(u64) * n); | ||
835 | } | ||
836 | |||
837 | void dt_prop_u32_list(struct iseries_flat_dt *dt, char *name, u32 *data, int n) | ||
838 | { | ||
839 | dt_prop(dt, name, (char *)data, sizeof(u32) * n); | ||
840 | } | ||
841 | |||
842 | void dt_prop_empty(struct iseries_flat_dt *dt, char *name) | ||
843 | { | ||
844 | dt_prop(dt, name, NULL, 0); | ||
845 | } | ||
846 | |||
847 | void dt_cpus(struct iseries_flat_dt *dt) | ||
848 | { | ||
849 | unsigned char buf[32]; | ||
850 | unsigned char *p; | ||
851 | unsigned int i, index; | ||
852 | struct IoHriProcessorVpd *d; | ||
853 | u32 pft_size[2]; | ||
854 | |||
855 | /* yuck */ | ||
856 | snprintf(buf, 32, "PowerPC,%s", cur_cpu_spec->cpu_name); | ||
857 | p = strchr(buf, ' '); | ||
858 | if (!p) p = buf + strlen(buf); | ||
859 | |||
860 | dt_start_node(dt, "cpus"); | ||
861 | dt_prop_u32(dt, "#address-cells", 1); | ||
862 | dt_prop_u32(dt, "#size-cells", 0); | ||
863 | |||
864 | pft_size[0] = 0; /* NUMA CEC cookie, 0 for non NUMA */ | ||
865 | pft_size[1] = __ilog2(HvCallHpt_getHptPages() * HW_PAGE_SIZE); | ||
866 | |||
867 | for (i = 0; i < NR_CPUS; i++) { | ||
868 | if (lppaca[i].dyn_proc_status >= 2) | ||
869 | continue; | ||
870 | |||
871 | snprintf(p, 32 - (p - buf), "@%d", i); | ||
872 | dt_start_node(dt, buf); | ||
873 | |||
874 | dt_prop_str(dt, "device_type", "cpu"); | ||
875 | |||
876 | index = lppaca[i].dyn_hv_phys_proc_index; | ||
877 | d = &xIoHriProcessorVpd[index]; | ||
878 | |||
879 | dt_prop_u32(dt, "i-cache-size", d->xInstCacheSize * 1024); | ||
880 | dt_prop_u32(dt, "i-cache-line-size", d->xInstCacheOperandSize); | ||
881 | |||
882 | dt_prop_u32(dt, "d-cache-size", d->xDataL1CacheSizeKB * 1024); | ||
883 | dt_prop_u32(dt, "d-cache-line-size", d->xDataCacheOperandSize); | ||
884 | |||
885 | /* magic conversions to Hz copied from old code */ | ||
886 | dt_prop_u32(dt, "clock-frequency", | ||
887 | ((1UL << 34) * 1000000) / d->xProcFreq); | ||
888 | dt_prop_u32(dt, "timebase-frequency", | ||
889 | ((1UL << 32) * 1000000) / d->xTimeBaseFreq); | ||
890 | |||
891 | dt_prop_u32(dt, "reg", i); | ||
892 | |||
893 | dt_prop_u32_list(dt, "ibm,pft-size", pft_size, 2); | ||
894 | |||
895 | dt_end_node(dt); | ||
896 | } | ||
897 | |||
898 | dt_end_node(dt); | ||
899 | } | ||
900 | |||
901 | void dt_model(struct iseries_flat_dt *dt) | ||
902 | { | ||
903 | char buf[16] = "IBM,"; | ||
904 | |||
905 | /* "IBM," + mfgId[2:3] + systemSerial[1:5] */ | ||
906 | strne2a(buf + 4, xItExtVpdPanel.mfgID + 2, 2); | ||
907 | strne2a(buf + 6, xItExtVpdPanel.systemSerial + 1, 5); | ||
908 | buf[11] = '\0'; | ||
909 | dt_prop_str(dt, "system-id", buf); | ||
910 | |||
911 | /* "IBM," + machineType[0:4] */ | ||
912 | strne2a(buf + 4, xItExtVpdPanel.machineType, 4); | ||
913 | buf[8] = '\0'; | ||
914 | dt_prop_str(dt, "model", buf); | ||
915 | |||
916 | dt_prop_str(dt, "compatible", "IBM,iSeries"); | ||
917 | } | ||
918 | |||
919 | void build_flat_dt(struct iseries_flat_dt *dt, unsigned long phys_mem_size) | ||
920 | { | ||
921 | u64 tmp[2]; | ||
922 | |||
923 | dt_init(dt); | ||
924 | |||
925 | dt_start_node(dt, ""); | ||
926 | |||
927 | dt_prop_u32(dt, "#address-cells", 2); | ||
928 | dt_prop_u32(dt, "#size-cells", 2); | ||
929 | dt_model(dt); | ||
930 | |||
931 | /* /memory */ | ||
932 | dt_start_node(dt, "memory@0"); | ||
933 | dt_prop_str(dt, "name", "memory"); | ||
934 | dt_prop_str(dt, "device_type", "memory"); | ||
935 | tmp[0] = 0; | ||
936 | tmp[1] = phys_mem_size; | ||
937 | dt_prop_u64_list(dt, "reg", tmp, 2); | ||
938 | dt_end_node(dt); | ||
939 | |||
940 | /* /chosen */ | ||
941 | dt_start_node(dt, "chosen"); | ||
942 | dt_prop_str(dt, "bootargs", cmd_line); | ||
943 | if (cmd_mem_limit) | ||
944 | dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit); | ||
945 | dt_end_node(dt); | ||
946 | |||
947 | dt_cpus(dt); | ||
948 | |||
949 | dt_end_node(dt); | ||
950 | |||
951 | dt_push_u32(dt, OF_DT_END); | ||
952 | } | ||
953 | |||
954 | void * __init iSeries_early_setup(void) | 709 | void * __init iSeries_early_setup(void) |
955 | { | 710 | { |
956 | unsigned long phys_mem_size; | 711 | unsigned long phys_mem_size; |
@@ -965,28 +720,8 @@ void * __init iSeries_early_setup(void) | |||
965 | 720 | ||
966 | iSeries_get_cmdline(); | 721 | iSeries_get_cmdline(); |
967 | 722 | ||
968 | /* Save unparsed command line copy for /proc/cmdline */ | 723 | return (void *) __pa(build_flat_dt(phys_mem_size)); |
969 | strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE); | ||
970 | |||
971 | /* Parse early parameters, in particular mem=x */ | ||
972 | parse_early_param(); | ||
973 | |||
974 | build_flat_dt(&iseries_dt, phys_mem_size); | ||
975 | |||
976 | return (void *) __pa(&iseries_dt); | ||
977 | } | ||
978 | |||
979 | /* | ||
980 | * On iSeries we just parse the mem=X option from the command line. | ||
981 | * On pSeries it's a bit more complicated, see prom_init_mem() | ||
982 | */ | ||
983 | static int __init early_parsemem(char *p) | ||
984 | { | ||
985 | if (p) | ||
986 | cmd_mem_limit = ALIGN(memparse(p, &p), PAGE_SIZE); | ||
987 | return 0; | ||
988 | } | 724 | } |
989 | early_param("mem", early_parsemem); | ||
990 | 725 | ||
991 | static void hvputc(char c) | 726 | static void hvputc(char c) |
992 | { | 727 | { |
diff --git a/arch/powerpc/platforms/iseries/setup.h b/arch/powerpc/platforms/iseries/setup.h index 5213044ec411..0a47ac53c959 100644 --- a/arch/powerpc/platforms/iseries/setup.h +++ b/arch/powerpc/platforms/iseries/setup.h | |||
@@ -21,4 +21,6 @@ extern unsigned long iSeries_get_boot_time(void); | |||
21 | extern int iSeries_set_rtc_time(struct rtc_time *tm); | 21 | extern int iSeries_set_rtc_time(struct rtc_time *tm); |
22 | extern void iSeries_get_rtc_time(struct rtc_time *tm); | 22 | extern void iSeries_get_rtc_time(struct rtc_time *tm); |
23 | 23 | ||
24 | extern void *build_flat_dt(unsigned long phys_mem_size); | ||
25 | |||
24 | #endif /* __ISERIES_SETUP_H__ */ | 26 | #endif /* __ISERIES_SETUP_H__ */ |
diff --git a/arch/powerpc/platforms/iseries/vio.c b/arch/powerpc/platforms/iseries/vio.c deleted file mode 100644 index ad36ab0639f0..000000000000 --- a/arch/powerpc/platforms/iseries/vio.c +++ /dev/null | |||
@@ -1,131 +0,0 @@ | |||
1 | /* | ||
2 | * IBM PowerPC iSeries Virtual I/O Infrastructure Support. | ||
3 | * | ||
4 | * Copyright (c) 2005 Stephen Rothwell, IBM Corp. | ||
5 | * | ||
6 | * This program is free software; you can redistribute it and/or | ||
7 | * modify it under the terms of the GNU General Public License | ||
8 | * as published by the Free Software Foundation; either version | ||
9 | * 2 of the License, or (at your option) any later version. | ||
10 | */ | ||
11 | #include <linux/types.h> | ||
12 | #include <linux/device.h> | ||
13 | #include <linux/init.h> | ||
14 | |||
15 | #include <asm/vio.h> | ||
16 | #include <asm/iommu.h> | ||
17 | #include <asm/tce.h> | ||
18 | #include <asm/abs_addr.h> | ||
19 | #include <asm/page.h> | ||
20 | #include <asm/iseries/vio.h> | ||
21 | #include <asm/iseries/hv_types.h> | ||
22 | #include <asm/iseries/hv_lp_config.h> | ||
23 | #include <asm/iseries/hv_call_xm.h> | ||
24 | |||
25 | #include "iommu.h" | ||
26 | |||
27 | struct device *iSeries_vio_dev = &vio_bus_device.dev; | ||
28 | EXPORT_SYMBOL(iSeries_vio_dev); | ||
29 | |||
30 | static struct iommu_table veth_iommu_table; | ||
31 | static struct iommu_table vio_iommu_table; | ||
32 | |||
33 | static void __init iommu_vio_init(void) | ||
34 | { | ||
35 | iommu_table_getparms_iSeries(255, 0, 0xff, &veth_iommu_table); | ||
36 | veth_iommu_table.it_size /= 2; | ||
37 | vio_iommu_table = veth_iommu_table; | ||
38 | vio_iommu_table.it_offset += veth_iommu_table.it_size; | ||
39 | |||
40 | if (!iommu_init_table(&veth_iommu_table)) | ||
41 | printk("Virtual Bus VETH TCE table failed.\n"); | ||
42 | if (!iommu_init_table(&vio_iommu_table)) | ||
43 | printk("Virtual Bus VIO TCE table failed.\n"); | ||
44 | } | ||
45 | |||
46 | /** | ||
47 | * vio_register_device_iseries: - Register a new iSeries vio device. | ||
48 | * @voidev: The device to register. | ||
49 | */ | ||
50 | static struct vio_dev *__init vio_register_device_iseries(char *type, | ||
51 | uint32_t unit_num) | ||
52 | { | ||
53 | struct vio_dev *viodev; | ||
54 | |||
55 | /* allocate a vio_dev for this device */ | ||
56 | viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); | ||
57 | if (!viodev) | ||
58 | return NULL; | ||
59 | memset(viodev, 0, sizeof(struct vio_dev)); | ||
60 | |||
61 | snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%s%d", type, unit_num); | ||
62 | |||
63 | viodev->name = viodev->dev.bus_id; | ||
64 | viodev->type = type; | ||
65 | viodev->unit_address = unit_num; | ||
66 | viodev->iommu_table = &vio_iommu_table; | ||
67 | if (vio_register_device(viodev) == NULL) { | ||
68 | kfree(viodev); | ||
69 | return NULL; | ||
70 | } | ||
71 | return viodev; | ||
72 | } | ||
73 | |||
74 | void __init probe_bus_iseries(void) | ||
75 | { | ||
76 | HvLpIndexMap vlan_map; | ||
77 | struct vio_dev *viodev; | ||
78 | int i; | ||
79 | |||
80 | /* there is only one of each of these */ | ||
81 | vio_register_device_iseries("viocons", 0); | ||
82 | vio_register_device_iseries("vscsi", 0); | ||
83 | |||
84 | vlan_map = HvLpConfig_getVirtualLanIndexMap(); | ||
85 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALLANS; i++) { | ||
86 | if ((vlan_map & (0x8000 >> i)) == 0) | ||
87 | continue; | ||
88 | viodev = vio_register_device_iseries("vlan", i); | ||
89 | /* veth is special and has it own iommu_table */ | ||
90 | viodev->iommu_table = &veth_iommu_table; | ||
91 | } | ||
92 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALDISKS; i++) | ||
93 | vio_register_device_iseries("viodasd", i); | ||
94 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALCDROMS; i++) | ||
95 | vio_register_device_iseries("viocd", i); | ||
96 | for (i = 0; i < HVMAXARCHITECTEDVIRTUALTAPES; i++) | ||
97 | vio_register_device_iseries("viotape", i); | ||
98 | } | ||
99 | |||
100 | /** | ||
101 | * vio_match_device_iseries: - Tell if a iSeries VIO device matches a | ||
102 | * vio_device_id | ||
103 | */ | ||
104 | static int vio_match_device_iseries(const struct vio_device_id *id, | ||
105 | const struct vio_dev *dev) | ||
106 | { | ||
107 | return strncmp(dev->type, id->type, strlen(id->type)) == 0; | ||
108 | } | ||
109 | |||
110 | static struct vio_bus_ops vio_bus_ops_iseries = { | ||
111 | .match = vio_match_device_iseries, | ||
112 | }; | ||
113 | |||
114 | /** | ||
115 | * vio_bus_init_iseries: - Initialize the iSeries virtual IO bus | ||
116 | */ | ||
117 | static int __init vio_bus_init_iseries(void) | ||
118 | { | ||
119 | int err; | ||
120 | |||
121 | err = vio_bus_init(&vio_bus_ops_iseries); | ||
122 | if (err == 0) { | ||
123 | iommu_vio_init(); | ||
124 | vio_bus_device.iommu_table = &vio_iommu_table; | ||
125 | iSeries_vio_dev = &vio_bus_device.dev; | ||
126 | probe_bus_iseries(); | ||
127 | } | ||
128 | return err; | ||
129 | } | ||
130 | |||
131 | __initcall(vio_bus_init_iseries); | ||
diff --git a/arch/powerpc/platforms/maple/pci.c b/arch/powerpc/platforms/maple/pci.c index 85d6c93659cc..9a4efc0c3b29 100644 --- a/arch/powerpc/platforms/maple/pci.c +++ b/arch/powerpc/platforms/maple/pci.c | |||
@@ -437,9 +437,6 @@ void __init maple_pci_init(void) | |||
437 | 437 | ||
438 | /* Tell pci.c to not change any resource allocations. */ | 438 | /* Tell pci.c to not change any resource allocations. */ |
439 | pci_probe_only = 1; | 439 | pci_probe_only = 1; |
440 | |||
441 | /* Allow all IO */ | ||
442 | io_page_mask = -1; | ||
443 | } | 440 | } |
444 | 441 | ||
445 | int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) | 442 | int maple_pci_get_legacy_ide_irq(struct pci_dev *pdev, int channel) |
diff --git a/arch/powerpc/platforms/maple/setup.c b/arch/powerpc/platforms/maple/setup.c index 24c0aef4ea39..a0505ea48a86 100644 --- a/arch/powerpc/platforms/maple/setup.c +++ b/arch/powerpc/platforms/maple/setup.c | |||
@@ -189,7 +189,7 @@ void __init maple_setup_arch(void) | |||
189 | conswitchp = &dummy_con; | 189 | conswitchp = &dummy_con; |
190 | #endif | 190 | #endif |
191 | 191 | ||
192 | printk(KERN_INFO "Using native/NAP idle loop\n"); | 192 | printk(KERN_DEBUG "Using native/NAP idle loop\n"); |
193 | } | 193 | } |
194 | 194 | ||
195 | /* | 195 | /* |
diff --git a/arch/powerpc/platforms/powermac/cpufreq_32.c b/arch/powerpc/platforms/powermac/cpufreq_32.c index cfd6527a0d7e..af2a8f9f1222 100644 --- a/arch/powerpc/platforms/powermac/cpufreq_32.c +++ b/arch/powerpc/platforms/powermac/cpufreq_32.c | |||
@@ -314,7 +314,7 @@ static int pmu_set_cpu_speed(int low_speed) | |||
314 | _set_L3CR(save_l3cr); | 314 | _set_L3CR(save_l3cr); |
315 | 315 | ||
316 | /* Restore userland MMU context */ | 316 | /* Restore userland MMU context */ |
317 | set_context(current->active_mm->context, current->active_mm->pgd); | 317 | set_context(current->active_mm->context.id, current->active_mm->pgd); |
318 | 318 | ||
319 | #ifdef DEBUG_FREQ | 319 | #ifdef DEBUG_FREQ |
320 | printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); | 320 | printk(KERN_DEBUG "HID1, after: %x\n", mfspr(SPRN_HID1)); |
diff --git a/arch/powerpc/platforms/powermac/feature.c b/arch/powerpc/platforms/powermac/feature.c index a5063cd675c5..85e00cb0006e 100644 --- a/arch/powerpc/platforms/powermac/feature.c +++ b/arch/powerpc/platforms/powermac/feature.c | |||
@@ -2510,7 +2510,7 @@ found: | |||
2510 | if (get_property(np, "flush-on-lock", NULL)) | 2510 | if (get_property(np, "flush-on-lock", NULL)) |
2511 | break; | 2511 | break; |
2512 | powersave_nap = 1; | 2512 | powersave_nap = 1; |
2513 | printk(KERN_INFO "Processor NAP mode on idle enabled.\n"); | 2513 | printk(KERN_DEBUG "Processor NAP mode on idle enabled.\n"); |
2514 | break; | 2514 | break; |
2515 | } | 2515 | } |
2516 | 2516 | ||
diff --git a/arch/powerpc/platforms/powermac/pci.c b/arch/powerpc/platforms/powermac/pci.c index ea179afea632..80035853467b 100644 --- a/arch/powerpc/platforms/powermac/pci.c +++ b/arch/powerpc/platforms/powermac/pci.c | |||
@@ -1068,9 +1068,6 @@ void __init pmac_pci_init(void) | |||
1068 | /* Tell pci.c to not use the common resource allocation mechanism */ | 1068 | /* Tell pci.c to not use the common resource allocation mechanism */ |
1069 | pci_probe_only = 1; | 1069 | pci_probe_only = 1; |
1070 | 1070 | ||
1071 | /* Allow all IO */ | ||
1072 | io_page_mask = -1; | ||
1073 | |||
1074 | #else /* CONFIG_PPC64 */ | 1071 | #else /* CONFIG_PPC64 */ |
1075 | init_p2pbridge(); | 1072 | init_p2pbridge(); |
1076 | fixup_nec_usb2(); | 1073 | fixup_nec_usb2(); |
diff --git a/arch/powerpc/platforms/powermac/pfunc_core.c b/arch/powerpc/platforms/powermac/pfunc_core.c index f08173b0f065..047f954a89eb 100644 --- a/arch/powerpc/platforms/powermac/pfunc_core.c +++ b/arch/powerpc/platforms/powermac/pfunc_core.c | |||
@@ -871,10 +871,17 @@ int pmf_register_irq_client(struct device_node *target, | |||
871 | spin_unlock_irqrestore(&pmf_lock, flags); | 871 | spin_unlock_irqrestore(&pmf_lock, flags); |
872 | if (func == NULL) | 872 | if (func == NULL) |
873 | return -ENODEV; | 873 | return -ENODEV; |
874 | |||
875 | /* guard against manipulations of list */ | ||
874 | mutex_lock(&pmf_irq_mutex); | 876 | mutex_lock(&pmf_irq_mutex); |
875 | if (list_empty(&func->irq_clients)) | 877 | if (list_empty(&func->irq_clients)) |
876 | func->dev->handlers->irq_enable(func); | 878 | func->dev->handlers->irq_enable(func); |
879 | |||
880 | /* guard against pmf_do_irq while changing list */ | ||
881 | spin_lock_irqsave(&pmf_lock, flags); | ||
877 | list_add(&client->link, &func->irq_clients); | 882 | list_add(&client->link, &func->irq_clients); |
883 | spin_unlock_irqrestore(&pmf_lock, flags); | ||
884 | |||
878 | client->func = func; | 885 | client->func = func; |
879 | mutex_unlock(&pmf_irq_mutex); | 886 | mutex_unlock(&pmf_irq_mutex); |
880 | 887 | ||
@@ -885,12 +892,19 @@ EXPORT_SYMBOL_GPL(pmf_register_irq_client); | |||
885 | void pmf_unregister_irq_client(struct pmf_irq_client *client) | 892 | void pmf_unregister_irq_client(struct pmf_irq_client *client) |
886 | { | 893 | { |
887 | struct pmf_function *func = client->func; | 894 | struct pmf_function *func = client->func; |
895 | unsigned long flags; | ||
888 | 896 | ||
889 | BUG_ON(func == NULL); | 897 | BUG_ON(func == NULL); |
890 | 898 | ||
899 | /* guard against manipulations of list */ | ||
891 | mutex_lock(&pmf_irq_mutex); | 900 | mutex_lock(&pmf_irq_mutex); |
892 | client->func = NULL; | 901 | client->func = NULL; |
902 | |||
903 | /* guard against pmf_do_irq while changing list */ | ||
904 | spin_lock_irqsave(&pmf_lock, flags); | ||
893 | list_del(&client->link); | 905 | list_del(&client->link); |
906 | spin_unlock_irqrestore(&pmf_lock, flags); | ||
907 | |||
894 | if (list_empty(&func->irq_clients)) | 908 | if (list_empty(&func->irq_clients)) |
895 | func->dev->handlers->irq_disable(func); | 909 | func->dev->handlers->irq_disable(func); |
896 | mutex_unlock(&pmf_irq_mutex); | 910 | mutex_unlock(&pmf_irq_mutex); |
diff --git a/arch/powerpc/platforms/powermac/setup.c b/arch/powerpc/platforms/powermac/setup.c index b9200fb07815..9cc7db7a8bdc 100644 --- a/arch/powerpc/platforms/powermac/setup.c +++ b/arch/powerpc/platforms/powermac/setup.c | |||
@@ -458,7 +458,7 @@ static int pmac_pm_finish(suspend_state_t state) | |||
458 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); | 458 | printk(KERN_DEBUG "%s(%d)\n", __FUNCTION__, state); |
459 | 459 | ||
460 | /* Restore userland MMU context */ | 460 | /* Restore userland MMU context */ |
461 | set_context(current->active_mm->context, current->active_mm->pgd); | 461 | set_context(current->active_mm->context.id, current->active_mm->pgd); |
462 | 462 | ||
463 | return 0; | 463 | return 0; |
464 | } | 464 | } |
diff --git a/arch/powerpc/platforms/pseries/Makefile b/arch/powerpc/platforms/pseries/Makefile index 930898635c9f..e5e0ff466904 100644 --- a/arch/powerpc/platforms/pseries/Makefile +++ b/arch/powerpc/platforms/pseries/Makefile | |||
@@ -1,8 +1,11 @@ | |||
1 | ifeq ($(CONFIG_PPC64),y) | ||
2 | EXTRA_CFLAGS += -mno-minimal-toc | ||
3 | endif | ||
4 | |||
1 | obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ | 5 | obj-y := pci.o lpar.o hvCall.o nvram.o reconfig.o \ |
2 | setup.o iommu.o ras.o rtasd.o pci_dlpar.o \ | 6 | setup.o iommu.o ras.o rtasd.o pci_dlpar.o \ |
3 | firmware.o | 7 | firmware.o |
4 | obj-$(CONFIG_SMP) += smp.o | 8 | obj-$(CONFIG_SMP) += smp.o |
5 | obj-$(CONFIG_IBMVIO) += vio.o | ||
6 | obj-$(CONFIG_XICS) += xics.o | 9 | obj-$(CONFIG_XICS) += xics.o |
7 | obj-$(CONFIG_SCANLOG) += scanlog.o | 10 | obj-$(CONFIG_SCANLOG) += scanlog.o |
8 | obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o | 11 | obj-$(CONFIG_EEH) += eeh.o eeh_cache.o eeh_driver.o eeh_event.o |
diff --git a/arch/powerpc/platforms/pseries/eeh_cache.c b/arch/powerpc/platforms/pseries/eeh_cache.c index d4a402c5866c..98c23aec85be 100644 --- a/arch/powerpc/platforms/pseries/eeh_cache.c +++ b/arch/powerpc/platforms/pseries/eeh_cache.c | |||
@@ -304,6 +304,8 @@ void __init pci_addr_cache_build(void) | |||
304 | pci_addr_cache_insert_device(dev); | 304 | pci_addr_cache_insert_device(dev); |
305 | 305 | ||
306 | dn = pci_device_to_OF_node(dev); | 306 | dn = pci_device_to_OF_node(dev); |
307 | if (!dn) | ||
308 | continue; | ||
307 | pci_dev_get (dev); /* matching put is in eeh_remove_device() */ | 309 | pci_dev_get (dev); /* matching put is in eeh_remove_device() */ |
308 | PCI_DN(dn)->pcidev = dev; | 310 | PCI_DN(dn)->pcidev = dev; |
309 | } | 311 | } |
diff --git a/arch/powerpc/platforms/pseries/eeh_driver.c b/arch/powerpc/platforms/pseries/eeh_driver.c index 1fba695e32e8..0ec9a5445b95 100644 --- a/arch/powerpc/platforms/pseries/eeh_driver.c +++ b/arch/powerpc/platforms/pseries/eeh_driver.c | |||
@@ -23,9 +23,8 @@ | |||
23 | * | 23 | * |
24 | */ | 24 | */ |
25 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/irq.h> | ||
27 | #include <linux/interrupt.h> | 26 | #include <linux/interrupt.h> |
28 | #include <linux/notifier.h> | 27 | #include <linux/irq.h> |
29 | #include <linux/pci.h> | 28 | #include <linux/pci.h> |
30 | #include <asm/eeh.h> | 29 | #include <asm/eeh.h> |
31 | #include <asm/eeh_event.h> | 30 | #include <asm/eeh_event.h> |
@@ -202,7 +201,11 @@ static void eeh_report_failure(struct pci_dev *dev, void *userdata) | |||
202 | 201 | ||
203 | static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) | 202 | static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) |
204 | { | 203 | { |
205 | int rc; | 204 | int cnt, rc; |
205 | |||
206 | /* pcibios will clear the counter; save the value */ | ||
207 | cnt = pe_dn->eeh_freeze_count; | ||
208 | |||
206 | if (bus) | 209 | if (bus) |
207 | pcibios_remove_pci_devices(bus); | 210 | pcibios_remove_pci_devices(bus); |
208 | 211 | ||
@@ -241,6 +244,7 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) | |||
241 | ssleep (5); | 244 | ssleep (5); |
242 | pcibios_add_pci_devices(bus); | 245 | pcibios_add_pci_devices(bus); |
243 | } | 246 | } |
247 | pe_dn->eeh_freeze_count = cnt; | ||
244 | 248 | ||
245 | return 0; | 249 | return 0; |
246 | } | 250 | } |
@@ -250,23 +254,29 @@ static int eeh_reset_device (struct pci_dn *pe_dn, struct pci_bus *bus) | |||
250 | */ | 254 | */ |
251 | #define MAX_WAIT_FOR_RECOVERY 15 | 255 | #define MAX_WAIT_FOR_RECOVERY 15 |
252 | 256 | ||
253 | void handle_eeh_events (struct eeh_event *event) | 257 | struct pci_dn * handle_eeh_events (struct eeh_event *event) |
254 | { | 258 | { |
255 | struct device_node *frozen_dn; | 259 | struct device_node *frozen_dn; |
256 | struct pci_dn *frozen_pdn; | 260 | struct pci_dn *frozen_pdn; |
257 | struct pci_bus *frozen_bus; | 261 | struct pci_bus *frozen_bus; |
258 | int rc = 0; | 262 | int rc = 0; |
259 | enum pci_ers_result result = PCI_ERS_RESULT_NONE; | 263 | enum pci_ers_result result = PCI_ERS_RESULT_NONE; |
260 | const char *pci_str, *drv_str; | 264 | const char *location, *pci_str, *drv_str; |
261 | 265 | ||
262 | frozen_dn = find_device_pe(event->dn); | 266 | frozen_dn = find_device_pe(event->dn); |
263 | frozen_bus = pcibios_find_pci_bus(frozen_dn); | 267 | frozen_bus = pcibios_find_pci_bus(frozen_dn); |
264 | 268 | ||
265 | if (!frozen_dn) { | 269 | if (!frozen_dn) { |
266 | printk(KERN_ERR "EEH: Error: Cannot find partition endpoint for %s\n", | 270 | |
267 | pci_name(event->dev)); | 271 | location = (char *) get_property(event->dn, "ibm,loc-code", NULL); |
268 | return; | 272 | location = location ? location : "unknown"; |
273 | printk(KERN_ERR "EEH: Error: Cannot find partition endpoint " | ||
274 | "for location=%s pci addr=%s\n", | ||
275 | location, pci_name(event->dev)); | ||
276 | return NULL; | ||
269 | } | 277 | } |
278 | location = (char *) get_property(frozen_dn, "ibm,loc-code", NULL); | ||
279 | location = location ? location : "unknown"; | ||
270 | 280 | ||
271 | /* There are two different styles for coming up with the PE. | 281 | /* There are two different styles for coming up with the PE. |
272 | * In the old style, it was the highest EEH-capable device | 282 | * In the old style, it was the highest EEH-capable device |
@@ -278,9 +288,10 @@ void handle_eeh_events (struct eeh_event *event) | |||
278 | frozen_bus = pcibios_find_pci_bus (frozen_dn->parent); | 288 | frozen_bus = pcibios_find_pci_bus (frozen_dn->parent); |
279 | 289 | ||
280 | if (!frozen_bus) { | 290 | if (!frozen_bus) { |
281 | printk(KERN_ERR "EEH: Cannot find PCI bus for %s\n", | 291 | printk(KERN_ERR "EEH: Cannot find PCI bus " |
282 | frozen_dn->full_name); | 292 | "for location=%s dn=%s\n", |
283 | return; | 293 | location, frozen_dn->full_name); |
294 | return NULL; | ||
284 | } | 295 | } |
285 | 296 | ||
286 | #if 0 | 297 | #if 0 |
@@ -314,8 +325,9 @@ void handle_eeh_events (struct eeh_event *event) | |||
314 | 325 | ||
315 | eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); | 326 | eeh_slot_error_detail(frozen_pdn, 1 /* Temporary Error */); |
316 | printk(KERN_WARNING | 327 | printk(KERN_WARNING |
317 | "EEH: This PCI device has failed %d times since last reboot: %s - %s\n", | 328 | "EEH: This PCI device has failed %d times since last reboot: " |
318 | frozen_pdn->eeh_freeze_count, drv_str, pci_str); | 329 | "location=%s driver=%s pci addr=%s\n", |
330 | frozen_pdn->eeh_freeze_count, location, drv_str, pci_str); | ||
319 | 331 | ||
320 | /* Walk the various device drivers attached to this slot through | 332 | /* Walk the various device drivers attached to this slot through |
321 | * a reset sequence, giving each an opportunity to do what it needs | 333 | * a reset sequence, giving each an opportunity to do what it needs |
@@ -355,7 +367,7 @@ void handle_eeh_events (struct eeh_event *event) | |||
355 | /* Tell all device drivers that they can resume operations */ | 367 | /* Tell all device drivers that they can resume operations */ |
356 | pci_walk_bus(frozen_bus, eeh_report_resume, NULL); | 368 | pci_walk_bus(frozen_bus, eeh_report_resume, NULL); |
357 | 369 | ||
358 | return; | 370 | return frozen_pdn; |
359 | 371 | ||
360 | excess_failures: | 372 | excess_failures: |
361 | /* | 373 | /* |
@@ -364,17 +376,18 @@ excess_failures: | |||
364 | * due to actual, failed cards. | 376 | * due to actual, failed cards. |
365 | */ | 377 | */ |
366 | printk(KERN_ERR | 378 | printk(KERN_ERR |
367 | "EEH: PCI device %s - %s has failed %d times \n" | 379 | "EEH: PCI device at location=%s driver=%s pci addr=%s \n" |
368 | "and has been permanently disabled. Please try reseating\n" | 380 | "has failed %d times and has been permanently disabled. \n" |
369 | "this device or replacing it.\n", | 381 | "Please try reseating this device or replacing it.\n", |
370 | drv_str, pci_str, frozen_pdn->eeh_freeze_count); | 382 | location, drv_str, pci_str, frozen_pdn->eeh_freeze_count); |
371 | goto perm_error; | 383 | goto perm_error; |
372 | 384 | ||
373 | hard_fail: | 385 | hard_fail: |
374 | printk(KERN_ERR | 386 | printk(KERN_ERR |
375 | "EEH: Unable to recover from failure of PCI device %s - %s\n" | 387 | "EEH: Unable to recover from failure of PCI device " |
388 | "at location=%s driver=%s pci addr=%s \n" | ||
376 | "Please try reseating this device or replacing it.\n", | 389 | "Please try reseating this device or replacing it.\n", |
377 | drv_str, pci_str); | 390 | location, drv_str, pci_str); |
378 | 391 | ||
379 | perm_error: | 392 | perm_error: |
380 | eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); | 393 | eeh_slot_error_detail(frozen_pdn, 2 /* Permanent Error */); |
@@ -384,6 +397,8 @@ perm_error: | |||
384 | 397 | ||
385 | /* Shut down the device drivers for good. */ | 398 | /* Shut down the device drivers for good. */ |
386 | pcibios_remove_pci_devices(frozen_bus); | 399 | pcibios_remove_pci_devices(frozen_bus); |
400 | |||
401 | return NULL; | ||
387 | } | 402 | } |
388 | 403 | ||
389 | /* ---------- end of file ---------- */ | 404 | /* ---------- end of file ---------- */ |
diff --git a/arch/powerpc/platforms/pseries/eeh_event.c b/arch/powerpc/platforms/pseries/eeh_event.c index 40020c65c89e..8f2d12935b99 100644 --- a/arch/powerpc/platforms/pseries/eeh_event.c +++ b/arch/powerpc/platforms/pseries/eeh_event.c | |||
@@ -18,6 +18,7 @@ | |||
18 | * Copyright (c) 2005 Linas Vepstas <linas@linas.org> | 18 | * Copyright (c) 2005 Linas Vepstas <linas@linas.org> |
19 | */ | 19 | */ |
20 | 20 | ||
21 | #include <linux/delay.h> | ||
21 | #include <linux/list.h> | 22 | #include <linux/list.h> |
22 | #include <linux/mutex.h> | 23 | #include <linux/mutex.h> |
23 | #include <linux/pci.h> | 24 | #include <linux/pci.h> |
@@ -56,38 +57,43 @@ static int eeh_event_handler(void * dummy) | |||
56 | { | 57 | { |
57 | unsigned long flags; | 58 | unsigned long flags; |
58 | struct eeh_event *event; | 59 | struct eeh_event *event; |
60 | struct pci_dn *pdn; | ||
59 | 61 | ||
60 | daemonize ("eehd"); | 62 | daemonize ("eehd"); |
63 | set_current_state(TASK_INTERRUPTIBLE); | ||
61 | 64 | ||
62 | while (1) { | 65 | spin_lock_irqsave(&eeh_eventlist_lock, flags); |
63 | set_current_state(TASK_INTERRUPTIBLE); | 66 | event = NULL; |
64 | 67 | ||
65 | spin_lock_irqsave(&eeh_eventlist_lock, flags); | 68 | /* Unqueue the event, get ready to process. */ |
66 | event = NULL; | 69 | if (!list_empty(&eeh_eventlist)) { |
70 | event = list_entry(eeh_eventlist.next, struct eeh_event, list); | ||
71 | list_del(&event->list); | ||
72 | } | ||
73 | spin_unlock_irqrestore(&eeh_eventlist_lock, flags); | ||
67 | 74 | ||
68 | /* Unqueue the event, get ready to process. */ | 75 | if (event == NULL) |
69 | if (!list_empty(&eeh_eventlist)) { | 76 | return 0; |
70 | event = list_entry(eeh_eventlist.next, struct eeh_event, list); | ||
71 | list_del(&event->list); | ||
72 | } | ||
73 | spin_unlock_irqrestore(&eeh_eventlist_lock, flags); | ||
74 | 77 | ||
75 | if (event == NULL) | 78 | /* Serialize processing of EEH events */ |
76 | break; | 79 | mutex_lock(&eeh_event_mutex); |
80 | eeh_mark_slot(event->dn, EEH_MODE_RECOVERING); | ||
77 | 81 | ||
78 | /* Serialize processing of EEH events */ | 82 | printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", |
79 | mutex_lock(&eeh_event_mutex); | 83 | pci_name(event->dev)); |
80 | eeh_mark_slot(event->dn, EEH_MODE_RECOVERING); | ||
81 | 84 | ||
82 | printk(KERN_INFO "EEH: Detected PCI bus error on device %s\n", | 85 | pdn = handle_eeh_events(event); |
83 | pci_name(event->dev)); | ||
84 | 86 | ||
85 | handle_eeh_events(event); | 87 | eeh_clear_slot(event->dn, EEH_MODE_RECOVERING); |
88 | pci_dev_put(event->dev); | ||
89 | kfree(event); | ||
90 | mutex_unlock(&eeh_event_mutex); | ||
86 | 91 | ||
87 | eeh_clear_slot(event->dn, EEH_MODE_RECOVERING); | 92 | /* If there are no new errors after an hour, clear the counter. */ |
88 | pci_dev_put(event->dev); | 93 | if (pdn && pdn->eeh_freeze_count>0) { |
89 | kfree(event); | 94 | msleep_interruptible (3600*1000); |
90 | mutex_unlock(&eeh_event_mutex); | 95 | if (pdn->eeh_freeze_count>0) |
96 | pdn->eeh_freeze_count--; | ||
91 | } | 97 | } |
92 | 98 | ||
93 | return 0; | 99 | return 0; |
diff --git a/arch/powerpc/platforms/pseries/iommu.c b/arch/powerpc/platforms/pseries/iommu.c index 2643078433f0..d03a8b078f9d 100644 --- a/arch/powerpc/platforms/pseries/iommu.c +++ b/arch/powerpc/platforms/pseries/iommu.c | |||
@@ -1,23 +1,24 @@ | |||
1 | /* | 1 | /* |
2 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation | 2 | * Copyright (C) 2001 Mike Corrigan & Dave Engebretsen, IBM Corporation |
3 | * | 3 | * |
4 | * Rewrite, cleanup: | 4 | * Rewrite, cleanup: |
5 | * | 5 | * |
6 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation | 6 | * Copyright (C) 2004 Olof Johansson <olof@lixom.net>, IBM Corporation |
7 | * Copyright (C) 2006 Olof Johansson <olof@lixom.net> | ||
7 | * | 8 | * |
8 | * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR. | 9 | * Dynamic DMA mapping support, pSeries-specific parts, both SMP and LPAR. |
9 | * | 10 | * |
10 | * | 11 | * |
11 | * This program is free software; you can redistribute it and/or modify | 12 | * This program is free software; you can redistribute it and/or modify |
12 | * it under the terms of the GNU General Public License as published by | 13 | * it under the terms of the GNU General Public License as published by |
13 | * the Free Software Foundation; either version 2 of the License, or | 14 | * the Free Software Foundation; either version 2 of the License, or |
14 | * (at your option) any later version. | 15 | * (at your option) any later version. |
15 | * | 16 | * |
16 | * This program is distributed in the hope that it will be useful, | 17 | * This program is distributed in the hope that it will be useful, |
17 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 18 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
18 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | 19 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
19 | * GNU General Public License for more details. | 20 | * GNU General Public License for more details. |
20 | * | 21 | * |
21 | * You should have received a copy of the GNU General Public License | 22 | * You should have received a copy of the GNU General Public License |
22 | * along with this program; if not, write to the Free Software | 23 | * along with this program; if not, write to the Free Software |
23 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | 24 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
@@ -49,52 +50,46 @@ | |||
49 | 50 | ||
50 | #define DBG(fmt...) | 51 | #define DBG(fmt...) |
51 | 52 | ||
52 | static void tce_build_pSeries(struct iommu_table *tbl, long index, | 53 | static void tce_build_pSeries(struct iommu_table *tbl, long index, |
53 | long npages, unsigned long uaddr, | 54 | long npages, unsigned long uaddr, |
54 | enum dma_data_direction direction) | 55 | enum dma_data_direction direction) |
55 | { | 56 | { |
56 | union tce_entry t; | 57 | u64 proto_tce; |
57 | union tce_entry *tp; | 58 | u64 *tcep; |
59 | u64 rpn; | ||
58 | 60 | ||
59 | index <<= TCE_PAGE_FACTOR; | 61 | index <<= TCE_PAGE_FACTOR; |
60 | npages <<= TCE_PAGE_FACTOR; | 62 | npages <<= TCE_PAGE_FACTOR; |
61 | 63 | ||
62 | t.te_word = 0; | 64 | proto_tce = TCE_PCI_READ; // Read allowed |
63 | t.te_rdwr = 1; // Read allowed | ||
64 | 65 | ||
65 | if (direction != DMA_TO_DEVICE) | 66 | if (direction != DMA_TO_DEVICE) |
66 | t.te_pciwr = 1; | 67 | proto_tce |= TCE_PCI_WRITE; |
67 | 68 | ||
68 | tp = ((union tce_entry *)tbl->it_base) + index; | 69 | tcep = ((u64 *)tbl->it_base) + index; |
69 | 70 | ||
70 | while (npages--) { | 71 | while (npages--) { |
71 | /* can't move this out since we might cross LMB boundary */ | 72 | /* can't move this out since we might cross LMB boundary */ |
72 | t.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 73 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; |
73 | 74 | *tcep = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; | |
74 | tp->te_word = t.te_word; | ||
75 | 75 | ||
76 | uaddr += TCE_PAGE_SIZE; | 76 | uaddr += TCE_PAGE_SIZE; |
77 | tp++; | 77 | tcep++; |
78 | } | 78 | } |
79 | } | 79 | } |
80 | 80 | ||
81 | 81 | ||
82 | static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) | 82 | static void tce_free_pSeries(struct iommu_table *tbl, long index, long npages) |
83 | { | 83 | { |
84 | union tce_entry t; | 84 | u64 *tcep; |
85 | union tce_entry *tp; | ||
86 | 85 | ||
87 | npages <<= TCE_PAGE_FACTOR; | 86 | npages <<= TCE_PAGE_FACTOR; |
88 | index <<= TCE_PAGE_FACTOR; | 87 | index <<= TCE_PAGE_FACTOR; |
89 | 88 | ||
90 | t.te_word = 0; | 89 | tcep = ((u64 *)tbl->it_base) + index; |
91 | tp = ((union tce_entry *)tbl->it_base) + index; | 90 | |
92 | 91 | while (npages--) | |
93 | while (npages--) { | 92 | *(tcep++) = 0; |
94 | tp->te_word = t.te_word; | ||
95 | |||
96 | tp++; | ||
97 | } | ||
98 | } | 93 | } |
99 | 94 | ||
100 | 95 | ||
@@ -103,43 +98,44 @@ static void tce_build_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
103 | enum dma_data_direction direction) | 98 | enum dma_data_direction direction) |
104 | { | 99 | { |
105 | u64 rc; | 100 | u64 rc; |
106 | union tce_entry tce; | 101 | u64 proto_tce, tce; |
102 | u64 rpn; | ||
107 | 103 | ||
108 | tcenum <<= TCE_PAGE_FACTOR; | 104 | tcenum <<= TCE_PAGE_FACTOR; |
109 | npages <<= TCE_PAGE_FACTOR; | 105 | npages <<= TCE_PAGE_FACTOR; |
110 | 106 | ||
111 | tce.te_word = 0; | 107 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; |
112 | tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 108 | proto_tce = TCE_PCI_READ; |
113 | tce.te_rdwr = 1; | ||
114 | if (direction != DMA_TO_DEVICE) | 109 | if (direction != DMA_TO_DEVICE) |
115 | tce.te_pciwr = 1; | 110 | proto_tce |= TCE_PCI_WRITE; |
116 | 111 | ||
117 | while (npages--) { | 112 | while (npages--) { |
118 | rc = plpar_tce_put((u64)tbl->it_index, | 113 | tce = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; |
119 | (u64)tcenum << 12, | 114 | rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, tce); |
120 | tce.te_word ); | 115 | |
121 | |||
122 | if (rc && printk_ratelimit()) { | 116 | if (rc && printk_ratelimit()) { |
123 | printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); | 117 | printk("tce_build_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); |
124 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | 118 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); |
125 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); | 119 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); |
126 | printk("\ttce val = 0x%lx\n", tce.te_word ); | 120 | printk("\ttce val = 0x%lx\n", tce ); |
127 | show_stack(current, (unsigned long *)__get_SP()); | 121 | show_stack(current, (unsigned long *)__get_SP()); |
128 | } | 122 | } |
129 | 123 | ||
130 | tcenum++; | 124 | tcenum++; |
131 | tce.te_rpn++; | 125 | rpn++; |
132 | } | 126 | } |
133 | } | 127 | } |
134 | 128 | ||
135 | static DEFINE_PER_CPU(void *, tce_page) = NULL; | 129 | static DEFINE_PER_CPU(u64 *, tce_page) = NULL; |
136 | 130 | ||
137 | static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | 131 | static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, |
138 | long npages, unsigned long uaddr, | 132 | long npages, unsigned long uaddr, |
139 | enum dma_data_direction direction) | 133 | enum dma_data_direction direction) |
140 | { | 134 | { |
141 | u64 rc; | 135 | u64 rc; |
142 | union tce_entry tce, *tcep; | 136 | u64 proto_tce; |
137 | u64 *tcep; | ||
138 | u64 rpn; | ||
143 | long l, limit; | 139 | long l, limit; |
144 | 140 | ||
145 | if (TCE_PAGE_FACTOR == 0 && npages == 1) | 141 | if (TCE_PAGE_FACTOR == 0 && npages == 1) |
@@ -152,7 +148,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
152 | * from iommu_alloc{,_sg}() | 148 | * from iommu_alloc{,_sg}() |
153 | */ | 149 | */ |
154 | if (!tcep) { | 150 | if (!tcep) { |
155 | tcep = (void *)__get_free_page(GFP_ATOMIC); | 151 | tcep = (u64 *)__get_free_page(GFP_ATOMIC); |
156 | /* If allocation fails, fall back to the loop implementation */ | 152 | /* If allocation fails, fall back to the loop implementation */ |
157 | if (!tcep) | 153 | if (!tcep) |
158 | return tce_build_pSeriesLP(tbl, tcenum, npages, | 154 | return tce_build_pSeriesLP(tbl, tcenum, npages, |
@@ -163,11 +159,10 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
163 | tcenum <<= TCE_PAGE_FACTOR; | 159 | tcenum <<= TCE_PAGE_FACTOR; |
164 | npages <<= TCE_PAGE_FACTOR; | 160 | npages <<= TCE_PAGE_FACTOR; |
165 | 161 | ||
166 | tce.te_word = 0; | 162 | rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; |
167 | tce.te_rpn = (virt_to_abs(uaddr)) >> TCE_SHIFT; | 163 | proto_tce = TCE_PCI_READ; |
168 | tce.te_rdwr = 1; | ||
169 | if (direction != DMA_TO_DEVICE) | 164 | if (direction != DMA_TO_DEVICE) |
170 | tce.te_pciwr = 1; | 165 | proto_tce |= TCE_PCI_WRITE; |
171 | 166 | ||
172 | /* We can map max one pageful of TCEs at a time */ | 167 | /* We can map max one pageful of TCEs at a time */ |
173 | do { | 168 | do { |
@@ -175,11 +170,11 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
175 | * Set up the page with TCE data, looping through and setting | 170 | * Set up the page with TCE data, looping through and setting |
176 | * the values. | 171 | * the values. |
177 | */ | 172 | */ |
178 | limit = min_t(long, npages, 4096/sizeof(union tce_entry)); | 173 | limit = min_t(long, npages, 4096/TCE_ENTRY_SIZE); |
179 | 174 | ||
180 | for (l = 0; l < limit; l++) { | 175 | for (l = 0; l < limit; l++) { |
181 | tcep[l] = tce; | 176 | tcep[l] = proto_tce | (rpn & TCE_RPN_MASK) << TCE_RPN_SHIFT; |
182 | tce.te_rpn++; | 177 | rpn++; |
183 | } | 178 | } |
184 | 179 | ||
185 | rc = plpar_tce_put_indirect((u64)tbl->it_index, | 180 | rc = plpar_tce_put_indirect((u64)tbl->it_index, |
@@ -195,7 +190,7 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
195 | printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); | 190 | printk("tce_buildmulti_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); |
196 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | 191 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); |
197 | printk("\tnpages = 0x%lx\n", (u64)npages); | 192 | printk("\tnpages = 0x%lx\n", (u64)npages); |
198 | printk("\ttce[0] val = 0x%lx\n", tcep[0].te_word); | 193 | printk("\ttce[0] val = 0x%lx\n", tcep[0]); |
199 | show_stack(current, (unsigned long *)__get_SP()); | 194 | show_stack(current, (unsigned long *)__get_SP()); |
200 | } | 195 | } |
201 | } | 196 | } |
@@ -203,23 +198,17 @@ static void tce_buildmulti_pSeriesLP(struct iommu_table *tbl, long tcenum, | |||
203 | static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) | 198 | static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) |
204 | { | 199 | { |
205 | u64 rc; | 200 | u64 rc; |
206 | union tce_entry tce; | ||
207 | 201 | ||
208 | tcenum <<= TCE_PAGE_FACTOR; | 202 | tcenum <<= TCE_PAGE_FACTOR; |
209 | npages <<= TCE_PAGE_FACTOR; | 203 | npages <<= TCE_PAGE_FACTOR; |
210 | 204 | ||
211 | tce.te_word = 0; | ||
212 | |||
213 | while (npages--) { | 205 | while (npages--) { |
214 | rc = plpar_tce_put((u64)tbl->it_index, | 206 | rc = plpar_tce_put((u64)tbl->it_index, (u64)tcenum << 12, 0); |
215 | (u64)tcenum << 12, | ||
216 | tce.te_word); | ||
217 | 207 | ||
218 | if (rc && printk_ratelimit()) { | 208 | if (rc && printk_ratelimit()) { |
219 | printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); | 209 | printk("tce_free_pSeriesLP: plpar_tce_put failed. rc=%ld\n", rc); |
220 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | 210 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); |
221 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); | 211 | printk("\ttcenum = 0x%lx\n", (u64)tcenum); |
222 | printk("\ttce val = 0x%lx\n", tce.te_word ); | ||
223 | show_stack(current, (unsigned long *)__get_SP()); | 212 | show_stack(current, (unsigned long *)__get_SP()); |
224 | } | 213 | } |
225 | 214 | ||
@@ -231,31 +220,24 @@ static void tce_free_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages | |||
231 | static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) | 220 | static void tce_freemulti_pSeriesLP(struct iommu_table *tbl, long tcenum, long npages) |
232 | { | 221 | { |
233 | u64 rc; | 222 | u64 rc; |
234 | union tce_entry tce; | ||
235 | 223 | ||
236 | tcenum <<= TCE_PAGE_FACTOR; | 224 | tcenum <<= TCE_PAGE_FACTOR; |
237 | npages <<= TCE_PAGE_FACTOR; | 225 | npages <<= TCE_PAGE_FACTOR; |
238 | 226 | ||
239 | tce.te_word = 0; | 227 | rc = plpar_tce_stuff((u64)tbl->it_index, (u64)tcenum << 12, 0, npages); |
240 | |||
241 | rc = plpar_tce_stuff((u64)tbl->it_index, | ||
242 | (u64)tcenum << 12, | ||
243 | tce.te_word, | ||
244 | npages); | ||
245 | 228 | ||
246 | if (rc && printk_ratelimit()) { | 229 | if (rc && printk_ratelimit()) { |
247 | printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n"); | 230 | printk("tce_freemulti_pSeriesLP: plpar_tce_stuff failed\n"); |
248 | printk("\trc = %ld\n", rc); | 231 | printk("\trc = %ld\n", rc); |
249 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); | 232 | printk("\tindex = 0x%lx\n", (u64)tbl->it_index); |
250 | printk("\tnpages = 0x%lx\n", (u64)npages); | 233 | printk("\tnpages = 0x%lx\n", (u64)npages); |
251 | printk("\ttce val = 0x%lx\n", tce.te_word ); | ||
252 | show_stack(current, (unsigned long *)__get_SP()); | 234 | show_stack(current, (unsigned long *)__get_SP()); |
253 | } | 235 | } |
254 | } | 236 | } |
255 | 237 | ||
256 | static void iommu_table_setparms(struct pci_controller *phb, | 238 | static void iommu_table_setparms(struct pci_controller *phb, |
257 | struct device_node *dn, | 239 | struct device_node *dn, |
258 | struct iommu_table *tbl) | 240 | struct iommu_table *tbl) |
259 | { | 241 | { |
260 | struct device_node *node; | 242 | struct device_node *node; |
261 | unsigned long *basep; | 243 | unsigned long *basep; |
@@ -275,16 +257,16 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
275 | memset((void *)tbl->it_base, 0, *sizep); | 257 | memset((void *)tbl->it_base, 0, *sizep); |
276 | 258 | ||
277 | tbl->it_busno = phb->bus->number; | 259 | tbl->it_busno = phb->bus->number; |
278 | 260 | ||
279 | /* Units of tce entries */ | 261 | /* Units of tce entries */ |
280 | tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; | 262 | tbl->it_offset = phb->dma_window_base_cur >> PAGE_SHIFT; |
281 | 263 | ||
282 | /* Test if we are going over 2GB of DMA space */ | 264 | /* Test if we are going over 2GB of DMA space */ |
283 | if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { | 265 | if (phb->dma_window_base_cur + phb->dma_window_size > 0x80000000ul) { |
284 | udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); | 266 | udbg_printf("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); |
285 | panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); | 267 | panic("PCI_DMA: Unexpected number of IOAs under this PHB.\n"); |
286 | } | 268 | } |
287 | 269 | ||
288 | phb->dma_window_base_cur += phb->dma_window_size; | 270 | phb->dma_window_base_cur += phb->dma_window_size; |
289 | 271 | ||
290 | /* Set the tce table size - measured in entries */ | 272 | /* Set the tce table size - measured in entries */ |
@@ -299,30 +281,22 @@ static void iommu_table_setparms(struct pci_controller *phb, | |||
299 | * iommu_table_setparms_lpar | 281 | * iommu_table_setparms_lpar |
300 | * | 282 | * |
301 | * Function: On pSeries LPAR systems, return TCE table info, given a pci bus. | 283 | * Function: On pSeries LPAR systems, return TCE table info, given a pci bus. |
302 | * | ||
303 | * ToDo: properly interpret the ibm,dma-window property. The definition is: | ||
304 | * logical-bus-number (1 word) | ||
305 | * phys-address (#address-cells words) | ||
306 | * size (#cell-size words) | ||
307 | * | ||
308 | * Currently we hard code these sizes (more or less). | ||
309 | */ | 284 | */ |
310 | static void iommu_table_setparms_lpar(struct pci_controller *phb, | 285 | static void iommu_table_setparms_lpar(struct pci_controller *phb, |
311 | struct device_node *dn, | 286 | struct device_node *dn, |
312 | struct iommu_table *tbl, | 287 | struct iommu_table *tbl, |
313 | unsigned int *dma_window) | 288 | unsigned char *dma_window) |
314 | { | 289 | { |
290 | unsigned long offset, size; | ||
291 | |||
315 | tbl->it_busno = PCI_DN(dn)->bussubno; | 292 | tbl->it_busno = PCI_DN(dn)->bussubno; |
293 | of_parse_dma_window(dn, dma_window, &tbl->it_index, &offset, &size); | ||
316 | 294 | ||
317 | /* TODO: Parse field size properties properly. */ | ||
318 | tbl->it_size = (((unsigned long)dma_window[4] << 32) | | ||
319 | (unsigned long)dma_window[5]) >> PAGE_SHIFT; | ||
320 | tbl->it_offset = (((unsigned long)dma_window[2] << 32) | | ||
321 | (unsigned long)dma_window[3]) >> PAGE_SHIFT; | ||
322 | tbl->it_base = 0; | 295 | tbl->it_base = 0; |
323 | tbl->it_index = dma_window[0]; | ||
324 | tbl->it_blocksize = 16; | 296 | tbl->it_blocksize = 16; |
325 | tbl->it_type = TCE_PCI; | 297 | tbl->it_type = TCE_PCI; |
298 | tbl->it_offset = offset >> PAGE_SHIFT; | ||
299 | tbl->it_size = size >> PAGE_SHIFT; | ||
326 | } | 300 | } |
327 | 301 | ||
328 | static void iommu_bus_setup_pSeries(struct pci_bus *bus) | 302 | static void iommu_bus_setup_pSeries(struct pci_bus *bus) |
@@ -357,13 +331,9 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) | |||
357 | if (isa_dn_orig) | 331 | if (isa_dn_orig) |
358 | of_node_put(isa_dn_orig); | 332 | of_node_put(isa_dn_orig); |
359 | 333 | ||
360 | /* Count number of direct PCI children of the PHB. | 334 | /* Count number of direct PCI children of the PHB. */ |
361 | * All PCI device nodes have class-code property, so it's | ||
362 | * an easy way to find them. | ||
363 | */ | ||
364 | for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling) | 335 | for (children = 0, tmp = dn->child; tmp; tmp = tmp->sibling) |
365 | if (get_property(tmp, "class-code", NULL)) | 336 | children++; |
366 | children++; | ||
367 | 337 | ||
368 | DBG("Children: %d\n", children); | 338 | DBG("Children: %d\n", children); |
369 | 339 | ||
@@ -394,10 +364,11 @@ static void iommu_bus_setup_pSeries(struct pci_bus *bus) | |||
394 | pci->phb->dma_window_size = 0x8000000ul; | 364 | pci->phb->dma_window_size = 0x8000000ul; |
395 | pci->phb->dma_window_base_cur = 0x8000000ul; | 365 | pci->phb->dma_window_base_cur = 0x8000000ul; |
396 | 366 | ||
397 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 367 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
368 | pci->phb->node); | ||
398 | 369 | ||
399 | iommu_table_setparms(pci->phb, dn, tbl); | 370 | iommu_table_setparms(pci->phb, dn, tbl); |
400 | pci->iommu_table = iommu_init_table(tbl); | 371 | pci->iommu_table = iommu_init_table(tbl, pci->phb->node); |
401 | 372 | ||
402 | /* Divide the rest (1.75GB) among the children */ | 373 | /* Divide the rest (1.75GB) among the children */ |
403 | pci->phb->dma_window_size = 0x80000000ul; | 374 | pci->phb->dma_window_size = 0x80000000ul; |
@@ -414,7 +385,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
414 | struct iommu_table *tbl; | 385 | struct iommu_table *tbl; |
415 | struct device_node *dn, *pdn; | 386 | struct device_node *dn, *pdn; |
416 | struct pci_dn *ppci; | 387 | struct pci_dn *ppci; |
417 | unsigned int *dma_window = NULL; | 388 | unsigned char *dma_window = NULL; |
418 | 389 | ||
419 | DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); | 390 | DBG("iommu_bus_setup_pSeriesLP, bus %p, bus->self %p\n", bus, bus->self); |
420 | 391 | ||
@@ -422,7 +393,7 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
422 | 393 | ||
423 | /* Find nearest ibm,dma-window, walking up the device tree */ | 394 | /* Find nearest ibm,dma-window, walking up the device tree */ |
424 | for (pdn = dn; pdn != NULL; pdn = pdn->parent) { | 395 | for (pdn = dn; pdn != NULL; pdn = pdn->parent) { |
425 | dma_window = (unsigned int *)get_property(pdn, "ibm,dma-window", NULL); | 396 | dma_window = get_property(pdn, "ibm,dma-window", NULL); |
426 | if (dma_window != NULL) | 397 | if (dma_window != NULL) |
427 | break; | 398 | break; |
428 | } | 399 | } |
@@ -440,12 +411,12 @@ static void iommu_bus_setup_pSeriesLP(struct pci_bus *bus) | |||
440 | 411 | ||
441 | ppci->bussubno = bus->number; | 412 | ppci->bussubno = bus->number; |
442 | 413 | ||
443 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), | 414 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
444 | GFP_KERNEL); | 415 | ppci->phb->node); |
445 | 416 | ||
446 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); | 417 | iommu_table_setparms_lpar(ppci->phb, pdn, tbl, dma_window); |
447 | 418 | ||
448 | ppci->iommu_table = iommu_init_table(tbl); | 419 | ppci->iommu_table = iommu_init_table(tbl, ppci->phb->node); |
449 | } | 420 | } |
450 | 421 | ||
451 | if (pdn != dn) | 422 | if (pdn != dn) |
@@ -468,9 +439,11 @@ static void iommu_dev_setup_pSeries(struct pci_dev *dev) | |||
468 | */ | 439 | */ |
469 | if (!dev->bus->self) { | 440 | if (!dev->bus->self) { |
470 | DBG(" --> first child, no bridge. Allocating iommu table.\n"); | 441 | DBG(" --> first child, no bridge. Allocating iommu table.\n"); |
471 | tbl = kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | 442 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
443 | PCI_DN(dn)->phb->node); | ||
472 | iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); | 444 | iommu_table_setparms(PCI_DN(dn)->phb, dn, tbl); |
473 | PCI_DN(mydn)->iommu_table = iommu_init_table(tbl); | 445 | PCI_DN(dn)->iommu_table = iommu_init_table(tbl, |
446 | PCI_DN(dn)->phb->node); | ||
474 | 447 | ||
475 | return; | 448 | return; |
476 | } | 449 | } |
@@ -516,7 +489,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
516 | { | 489 | { |
517 | struct device_node *pdn, *dn; | 490 | struct device_node *pdn, *dn; |
518 | struct iommu_table *tbl; | 491 | struct iommu_table *tbl; |
519 | int *dma_window = NULL; | 492 | unsigned char *dma_window = NULL; |
520 | struct pci_dn *pci; | 493 | struct pci_dn *pci; |
521 | 494 | ||
522 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); | 495 | DBG("iommu_dev_setup_pSeriesLP, dev %p (%s)\n", dev, pci_name(dev)); |
@@ -531,8 +504,7 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
531 | 504 | ||
532 | for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; | 505 | for (pdn = dn; pdn && PCI_DN(pdn) && !PCI_DN(pdn)->iommu_table; |
533 | pdn = pdn->parent) { | 506 | pdn = pdn->parent) { |
534 | dma_window = (unsigned int *) | 507 | dma_window = get_property(pdn, "ibm,dma-window", NULL); |
535 | get_property(pdn, "ibm,dma-window", NULL); | ||
536 | if (dma_window) | 508 | if (dma_window) |
537 | break; | 509 | break; |
538 | } | 510 | } |
@@ -553,12 +525,12 @@ static void iommu_dev_setup_pSeriesLP(struct pci_dev *dev) | |||
553 | /* iommu_table_setparms_lpar needs bussubno. */ | 525 | /* iommu_table_setparms_lpar needs bussubno. */ |
554 | pci->bussubno = pci->phb->bus->number; | 526 | pci->bussubno = pci->phb->bus->number; |
555 | 527 | ||
556 | tbl = (struct iommu_table *)kmalloc(sizeof(struct iommu_table), | 528 | tbl = kmalloc_node(sizeof(struct iommu_table), GFP_KERNEL, |
557 | GFP_KERNEL); | 529 | pci->phb->node); |
558 | 530 | ||
559 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); | 531 | iommu_table_setparms_lpar(pci->phb, pdn, tbl, dma_window); |
560 | 532 | ||
561 | pci->iommu_table = iommu_init_table(tbl); | 533 | pci->iommu_table = iommu_init_table(tbl, pci->phb->node); |
562 | } | 534 | } |
563 | 535 | ||
564 | if (pdn != dn) | 536 | if (pdn != dn) |
diff --git a/arch/powerpc/platforms/pseries/rtasd.c b/arch/powerpc/platforms/pseries/rtasd.c index e0000ce769e5..2e4e04042d85 100644 --- a/arch/powerpc/platforms/pseries/rtasd.c +++ b/arch/powerpc/platforms/pseries/rtasd.c | |||
@@ -348,7 +348,7 @@ static int enable_surveillance(int timeout) | |||
348 | return 0; | 348 | return 0; |
349 | 349 | ||
350 | if (error == -EINVAL) { | 350 | if (error == -EINVAL) { |
351 | printk(KERN_INFO "rtasd: surveillance not supported\n"); | 351 | printk(KERN_DEBUG "rtasd: surveillance not supported\n"); |
352 | return 0; | 352 | return 0; |
353 | } | 353 | } |
354 | 354 | ||
@@ -440,7 +440,7 @@ static int rtasd(void *unused) | |||
440 | goto error; | 440 | goto error; |
441 | } | 441 | } |
442 | 442 | ||
443 | printk(KERN_INFO "RTAS daemon started\n"); | 443 | printk(KERN_DEBUG "RTAS daemon started\n"); |
444 | 444 | ||
445 | DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate)); | 445 | DEBUG("will sleep for %d milliseconds\n", (30000/rtas_event_scan_rate)); |
446 | 446 | ||
@@ -487,7 +487,7 @@ static int __init rtas_init(void) | |||
487 | 487 | ||
488 | /* No RTAS */ | 488 | /* No RTAS */ |
489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { | 489 | if (rtas_token("event-scan") == RTAS_UNKNOWN_SERVICE) { |
490 | printk(KERN_INFO "rtasd: no event-scan on system\n"); | 490 | printk(KERN_DEBUG "rtasd: no event-scan on system\n"); |
491 | return -ENODEV; | 491 | return -ENODEV; |
492 | } | 492 | } |
493 | 493 | ||
diff --git a/arch/powerpc/platforms/pseries/scanlog.c b/arch/powerpc/platforms/pseries/scanlog.c index 50643496eb63..77a5bb1d9c30 100644 --- a/arch/powerpc/platforms/pseries/scanlog.c +++ b/arch/powerpc/platforms/pseries/scanlog.c | |||
@@ -107,9 +107,9 @@ static ssize_t scanlog_read(struct file *file, char __user *buf, | |||
107 | /* Break to sleep default time */ | 107 | /* Break to sleep default time */ |
108 | break; | 108 | break; |
109 | default: | 109 | default: |
110 | if (status > 9900 && status <= 9905) { | 110 | /* Assume extended busy */ |
111 | wait_time = rtas_extended_busy_delay_time(status); | 111 | wait_time = rtas_busy_delay_time(status); |
112 | } else { | 112 | if (!wait_time) { |
113 | printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status); | 113 | printk(KERN_ERR "scanlog: unknown error from rtas: %d\n", status); |
114 | return -EIO; | 114 | return -EIO; |
115 | } | 115 | } |
diff --git a/arch/powerpc/platforms/pseries/setup.c b/arch/powerpc/platforms/pseries/setup.c index 3ba87835757e..1e28518c6121 100644 --- a/arch/powerpc/platforms/pseries/setup.c +++ b/arch/powerpc/platforms/pseries/setup.c | |||
@@ -235,14 +235,14 @@ static void __init pSeries_setup_arch(void) | |||
235 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { | 235 | if (firmware_has_feature(FW_FEATURE_SPLPAR)) { |
236 | vpa_init(boot_cpuid); | 236 | vpa_init(boot_cpuid); |
237 | if (get_lppaca()->shared_proc) { | 237 | if (get_lppaca()->shared_proc) { |
238 | printk(KERN_INFO "Using shared processor idle loop\n"); | 238 | printk(KERN_DEBUG "Using shared processor idle loop\n"); |
239 | ppc_md.power_save = pseries_shared_idle_sleep; | 239 | ppc_md.power_save = pseries_shared_idle_sleep; |
240 | } else { | 240 | } else { |
241 | printk(KERN_INFO "Using dedicated idle loop\n"); | 241 | printk(KERN_DEBUG "Using dedicated idle loop\n"); |
242 | ppc_md.power_save = pseries_dedicated_idle_sleep; | 242 | ppc_md.power_save = pseries_dedicated_idle_sleep; |
243 | } | 243 | } |
244 | } else { | 244 | } else { |
245 | printk(KERN_INFO "Using default idle loop\n"); | 245 | printk(KERN_DEBUG "Using default idle loop\n"); |
246 | } | 246 | } |
247 | 247 | ||
248 | if (firmware_has_feature(FW_FEATURE_LPAR)) | 248 | if (firmware_has_feature(FW_FEATURE_LPAR)) |
diff --git a/arch/powerpc/platforms/pseries/vio.c b/arch/powerpc/platforms/pseries/vio.c deleted file mode 100644 index 8e53e04ada8b..000000000000 --- a/arch/powerpc/platforms/pseries/vio.c +++ /dev/null | |||
@@ -1,274 +0,0 @@ | |||
1 | /* | ||
2 | * IBM PowerPC pSeries Virtual I/O Infrastructure Support. | ||
3 | * | ||
4 | * Copyright (c) 2003-2005 IBM Corp. | ||
5 | * Dave Engebretsen engebret@us.ibm.com | ||
6 | * Santiago Leon santil@us.ibm.com | ||
7 | * Hollis Blanchard <hollisb@us.ibm.com> | ||
8 | * Stephen Rothwell | ||
9 | * | ||
10 | * This program is free software; you can redistribute it and/or | ||
11 | * modify it under the terms of the GNU General Public License | ||
12 | * as published by the Free Software Foundation; either version | ||
13 | * 2 of the License, or (at your option) any later version. | ||
14 | */ | ||
15 | |||
16 | #include <linux/init.h> | ||
17 | #include <linux/module.h> | ||
18 | #include <linux/mm.h> | ||
19 | #include <linux/kobject.h> | ||
20 | #include <asm/iommu.h> | ||
21 | #include <asm/dma.h> | ||
22 | #include <asm/prom.h> | ||
23 | #include <asm/vio.h> | ||
24 | #include <asm/hvcall.h> | ||
25 | #include <asm/tce.h> | ||
26 | |||
27 | extern struct subsystem devices_subsys; /* needed for vio_find_name() */ | ||
28 | |||
29 | static void probe_bus_pseries(void) | ||
30 | { | ||
31 | struct device_node *node_vroot, *of_node; | ||
32 | |||
33 | node_vroot = find_devices("vdevice"); | ||
34 | if ((node_vroot == NULL) || (node_vroot->child == NULL)) | ||
35 | /* this machine doesn't do virtual IO, and that's ok */ | ||
36 | return; | ||
37 | |||
38 | /* | ||
39 | * Create struct vio_devices for each virtual device in the device tree. | ||
40 | * Drivers will associate with them later. | ||
41 | */ | ||
42 | for (of_node = node_vroot->child; of_node != NULL; | ||
43 | of_node = of_node->sibling) { | ||
44 | printk(KERN_DEBUG "%s: processing %p\n", __FUNCTION__, of_node); | ||
45 | vio_register_device_node(of_node); | ||
46 | } | ||
47 | } | ||
48 | |||
49 | /** | ||
50 | * vio_match_device_pseries: - Tell if a pSeries VIO device matches a | ||
51 | * vio_device_id | ||
52 | */ | ||
53 | static int vio_match_device_pseries(const struct vio_device_id *id, | ||
54 | const struct vio_dev *dev) | ||
55 | { | ||
56 | return (strncmp(dev->type, id->type, strlen(id->type)) == 0) && | ||
57 | device_is_compatible(dev->dev.platform_data, id->compat); | ||
58 | } | ||
59 | |||
60 | static void vio_release_device_pseries(struct device *dev) | ||
61 | { | ||
62 | /* XXX free TCE table */ | ||
63 | of_node_put(dev->platform_data); | ||
64 | } | ||
65 | |||
66 | static ssize_t viodev_show_devspec(struct device *dev, | ||
67 | struct device_attribute *attr, char *buf) | ||
68 | { | ||
69 | struct device_node *of_node = dev->platform_data; | ||
70 | |||
71 | return sprintf(buf, "%s\n", of_node->full_name); | ||
72 | } | ||
73 | DEVICE_ATTR(devspec, S_IRUSR | S_IRGRP | S_IROTH, viodev_show_devspec, NULL); | ||
74 | |||
75 | static void vio_unregister_device_pseries(struct vio_dev *viodev) | ||
76 | { | ||
77 | device_remove_file(&viodev->dev, &dev_attr_devspec); | ||
78 | } | ||
79 | |||
80 | static struct vio_bus_ops vio_bus_ops_pseries = { | ||
81 | .match = vio_match_device_pseries, | ||
82 | .unregister_device = vio_unregister_device_pseries, | ||
83 | .release_device = vio_release_device_pseries, | ||
84 | }; | ||
85 | |||
86 | /** | ||
87 | * vio_bus_init_pseries: - Initialize the pSeries virtual IO bus | ||
88 | */ | ||
89 | static int __init vio_bus_init_pseries(void) | ||
90 | { | ||
91 | int err; | ||
92 | |||
93 | err = vio_bus_init(&vio_bus_ops_pseries); | ||
94 | if (err == 0) | ||
95 | probe_bus_pseries(); | ||
96 | return err; | ||
97 | } | ||
98 | |||
99 | __initcall(vio_bus_init_pseries); | ||
100 | |||
101 | /** | ||
102 | * vio_build_iommu_table: - gets the dma information from OF and | ||
103 | * builds the TCE tree. | ||
104 | * @dev: the virtual device. | ||
105 | * | ||
106 | * Returns a pointer to the built tce tree, or NULL if it can't | ||
107 | * find property. | ||
108 | */ | ||
109 | static struct iommu_table *vio_build_iommu_table(struct vio_dev *dev) | ||
110 | { | ||
111 | unsigned int *dma_window; | ||
112 | struct iommu_table *newTceTable; | ||
113 | unsigned long offset; | ||
114 | int dma_window_property_size; | ||
115 | |||
116 | dma_window = (unsigned int *) get_property(dev->dev.platform_data, "ibm,my-dma-window", &dma_window_property_size); | ||
117 | if(!dma_window) { | ||
118 | return NULL; | ||
119 | } | ||
120 | |||
121 | newTceTable = (struct iommu_table *) kmalloc(sizeof(struct iommu_table), GFP_KERNEL); | ||
122 | |||
123 | /* There should be some code to extract the phys-encoded offset | ||
124 | using prom_n_addr_cells(). However, according to a comment | ||
125 | on earlier versions, it's always zero, so we don't bother */ | ||
126 | offset = dma_window[1] >> PAGE_SHIFT; | ||
127 | |||
128 | /* TCE table size - measured in tce entries */ | ||
129 | newTceTable->it_size = dma_window[4] >> PAGE_SHIFT; | ||
130 | /* offset for VIO should always be 0 */ | ||
131 | newTceTable->it_offset = offset; | ||
132 | newTceTable->it_busno = 0; | ||
133 | newTceTable->it_index = (unsigned long)dma_window[0]; | ||
134 | newTceTable->it_type = TCE_VB; | ||
135 | |||
136 | return iommu_init_table(newTceTable); | ||
137 | } | ||
138 | |||
139 | /** | ||
140 | * vio_register_device_node: - Register a new vio device. | ||
141 | * @of_node: The OF node for this device. | ||
142 | * | ||
143 | * Creates and initializes a vio_dev structure from the data in | ||
144 | * of_node (dev.platform_data) and adds it to the list of virtual devices. | ||
145 | * Returns a pointer to the created vio_dev or NULL if node has | ||
146 | * NULL device_type or compatible fields. | ||
147 | */ | ||
148 | struct vio_dev * __devinit vio_register_device_node(struct device_node *of_node) | ||
149 | { | ||
150 | struct vio_dev *viodev; | ||
151 | unsigned int *unit_address; | ||
152 | unsigned int *irq_p; | ||
153 | |||
154 | /* we need the 'device_type' property, in order to match with drivers */ | ||
155 | if ((NULL == of_node->type)) { | ||
156 | printk(KERN_WARNING | ||
157 | "%s: node %s missing 'device_type'\n", __FUNCTION__, | ||
158 | of_node->name ? of_node->name : "<unknown>"); | ||
159 | return NULL; | ||
160 | } | ||
161 | |||
162 | unit_address = (unsigned int *)get_property(of_node, "reg", NULL); | ||
163 | if (!unit_address) { | ||
164 | printk(KERN_WARNING "%s: node %s missing 'reg'\n", __FUNCTION__, | ||
165 | of_node->name ? of_node->name : "<unknown>"); | ||
166 | return NULL; | ||
167 | } | ||
168 | |||
169 | /* allocate a vio_dev for this node */ | ||
170 | viodev = kmalloc(sizeof(struct vio_dev), GFP_KERNEL); | ||
171 | if (!viodev) { | ||
172 | return NULL; | ||
173 | } | ||
174 | memset(viodev, 0, sizeof(struct vio_dev)); | ||
175 | |||
176 | viodev->dev.platform_data = of_node_get(of_node); | ||
177 | |||
178 | viodev->irq = NO_IRQ; | ||
179 | irq_p = (unsigned int *)get_property(of_node, "interrupts", NULL); | ||
180 | if (irq_p) { | ||
181 | int virq = virt_irq_create_mapping(*irq_p); | ||
182 | if (virq == NO_IRQ) { | ||
183 | printk(KERN_ERR "Unable to allocate interrupt " | ||
184 | "number for %s\n", of_node->full_name); | ||
185 | } else | ||
186 | viodev->irq = irq_offset_up(virq); | ||
187 | } | ||
188 | |||
189 | snprintf(viodev->dev.bus_id, BUS_ID_SIZE, "%x", *unit_address); | ||
190 | viodev->name = of_node->name; | ||
191 | viodev->type = of_node->type; | ||
192 | viodev->unit_address = *unit_address; | ||
193 | viodev->iommu_table = vio_build_iommu_table(viodev); | ||
194 | |||
195 | /* register with generic device framework */ | ||
196 | if (vio_register_device(viodev) == NULL) { | ||
197 | /* XXX free TCE table */ | ||
198 | kfree(viodev); | ||
199 | return NULL; | ||
200 | } | ||
201 | device_create_file(&viodev->dev, &dev_attr_devspec); | ||
202 | |||
203 | return viodev; | ||
204 | } | ||
205 | EXPORT_SYMBOL(vio_register_device_node); | ||
206 | |||
207 | /** | ||
208 | * vio_get_attribute: - get attribute for virtual device | ||
209 | * @vdev: The vio device to get property. | ||
210 | * @which: The property/attribute to be extracted. | ||
211 | * @length: Pointer to length of returned data size (unused if NULL). | ||
212 | * | ||
213 | * Calls prom.c's get_property() to return the value of the | ||
214 | * attribute specified by the preprocessor constant @which | ||
215 | */ | ||
216 | const void * vio_get_attribute(struct vio_dev *vdev, void* which, int* length) | ||
217 | { | ||
218 | return get_property(vdev->dev.platform_data, (char*)which, length); | ||
219 | } | ||
220 | EXPORT_SYMBOL(vio_get_attribute); | ||
221 | |||
222 | /* vio_find_name() - internal because only vio.c knows how we formatted the | ||
223 | * kobject name | ||
224 | * XXX once vio_bus_type.devices is actually used as a kset in | ||
225 | * drivers/base/bus.c, this function should be removed in favor of | ||
226 | * "device_find(kobj_name, &vio_bus_type)" | ||
227 | */ | ||
228 | static struct vio_dev *vio_find_name(const char *kobj_name) | ||
229 | { | ||
230 | struct kobject *found; | ||
231 | |||
232 | found = kset_find_obj(&devices_subsys.kset, kobj_name); | ||
233 | if (!found) | ||
234 | return NULL; | ||
235 | |||
236 | return to_vio_dev(container_of(found, struct device, kobj)); | ||
237 | } | ||
238 | |||
239 | /** | ||
240 | * vio_find_node - find an already-registered vio_dev | ||
241 | * @vnode: device_node of the virtual device we're looking for | ||
242 | */ | ||
243 | struct vio_dev *vio_find_node(struct device_node *vnode) | ||
244 | { | ||
245 | uint32_t *unit_address; | ||
246 | char kobj_name[BUS_ID_SIZE]; | ||
247 | |||
248 | /* construct the kobject name from the device node */ | ||
249 | unit_address = (uint32_t *)get_property(vnode, "reg", NULL); | ||
250 | if (!unit_address) | ||
251 | return NULL; | ||
252 | snprintf(kobj_name, BUS_ID_SIZE, "%x", *unit_address); | ||
253 | |||
254 | return vio_find_name(kobj_name); | ||
255 | } | ||
256 | EXPORT_SYMBOL(vio_find_node); | ||
257 | |||
258 | int vio_enable_interrupts(struct vio_dev *dev) | ||
259 | { | ||
260 | int rc = h_vio_signal(dev->unit_address, VIO_IRQ_ENABLE); | ||
261 | if (rc != H_SUCCESS) | ||
262 | printk(KERN_ERR "vio: Error 0x%x enabling interrupts\n", rc); | ||
263 | return rc; | ||
264 | } | ||
265 | EXPORT_SYMBOL(vio_enable_interrupts); | ||
266 | |||
267 | int vio_disable_interrupts(struct vio_dev *dev) | ||
268 | { | ||
269 | int rc = h_vio_signal(dev->unit_address, VIO_IRQ_DISABLE); | ||
270 | if (rc != H_SUCCESS) | ||
271 | printk(KERN_ERR "vio: Error 0x%x disabling interrupts\n", rc); | ||
272 | return rc; | ||
273 | } | ||
274 | EXPORT_SYMBOL(vio_disable_interrupts); | ||
diff --git a/arch/powerpc/platforms/pseries/xics.c b/arch/powerpc/platforms/pseries/xics.c index 2d60ea30fed6..b14f9b5c114e 100644 --- a/arch/powerpc/platforms/pseries/xics.c +++ b/arch/powerpc/platforms/pseries/xics.c | |||
@@ -522,7 +522,7 @@ nextnode: | |||
522 | 522 | ||
523 | np = of_find_node_by_type(NULL, "interrupt-controller"); | 523 | np = of_find_node_by_type(NULL, "interrupt-controller"); |
524 | if (!np) { | 524 | if (!np) { |
525 | printk(KERN_WARNING "xics: no ISA interrupt controller\n"); | 525 | printk(KERN_DEBUG "xics: no ISA interrupt controller\n"); |
526 | xics_irq_8259_cascade_real = -1; | 526 | xics_irq_8259_cascade_real = -1; |
527 | xics_irq_8259_cascade = -1; | 527 | xics_irq_8259_cascade = -1; |
528 | } else { | 528 | } else { |
@@ -641,23 +641,26 @@ void xics_teardown_cpu(int secondary) | |||
641 | ops->cppr_info(cpu, 0x00); | 641 | ops->cppr_info(cpu, 0x00); |
642 | iosync(); | 642 | iosync(); |
643 | 643 | ||
644 | /* Clear IPI */ | ||
645 | ops->qirr_info(cpu, 0xff); | ||
646 | |||
647 | /* | ||
648 | * we need to EOI the IPI if we got here from kexec down IPI | ||
649 | * | ||
650 | * probably need to check all the other interrupts too | ||
651 | * should we be flagging idle loop instead? | ||
652 | * or creating some task to be scheduled? | ||
653 | */ | ||
654 | ops->xirr_info_set(cpu, XICS_IPI); | ||
655 | |||
644 | /* | 656 | /* |
645 | * Some machines need to have at least one cpu in the GIQ, | 657 | * Some machines need to have at least one cpu in the GIQ, |
646 | * so leave the master cpu in the group. | 658 | * so leave the master cpu in the group. |
647 | */ | 659 | */ |
648 | if (secondary) { | 660 | if (secondary) |
649 | /* | ||
650 | * we need to EOI the IPI if we got here from kexec down IPI | ||
651 | * | ||
652 | * probably need to check all the other interrupts too | ||
653 | * should we be flagging idle loop instead? | ||
654 | * or creating some task to be scheduled? | ||
655 | */ | ||
656 | ops->xirr_info_set(cpu, XICS_IPI); | ||
657 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, | 661 | rtas_set_indicator(GLOBAL_INTERRUPT_QUEUE, |
658 | (1UL << interrupt_server_size) - 1 - | 662 | (1UL << interrupt_server_size) - 1 - |
659 | default_distrib_server, 0); | 663 | default_distrib_server, 0); |
660 | } | ||
661 | } | 664 | } |
662 | 665 | ||
663 | #ifdef CONFIG_HOTPLUG_CPU | 666 | #ifdef CONFIG_HOTPLUG_CPU |