1
2
3
4
5
6
7
8
9#define __EXTERN_INLINE inline
10#include <asm/io.h>
11#include <asm/core_tsunami.h>
12#undef __EXTERN_INLINE
13
14#include <linux/types.h>
15#include <linux/pci.h>
16#include <linux/sched.h>
17#include <linux/init.h>
18#include <linux/bootmem.h>
19
20#include <asm/ptrace.h>
21#include <asm/smp.h>
22#include <asm/vga.h>
23
24#include "proto.h"
25#include "pci_impl.h"
26
27
28
29struct
30{
31 unsigned long wsba[4];
32 unsigned long wsm[4];
33 unsigned long tba[4];
34} saved_config[2] __attribute__((common));
35
36
37
38
39
40
41
42
43
44
45
46#define DEBUG_CONFIG 0
47
48#if DEBUG_CONFIG
49# define DBG_CFG(args) printk args
50#else
51# define DBG_CFG(args)
52#endif
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89static int
90mk_conf_addr(struct pci_bus *pbus, unsigned int device_fn, int where,
91 unsigned long *pci_addr, unsigned char *type1)
92{
93 struct pci_controller *hose = pbus->sysdata;
94 unsigned long addr;
95 u8 bus = pbus->number;
96
97 DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
98 "pci_addr=0x%p, type1=0x%p)\n",
99 bus, device_fn, where, pci_addr, type1));
100
101 if (!pbus->parent)
102 bus = 0;
103 *type1 = (bus != 0);
104
105 addr = (bus << 16) | (device_fn << 8) | where;
106 addr |= hose->config_space_base;
107
108 *pci_addr = addr;
109 DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
110 return 0;
111}
112
113static int
114tsunami_read_config(struct pci_bus *bus, unsigned int devfn, int where,
115 int size, u32 *value)
116{
117 unsigned long addr;
118 unsigned char type1;
119
120 if (mk_conf_addr(bus, devfn, where, &addr, &type1))
121 return PCIBIOS_DEVICE_NOT_FOUND;
122
123 switch (size) {
124 case 1:
125 *value = __kernel_ldbu(*(vucp)addr);
126 break;
127 case 2:
128 *value = __kernel_ldwu(*(vusp)addr);
129 break;
130 case 4:
131 *value = *(vuip)addr;
132 break;
133 }
134
135 return PCIBIOS_SUCCESSFUL;
136}
137
138static int
139tsunami_write_config(struct pci_bus *bus, unsigned int devfn, int where,
140 int size, u32 value)
141{
142 unsigned long addr;
143 unsigned char type1;
144
145 if (mk_conf_addr(bus, devfn, where, &addr, &type1))
146 return PCIBIOS_DEVICE_NOT_FOUND;
147
148 switch (size) {
149 case 1:
150 __kernel_stb(value, *(vucp)addr);
151 mb();
152 __kernel_ldbu(*(vucp)addr);
153 break;
154 case 2:
155 __kernel_stw(value, *(vusp)addr);
156 mb();
157 __kernel_ldwu(*(vusp)addr);
158 break;
159 case 4:
160 *(vuip)addr = value;
161 mb();
162 *(vuip)addr;
163 break;
164 }
165
166 return PCIBIOS_SUCCESSFUL;
167}
168
169struct pci_ops tsunami_pci_ops =
170{
171 .read = tsunami_read_config,
172 .write = tsunami_write_config,
173};
174
175void
176tsunami_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end)
177{
178 tsunami_pchip *pchip = hose->index ? TSUNAMI_pchip1 : TSUNAMI_pchip0;
179 volatile unsigned long *csr;
180 unsigned long value;
181
182
183
184 csr = &pchip->tlbia.csr;
185 if (((start ^ end) & 0xffff0000) == 0)
186 csr = &pchip->tlbiv.csr;
187
188
189
190 value = (start & 0xffff0000) >> 12;
191
192 *csr = value;
193 mb();
194 *csr;
195}
196
197#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
198static long __init
199tsunami_probe_read(volatile unsigned long *vaddr)
200{
201 long dont_care, probe_result;
202 int cpu = smp_processor_id();
203 int s = swpipl(IPL_MCHECK - 1);
204
205 mcheck_taken(cpu) = 0;
206 mcheck_expected(cpu) = 1;
207 mb();
208 dont_care = *vaddr;
209 draina();
210 mcheck_expected(cpu) = 0;
211 probe_result = !mcheck_taken(cpu);
212 mcheck_taken(cpu) = 0;
213 setipl(s);
214
215 printk("dont_care == 0x%lx\n", dont_care);
216
217 return probe_result;
218}
219
220static long __init
221tsunami_probe_write(volatile unsigned long *vaddr)
222{
223 long true_contents, probe_result = 1;
224
225 TSUNAMI_cchip->misc.csr |= (1L << 28);
226 true_contents = *vaddr;
227 *vaddr = 0;
228 draina();
229 if (TSUNAMI_cchip->misc.csr & (1L << 28)) {
230 int source = (TSUNAMI_cchip->misc.csr >> 29) & 7;
231 TSUNAMI_cchip->misc.csr |= (1L << 28);
232 probe_result = 0;
233 printk("tsunami_probe_write: unit %d at 0x%016lx\n", source,
234 (unsigned long)vaddr);
235 }
236 if (probe_result)
237 *vaddr = true_contents;
238 return probe_result;
239}
240#else
241#define tsunami_probe_read(ADDR) 1
242#endif
243
244static void __init
245tsunami_init_one_pchip(tsunami_pchip *pchip, int index)
246{
247 struct pci_controller *hose;
248
249 if (tsunami_probe_read(&pchip->pctl.csr) == 0)
250 return;
251
252 hose = alloc_pci_controller();
253 if (index == 0)
254 pci_isa_hose = hose;
255 hose->io_space = alloc_resource();
256 hose->mem_space = alloc_resource();
257
258
259
260
261
262 hose->sparse_mem_base = 0;
263 hose->sparse_io_base = 0;
264 hose->dense_mem_base
265 = (TSUNAMI_MEM(index) & 0xffffffffffL) | 0x80000000000L;
266 hose->dense_io_base
267 = (TSUNAMI_IO(index) & 0xffffffffffL) | 0x80000000000L;
268
269 hose->config_space_base = TSUNAMI_CONF(index);
270 hose->index = index;
271
272 hose->io_space->start = TSUNAMI_IO(index) - TSUNAMI_IO_BIAS;
273 hose->io_space->end = hose->io_space->start + TSUNAMI_IO_SPACE - 1;
274 hose->io_space->name = pci_io_names[index];
275 hose->io_space->flags = IORESOURCE_IO;
276
277 hose->mem_space->start = TSUNAMI_MEM(index) - TSUNAMI_MEM_BIAS;
278 hose->mem_space->end = hose->mem_space->start + 0xffffffff;
279 hose->mem_space->name = pci_mem_names[index];
280 hose->mem_space->flags = IORESOURCE_MEM;
281
282 if (request_resource(&ioport_resource, hose->io_space) < 0)
283 printk(KERN_ERR "Failed to request IO on hose %d\n", index);
284 if (request_resource(&iomem_resource, hose->mem_space) < 0)
285 printk(KERN_ERR "Failed to request MEM on hose %d\n", index);
286
287
288
289
290
291
292 saved_config[index].wsba[0] = pchip->wsba[0].csr;
293 saved_config[index].wsm[0] = pchip->wsm[0].csr;
294 saved_config[index].tba[0] = pchip->tba[0].csr;
295
296 saved_config[index].wsba[1] = pchip->wsba[1].csr;
297 saved_config[index].wsm[1] = pchip->wsm[1].csr;
298 saved_config[index].tba[1] = pchip->tba[1].csr;
299
300 saved_config[index].wsba[2] = pchip->wsba[2].csr;
301 saved_config[index].wsm[2] = pchip->wsm[2].csr;
302 saved_config[index].tba[2] = pchip->tba[2].csr;
303
304 saved_config[index].wsba[3] = pchip->wsba[3].csr;
305 saved_config[index].wsm[3] = pchip->wsm[3].csr;
306 saved_config[index].tba[3] = pchip->tba[3].csr;
307
308
309
310
311
312
313
314
315
316
317
318
319
320 hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0);
321
322 hose->sg_isa->align_entry = 4;
323
324 hose->sg_pci = iommu_arena_new(hose, 0x40000000,
325 size_for_memory(0x40000000), 0);
326 hose->sg_pci->align_entry = 4;
327
328 __direct_map_base = 0x80000000;
329 __direct_map_size = 0x80000000;
330
331 pchip->wsba[0].csr = hose->sg_isa->dma_base | 3;
332 pchip->wsm[0].csr = (hose->sg_isa->size - 1) & 0xfff00000;
333 pchip->tba[0].csr = virt_to_phys(hose->sg_isa->ptes);
334
335 pchip->wsba[1].csr = hose->sg_pci->dma_base | 3;
336 pchip->wsm[1].csr = (hose->sg_pci->size - 1) & 0xfff00000;
337 pchip->tba[1].csr = virt_to_phys(hose->sg_pci->ptes);
338
339 pchip->wsba[2].csr = 0x80000000 | 1;
340 pchip->wsm[2].csr = (0x80000000 - 1) & 0xfff00000;
341 pchip->tba[2].csr = 0;
342
343 pchip->wsba[3].csr = 0;
344
345
346 pchip->pctl.csr |= pctl_m_mwin;
347
348 tsunami_pci_tbi(hose, 0, -1);
349}
350
351
352void __iomem *
353tsunami_ioportmap(unsigned long addr)
354{
355 FIXUP_IOADDR_VGA(addr);
356 return (void __iomem *)(addr + TSUNAMI_IO_BIAS);
357}
358
359void __iomem *
360tsunami_ioremap(unsigned long addr, unsigned long size)
361{
362 FIXUP_MEMADDR_VGA(addr);
363 return (void __iomem *)(addr + TSUNAMI_MEM_BIAS);
364}
365
366#ifndef CONFIG_ALPHA_GENERIC
367EXPORT_SYMBOL(tsunami_ioportmap);
368EXPORT_SYMBOL(tsunami_ioremap);
369#endif
370
371void __init
372tsunami_init_arch(void)
373{
374#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
375 unsigned long tmp;
376
377
378
379 wrent(entInt, 0);
380
381
382
383 tmp = (unsigned long)(TSUNAMI_cchip - 1);
384 printk("%s: probing bogus address: 0x%016lx\n", __func__, bogus_addr);
385 printk("\tprobe %s\n",
386 tsunami_probe_write((unsigned long *)bogus_addr)
387 ? "succeeded" : "failed");
388#endif
389
390#if 0
391 printk("%s: CChip registers:\n", __func__);
392 printk("%s: CSR_CSC 0x%lx\n", __func__, TSUNAMI_cchip->csc.csr);
393 printk("%s: CSR_MTR 0x%lx\n", __func__, TSUNAMI_cchip.mtr.csr);
394 printk("%s: CSR_MISC 0x%lx\n", __func__, TSUNAMI_cchip->misc.csr);
395 printk("%s: CSR_DIM0 0x%lx\n", __func__, TSUNAMI_cchip->dim0.csr);
396 printk("%s: CSR_DIM1 0x%lx\n", __func__, TSUNAMI_cchip->dim1.csr);
397 printk("%s: CSR_DIR0 0x%lx\n", __func__, TSUNAMI_cchip->dir0.csr);
398 printk("%s: CSR_DIR1 0x%lx\n", __func__, TSUNAMI_cchip->dir1.csr);
399 printk("%s: CSR_DRIR 0x%lx\n", __func__, TSUNAMI_cchip->drir.csr);
400
401 printk("%s: DChip registers:\n");
402 printk("%s: CSR_DSC 0x%lx\n", __func__, TSUNAMI_dchip->dsc.csr);
403 printk("%s: CSR_STR 0x%lx\n", __func__, TSUNAMI_dchip->str.csr);
404 printk("%s: CSR_DREV 0x%lx\n", __func__, TSUNAMI_dchip->drev.csr);
405#endif
406
407 ioport_resource.end = ~0UL;
408
409
410
411
412 tsunami_init_one_pchip(TSUNAMI_pchip0, 0);
413 if (TSUNAMI_cchip->csc.csr & 1L<<14)
414 tsunami_init_one_pchip(TSUNAMI_pchip1, 1);
415
416
417 find_console_vga_hose();
418}
419
420static void
421tsunami_kill_one_pchip(tsunami_pchip *pchip, int index)
422{
423 pchip->wsba[0].csr = saved_config[index].wsba[0];
424 pchip->wsm[0].csr = saved_config[index].wsm[0];
425 pchip->tba[0].csr = saved_config[index].tba[0];
426
427 pchip->wsba[1].csr = saved_config[index].wsba[1];
428 pchip->wsm[1].csr = saved_config[index].wsm[1];
429 pchip->tba[1].csr = saved_config[index].tba[1];
430
431 pchip->wsba[2].csr = saved_config[index].wsba[2];
432 pchip->wsm[2].csr = saved_config[index].wsm[2];
433 pchip->tba[2].csr = saved_config[index].tba[2];
434
435 pchip->wsba[3].csr = saved_config[index].wsba[3];
436 pchip->wsm[3].csr = saved_config[index].wsm[3];
437 pchip->tba[3].csr = saved_config[index].tba[3];
438}
439
440void
441tsunami_kill_arch(int mode)
442{
443 tsunami_kill_one_pchip(TSUNAMI_pchip0, 0);
444 if (TSUNAMI_cchip->csc.csr & 1L<<14)
445 tsunami_kill_one_pchip(TSUNAMI_pchip1, 1);
446}
447
448static inline void
449tsunami_pci_clr_err_1(tsunami_pchip *pchip)
450{
451 pchip->perror.csr;
452 pchip->perror.csr = 0x040;
453 mb();
454 pchip->perror.csr;
455}
456
457static inline void
458tsunami_pci_clr_err(void)
459{
460 tsunami_pci_clr_err_1(TSUNAMI_pchip0);
461
462
463 if (TSUNAMI_cchip->csc.csr & 1L<<14)
464 tsunami_pci_clr_err_1(TSUNAMI_pchip1);
465}
466
467void
468tsunami_machine_check(unsigned long vector, unsigned long la_ptr)
469{
470
471 mb();
472 mb();
473 draina();
474 tsunami_pci_clr_err();
475 wrmces(0x7);
476 mb();
477
478 process_mcheck_info(vector, la_ptr, "TSUNAMI",
479 mcheck_expected(smp_processor_id()));
480}
481