Ver código fonte

efHeterogeneousSynchronization memoryOperation.c 姚强 commit at 2020-10-27

姚强 4 anos atrás
pai
commit
37bb583311

+ 121 - 0
efHeterogeneousSynchronization/dataSharedMemory/memoryOperation.c

@@ -87,3 +87,124 @@ conf_read(unsigned long addr, unsigned char type1,
 	  struct pci_controller *hose)
 {
 	unsigned long flags;
+	unsigned long mid = MCPCIA_HOSE2MID(hose->index);
+	unsigned int stat0, value, cpu;
+
+	cpu = smp_processor_id();
+
+	local_irq_save(flags);
+
+	DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n",
+		 addr, type1, mid));
+
+	/* Reset status register to avoid losing errors.  */
+	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
+	*(vuip)MCPCIA_CAP_ERR(mid) = stat0;
+	mb();
+	*(vuip)MCPCIA_CAP_ERR(mid);
+	DBG_CFG(("conf_read: MCPCIA_CAP_ERR(%d) was 0x%x\n", mid, stat0));
+
+	mb();
+	draina();
+	mcheck_expected(cpu) = 1;
+	mcheck_taken(cpu) = 0;
+	mcheck_extra(cpu) = mid;
+	mb();
+
+	/* Access configuration space.  */
+	value = *((vuip)addr);
+	mb();
+	mb();  /* magic */
+
+	if (mcheck_taken(cpu)) {
+		mcheck_taken(cpu) = 0;
+		value = 0xffffffffU;
+		mb();
+	}
+	mcheck_expected(cpu) = 0;
+	mb();
+
+	DBG_CFG(("conf_read(): finished\n"));
+
+	local_irq_restore(flags);
+	return value;
+}
+
+static void
+conf_write(unsigned long addr, unsigned int value, unsigned char type1,
+	   struct pci_controller *hose)
+{
+	unsigned long flags;
+	unsigned long mid = MCPCIA_HOSE2MID(hose->index);
+	unsigned int stat0, cpu;
+
+	cpu = smp_processor_id();
+
+	local_irq_save(flags);	/* avoid getting hit by machine check */
+
+	/* Reset status register to avoid losing errors.  */
+	stat0 = *(vuip)MCPCIA_CAP_ERR(mid);
+	*(vuip)MCPCIA_CAP_ERR(mid) = stat0; mb();
+	*(vuip)MCPCIA_CAP_ERR(mid);
+	DBG_CFG(("conf_write: MCPCIA CAP_ERR(%d) was 0x%x\n", mid, stat0));
+
+	draina();
+	mcheck_expected(cpu) = 1;
+	mcheck_extra(cpu) = mid;
+	mb();
+
+	/* Access configuration space.  */
+	*((vuip)addr) = value;
+	mb();
+	mb();  /* magic */
+	*(vuip)MCPCIA_CAP_ERR(mid); /* read to force the write */
+	mcheck_expected(cpu) = 0;
+	mb();
+
+	DBG_CFG(("conf_write(): finished\n"));
+	local_irq_restore(flags);
+}
+
+static int
+mk_conf_addr(struct pci_bus *pbus, unsigned int devfn, int where,
+	     struct pci_controller *hose, unsigned long *pci_addr,
+	     unsigned char *type1)
+{
+	u8 bus = pbus->number;
+	unsigned long addr;
+
+	DBG_CFG(("mk_conf_addr(bus=%d,devfn=0x%x,hose=%d,where=0x%x,"
+		 " pci_addr=0x%p, type1=0x%p)\n",
+		 bus, devfn, hose->index, where, pci_addr, type1));
+
+	/* Type 1 configuration cycle for *ALL* busses.  */
+	*type1 = 1;
+
+	if (!pbus->parent) /* No parent means peer PCI bus. */
+		bus = 0;
+	addr = (bus << 16) | (devfn << 8) | (where);
+	addr <<= 5; /* swizzle for SPARSE */
+	addr |= hose->config_space_base;
+
+	*pci_addr = addr;
+	DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr));
+	return 0;
+}
+
+static int
+mcpcia_read_config(struct pci_bus *bus, unsigned int devfn, int where,
+		   int size, u32 *value)
+{
+	struct pci_controller *hose = bus->sysdata;
+	unsigned long addr, w;
+	unsigned char type1;
+
+	if (mk_conf_addr(bus, devfn, where, hose, &addr, &type1))
+		return PCIBIOS_DEVICE_NOT_FOUND;
+
+	addr |= (size - 1) * 8;
+	w = conf_read(addr, type1, hose);
+	switch (size) {
+	case 1:
+		*value = __kernel_extbl(w, where & 3);
+		break;