Kaynağa Gözat

efHeterogeneousSynchronization normalDataOperation.c 吉超博 commit at 2021-03-16

吉超博 4 yıl önce
ebeveyn
işleme
ca51e6e51d

+ 115 - 0
efHeterogeneousSynchronization/databaseOperation/normalDataOperation.c

@@ -238,3 +238,118 @@ conf_write(unsigned long addr, unsigned int value, unsigned char type1)
 
 	cpu = smp_processor_id();
 
+	/* If Type1 access, must set T2 CFG.  */
+	if (type1) {
+		t2_cfg = *(vulp)T2_HAE_3 & ~0xc0000000UL;
+		*(vulp)T2_HAE_3 = t2_cfg | 0x40000000UL;
+		mb();
+	}
+	mb();
+	draina();
+
+	mcheck_expected(cpu) = 1;
+	mcheck_taken(cpu) = 0;
+	t2_mcheck_any_expected |= (1 << cpu);
+	mb();
+
+	/* Access configuration space.  */
+	*(vuip)addr = value;
+	mb();
+	mb();  /* magic */
+
+	/* Wait for possible mcheck. Also, this lets other CPUs clear
+	   their mchecks as well, as they can reliably tell when
+	   this CPU is in the midst of handling a real mcheck via
+	   the "taken" function. */
+	udelay(100);
+
+	if ((taken = mcheck_taken(cpu))) {
+		mcheck_taken(cpu) = 0;
+		t2_mcheck_last_taken |= (1 << cpu);
+		mb();
+	}
+	mcheck_expected(cpu) = 0;
+	t2_mcheck_any_expected = 0;
+	mb();
+
+	/* If Type1 access, must reset T2 CFG so normal IO space ops work.  */
+	if (type1) {
+		*(vulp)T2_HAE_3 = t2_cfg;
+		mb();
+	}
+}
+
+static int
+t2_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+	       int size, u32 *value)
+{
+	unsigned long addr, pci_addr;
+	unsigned char type1;
+	int shift;
+	long mask;
+
+	if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	mask = (size - 1) * 8;
+	shift = (where & 3) * 8;
+	addr = (pci_addr << 5) + mask + T2_CONF;
+	*value = conf_read(addr, type1) >> (shift);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+static int 
+t2_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size,
+		u32 value)
+{
+	unsigned long addr, pci_addr;
+	unsigned char type1;
+	long mask;
+
+	if (mk_conf_addr(bus, devfn, where, &pci_addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	mask = (size - 1) * 8;
+	addr = (pci_addr << 5) + mask + T2_CONF;
+	conf_write(addr, value << ((where & 3) * 8), type1);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops t2_pci_ops = 
+{
+	.read =		t2_read_config,
+	.write =	t2_write_config,
+};
+
+static void __init
+t2_direct_map_window1(unsigned long base, unsigned long length)
+{
+	unsigned long temp;
+
+	__direct_map_base = base;
+	__direct_map_size = length;
+
+	temp = (base & 0xfff00000UL) | ((base + length - 1) >> 20);
+	*(vulp)T2_WBASE1 = temp | 0x80000UL; /* OR in ENABLE bit */
+	temp = (length - 1) & 0xfff00000UL;
+	*(vulp)T2_WMASK1 = temp;
+	*(vulp)T2_TBASE1 = 0;
+
+#if DEBUG_PRINT_FINAL_SETTINGS
+	printk("%s: setting WBASE1=0x%lx WMASK1=0x%lx TBASE1=0x%lx\n",
+	       __func__, *(vulp)T2_WBASE1, *(vulp)T2_WMASK1, *(vulp)T2_TBASE1);
+#endif
+}
+
+static void __init
+t2_sg_map_window2(struct pci_controller *hose,
+		  unsigned long base,
+		  unsigned long length)
+{
+	unsigned long temp;
+
+	/* Note we can only do 1 SG window, as the other is for direct, so
+	   do an ISA SG area, especially for the floppy. */
+	hose->sg_isa = iommu_arena_new(hose, base, length, 0);
+	hose->sg_pci = NULL;
+