11da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 21da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * linux/arch/alpha/kernel/core_mcpcia.c 31da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 41da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Based on code written by David A Rusling (david.rusling@reo.mts.dec.com). 51da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 61da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Code common to all MCbus-PCI Adaptor core logic chipsets 71da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 81da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 91da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define __EXTERN_INLINE inline 101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/io.h> 111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/core_mcpcia.h> 121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#undef __EXTERN_INLINE 131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/types.h> 151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/pci.h> 161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/sched.h> 171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/init.h> 181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <linux/delay.h> 191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include <asm/ptrace.h> 211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "proto.h" 231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#include "pci_impl.h" 241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * NOTE: Herein lie back-to-back mb instructions. They are magic. 271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * One plausible explanation is that the i/o controller does not properly 281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * handle the system transaction. Another involves timing. Ho hum. 291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * BIOS32-style PCI interface: 331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#define DEBUG_CFG 0 361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#if DEBUG_CFG 381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define DBG_CFG(args) printk args 391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#else 401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds# define DBG_CFG(args) 411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds#endif 421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* 441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Given a bus, device, and function number, compute resulting 451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * configuration space address and setup the MCPCIA_HAXR2 register 461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * accordingly. It is therefore not safe to have concurrent 471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * invocations to configuration space access routines, but there 481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * really shouldn't be any need for this. 491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Type 0: 511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 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 541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | | |D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|0| 561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31:11 Device select bit. 591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10:8 Function number 601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7:2 Register number 611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Type 1: 631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3 3|3 3 2 2|2 2 2 2|2 2 2 2|1 1 1 1|1 1 1 1|1 1 651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 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 661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * | | | | | | | | | | |B|B|B|B|B|B|B|B|D|D|D|D|D|F|F|F|R|R|R|R|R|R|0|1| 681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ 691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 31:24 reserved 711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 23:16 bus number (8 bits = 128 possible buses) 721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 15:11 Device number (5 bits) 731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 10:8 function number 741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 7:2 register number 751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Notes: 771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The function number selects which function of a multi-function device 781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * (e.g., SCSI and Ethernet). 791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * The register selects a DWORD (32 bit) register offset. Hence it 811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * doesn't get shifted by 2 bits as we want to "drop" the bottom two 821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * bits. 831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic unsigned int 861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsconf_read(unsigned long addr, unsigned char type1, 871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose) 881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long mid = MCPCIA_HOSE2MID(hose->index); 91280da4e4d306667b7faa95152b54f7ca4266ff1eRichard Henderson unsigned int stat0, value, cpu; 921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu = smp_processor_id(); 941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_save(flags); 961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n", 981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr, type1, mid)); 991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reset status register to avoid losing errors. */ 1011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stat0 = *(vuip)MCPCIA_CAP_ERR(mid); 1021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_CAP_ERR(mid) = stat0; 1031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 104280da4e4d306667b7faa95152b54f7ca4266ff1eRichard Henderson *(vuip)MCPCIA_CAP_ERR(mid); 1051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0)); 1061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 1081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds draina(); 1091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_expected(cpu) = 1; 1101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_taken(cpu) = 0; 1111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_extra(cpu) = mid; 1121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 1131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Access configuration space. */ 1151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = *((vuip)addr); 1161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 1171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); /* magic */ 1181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mcheck_taken(cpu)) { 1201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_taken(cpu) = 0; 1211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = 0xffffffffU; 1221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 1231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 1241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_expected(cpu) = 0; 1251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 1261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_CFG(("conf_read(): finished\n")); 1281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_restore(flags); 1301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return value; 1311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 1341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsconf_write(unsigned long addr, unsigned int value, unsigned char type1, 1351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose) 1361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long flags; 1381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long mid = MCPCIA_HOSE2MID(hose->index); 139280da4e4d306667b7faa95152b54f7ca4266ff1eRichard Henderson unsigned int stat0, cpu; 1401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds cpu = smp_processor_id(); 1421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_save(flags); /* avoid getting hit by machine check */ 1441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Reset status register to avoid losing errors. */ 1461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds stat0 = *(vuip)MCPCIA_CAP_ERR(mid); 1471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb(); 148280da4e4d306667b7faa95152b54f7ca4266ff1eRichard Henderson *(vuip)MCPCIA_CAP_ERR(mid); 1491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0)); 1501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds draina(); 1521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_expected(cpu) = 1; 1531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_extra(cpu) = mid; 1541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 1551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Access configuration space. */ 1571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *((vuip)addr) = value; 1581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 1591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); /* magic */ 160280da4e4d306667b7faa95152b54f7ca4266ff1eRichard Henderson *(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */ 1611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_expected(cpu) = 0; 1621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 1631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_CFG(("conf_write(): finished\n")); 1651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds local_irq_restore(flags); 1661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 1691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where, 1701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose, unsigned long *pci_addr, 1711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char *type1) 1721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds u8 bus = pbus->number; 1741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long addr; 1751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_CFG(("mk_conf_addr(bus=%d,devfn=0x%x,hose=%d,where=0x%x," 1771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds " pci_addr=0x%p, type1=0x%p)\n", 1781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bus, devfn, hose->index, where, pci_addr, type1)); 1791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Type 1 configuration cycle for *ALL* busses. */ 1811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *type1 = 1; 1821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!pbus->parent) /* No parent means peer PCI bus. */ 1841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds bus = 0; 1851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr = (bus << 16) | (devfn << 8) | (where); 1861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr <<= 5; /* swizzle for SPARSE */ 1871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr |= hose->config_space_base; 1881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *pci_addr = addr; 1901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); 1911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return 0; 1921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 1931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 1941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 1951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_read_config(struct pci_bus *bus, unsigned int devfn, int where, 1961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size, u32 *value) 1971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 1981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose = bus->sysdata; 1991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long addr, w; 2001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char type1; 2011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mk_conf_addr(bus, devfn, where, hose, &addr, &type1)) 2031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return PCIBIOS_DEVICE_NOT_FOUND; 2041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr |= (size - 1) * 8; 2061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds w = conf_read(addr, type1, hose); 2071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (size) { 2081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 2091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *value = __kernel_extbl(w, where & 3); 2101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 2: 2121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *value = __kernel_extwl(w, where & 3); 2131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 2151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *value = w; 2161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 2171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return PCIBIOS_SUCCESSFUL; 2191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int 2221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_write_config(struct pci_bus *bus, unsigned int devfn, int where, 2231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int size, u32 value) 2241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose = bus->sysdata; 2261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long addr; 2271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned char type1; 2281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mk_conf_addr(bus, devfn, where, hose, &addr, &type1)) 2301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return PCIBIOS_DEVICE_NOT_FOUND; 2311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds addr |= (size - 1) * 8; 2331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds value = __kernel_insql(value, where & 3); 2341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds conf_write(addr, value, type1, hose); 2351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return PCIBIOS_SUCCESSFUL; 2361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstruct pci_ops mcpcia_pci_ops = 2391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .read = mcpcia_read_config, 2411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds .write = mcpcia_write_config, 2421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds}; 2431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 2451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_pci_tbi(struct pci_controller *hose, dma_addr_t start, dma_addr_t end) 2461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wmb(); 2481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_SG_TBIA(MCPCIA_HOSE2MID(hose->index)) = 0; 2491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 2501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic int __init 2531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_probe_hose(int h) 2541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int cpu = smp_processor_id(); 2561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mid = MCPCIA_HOSE2MID(h); 2571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int pci_rev; 2581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Gotta be REAL careful. If hose is absent, we get an mcheck. */ 2601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 2621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 2631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds draina(); 2641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wrmces(7); 2651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_expected(cpu) = 2; /* indicates probing */ 2671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_taken(cpu) = 0; 2681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_extra(cpu) = mid; 2691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 2701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Access the bus revision word. */ 2721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_rev = *(vuip)MCPCIA_REV(mid); 2731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 2751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); /* magic */ 2761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mcheck_taken(cpu)) { 2771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_taken(cpu) = 0; 2781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_rev = 0xffffffff; 2791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 2801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 2811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcheck_expected(cpu) = 0; 2821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 2831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds return (pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST; 2851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 2861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init 2881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_new_hose(int h) 2891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 2901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose; 2911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct resource *io, *mem, *hae_mem; 2921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mid = MCPCIA_HOSE2MID(h); 2931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 2941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose = alloc_pci_controller(); 2951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (h == 0) 2961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds pci_isa_hose = hose; 2971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds io = alloc_resource(); 2981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem = alloc_resource(); 2991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hae_mem = alloc_resource(); 3001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->io_space = io; 3021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->mem_space = hae_mem; 3031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->sparse_mem_base = MCPCIA_SPARSE(mid) - IDENT_ADDR; 3041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->dense_mem_base = MCPCIA_DENSE(mid) - IDENT_ADDR; 3051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->sparse_io_base = MCPCIA_IO(mid) - IDENT_ADDR; 3061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->dense_io_base = 0; 3071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->config_space_base = MCPCIA_CONF(mid); 3081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->index = h; 3091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds io->start = MCPCIA_IO(mid) - MCPCIA_IO_BIAS; 3111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds io->end = io->start + 0xffff; 3121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds io->name = pci_io_names[h]; 3131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds io->flags = IORESOURCE_IO; 3141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem->start = MCPCIA_DENSE(mid) - MCPCIA_MEM_BIAS; 3161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem->end = mem->start + 0xffffffff; 3171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem->name = pci_mem_names[h]; 3181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mem->flags = IORESOURCE_MEM; 3191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hae_mem->start = mem->start; 3211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hae_mem->end = mem->start + MCPCIA_MEM_MASK; 3221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hae_mem->name = pci_hae0_name; 3231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hae_mem->flags = IORESOURCE_MEM; 3241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_resource(&ioport_resource, io) < 0) 3261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "Failed to request IO on hose %d\n", h); 3271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_resource(&iomem_resource, mem) < 0) 3281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "Failed to request MEM on hose %d\n", h); 3291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (request_resource(mem, hae_mem) < 0) 3301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(KERN_ERR "Failed to request HAE_MEM on hose %d\n", h); 3311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 3341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_pci_clr_err(int mid) 3351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_CAP_ERR(mid); 3371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_CAP_ERR(mid) = 0xffffffff; /* Clear them all. */ 3381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 3391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_CAP_ERR(mid); /* Re-read for force write. */ 3401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void __init 3431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_startup_hose(struct pci_controller *hose) 3441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 3451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int mid = MCPCIA_HOSE2MID(hose->index); 3461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int tmp; 3471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_pci_clr_err(mid); 3491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Set up error reporting. 3521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = *(vuip)MCPCIA_CAP_ERR(mid); 3541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp |= 0x0006; /* master/target abort */ 3551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_CAP_ERR(mid) = tmp; 3561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 3571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds tmp = *(vuip)MCPCIA_CAP_ERR(mid); 3581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* 3601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Set up the PCI->physical memory translation windows. 3611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * 3621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Window 0 is scatter-gather 8MB at 8MB (for isa) 3631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Window 1 is scatter-gather (up to) 1GB at 1GB (for pci) 3641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds * Window 2 is direct access 2GB at 2GB 3651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds */ 3661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->sg_isa = iommu_arena_new(hose, 0x00800000, 0x00800000, 0); 3671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->sg_pci = iommu_arena_new(hose, 0x40000000, 3681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds size_for_memory(0x40000000), 0); 3691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __direct_map_base = 0x80000000; 3711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds __direct_map_size = 0x80000000; 3721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_W0_BASE(mid) = hose->sg_isa->dma_base | 3; 3741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_W0_MASK(mid) = (hose->sg_isa->size - 1) & 0xfff00000; 3751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_T0_BASE(mid) = virt_to_phys(hose->sg_isa->ptes) >> 8; 3761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_W1_BASE(mid) = hose->sg_pci->dma_base | 3; 3781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_W1_MASK(mid) = (hose->sg_pci->size - 1) & 0xfff00000; 3791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_T1_BASE(mid) = virt_to_phys(hose->sg_pci->ptes) >> 8; 3801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_W2_BASE(mid) = __direct_map_base | 1; 3821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_W2_MASK(mid) = (__direct_map_size - 1) & 0xfff00000; 3831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_T2_BASE(mid) = 0; 3841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_W3_BASE(mid) = 0x0; 3861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_pci_tbi(hose, 0, -1); 3881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_HBASE(mid) = 0x0; 3901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 3911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 3921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_HAE_MEM(mid) = 0U; 3931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 3941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_HAE_MEM(mid); /* read it back. */ 3951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_HAE_IO(mid) = 0; 3961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 3971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds *(vuip)MCPCIA_HAE_IO(mid); /* read it back. */ 3981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 3991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init 4011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_init_arch(void) 4021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* With multiple PCI busses, we play with I/O as physical addrs. */ 4041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds ioport_resource.end = ~0UL; 4051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Allocate hose 0. That's the one that all the ISA junk hangs 4071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds off of, from which we'll be registering stuff here in a bit. 4081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds Other hose detection is done in mcpcia_init_hoses, which is 4091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds called from init_IRQ. */ 4101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_new_hose(0); 4121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds/* This is called from init_IRQ, since we cannot take interrupts 4151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds before then. Which means we cannot do this in init_arch. */ 4161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid __init 4181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_init_hoses(void) 4191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose; 4211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int hose_count; 4221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int h; 4231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* First, find how many hoses we have. */ 4251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose_count = 0; 4261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (h = 0; h < MCPCIA_MAX_HOSES; ++h) { 4271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (mcpcia_probe_hose(h)) { 4281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (h != 0) 4291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_new_hose(h); 4301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose_count++; 4311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("mcpcia_init_hoses: found %d hoses\n", hose_count); 4351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Now do init for each hose. */ 4371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (hose = hose_head; hose; hose = hose->next) 4381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_startup_hose(hose); 4391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 4401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 4421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_print_uncorrectable(struct el_MCPCIA_uncorrected_frame_mcheck *logout) 4431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 4441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_common_EV5_uncorrectable_mcheck *frame; 4451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int i; 4461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame = &logout->procdata; 4481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 4491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Print PAL fields */ 4501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 24; i += 2) { 4511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" paltmp[%d-%d] = %16lx %16lx\n", 4521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i, i+1, frame->paltemp[i], frame->paltemp[i+1]); 4531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (i = 0; i < 8; i += 2) { 4551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" shadow[%d-%d] = %16lx %16lx\n", 4561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds i, i+1, frame->shadow[i], 4571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->shadow[i+1]); 4581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Addr of excepting instruction = %16lx\n", 4601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->exc_addr); 4611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Summary of arithmetic traps = %16lx\n", 4621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->exc_sum); 4631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Exception mask = %16lx\n", 4641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->exc_mask); 4651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Base address for PALcode = %16lx\n", 4661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->pal_base); 4671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Interrupt Status Reg = %16lx\n", 4681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->isr); 4691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" CURRENT SETUP OF EV5 IBOX = %16lx\n", 4701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->icsr); 4711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" I-CACHE Reg %s parity error = %16lx\n", 4721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds (frame->ic_perr_stat & 0x800L) ? 4731da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds "Data" : "Tag", 4741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->ic_perr_stat); 4751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" D-CACHE error Reg = %16lx\n", 4761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->dc_perr_stat); 4771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (frame->dc_perr_stat & 0x2) { 4781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (frame->dc_perr_stat & 0x03c) { 4791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 8: 4801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Data error in bank 1\n"); 4811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 4: 4831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Data error in bank 0\n"); 4841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 20: 4861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Tag error in bank 1\n"); 4871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 10: 4891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Tag error in bank 0\n"); 4901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 4911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 4931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Effective VA = %16lx\n", 4941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->va); 4951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Reason for D-stream = %16lx\n", 4961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->mm_stat); 4971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" EV5 SCache address = %16lx\n", 4981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->sc_addr); 4991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" EV5 SCache TAG/Data parity = %16lx\n", 5001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->sc_stat); 5011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" EV5 BC_TAG_ADDR = %16lx\n", 5021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->bc_tag_addr); 5031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" EV5 EI_ADDR: Phys addr of Xfer = %16lx\n", 5041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->ei_addr); 5051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" Fill Syndrome = %16lx\n", 5061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->fill_syndrome); 5071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" EI_STAT reg = %16lx\n", 5081da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->ei_stat); 5091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" LD_LOCK = %16lx\n", 5101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame->ld_lock); 5111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsstatic void 5141da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsmcpcia_print_system_area(unsigned long la_ptr) 5151da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5161da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_common *frame; 5171da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose; 5181da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5191da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct IOD_subpacket { 5201da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned long base; 5211da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int whoami; 5221da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int rsvd1; 5231da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int pci_rev; 5241da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cap_ctrl; 5251da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int hae_mem; 5261da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int hae_io; 5271da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int int_ctl; 5281da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int int_reg; 5291da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int int_mask0; 5301da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int int_mask1; 5311da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mc_err0; 5321da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mc_err1; 5331da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cap_err; 5341da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int rsvd2; 5351da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int pci_err1; 5361da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mdpa_stat; 5371da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mdpa_syn; 5381da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mdpb_stat; 5391da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int mdpb_syn; 5401da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int rsvd3; 5411da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int rsvd4; 5421da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int rsvd5; 5431da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } *iodpp; 5441da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5451da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds frame = (struct el_common *)la_ptr; 5461da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds iodpp = (struct IOD_subpacket *) (la_ptr + frame->sys_offset); 5471da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5481da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (hose = hose_head; hose; hose = hose->next, iodpp++) { 5491da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5501da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk("IOD %d Register Subpacket - Bridge Base Address %16lx\n", 5511da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds hose->index, iodpp->base); 5521da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" WHOAMI = %8x\n", iodpp->whoami); 5531da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" PCI_REV = %8x\n", iodpp->pci_rev); 5541da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" CAP_CTRL = %8x\n", iodpp->cap_ctrl); 5551da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" HAE_MEM = %8x\n", iodpp->hae_mem); 5561da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" HAE_IO = %8x\n", iodpp->hae_io); 5571da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" INT_CTL = %8x\n", iodpp->int_ctl); 5581da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" INT_REG = %8x\n", iodpp->int_reg); 5591da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" INT_MASK0 = %8x\n", iodpp->int_mask0); 5601da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" INT_MASK1 = %8x\n", iodpp->int_mask1); 5611da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" MC_ERR0 = %8x\n", iodpp->mc_err0); 5621da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" MC_ERR1 = %8x\n", iodpp->mc_err1); 5631da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" CAP_ERR = %8x\n", iodpp->cap_err); 5641da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" PCI_ERR1 = %8x\n", iodpp->pci_err1); 5651da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" MDPA_STAT = %8x\n", iodpp->mdpa_stat); 5661da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" MDPA_SYN = %8x\n", iodpp->mdpa_syn); 5671da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" MDPB_STAT = %8x\n", iodpp->mdpb_stat); 5681da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds printk(" MDPB_SYN = %8x\n", iodpp->mdpb_syn); 5691da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5701da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 5711da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5721da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvaldsvoid 5734fa1970a23bf8fc68e86b65a87c32556e20a6be6Al Viromcpcia_machine_check(unsigned long vector, unsigned long la_ptr) 5741da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds{ 5751da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct el_MCPCIA_uncorrected_frame_mcheck *mchk_logout; 5761da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds unsigned int cpu = smp_processor_id(); 5771da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds int expected; 5781da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5791da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mchk_logout = (struct el_MCPCIA_uncorrected_frame_mcheck *)la_ptr; 5801da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds expected = mcheck_expected(cpu); 5811da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5821da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 5831da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); /* magic */ 5841da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds draina(); 5851da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 5861da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds switch (expected) { 5871da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 0: 5881da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds { 5891da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* FIXME: how do we figure out which hose the 5901da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds error was on? */ 5911da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds struct pci_controller *hose; 5921da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds for (hose = hose_head; hose; hose = hose->next) 5931da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_pci_clr_err(MCPCIA_HOSE2MID(hose->index)); 5941da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5951da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 5961da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds case 1: 5971da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_pci_clr_err(mcheck_extra(cpu)); 5981da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 5991da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds default: 6001da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds /* Otherwise, we're being called from mcpcia_probe_hose 6011da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds and there's no hose clear an error from. */ 6021da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds break; 6031da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6041da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6051da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds wrmces(0x7); 6061da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mb(); 6071da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds 6084fa1970a23bf8fc68e86b65a87c32556e20a6be6Al Viro process_mcheck_info(vector, la_ptr, "MCPCIA", expected != 0); 6091da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds if (!expected && vector != 0x620 && vector != 0x630) { 6101da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_print_uncorrectable(mchk_logout); 6111da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds mcpcia_print_system_area(la_ptr); 6121da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds } 6131da177e4c3f41524e886b7f1b8a0c1fc7321cacLinus Torvalds} 614