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