Import 2.3.13pre1
[davej-history.git] / arch / alpha / kernel / core_tsunami.c
blobefcce56d5557b7239287186490f9657ccf0c2f31
1 /*
2 * linux/arch/alpha/kernel/core_tsunami.c
4 * Code common to all TSUNAMI core logic chips.
6 * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com).
8 */
10 #include <linux/config.h>
11 #include <linux/kernel.h>
12 #include <linux/types.h>
13 #include <linux/pci.h>
14 #include <linux/sched.h>
15 #include <linux/init.h>
17 #include <asm/ptrace.h>
18 #include <asm/system.h>
19 #include <asm/pci.h>
21 #define __EXTERN_INLINE inline
22 #include <asm/io.h>
23 #include <asm/core_tsunami.h>
24 #undef __EXTERN_INLINE
26 #include "proto.h"
27 #include "bios32.h"
30 * NOTE: Herein lie back-to-back mb instructions. They are magic.
31 * One plausible explanation is that the I/O controller does not properly
32 * handle the system transaction. Another involves timing. Ho hum.
36 * BIOS32-style PCI interface:
39 #ifdef DEBUG_CONFIG
40 # define DBG_CFG(args) printk args
41 #else
42 # define DBG_CFG(args)
43 #endif
45 #define DEBUG_MCHECK
46 #ifdef DEBUG_MCHECK
47 # define DBG_MCK(args) printk args
48 #define DEBUG_MCHECK_DUMP
49 #else
50 # define DBG_MCK(args)
51 #endif
53 static volatile unsigned int TSUNAMI_mcheck_expected[NR_CPUS];
54 static volatile unsigned int TSUNAMI_mcheck_taken[NR_CPUS];
55 static unsigned int TSUNAMI_jd[NR_CPUS];
56 int TSUNAMI_bootcpu;
59 * Given a bus, device, and function number, compute resulting
60 * configuration space address
61 * accordingly. It is therefore not safe to have concurrent
62 * invocations to configuration space access routines, but there
63 * really shouldn't be any need for this.
65 * Note that all config space accesses use Type 1 address format.
67 * Note also that type 1 is determined by non-zero bus number.
69 * Type 1:
71 * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1
72 * 3 2|1 0 9 8|7 6 5 4|3 2 1 0|9 8 7 6|5 4 3 2|1 0 9 8|7 6 5 4|3 2 1 0
73 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
74 * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1|
75 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+
77 * 31:24 reserved
78 * 23:16 bus number (8 bits = 128 possible buses)
79 * 15:11 Device number (5 bits)
80 * 10:8 function number
81 * 7:2 register number
83 * Notes:
84 * The function number selects which function of a multi-function device
85 * (e.g., SCSI and Ethernet).
87 * The register selects a DWORD (32 bit) register offset. Hence it
88 * doesn't get shifted by 2 bits as we want to "drop" the bottom two
89 * bits.
92 static int
93 mk_conf_addr(u8 bus, u8 device_fn, u8 where, struct linux_hose_info *hose,
94 unsigned long *pci_addr, unsigned char *type1)
96 unsigned long addr;
98 if (!pci_probe_enabled)
99 return -1;
101 DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, "
102 "pci_addr=0x%p, type1=0x%p)\n",
103 bus, device_fn, where, pci_addr, type1));
105 *type1 = (bus != 0);
107 if (hose->pci_first_busno == bus)
108 bus = 0;
110 addr = (bus << 16) | (device_fn << 8) | where;
111 addr |= hose->pci_config_space;
113 *pci_addr = addr;
114 DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
115 return 0;
118 int
119 tsunami_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value,
120 struct linux_hose_info *hose)
122 unsigned long addr;
123 unsigned char type1;
125 if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
126 return PCIBIOS_DEVICE_NOT_FOUND;
128 *value = __kernel_ldbu(*(vucp)addr);
129 return PCIBIOS_SUCCESSFUL;
133 tsunami_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value,
134 struct linux_hose_info *hose)
136 unsigned long addr;
137 unsigned char type1;
139 if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
140 return PCIBIOS_DEVICE_NOT_FOUND;
142 *value = __kernel_ldwu(*(vusp)addr);
143 return PCIBIOS_SUCCESSFUL;
147 tsunami_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value,
148 struct linux_hose_info *hose)
150 unsigned long addr;
151 unsigned char type1;
153 if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
154 return PCIBIOS_DEVICE_NOT_FOUND;
156 *value = *(vuip)addr;
157 return PCIBIOS_SUCCESSFUL;
160 int
161 tsunami_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value,
162 struct linux_hose_info *hose)
164 unsigned long addr;
165 unsigned char type1;
167 if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
168 return PCIBIOS_DEVICE_NOT_FOUND;
170 __kernel_stb(value, *(vucp)addr);
171 return PCIBIOS_SUCCESSFUL;
174 int
175 tsunami_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value,
176 struct linux_hose_info *hose)
178 unsigned long addr;
179 unsigned char type1;
181 if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
182 return PCIBIOS_DEVICE_NOT_FOUND;
184 __kernel_stw(value, *(vusp)addr);
185 return PCIBIOS_SUCCESSFUL;
189 tsunami_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value,
190 struct linux_hose_info *hose)
192 unsigned long addr;
193 unsigned char type1;
195 if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1))
196 return PCIBIOS_DEVICE_NOT_FOUND;
198 *(vuip)addr = value;
199 return PCIBIOS_SUCCESSFUL;
202 #ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
203 static long
204 tsunami_probe_read(volatile unsigned long *vaddr)
206 long dont_care, probe_result;
207 int cpu = smp_processor_id();
208 int s = swpipl(6); /* Block everything but machine checks. */
210 TSUNAMI_mcheck_taken[cpu] = 0;
211 TSUNAMI_mcheck_expected[cpu] = 1;
212 dont_care = *vaddr;
213 draina();
214 TSUNAMI_mcheck_expected[cpu] = 0;
215 probe_result = !TSUNAMI_mcheck_taken[cpu];
216 TSUNAMI_mcheck_taken[cpu] = 0;
217 setipl(s);
219 printk("dont_care == 0x%lx\n", dont_care);
221 return probe_result;
224 static long
225 tsunami_probe_write(volatile unsigned long *vaddr)
227 long true_contents, probe_result = 1;
229 TSUNAMI_cchip->misc.csr |= (1L << 28); /* clear NXM... */
230 true_contents = *vaddr;
231 *vaddr = 0;
232 draina();
233 if (TSUNAMI_cchip->misc.csr & (1L << 28)) {
234 int source = (TSUNAMI_cchip->misc.csr >> 29) & 7;
235 TSUNAMI_cchip->misc.csr |= (1L << 28); /* ...and unlock NXS. */
236 probe_result = 0;
237 printk("tsunami_probe_write: unit %d at 0x%016lx\n", source,
238 (unsigned long)vaddr);
240 if (probe_result)
241 *vaddr = true_contents;
242 return probe_result;
244 #else
245 #define tsunami_probe_read(ADDR) 1
246 #endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */
248 #define FN __FUNCTION__
250 static void __init
251 tsunami_init_one_pchip(tsunami_pchip *pchip, int index,
252 unsigned long *mem_start)
254 struct linux_hose_info *hose;
255 int i;
257 if (tsunami_probe_read(&pchip->pctl.csr) == 0)
258 return;
260 hose = (struct linux_hose_info *)*mem_start;
261 *mem_start = (unsigned long)(hose + 1);
262 memset(hose, 0, sizeof(*hose));
264 *hose_tail = hose;
265 hose_tail = &hose->next;
267 hose->pci_io_space = TSUNAMI_IO(index);
268 hose->pci_mem_space = TSUNAMI_MEM(index);
269 hose->pci_config_space = TSUNAMI_CONF(index);
270 hose->pci_sparse_space = 0;
271 hose->pci_hose_index = index;
273 switch (alpha_use_srm_setup)
275 default:
276 #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP)
277 for (i = 0; i < 4; ++i) {
278 if ((pchip->wsba[i].csr & 3) == 1
279 && pchip->tba[i].csr == 0
280 && (pchip->wsm[i].csr & 0xfff00000) > 0x0ff00000) {
281 TSUNAMI_DMA_WIN_BASE = pchip->wsba[i].csr & 0xfff00000;
282 TSUNAMI_DMA_WIN_SIZE = pchip->wsm[i].csr & 0xfff00000;
283 TSUNAMI_DMA_WIN_SIZE += 0x00100000;
284 #if 1
285 printk("%s: using Window %d settings\n", FN, i);
286 printk("%s: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n",
287 FN, pchip->wsba[i].csr, pchip->wsm[i].csr,
288 pchip->tba[i].csr);
289 #endif
290 goto found;
294 /* Otherwise, we must use our defaults. */
295 TSUNAMI_DMA_WIN_BASE = TSUNAMI_DMA_WIN_BASE_DEFAULT;
296 TSUNAMI_DMA_WIN_SIZE = TSUNAMI_DMA_WIN_SIZE_DEFAULT;
297 #endif
298 case 0:
300 * Set up the PCI->physical memory translation windows.
301 * For now, windows 1,2 and 3 are disabled. In the future,
302 * we may want to use them to do scatter/gather DMA.
304 * Window 0 goes at 1 GB and is 1 GB large, mapping to 0.
307 pchip->wsba[0].csr = 1L | (TSUNAMI_DMA_WIN_BASE_DEFAULT & 0xfff00000U);
308 pchip->wsm[0].csr = (TSUNAMI_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000UL;
309 pchip->tba[0].csr = 0;
311 #if 0
312 pchip->wsba[1].csr = 0;
313 #else
314 /* make the second window at 2Gb for 1Gb mapping to 1Gb */
315 pchip->wsba[1].csr = 1L | ((0x80000000U) & 0xfff00000U);
316 pchip->wsm[1].csr = (0x40000000UL - 1) & 0xfff00000UL;
317 pchip->tba[1].csr = 0x40000000;
318 #endif
320 pchip->wsba[2].csr = 0;
321 pchip->wsba[3].csr = 0;
322 mb();
324 found:;
327 void __init
328 tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end)
330 #ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI
331 extern asmlinkage void entInt(void);
332 unsigned long tmp;
334 /* Ho hum.. init_arch is called before init_IRQ, but we need to be
335 able to handle machine checks. So install the handler now. */
336 wrent(entInt, 0);
338 /* NXMs just don't matter to Tsunami--unless they make it
339 choke completely. */
340 tmp = (unsigned long)(TSUNAMI_cchip - 1);
341 printk("%s: probing bogus address: 0x%016lx\n", FN, bogus_addr);
342 printk("\tprobe %s\n",
343 tsunami_probe_write((unsigned long *)bogus_addr)
344 ? "succeeded" : "failed");
345 #endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */
347 #if 0
348 printk("%s: CChip registers:\n", FN);
349 printk("%s: CSR_CSC 0x%lx\n", FN, TSUNAMI_cchip->csc.csr);
350 printk("%s: CSR_MTR 0x%lx\n", FN, TSUNAMI_cchip.mtr.csr);
351 printk("%s: CSR_MISC 0x%lx\n", FN, TSUNAMI_cchip->misc.csr);
352 printk("%s: CSR_DIM0 0x%lx\n", FN, TSUNAMI_cchip->dim0.csr);
353 printk("%s: CSR_DIM1 0x%lx\n", FN, TSUNAMI_cchip->dim1.csr);
354 printk("%s: CSR_DIR0 0x%lx\n", FN, TSUNAMI_cchip->dir0.csr);
355 printk("%s: CSR_DIR1 0x%lx\n", FN, TSUNAMI_cchip->dir1.csr);
356 printk("%s: CSR_DRIR 0x%lx\n", FN, TSUNAMI_cchip->drir.csr);
358 printk("%s: DChip registers:\n");
359 printk("%s: CSR_DSC 0x%lx\n", FN, TSUNAMI_dchip->dsc.csr);
360 printk("%s: CSR_STR 0x%lx\n", FN, TSUNAMI_dchip->str.csr);
361 printk("%s: CSR_DREV 0x%lx\n", FN, TSUNAMI_dchip->drev.csr);
362 #endif
364 /* Align memory to cache line; we'll be allocating from it. */
365 *mem_start = (*mem_start | 31) + 1;
367 /* Find how many hoses we have, and initialize them. */
368 tsunami_init_one_pchip(TSUNAMI_pchip0, 0, mem_start);
369 /* must change this for TYPHOON which may have 4 */
370 if (TSUNAMI_cchip->csc.csr & 1L<<14)
371 tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start);
374 static inline void
375 tsunami_pci_clr_err_1(tsunami_pchip *pchip, int cpu)
377 TSUNAMI_jd[cpu] = pchip->perror.csr;
378 DBG_MCK(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n",
379 TSUNAMI_jd[cpu]));
380 pchip->perror.csr = 0x040;
381 mb();
382 TSUNAMI_jd[cpu] = pchip->perror.csr;
385 static int
386 tsunami_pci_clr_err(void)
388 int cpu = smp_processor_id();
389 tsunami_pci_clr_err_1(TSUNAMI_pchip0, cpu);
390 /* must change this for TYPHOON which may have 4 */
391 if (TSUNAMI_cchip->csc.csr & 1L<<14)
392 tsunami_pci_clr_err_1(TSUNAMI_pchip1, cpu);
393 return 0;
396 void
397 tsunami_machine_check(unsigned long vector, unsigned long la_ptr,
398 struct pt_regs * regs)
400 #if 0
401 printk("TSUNAMI machine check ignored\n") ;
402 #else
403 struct el_common *mchk_header;
404 struct el_TSUNAMI_sysdata_mcheck *mchk_sysdata;
405 unsigned int cpu = smp_processor_id();
407 mb();
408 mchk_header = (struct el_common *)la_ptr;
410 mchk_sysdata = (struct el_TSUNAMI_sysdata_mcheck *)
411 (la_ptr + mchk_header->sys_offset);
413 #if 0
414 DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n",
415 vector, la_ptr));
416 DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
417 regs->pc, mchk_header->size, mchk_header->proc_offset,
418 mchk_header->sys_offset));
419 DBG_MCK(("tsunami_machine_check: expected %d DCSR 0x%lx PEAR 0x%lx\n",
420 TSUNAMI_mcheck_expected[cpu], mchk_sysdata->epic_dcsr,
421 mchk_sysdata->epic_pear));
422 #endif
423 #ifdef DEBUG_MCHECK_DUMP
425 unsigned long *ptr;
426 int i;
428 ptr = (unsigned long *)la_ptr;
429 for (i = 0; i < mchk_header->size / sizeof(long); i += 2) {
430 printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]);
433 #endif /* DEBUG_MCHECK_DUMP */
435 * Check if machine check is due to a badaddr() and if so,
436 * ignore the machine check.
438 mb();
439 mb(); /* magic */
440 if (TSUNAMI_mcheck_expected[cpu]) {
441 DBG_MCK(("TSUNAMI machine check expected\n"));
442 TSUNAMI_mcheck_expected[cpu] = 0;
443 TSUNAMI_mcheck_taken[cpu] = 1;
444 mb();
445 mb(); /* magic */
446 draina();
447 tsunami_pci_clr_err();
448 wrmces(0x7);
449 mb();
451 #if 1
452 else {
453 printk("TSUNAMI machine check NOT expected\n") ;
454 DBG_MCK(("tsunami_machine_check: vector=0x%lx la_ptr=0x%lx\n",
455 vector, la_ptr));
456 DBG_MCK(("\t\t pc=0x%lx size=0x%x procoffset=0x%x sysoffset 0x%x\n",
457 regs->pc, mchk_header->size, mchk_header->proc_offset,
458 mchk_header->sys_offset));
459 TSUNAMI_mcheck_expected[cpu] = 0;
460 TSUNAMI_mcheck_taken[cpu] = 1;
461 mb();
462 mb(); /* magic */
463 draina();
464 tsunami_pci_clr_err();
465 wrmces(0x7);
466 mb();
468 #endif
469 #endif