diff options
author | Jason Wright <jason@cvs.openbsd.org> | 2006-05-28 22:09:58 +0000 |
---|---|---|
committer | Jason Wright <jason@cvs.openbsd.org> | 2006-05-28 22:09:58 +0000 |
commit | c87f4e515f1b18476dbc9647da2b23ec01ca241b (patch) | |
tree | 9a89f70916b7b9f9e323fca9a8e8d36a4413208f /sys | |
parent | 726de3291890e1627458e3144ae99d4e6c54b52c (diff) |
- Implement schizo_intr_map (mainly to | in the agentid).
- get correct IGN for intr_establish
all of this is from kettenis and henric, I'm just cleaning it up and committing
the easy bits
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/sparc64/dev/schizo.c | 69 | ||||
-rw-r--r-- | sys/arch/sparc64/dev/schizoreg.h | 13 |
2 files changed, 70 insertions, 12 deletions
diff --git a/sys/arch/sparc64/dev/schizo.c b/sys/arch/sparc64/dev/schizo.c index 582fd538b22..f3452ee2d89 100644 --- a/sys/arch/sparc64/dev/schizo.c +++ b/sys/arch/sparc64/dev/schizo.c @@ -1,4 +1,4 @@ -/* $OpenBSD: schizo.c,v 1.19 2006/05/28 06:28:08 jason Exp $ */ +/* $OpenBSD: schizo.c,v 1.20 2006/05/28 22:09:57 jason Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -79,6 +79,7 @@ bus_space_tag_t _schizo_alloc_bus_tag(struct schizo_pbm *, const char *, bus_dma_tag_t schizo_alloc_dma_tag(struct schizo_pbm *); paddr_t schizo_bus_mmap(bus_space_tag_t, bus_addr_t, off_t, int, int); +int schizo_intr_map(struct pci_attach_args *, pci_intr_handle_t *); int _schizo_bus_map(bus_space_tag_t, bus_space_tag_t, bus_addr_t, bus_size_t, int, bus_space_handle_t *); void *_schizo_intr_establish(bus_space_tag_t, bus_space_tag_t, int, int, int, @@ -199,6 +200,7 @@ schizo_init(struct schizo_softc *sc, int busa) pba.pba_dmat = pbm->sp_dmat; pba.pba_memt = pbm->sp_memt; pba.pba_iot = pbm->sp_iot; + pba.pba_pc->intr_map = schizo_intr_map; free(busranges, M_DEVBUF); @@ -259,6 +261,58 @@ schizo_print(void *aux, const char *p) return (QUIET); } +/* + * Bus-specific interrupt mapping + */ +int +schizo_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp) +{ + struct schizo_pbm *sp = pa->pa_pc->cookie; + struct schizo_softc *sc = sp->sp_sc; + u_int dev; + u_int ino; + u_int64_t agentid; + + ino = *ihp; + + agentid = bus_space_read_8(sc->sc_bust, sc->sc_ctrlh, + SCZ_CONTROL_STATUS); + printf("AGENT(%llx)", agentid); + agentid = ((agentid >> 20) & 31) << 6; + printf("agent(%llx)", agentid); + + if (ino & ~INTMAP_PCIINT) { + *ihp |= agentid; + return (0); + } + + /* + * This deserves some documentation. Should anyone + * have anything official looking, please speak up. + */ + dev = pa->pa_device - 1; + + if (ino == 0 || ino > 4) { + u_int32_t intreg; + + intreg = pci_conf_read(pa->pa_pc, pa->pa_tag, + PCI_INTERRUPT_REG); + + ino = PCI_INTERRUPT_PIN(intreg) - 1; + } else + ino -= 1; + + ino &= INTMAP_PCIINT; + ino |= agentid; + ino |= (dev << 2) & INTMAP_PCISLOT; + + printf("******** mapping interrupt %x -> %x\n", *ihp, ino); + + *ihp = ino; + + return (0); +} + bus_space_tag_t schizo_alloc_mem_tag(struct schizo_pbm *sp) { @@ -355,9 +409,9 @@ schizo_dmamap_create(bus_dma_tag_t t, bus_dma_tag_t t0, bus_size_t size, int nsegments, bus_size_t maxsegsz, bus_size_t boundary, int flags, bus_dmamap_t *dmamp) { - struct schizo_pbm *sp = t->_cookie; + struct schizo_pbm *sp = t->_cookie; - return (iommu_dvmamap_create(t, t0, &sp->sp_sb, size, nsegments, + return (iommu_dvmamap_create(t, t0, &sp->sp_sb, size, nsegments, maxsegsz, boundary, flags, dmamp)); } @@ -380,12 +434,12 @@ _schizo_bus_map(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t offset, if (t->parent == 0 || t->parent->sparc_bus_map == 0) { printf("\n_psycho_bus_map: invalid parent"); return (EINVAL); - } + } if (flags & BUS_SPACE_MAP_PROMADDRESS) { return ((*t->parent->sparc_bus_map) (t, t0, offset, size, flags, hp)); - } + } for (i = 0; i < pbm->sp_nrange; i++) { bus_addr_t paddr; @@ -415,10 +469,10 @@ _schizo_bus_mmap(bus_space_tag_t t, bus_space_tag_t t0, bus_addr_t paddr, DPRINTF(SDB_BUSMAP, ("_schizo_bus_mmap: prot %d flags %d pa %qx\n", prot, flags, (unsigned long long)paddr)); - if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) { + if (t->parent == 0 || t->parent->sparc_bus_mmap == 0) { printf("\n_schizo_bus_mmap: invalid parent"); return (-1); - } + } for (i = 0; i < pbm->sp_nrange; i++) { bus_addr_t paddr; @@ -461,6 +515,7 @@ _schizo_intr_establish(bus_space_tag_t t, bus_space_tag_t t0, int ihandle, pbmreg = bus_space_vaddr(pbm->sp_regt, pbm->sp_regh); intrmapptr = &pbmreg->imap[ino]; intrclrptr = &pbmreg->iclr[ino]; + ino |= (*intrmapptr) & INTMAP_IGN; } ih = bus_intr_allocate(t0, handler, arg, ino, level, intrmapptr, diff --git a/sys/arch/sparc64/dev/schizoreg.h b/sys/arch/sparc64/dev/schizoreg.h index bbff473b2b0..2d78855146f 100644 --- a/sys/arch/sparc64/dev/schizoreg.h +++ b/sys/arch/sparc64/dev/schizoreg.h @@ -1,4 +1,4 @@ -/* $OpenBSD: schizoreg.h,v 1.8 2005/05/19 18:28:59 mickey Exp $ */ +/* $OpenBSD: schizoreg.h,v 1.9 2006/05/28 22:09:57 jason Exp $ */ /* * Copyright (c) 2002 Jason L. Wright (jason@thought.net) @@ -26,9 +26,9 @@ * POSSIBILITY OF SUCH DAMAGE. */ struct schizo_pbm_regs { - volatile u_int64_t _unused1[64]; - struct iommureg iommu; - volatile u_int64_t iommu_ctxflush; + volatile u_int64_t _unused1[64]; /* 0x0000 - 0x01ff */ + struct iommureg iommu; /* 0x0200 - 0x0217 */ + volatile u_int64_t iommu_ctxflush; /* 0x0218 - 0x021f */ volatile u_int64_t _unused2[444]; volatile u_int64_t imap[64]; volatile u_int64_t _unused3[64]; @@ -62,7 +62,9 @@ struct schizo_regs { volatile u_int64_t pcib_io_mask; volatile u_int64_t _unused1[8176]; - volatile u_int64_t _unused2[3]; + volatile u_int64_t control_status; + volatile u_int64_t error_control; + volatile u_int64_t interrupt_control; volatile u_int64_t safari_errlog; volatile u_int64_t eccctrl; volatile u_int64_t _unused3[1]; @@ -84,6 +86,7 @@ struct schizo_regs { #define SCZ_PCIB_MEM_MASK 0x00068 #define SCZ_PCIB_IO_MATCH 0x00070 #define SCZ_PCIB_IO_MASK 0x00078 +#define SCZ_CONTROL_STATUS 0x10000 #define SCZ_SAFARI_ERRLOG 0x10018 #define SCZ_ECCCTRL 0x10020 #define SCZ_UE_AFSR 0x10030 |