#include "pci_errata.h" #include "pci.h" #include __attribute__((aligned(16))) void chip_errata_135(void) { /* * Errata type: Silicon * Affected component: PCI * Description: When core PCI transactions that involve writes to configuration or I/O space * are followed by a core line access to line addresses 0x4 and 0xC, core access * to the XL bus can hang. * Workaround: Prevent PCI configuration and I/O writes from being followed by the described * line access by the core by generating a known good XL bus transaction after * the PCI transaction. * Create a dummy function which is called immediately after each of the affected * transactions. There are three requirements for this dummy function. * 1. The function must be aligned to a 16-byte boundary. * 2. The function must contain a dummy write to a location on the XL bus, * preferably one with no side effects. * 3. The function must be longer than 32 bytes. If it is not, the function should * be padded with 16- or 48-bit TPF instructions placed after the end of * the function (after the RTS instruction) such that the length is longer * than 32 bytes. */ __asm__ __volatile( " .extern __MBAR \n\t" " clr.l d0 \n\t" " move.l d0,__MBAR+0xF0C \n\t" /* Must use direct addressing. write to EPORT module */ /* xlbus -> slavebus -> eport, writing '0' to register */ /* has no effect */ " rts \n\t" " tpf.l #0x0 \n\t" " tpf.l #0x0 \n\t" " tpf.l #0x0 \n\t" " tpf.l #0x0 \n\t" " tpf.l #0x0 \n\t" ::: "d0", "memory"); } void chip_errata_055(int32_t handle) { uint32_t dummy; return; /* test */ /* initiate PCI configuration access to device */ MCF_PCI_PCICAR = MCF_PCI_PCICAR_E | /* enable configuration access special cycle */ MCF_PCI_PCICAR_BUSNUM(3) | /* note: invalid bus number */ MCF_PCI_PCICAR_DEVNUM(PCI_DEVICE_FROM_HANDLE(handle)) | /* device number, devices 0 - 9 are reserved */ MCF_PCI_PCICAR_FUNCNUM(PCI_FUNCTION_FROM_HANDLE(handle)) | /* function number */ MCF_PCI_PCICAR_DWORD(0); /* issue a dummy read to an unsupported bus number (will fail) */ dummy = * (volatile uint32_t *) PCI_IO_OFFSET; /* access device */ /* silently clear the PCI errors we produced just now */ MCF_PCI_PCIISR = 0xffffffff; /* clear all errors */ MCF_PCI_PCIGSCR = MCF_PCI_PCIGSCR_PE | MCF_PCI_PCIGSCR_SE; (void) dummy; }