static __inline int virt_addr_is_valid(void *addr, int len, int write, int is_kernel) { int to_nextpage; char tmp = 0; while (len > 0) { if (write) { if (is_kernel) *(char *)addr = 0; else if (subyte(addr, 0) != 0) { return (0); } } else { if (is_kernel) badaddr_read(addr, 1, &tmp); else if (fubyte(addr) == -1) { return (0); } } to_nextpage = ((vm_offset_t)addr & ~PAGE_MASK) + PAGE_SIZE - (vm_offset_t)addr; if (to_nextpage >= len) break; len -= to_nextpage; addr = (void *)((vm_offset_t)addr + to_nextpage); } return (1); }
pcireg_t i80321_pci_conf_read(void *v, pcitag_t tag, int offset) { struct i80321_softc *sc = v; struct pciconf_state ps; vaddr_t va; uint32_t isr; pcireg_t rv; u_int s; if (i80321_pci_conf_setup(sc, tag, offset, &ps)) return ((pcireg_t) -1); PCI_CONF_LOCK(s); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR, ps.ps_addr_val); va = (vaddr_t) bus_space_vaddr(sc->sc_st, sc->sc_atu_sh); if (badaddr_read((void *) (va + ATU_OCCDR), sizeof(rv), &rv)) { isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR, isr & (ATUISR_P_SERR_DET|ATUISR_PMA|ATUISR_PTAM| ATUISR_PTAT|ATUISR_PMPE)); #if 0 printf("conf_read: %d/%d/%d bad address\n", ps.ps_b, ps.ps_d, ps.ps_f); #endif rv = (pcireg_t) -1; } PCI_CONF_UNLOCK(s); return (rv); }
static u_int32_t i80321_pci_read_config(device_t dev, int bus, int slot, int func, int reg, int bytes) { struct i80321_pci_softc *sc = device_get_softc(dev); uint32_t isr; uint32_t addr; u_int32_t ret = 0; vm_offset_t va; int err = 0; if (i80321_pci_conf_setup(sc, bus, slot, func, reg & ~3, &addr)) return (-1); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_OCCAR, addr); va = sc->sc_atu_sh; switch (bytes) { case 1: err = badaddr_read((void*)(va + ATU_OCCDR + (reg & 3)), 1, &ret); break; case 2: err = badaddr_read((void*)(va + ATU_OCCDR + (reg & 3)), 2, &ret); break; case 4: err = badaddr_read((void *)(va + ATU_OCCDR), 4, &ret); break; default: printf("i80321_read_config: invalid size %d\n", bytes); ret = -1; } if (err) { isr = bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ATU_ATUISR, isr & (ATUISR_P_SERR_DET|ATUISR_PMA|ATUISR_PTAM| ATUISR_PTAT|ATUISR_PMPE)); return (-1); } return (ret); }
pcireg_t becc_pci_conf_read(void *v, pcitag_t tag, int offset) { struct becc_softc *sc = v; struct pciconf_state ps; vaddr_t va; pcireg_t rv; u_int s; if (becc_pci_conf_setup(sc, tag, offset, &ps)) return ((pcireg_t) -1); /* * Skip device 0 (the BECC itself). We don't want it * to appear as part of the PCI device space. */ if (ps.ps_b == 0 && ps.ps_d == 0) return ((pcireg_t) -1); PCI_CONF_LOCK(s); va = sc->sc_pci_cfg_base + ps.ps_offset; BECC_CSR_WRITE(BECC_POCR, ps.ps_type); if (badaddr_read((void *) va, sizeof(rv), &rv)) { /* XXX Check master/target abort? */ #if 0 printf("conf_read: %d/%d/%d bad address\n", ps.ps_b, ps.ps_d, ps.ps_f); #endif rv = (pcireg_t) -1; } if (becc_pci_conf_cleanup(sc)) rv = (pcireg_t) -1; PCI_CONF_UNLOCK(s); return (rv); }
pcireg_t i80312_pci_conf_read(void *v, pcitag_t tag, int offset) { struct i80312_softc *sc = v; struct pciconf_state ps; vaddr_t va; pcireg_t rv; u_int s; if (i80312_pci_conf_setup(sc, tag, offset, &ps)) return ((pcireg_t) -1); PCI_CONF_LOCK(s); bus_space_write_4(sc->sc_st, sc->sc_atu_sh, ps.ps_addr_reg, ps.ps_addr_val); va = (vaddr_t) bus_space_vaddr(sc->sc_st, sc->sc_atu_sh); if (badaddr_read((void *) (va + ps.ps_data_reg), sizeof(rv), &rv)) { /* * Clear the Master Abort by reading the PCI * Status Register. */ (void) bus_space_read_4(sc->sc_st, sc->sc_atu_sh, ps.ps_csr_reg); #if 0 printf("conf_read: %d/%d/%d bad address\n", ps.ps_b, ps.ps_d, ps.ps_f); #endif rv = (pcireg_t) -1; } PCI_CONF_UNLOCK(s); return (rv); }
int badaddr(void *addr, size_t size) { return(badaddr_read(addr, size, NULL)); }