|
@@ -423,3 +423,159 @@ verify_tb_operation(void)
|
|
|
page[0] = data0;
|
|
|
mcheck_expected(0) = 1;
|
|
|
mcheck_taken(0) = 0;
|
|
|
+ mb();
|
|
|
+ temp = cia_readl(bus_addr);
|
|
|
+ mb();
|
|
|
+ mcheck_expected(0) = 0;
|
|
|
+ mb();
|
|
|
+ if (mcheck_taken(0)) {
|
|
|
+ printk("pci: failed sg loopback i/o read test (mcheck)\n");
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+ if (temp != data0) {
|
|
|
+ printk("pci: failed sg loopback i/o read test "
|
|
|
+ "(%#x != %#x)\n", temp, data0);
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+ printk("pci: passed sg loopback i/o read test\n");
|
|
|
+
|
|
|
+ /* Third, try to invalidate the TLB. */
|
|
|
+
|
|
|
+ if (! use_tbia_try2) {
|
|
|
+ cia_pci_tbi(arena->hose, 0, -1);
|
|
|
+ temp = *(vip)CIA_IOC_TB_TAGn(0);
|
|
|
+ if (temp & 1) {
|
|
|
+ use_tbia_try2 = 1;
|
|
|
+ printk("pci: failed tbia test; workaround available\n");
|
|
|
+ } else {
|
|
|
+ printk("pci: passed tbia test\n");
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Fourth, verify the TLB snoops the EV5's caches when
|
|
|
+ doing a tlb fill. */
|
|
|
+
|
|
|
+ data0 = 0x5adda15e;
|
|
|
+ page[0] = data0;
|
|
|
+ arena->ptes[4] = pte0;
|
|
|
+ mcheck_expected(0) = 1;
|
|
|
+ mcheck_taken(0) = 0;
|
|
|
+ mb();
|
|
|
+ temp = cia_readl(bus_addr + 4*PAGE_SIZE);
|
|
|
+ mb();
|
|
|
+ mcheck_expected(0) = 0;
|
|
|
+ mb();
|
|
|
+ if (mcheck_taken(0)) {
|
|
|
+ printk("pci: failed pte write cache snoop test (mcheck)\n");
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+ if (temp != data0) {
|
|
|
+ printk("pci: failed pte write cache snoop test "
|
|
|
+ "(%#x != %#x)\n", temp, data0);
|
|
|
+ goto failed;
|
|
|
+ }
|
|
|
+ printk("pci: passed pte write cache snoop test\n");
|
|
|
+
|
|
|
+ /* Fifth, verify that a previously invalid PTE entry gets
|
|
|
+ filled from the page table. */
|
|
|
+
|
|
|
+ data0 = 0xabcdef12;
|
|
|
+ page[0] = data0;
|
|
|
+ arena->ptes[5] = pte0;
|
|
|
+ mcheck_expected(0) = 1;
|
|
|
+ mcheck_taken(0) = 0;
|
|
|
+ mb();
|
|
|
+ temp = cia_readl(bus_addr + 5*PAGE_SIZE);
|
|
|
+ mb();
|
|
|
+ mcheck_expected(0) = 0;
|
|
|
+ mb();
|
|
|
+ if (mcheck_taken(0)) {
|
|
|
+ printk("pci: failed valid tag invalid pte reload test "
|
|
|
+ "(mcheck; workaround available)\n");
|
|
|
+ /* Work around this bug by aligning new allocations
|
|
|
+ on 4 page boundaries. */
|
|
|
+ arena->align_entry = 4;
|
|
|
+ } else if (temp != data0) {
|
|
|
+ printk("pci: failed valid tag invalid pte reload test "
|
|
|
+ "(%#x != %#x)\n", temp, data0);
|
|
|
+ goto failed;
|
|
|
+ } else {
|
|
|
+ printk("pci: passed valid tag invalid pte reload test\n");
|
|
|
+ }
|
|
|
+
|
|
|
+ /* Sixth, verify machine checks are working. Test invalid
|
|
|
+ pte under the same valid tag as we used above. */
|
|
|
+
|
|
|
+ mcheck_expected(0) = 1;
|
|
|
+ mcheck_taken(0) = 0;
|
|
|
+ mb();
|
|
|
+ temp = cia_readl(bus_addr + 6*PAGE_SIZE);
|
|
|
+ mb();
|
|
|
+ mcheck_expected(0) = 0;
|
|
|
+ mb();
|
|
|
+ printk("pci: %s pci machine check test\n",
|
|
|
+ mcheck_taken(0) ? "passed" : "failed");
|
|
|
+
|
|
|
+ /* Clean up after the tests. */
|
|
|
+ arena->ptes[4] = 0;
|
|
|
+ arena->ptes[5] = 0;
|
|
|
+
|
|
|
+ if (use_tbia_try2) {
|
|
|
+ alpha_mv.mv_pci_tbi = cia_pci_tbi_try2;
|
|
|
+
|
|
|
+ /* Tags 0-3 must be disabled if we use this workaraund. */
|
|
|
+ wmb();
|
|
|
+ *(vip)CIA_IOC_TB_TAGn(0) = 2;
|
|
|
+ *(vip)CIA_IOC_TB_TAGn(1) = 2;
|
|
|
+ *(vip)CIA_IOC_TB_TAGn(2) = 2;
|
|
|
+ *(vip)CIA_IOC_TB_TAGn(3) = 2;
|
|
|
+
|
|
|
+ printk("pci: tbia workaround enabled\n");
|
|
|
+ }
|
|
|
+ alpha_mv.mv_pci_tbi(arena->hose, 0, -1);
|
|
|
+
|
|
|
+exit:
|
|
|
+ /* unmap the bus addr */
|
|
|
+ cia_iounmap(bus_addr);
|
|
|
+
|
|
|
+ /* Restore normal PCI operation. */
|
|
|
+ mb();
|
|
|
+ *(vip)CIA_IOC_CIA_CTRL = ctrl;
|
|
|
+ mb();
|
|
|
+ *(vip)CIA_IOC_CIA_CTRL;
|
|
|
+ mb();
|
|
|
+ return;
|
|
|
+
|
|
|
+failed:
|
|
|
+ printk("pci: disabling sg translation window\n");
|
|
|
+ *(vip)CIA_IOC_PCI_W0_BASE = 0;
|
|
|
+ *(vip)CIA_IOC_PCI_W1_BASE = 0;
|
|
|
+ pci_isa_hose->sg_isa = NULL;
|
|
|
+ alpha_mv.mv_pci_tbi = NULL;
|
|
|
+ goto exit;
|
|
|
+}
|
|
|
+
|
|
|
+#if defined(ALPHA_RESTORE_SRM_SETUP)
|
|
|
+/* Save CIA configuration data as the console had it set up. */
|
|
|
+struct
|
|
|
+{
|
|
|
+ unsigned int hae_mem;
|
|
|
+ unsigned int hae_io;
|
|
|
+ unsigned int pci_dac_offset;
|
|
|
+ unsigned int err_mask;
|
|
|
+ unsigned int cia_ctrl;
|
|
|
+ unsigned int cia_cnfg;
|
|
|
+ struct {
|
|
|
+ unsigned int w_base;
|
|
|
+ unsigned int w_mask;
|
|
|
+ unsigned int t_base;
|
|
|
+ } window[4];
|
|
|
+} saved_config __attribute((common));
|
|
|
+
|
|
|
+void
|
|
|
+cia_save_srm_settings(int is_pyxis)
|
|
|
+{
|
|
|
+ int i;
|
|
|
+
|
|
|
+ /* Save some important registers. */
|
|
|
+ saved_config.err_mask = *(vip)CIA_IOC_ERR_MASK;
|