#include <dev/pci/pcivar.h>
#include <dev/pci/ppbreg.h>
+#include <octeon/dev/obiovar.h>
#include <octeon/dev/octeon_pcibus.h>
#include <octeon/dev/octeon_pcibusvar.h>
-#include <octeon/dev/octeon_pcibus_irq.h>
-
-#include <machine/octeon_pcmap_regs.h>
#include <uvm/uvm_extern.h>
-#if 0
+#if 1
#define OCTEON_PCIBUS_DEBUG
#endif
#define DEBUG_PRINT(p)
#endif
+#define REG_READ32(addr) (*(volatile uint32_t *)(addr))
+#define REG_WRITE32(addr, data) (*(volatile uint32_t *)(addr) = (uint32_t)(data))
+
int octeon_pcibus_match(struct device *, void *, void *);
void octeon_pcibus_attach(struct device *, struct device *, void *);
-int octeon_pcibus_intr_map(int dev, int fn, int pin);
-void octeon_pcibus_pci_attach_hook(pci_chipset_tag_t pc);
+int octeon_pcibus_intr_map(int dev, int fn, int pin);
+void octeon_pcibus_pci_attach_hook(pci_chipset_tag_t pc);
const struct cfattach pcibus_ca = {
- sizeof(struct octeon_pcibus_softc), octeon_pcibus_match, octeon_pcibus_attach
+ sizeof(struct octeon_pcibus_softc),
+ octeon_pcibus_match, octeon_pcibus_attach
};
struct cfdriver pcibus_cd = {
NULL, "pcibus", DV_DULL
};
-struct octeon_pcibus_config octeon_pcibus_config = {
- .oc_adbase = 16,
- .oc_gpioIE = 0xffffffff,
- .oc_intEdge = 0,
- .oc_intSteer = 0,
- .oc_intPol = 0,
-
- .oc_attach_hook = octeon_pcibus_pci_attach_hook,
- .oc_intr_map = octeon_pcibus_intr_map
-};
-
-#define wbflush() __asm__ __volatile__ ("sync" ::: "memory")
-
-bus_addr_t octeon_pcibus_pa_to_device(paddr_t);
-paddr_t octeon_pcibus_device_to_pa(bus_addr_t);
-
-void octeon_pcibus_intr_makemasks(void);
-uint32_t octeon_pcibus_intr_2e(uint32_t, struct trap_frame *);
-uint32_t octeon_pcibus_intr_2f(uint32_t, struct trap_frame *);
-void octeon_pcibus_intr_dispatch(uint64_t, int, struct trap_frame *);
-
-void octeon_pcibus_attach_hook(struct device *, struct device *,
- struct pcibus_attach_args *);
-int octeon_pcibus_bus_maxdevs(void *, int);
-pcitag_t octeon_pcibus_make_tag(void *, int, int, int);
-void octeon_pcibus_decompose_tag(void *, pcitag_t, int *, int *, int *);
-pcireg_t octeon_pcibus_conf_read(void *, pcitag_t, int);
-pcireg_t octeon_pcibus_conf_read_internal(const struct octeon_pcibus_config *, pcitag_t, int);
-void octeon_pcibus_conf_write(void *, pcitag_t, int, pcireg_t);
-int octeon_pcibus_pci_intr_map(struct pci_attach_args *, pci_intr_handle_t *);
-const char *
- octeon_pcibus_pci_intr_string(void *, pci_intr_handle_t);
-void *octeon_pcibus_pci_intr_establish(void *, pci_intr_handle_t, int,
- int (*)(void *), void *, char *);
-void octeon_pcibus_pci_intr_disestablish(void *, void *);
-
-int octeon_pcibus_conf_addr(const struct octeon_pcibus_config *, pcitag_t, int,
- uint64_t *, uint64_t *);
+bus_addr_t octeon_pcibus_pa_to_device(paddr_t);
+paddr_t octeon_pcibus_device_to_pa(bus_addr_t);
+void octeon_pcibus_attach_hook(struct device *, struct device *,
+ struct pcibus_attach_args *);
+int octeon_pcibus_bus_maxdevs(void *, int);
+pcitag_t octeon_pcibus_make_tag(void *, int, int, int);
+void octeon_pcibus_decompose_tag(void *, pcitag_t, int *, int *, int *);
+pcireg_t octeon_pcibus_pci_conf_read(void *, pcitag_t, int);
+pcireg_t octeon_pcibus_pci_conf_read_internal(pcitag_t, int);
+void octeon_pcibus_pci_conf_write(void *, pcitag_t, int, pcireg_t);
+int octeon_pcibus_pci_intr_map(struct pci_attach_args *,
+ pci_intr_handle_t *);
+const char *octeon_pcibus_pci_intr_string(void *, pci_intr_handle_t);
+void *octeon_pcibus_pci_intr_establish(void *, pci_intr_handle_t, int,
+ int (*)(void *), void *, char *);
+void octeon_pcibus_pci_intr_disestablish(void *, void *);
-void octeon_pcibus_splx(int);
-
-/*
- * Octeon_Pcibus interrupt handling declarations.
- * See <loongson/dev/octeon_pcibus_irq.h> for details.
- */
-struct intrhand *octeon_pcibus_intrhand[OCTEON_PCIBUS_NINTS];
-uint64_t octeon_pcibus_intem;
-uint64_t octeon_pcibus_imask[NIPLS];
struct machine_bus_dma_tag octeon_pcibus_bus_dma_tag = {
- ._dmamap_create = _dmamap_create,
- ._dmamap_destroy = _dmamap_destroy,
- ._dmamap_load = _dmamap_load,
- ._dmamap_load_mbuf = _dmamap_load_mbuf,
- ._dmamap_load_uio = _dmamap_load_uio,
- ._dmamap_load_raw = _dmamap_load_raw,
- ._dmamap_load_buffer = _dmamap_load_buffer,
- ._dmamap_unload = _dmamap_unload,
- ._dmamap_sync = _dmamap_sync,
-
- ._dmamem_alloc = _dmamem_alloc,
- ._dmamem_free = _dmamem_free,
- ._dmamem_map = _dmamem_map,
- ._dmamem_unmap = _dmamem_unmap,
- ._dmamem_mmap = _dmamem_mmap,
-
- ._pa_to_device = octeon_pcibus_pa_to_device,
- ._device_to_pa = octeon_pcibus_device_to_pa
+ ._cookie = NULL,
+ ._dmamap_create = _dmamap_create,
+ ._dmamap_destroy = _dmamap_destroy,
+ ._dmamap_load = _dmamap_load,
+ ._dmamap_load_mbuf = _dmamap_load_mbuf,
+ ._dmamap_load_uio = _dmamap_load_uio,
+ ._dmamap_load_raw = _dmamap_load_raw,
+ ._dmamap_load_buffer = _dmamap_load_buffer,
+ ._dmamap_unload = _dmamap_unload,
+ ._dmamap_sync = _dmamap_sync,
+ ._dmamem_alloc = _dmamem_alloc,
+ ._dmamem_free = _dmamem_free,
+ ._dmamem_map = _dmamem_map,
+ ._dmamem_unmap = _dmamem_unmap,
+ ._dmamem_mmap = _dmamem_mmap,
+ ._pa_to_device = octeon_pcibus_pa_to_device,
+ ._device_to_pa = octeon_pcibus_device_to_pa
};
-int octeon_pcibus_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
- bus_space_handle_t *);
-int octeon_pcibus_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
- bus_space_handle_t *);
-
-struct mips_bus_space octeon_pcibus_pci_io_space_tag = {
- .bus_base = PHYS_TO_XKPHYS(OCTEON_PCIBUS_PCIIO_BASE, CCA_NC),
- ._space_read_1 = generic_space_read_1,
- ._space_write_1 = generic_space_write_1,
- ._space_read_2 = generic_space_read_2,
- ._space_write_2 = generic_space_write_2,
- ._space_read_4 = generic_space_read_4,
- ._space_write_4 = generic_space_write_4,
- ._space_read_8 = generic_space_read_8,
- ._space_write_8 = generic_space_write_8,
- ._space_read_raw_2 = generic_space_read_raw_2,
- ._space_write_raw_2 = generic_space_write_raw_2,
- ._space_read_raw_4 = generic_space_read_raw_4,
- ._space_write_raw_4 = generic_space_write_raw_4,
- ._space_read_raw_8 = generic_space_read_raw_8,
- ._space_write_raw_8 = generic_space_write_raw_8,
- ._space_map = octeon_pcibus_io_map,
- ._space_unmap = generic_space_unmap,
- ._space_subregion = generic_space_region,
- ._space_vaddr = generic_space_vaddr
+int octeon_pcibus_io_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
+ bus_space_handle_t *);
+int octeon_pcibus_mem_map(bus_space_tag_t, bus_addr_t, bus_size_t, int,
+ bus_space_handle_t *);
+
+#define _OCTEON_PCIBUS_PCIIO_BASE 0x00001000
+#define _OCTEON_PCIBUS_PCIIO_SIZE 0x08000000
+#define _OCTEON_PCIBUS_PCIMEM_BASE 0x80000000
+#define _OCTEON_PCIBUS_PCIMEM_SIZE 0x40000000
+
+bus_space_t octeon_pcibus_pci_io_space_tag = {
+ .bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIIO_BASE, CCA_NC),
+ .bus_private = NULL,
+ ._space_read_1 = generic_space_read_1,
+ ._space_write_1 = generic_space_write_1,
+ ._space_read_2 = generic_space_read_2,
+ ._space_write_2 = generic_space_write_2,
+ ._space_read_4 = generic_space_read_4,
+ ._space_write_4 = generic_space_write_4,
+ ._space_read_8 = generic_space_read_8,
+ ._space_write_8 = generic_space_write_8,
+ ._space_read_raw_2 = generic_space_read_raw_2,
+ ._space_write_raw_2 = generic_space_write_raw_2,
+ ._space_read_raw_4 = generic_space_read_raw_4,
+ ._space_write_raw_4 = generic_space_write_raw_4,
+ ._space_read_raw_8 = generic_space_read_raw_8,
+ ._space_write_raw_8 = generic_space_write_raw_8,
+ ._space_map = octeon_pcibus_io_map,
+ ._space_unmap = generic_space_unmap,
+ ._space_subregion = generic_space_region,
+ ._space_vaddr = generic_space_vaddr
};
-struct mips_bus_space octeon_pcibus_pci_mem_space_tag = {
- .bus_base = PHYS_TO_XKPHYS(0, CCA_NC),
- ._space_read_1 = generic_space_read_1,
- ._space_write_1 = generic_space_write_1,
- ._space_read_2 = generic_space_read_2,
- ._space_write_2 = generic_space_write_2,
- ._space_read_4 = generic_space_read_4,
- ._space_write_4 = generic_space_write_4,
- ._space_read_8 = generic_space_read_8,
- ._space_write_8 = generic_space_write_8,
- ._space_read_raw_2 = generic_space_read_raw_2,
- ._space_write_raw_2 = generic_space_write_raw_2,
- ._space_read_raw_4 = generic_space_read_raw_4,
- ._space_write_raw_4 = generic_space_write_raw_4,
- ._space_read_raw_8 = generic_space_read_raw_8,
- ._space_write_raw_8 = generic_space_write_raw_8,
- ._space_map = octeon_pcibus_mem_map,
- ._space_unmap = generic_space_unmap,
- ._space_subregion = generic_space_region,
- ._space_vaddr = generic_space_vaddr
+bus_space_t octeon_pcibus_pci_mem_space_tag = {
+ .bus_base = PHYS_TO_XKPHYS(_OCTEON_PCIBUS_PCIMEM_BASE, CCA_NC),
+ .bus_private = NULL,
+ ._space_read_1 = generic_space_read_1,
+ ._space_write_1 = generic_space_write_1,
+ ._space_read_2 = generic_space_read_2,
+ ._space_write_2 = generic_space_write_2,
+ ._space_read_4 = generic_space_read_4,
+ ._space_write_4 = generic_space_write_4,
+ ._space_read_8 = generic_space_read_8,
+ ._space_write_8 = generic_space_write_8,
+ ._space_read_raw_2 = generic_space_read_raw_2,
+ ._space_write_raw_2 = generic_space_write_raw_2,
+ ._space_read_raw_4 = generic_space_read_raw_4,
+ ._space_write_raw_4 = generic_space_write_raw_4,
+ ._space_read_raw_8 = generic_space_read_raw_8,
+ ._space_write_raw_8 = generic_space_write_raw_8,
+ ._space_map = octeon_pcibus_mem_map,
+ ._space_unmap = generic_space_unmap,
+ ._space_subregion = generic_space_region,
+ ._space_vaddr = generic_space_vaddr
};
int
octeon_pcibus_match(struct device *parent, void *vcf, void *aux)
{
- struct mainbus_attach_args *maa = aux;
- DEBUG_PRINT(("%s:%d:%s %s\n",__FUNCTION__,__LINE__,maa->maa_name, pcibus_cd.cd_name));
+ struct obio_attach_args *oba = aux;
- if (strcmp(maa->maa_name, pcibus_cd.cd_name) == 0)
- return (1);
+ if (strcmp(oba->oba_name, pcibus_cd.cd_name) == 0)
+ return 1;
- return (0);
+ return 0;
}
void
octeon_pcibus_attach(struct device *parent, struct device *self, void *aux)
{
- struct octeon_pcibus_softc *sc = (struct octeon_pcibus_softc *)self;
+ struct octeon_pcibus_softc *sc;
+ struct obio_attach_args *oba;
struct pcibus_attach_args pba;
- pci_chipset_tag_t pc = &sc->sc_pc;
- const struct octeon_pcibus_config *oc;
+ sc = (struct octeon_pcibus_softc *)self;
+ oba = aux;
+ sc->sc_oba = oba;
- oc = sys_platform->octeon_pcibus_config;
- sc->sc_octeon_pcibus = oc;
SLIST_INIT(&sc->sc_hook);
/*
- * Setup proper abitration.
- */
-
- /*
- * Setup interrupt handling.
- */
- DEBUG_PRINT(("%s:%d:\n",__FUNCTION__,__LINE__));
-
-#if 0
- REGVAL(OCTEON_PCIBUS_GPIOIE) = oc->oc_gpioIE;
- REGVAL(OCTEON_PCIBUS_INTEDGE) = oc->oc_intEdge;
- if (sc->sc_compatible)
- REGVAL(OCTEON_PCIBUS_INTSTEER) = oc->oc_intSteer;
- REGVAL(OCTEON_PCIBUS_INTPOL) = oc->oc_intPol;
-
- REGVAL(OCTEON_PCIBUS_INTENCLR) = 0xffffffff;
- (void)REGVAL(OCTEON_PCIBUS_INTENCLR);
-
- if (sc->sc_compatible) {
- octeon_pcibus_intem |= OCTEON_PCIBUS_INTRMASK_MASTERERR;
- }
-
- if (loongson_ver == 0x2f)
- set_intr(INTPRI_OCTEON_PCIBUS, CR_INT_4, octeon_pcibus_intr_2f);
- else
- set_intr(INTPRI_OCTEON_PCIBUS, CR_INT_0, octeon_pcibus_intr_2e);
- register_splx_handler(octeon_pcibus_splx);
-
-#endif
- /*
* Attach PCI bus.
*/
+ sc->sc_pc.pc_attach_hook = octeon_pcibus_attach_hook;
+ sc->sc_pc.pc_bus_maxdevs = octeon_pcibus_bus_maxdevs;
+ sc->sc_pc.pc_make_tag = octeon_pcibus_make_tag;
+ sc->sc_pc.pc_decompose_tag = octeon_pcibus_decompose_tag;
- pc->pc_conf_v = sc;
- pc->pc_attach_hook = octeon_pcibus_attach_hook;
- pc->pc_bus_maxdevs = octeon_pcibus_bus_maxdevs;
- pc->pc_make_tag = octeon_pcibus_make_tag;
- pc->pc_decompose_tag = octeon_pcibus_decompose_tag;
- pc->pc_conf_read = octeon_pcibus_conf_read;
- pc->pc_conf_write = octeon_pcibus_conf_write;
+ sc->sc_pc.pc_conf_v = sc;
+ sc->sc_pc.pc_conf_read = octeon_pcibus_pci_conf_read;
+ sc->sc_pc.pc_conf_write = octeon_pcibus_pci_conf_write;
- pc->pc_intr_v = sc;
- pc->pc_intr_map = octeon_pcibus_pci_intr_map;
- pc->pc_intr_string = octeon_pcibus_pci_intr_string;
- pc->pc_intr_establish = octeon_pcibus_pci_intr_establish;
- pc->pc_intr_disestablish = octeon_pcibus_pci_intr_disestablish;
+ sc->sc_pc.pc_intr_v = sc;
+ sc->sc_pc.pc_intr_map = octeon_pcibus_pci_intr_map;
+ sc->sc_pc.pc_intr_string = octeon_pcibus_pci_intr_string;
+ sc->sc_pc.pc_intr_establish = octeon_pcibus_pci_intr_establish;
+ sc->sc_pc.pc_intr_disestablish = octeon_pcibus_pci_intr_disestablish;
bzero(&pba, sizeof pba);
pba.pba_busname = "pci";
pba.pba_iot = &octeon_pcibus_pci_io_space_tag;
pba.pba_memt = &octeon_pcibus_pci_mem_space_tag;
pba.pba_dmat = &octeon_pcibus_bus_dma_tag;
- pba.pba_pc = pc;
+ pba.pba_pc = &sc->sc_pc;
pba.pba_domain = pci_ndomains++;
pba.pba_bus = 0;
-#ifdef notyet
- pba.pba_ioex = octeon_pcibus_get_resource_extent(pc, 1);
- pba.pba_memex = octeon_pcibus_get_resource_extent(pc, 0);
-#endif
+ pba.pba_ioex = octeon_pcibus_get_resource_extent(&sc->sc_pc, 1);
+ pba.pba_memex = octeon_pcibus_get_resource_extent(&sc->sc_pc, 0);
config_found(&sc->sc_dev, &pba, octeon_pcibus_print);
}
bus_addr_t
octeon_pcibus_pa_to_device(paddr_t pa)
{
+ printf("%s:%d: pa=%p\n", __func__, __LINE__, pa);
+
return pa & 0x1ffffffffffffUL;
}
paddr_t
octeon_pcibus_device_to_pa(bus_addr_t addr)
{
+ printf("%s:%d: addr=%p\n", __func__, __LINE__, addr);
+
return PHYS_TO_XKPHYS(addr, CCA_NC);
}
}
/*
- * Octeon_Pcibus interrupt handling
- */
-
-void *
-octeon_pcibus_intr_establish(int irq, int type, int level, int (*handler)(void *),
- void *arg, const char *name)
-{
- struct intrhand **p, *q, *ih;
- int s;
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-
-#ifdef DIAGNOSTIC
- if (irq >= OCTEON_PCIBUS_NINTS || irq == OCTEON_PCIBUS_ISA_IRQ(2) || irq < 0)
- panic("octeon_pcibus_intr_establish: illegal irq %d", irq);
-#endif
-
- ih = malloc(sizeof *ih, M_DEVBUF, M_NOWAIT);
- if (ih == NULL)
- return NULL;
-
- ih->ih_next = NULL;
- ih->ih_fun = handler;
- ih->ih_arg = arg;
- ih->ih_level = level;
- ih->ih_irq = irq;
- evcount_attach(&ih->ih_count, name, (void *)&ih->ih_irq, &evcount_intr);
-
- s = splhigh();
-
- /*
- * Figure out where to put the handler.
- * This is O(N^2), but we want to preserve the order, and N is
- * generally small.
- */
- for (p = &octeon_pcibus_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
- ;
- *p = ih;
-
- octeon_pcibus_intem |= 1UL << irq;
- octeon_pcibus_intr_makemasks();
-
- splx(s); /* causes hw mask update */
-
- return (ih);
-}
-
-void
-octeon_pcibus_intr_disestablish(void *vih)
-{
- struct intrhand *ih = (struct intrhand *)vih;
- struct intrhand **p, *q;
- int irq = ih->ih_irq;
- int s;
-
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-#ifdef DIAGNOSTIC
- if (irq >= OCTEON_PCIBUS_NINTS || irq == OCTEON_PCIBUS_ISA_IRQ(2) || irq < 0)
- panic("octeon_pcibus_intr_disestablish: illegal irq %d", irq);
-#endif
-
- s = splhigh();
-
- evcount_detach(&ih->ih_count);
-
- for (p = &octeon_pcibus_intrhand[irq]; (q = *p) != NULL; p = &q->ih_next)
- if (q == ih)
- break;
-#ifdef DIAGNOSTIC
- if (q == NULL)
- panic("octeon_pcibus_intr_disestablish: never registered");
-#endif
- *p = ih->ih_next;
-
- if (ih->ih_next == NULL && p == &octeon_pcibus_intrhand[irq]) {
- octeon_pcibus_intem &= ~(1UL << irq);
- octeon_pcibus_intr_makemasks();
- /*
- * No need to clear a bit in INTEN through INTCLR,
- * splhigh() took care of disabling everything and
- * splx() will not reenable this source after the
- * mask update.
- */
- }
-
- splx(s);
-
- free(ih, M_DEVBUF);
-}
-
-/*
- * Update interrupt masks. This is for designs without legacy PIC.
- */
-
-void
-octeon_pcibus_splx(int newipl)
-{
- struct cpu_info *ci = curcpu();
-
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- /* Update masks to new ipl. Order highly important! */
- __asm__ (".set noreorder\n");
- ci->ci_ipl = newipl;
- __asm__ ("sync\n\t.set reorder\n");
- octeon_pcibus_setintrmask(newipl);
- /* If we still have softints pending trigger processing. */
- if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT)
- setsoftintr0();
-}
-
-void
-octeon_pcibus_setintrmask(int level)
-{
- uint64_t active;
- uint32_t clear, set;
- uint32_t sr;
-
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- active = octeon_pcibus_intem & ~octeon_pcibus_imask[level];
- /* be sure to mask high bits, there may be other interrupt sources */
- clear = OCTEON_PCIBUS_DIRECT_MASK(octeon_pcibus_imask[level]);
- set = OCTEON_PCIBUS_DIRECT_MASK(active);
-
- sr = disableintr();
-
- DEBUG_PRINT(("%s:%d:\n",__FUNCTION__,__LINE__));
-#if 0
- if (clear != 0) {
- REGVAL(OCTEON_PCIBUS_INTENCLR) = clear;
- (void)REGVAL(OCTEON_PCIBUS_INTENCLR);
- }
- if (set != 0) {
- REGVAL(OCTEON_PCIBUS_INTENSET) = set;
- (void)REGVAL(OCTEON_PCIBUS_INTENSET);
- }
-#endif
- setsr(sr);
-}
-
-/*
- * Recompute interrupt masks.
- */
-void
-octeon_pcibus_intr_makemasks()
-{
- int irq, level;
- struct intrhand *q;
- uint intrlevel[OCTEON_PCIBUS_NINTS];
-
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- /* First, figure out which levels each IRQ uses. */
- for (irq = 0; irq < OCTEON_PCIBUS_NINTS; irq++) {
- uint levels = 0;
- for (q = octeon_pcibus_intrhand[irq]; q != NULL; q = q->ih_next)
- levels |= 1 << q->ih_level;
- intrlevel[irq] = levels;
- }
-
- /*
- * Then figure out which IRQs use each level.
- * Note that we make sure never to overwrite imask[IPL_HIGH], in
- * case an interrupt occurs during intr_disestablish() and causes
- * an unfortunate splx() while we are here recomputing the masks.
- */
- for (level = IPL_NONE; level < IPL_HIGH; level++) {
- uint64_t irqs = 0;
- for (irq = 0; irq < OCTEON_PCIBUS_NINTS; irq++)
- if (intrlevel[irq] & (1 << level))
- irqs |= 1UL << irq;
- octeon_pcibus_imask[level] = irqs;
- }
-
- /*
- * There are tty, network and disk drivers that use free() at interrupt
- * time, so vm > (tty | net | bio).
- *
- * Enforce a hierarchy that gives slow devices a better chance at not
- * dropping data.
- */
- octeon_pcibus_imask[IPL_NET] |= octeon_pcibus_imask[IPL_BIO];
- octeon_pcibus_imask[IPL_TTY] |= octeon_pcibus_imask[IPL_NET];
- octeon_pcibus_imask[IPL_VM] |= octeon_pcibus_imask[IPL_TTY];
- octeon_pcibus_imask[IPL_CLOCK] |= octeon_pcibus_imask[IPL_VM];
-
- /*
- * These are pseudo-levels.
- */
- octeon_pcibus_imask[IPL_NONE] = 0;
- octeon_pcibus_imask[IPL_HIGH] = -1UL;
-}
-
-/*
- * Process native interrupts
- */
-
-uint32_t
-octeon_pcibus_intr_2e(uint32_t hwpend, struct trap_frame *frame)
-{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-#if 0
- uint64_t imr, isr, mask;
-
- isr = REGVAL(OCTEON_PCIBUS_INTISR);
- /*
- * According to Linux code, Octeon_Pcibus64 - at least on Loongson
- * systems - triggers an interrupt during DMA, which is to be
- * ignored. Smells like a chip errata to me.
- */
- while (ISSET(isr, OCTEON_PCIBUS_INTRMASK_MASTERERR)) {
- delay(1);
- isr = REGVAL(OCTEON_PCIBUS_INTISR);
- }
-
- isr &= OCTEON_PCIBUS_INTRMASK_GPIN;
- imr = REGVAL(OCTEON_PCIBUS_INTEN);
- isr &= imr;
-
- DEBUG_PRINT(("pci interrupt: imr %04x isr %04x\n", imr, isr));
-
- if (isr == 0)
- return 0; /* not for us */
-
- /*
- * Mask all pending interrupts.
- */
- REGVAL(OCTEON_PCIBUS_INTENCLR) = isr;
- (void)REGVAL(OCTEON_PCIBUS_INTENCLR);
-
- /*
- * If interrupts are spl-masked, mask them and wait for splx()
- * to reenable them when necessary.
- */
- if ((mask = isr & octeon_pcibus_imask[frame->ipl]) != 0) {
- isr &= ~mask;
- imr &= ~mask;
- }
-
- /*
- * Now process allowed interrupts.
- */
- if (isr != 0) {
- octeon_pcibus_intr_dispatch(isr, 30, frame);
-
- /*
- * Reenable interrupts which have been serviced.
- */
- REGVAL(OCTEON_PCIBUS_INTENSET) = imr;
- (void)REGVAL(OCTEON_PCIBUS_INTENSET);
- }
-
-#endif
- return hwpend;
-}
-
-uint32_t
-octeon_pcibus_intr_2f(uint32_t hwpend, struct trap_frame *frame)
-{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-#if 0
- uint64_t imr, isr, mask;
-
- isr = REGVAL(OCTEON_PCIBUS_INTISR) & LOONGSON_INTRMASK_LVL4;
- imr = REGVAL(OCTEON_PCIBUS_INTEN);
- isr &= imr;
-
- DEBUG_PRINT(("pci interrupt: imr %04x isr %04x\n", imr, isr));
-
- if (isr == 0)
- return 0; /* not for us */
-
- /*
- * Mask all pending interrupts.
- */
-
- REGVAL(OCTEON_PCIBUS_INTENCLR) = isr;
- (void)REGVAL(OCTEON_PCIBUS_INTENCLR);
-
- /*
- * If interrupts are spl-masked, mask them and wait for splx()
- * to reenable them when necessary.
- */
- if ((mask = isr & octeon_pcibus_imask[frame->ipl]) != 0) {
- isr &= ~mask;
- imr &= ~mask;
- }
-
- /*
- * Now process allowed interrupts.
- */
- if (isr != 0) {
- octeon_pcibus_intr_dispatch(isr,
- LOONGSON_INTR_DRAM_PARERR /* skip non-pci interrupts */,
- frame);
-
- /*
- * Reenable interrupts which have been serviced.
- */
- REGVAL(OCTEON_PCIBUS_INTENSET) = imr;
- (void)REGVAL(OCTEON_PCIBUS_INTENSET);
- }
-#endif
- return hwpend;
-}
-
-void
-octeon_pcibus_intr_dispatch(uint64_t isr, int startbit, struct trap_frame *frame)
-{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-#if 0
- int lvl, bitno;
- uint64_t tmpisr, mask;
- struct intrhand *ih;
- int rc;
-
- /* Service higher level interrupts first */
- for (lvl = IPL_HIGH - 1; lvl != IPL_NONE; lvl--) {
- tmpisr = isr & (octeon_pcibus_imask[lvl] ^ octeon_pcibus_imask[lvl - 1]);
- if (tmpisr == 0)
- continue;
- for (bitno = startbit, mask = 1UL << bitno; mask != 0;
- bitno--, mask >>= 1) {
- if ((tmpisr & mask) == 0)
- continue;
-
- rc = 0;
- for (ih = octeon_pcibus_intrhand[bitno]; ih != NULL;
- ih = ih->ih_next) {
- splraise(ih->ih_level);
- if ((*ih->ih_fun)(ih->ih_arg) != 0) {
- rc = 1;
- ih->ih_count.ec_count++;
- }
- __asm__ (".set noreorder\n");
- curcpu()->ci_ipl = frame->ipl;
- __asm__ ("sync\n\t.set reorder\n");
- }
- if (rc == 0) {
- printf("spurious interrupt %d\n", bitno);
-
- DEBUG_PRINT(("ISR %08x IMR %08x ipl %d mask %08x\n",
- REGVAL(OCTEON_PCIBUS_INTISR), REGVAL(OCTEON_PCIBUS_INTEN),
- frame->ipl, octeon_pcibus_imask[frame->ipl]));
-#ifdef DDB
- Debugger();
-#endif
-
- }
-
- if ((isr ^= mask) == 0)
- return;
- if ((tmpisr ^= mask) == 0)
- break;
- }
- }
-#endif
-}
-
-/*
* various PCI helpers
*/
-
void
octeon_pcibus_attach_hook(struct device *parent, struct device *self,
struct pcibus_attach_args *pba)
{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-#if 0
- pci_chipset_tag_t pc = pba->pba_pc;
- struct octeon_pcibus_softc *sc = pc->pc_conf_v;
-
- const struct octeon_pcibus_config *oc = sc->sc_octeon_pcibus;
-
- if (pba->pba_bus != 0)
- return;
-
- (*oc->oc_attach_hook)(pc);
-#endif
-
}
/*
* PCI configuration space access routines
*/
-
int
octeon_pcibus_bus_maxdevs(void *v, int busno)
{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
+ /* XXX */
return 32;
-#if 0
- struct octeon_pcibus_softc *sc = v;
- const struct octeon_pcibus_config *oc = sc->sc_octeon_pcibus;
-
- return busno == 0 ? 32 - oc->oc_adbase : 32;
-#endif
}
pcitag_t
*fp = (tag >> 8) & 0x7;
}
-int
-octeon_pcibus_conf_addr(const struct octeon_pcibus_config *oc, pcitag_t tag, int offset,
- uint64_t *cfgoff, uint64_t *pcimap_cfg)
-{
- int b, d, f;
-
- octeon_pcibus_decompose_tag(NULL, tag, &b, &d, &f);
-
- if (b == 0) {
- d += oc->oc_adbase;
- if (d > 31)
- return 1;
- *cfgoff = (1UL << d) | (f << 8) | offset;
- *pcimap_cfg = 0;
- } else {
- *cfgoff = tag | offset;
- *pcimap_cfg = OCTEON_PCIBUS_PCIMAPCFG_TYPE1;
- }
-
- return 0;
-}
-
/* PCI Configuration Space access hook structure */
struct octeon_pcibus_cfg_hook {
SLIST_ENTRY(octeon_pcibus_cfg_hook) next;
struct octeon_pcibus_softc *sc = pc->pc_conf_v;
struct octeon_pcibus_cfg_hook *och;
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
+ DEBUG_PRINT(("%s:%s:%d:\n", __FILE__, __FUNCTION__, __LINE__));
och = malloc(sizeof *och, M_DEVBUF, M_NOWAIT);
if (och == NULL)
return ENOMEM;
}
pcireg_t
-octeon_pcibus_conf_read(void *v, pcitag_t tag, int offset)
+octeon_pcibus_pci_conf_read(void *v, pcitag_t tag, int offset)
{
struct octeon_pcibus_softc *sc = v;
struct octeon_pcibus_cfg_hook *hook;
return data;
}
- return octeon_pcibus_conf_read_internal(sc->sc_octeon_pcibus, tag, offset);
+ return octeon_pcibus_pci_conf_read_internal(tag, offset);
}
pcireg_t
-octeon_pcibus_conf_read_internal(const struct octeon_pcibus_config *oc, pcitag_t tag,
- int offset)
+octeon_pcibus_pci_conf_read_internal(pcitag_t tag, int offset)
{
pcireg_t data;
uint64_t cfgoff;
- if(tag==0){
- if(offset&0x4){
- cfgoff = OCTEON_PCI_CFG1 + (offset&0xfff8);
- }else{
- cfgoff = OCTEON_PCI_CFG0 + (offset&0xfff8);
+ if (tag == 0){
+ if (offset & 0x4){
+ cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8);
+ } else {
+ cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8);
}
- }else{
- cfgoff = tag+offset;
- /* printf("cfgoff %016lx\n",cfgoff);*/
- if(offset&0x4){
- cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff&0xfffffff8);
- }else{
- cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff&0xfffffff8);
+ } else {
+ cfgoff = tag + offset;
+ if (offset & 0x4) {
+ cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8);
+ } else {
+ cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8);
}
}
- data = oct_read32(cfgoff);
- /*
- printf("%s:%d:tag %04x offset %04x %08x\n",__FUNCTION__,__LINE__,tag,offset,data);
- printf("Address %016lx\n",cfgoff);
- */
-#if 0
- u_int32_t cfgoff, pcimap_cfg;
- uint32_t sr;
- uint64_t imr;
-
- if (octeon_pcibus_conf_addr(oc, tag, offset, &cfgoff, &pcimap_cfg))
- return (pcireg_t)-1;
-
- sr = disableintr();
- imr = REGVAL(OCTEON_PCIBUS_INTEN);
- REGVAL(OCTEON_PCIBUS_INTENCLR) = 0xffffffff;
- (void)REGVAL(OCTEON_PCIBUS_INTENCLR);
-
- /* clear aborts */
- REGVAL(OCTEON_PCIBUS_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
- PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
-
- /* high 16 bits of address go into PciMapCfg register */
- REGVAL(OCTEON_PCIBUS_PCIMAP_CFG) = (cfgoff >> 16) | pcimap_cfg;
- (void)REGVAL(OCTEON_PCIBUS_PCIMAP_CFG);
- wbflush();
-
- /* low 16 bits of address are offset into config space */
- data = REGVAL(OCTEON_PCIBUS_PCICFG_BASE + (cfgoff & 0xfffc));
-
- /* check for error */
- if (REGVAL(OCTEON_PCIBUS_PCI_REG(PCI_COMMAND_STATUS_REG)) &
- (PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT)) {
- REGVAL(OCTEON_PCIBUS_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
- PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
- data = (pcireg_t) -1;
- }
-
- REGVAL(OCTEON_PCIBUS_INTENSET) = imr;
- (void)REGVAL(OCTEON_PCIBUS_INTENSET);
- setsr(sr);
-#endif
+ data = REG_READ32(cfgoff);
return data;
}
void
-octeon_pcibus_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
+octeon_pcibus_pci_conf_write(void *v, pcitag_t tag, int offset, pcireg_t data)
{
uint64_t cfgoff;
-/*
- struct octeon_pcibus_softc *sc = v;
- const struct octeon_pcibus_config *oc = sc->sc_octeon_pcibus;
-*/
- if(tag==0){
- if(offset&0x4){
- cfgoff = OCTEON_PCI_CFG1 + (offset&0xfff8);
- }else{
- cfgoff = OCTEON_PCI_CFG0 + (offset&0xfff8);
+
+ if (tag == 0){
+ if (offset & 0x4){
+ cfgoff = OCTEON_PCI_CFG1 + (offset & 0xfff8);
+ } else {
+ cfgoff = OCTEON_PCI_CFG0 + (offset & 0xfff8);
}
- }else{
- cfgoff = tag+offset;
- /* printf("cfgoff %016lx\n",cfgoff);*/
- if(offset&0x4){
- cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff&0xfffffff8);
- }else{
- cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff&0xfffffff8);
+ } else {
+ cfgoff = tag + offset;
+ if (offset & 0x4){
+ cfgoff = OCTEON_PCI_CONFIG_BASE1 + (cfgoff & 0xfffffff8);
+ } else {
+ cfgoff = OCTEON_PCI_CONFIG_BASE0 + (cfgoff & 0xfffffff8);
}
}
- /*
- printf("%s:%d:tag %04x offset %04x data %08x\n",__FUNCTION__,__LINE__,tag,offset,data);
- printf("Address %016lx\n",cfgoff);
- */
- oct_write32(cfgoff,data);
-#if 0
- struct octeon_pcibus_softc *sc = v;
- u_int32_t cfgoff, pcimap_cfg;
- struct octeon_pcibus_cfg_hook *hook;
- uint32_t sr;
- uint64_t imr;
-
- SLIST_FOREACH(hook, &sc->sc_hook, next) {
- if (hook->write != NULL &&
- (*hook->write)(hook->cookie, &sc->sc_pc, tag, offset,
- data) != 0)
- return;
- }
-
- if (octeon_pcibus_conf_addr(sc->sc_octeon_pcibus, tag, offset, &cfgoff, &pcimap_cfg))
- panic("octeon_pcibus_conf_write");
-
- sr = disableintr();
- imr = REGVAL(OCTEON_PCIBUS_INTEN);
- REGVAL(OCTEON_PCIBUS_INTENCLR) = 0xffffffff;
- (void)REGVAL(OCTEON_PCIBUS_INTENCLR);
-
- /* clear aborts */
- REGVAL(OCTEON_PCIBUS_PCI_REG(PCI_COMMAND_STATUS_REG)) |=
- PCI_STATUS_MASTER_ABORT | PCI_STATUS_MASTER_TARGET_ABORT;
-
- /* high 16 bits of address go into PciMapCfg register */
- REGVAL(OCTEON_PCIBUS_PCIMAP_CFG) = (cfgoff >> 16) | pcimap_cfg;
- (void)REGVAL(OCTEON_PCIBUS_PCIMAP_CFG);
- wbflush();
- /* low 16 bits of address are offset into config space */
- REGVAL(OCTEON_PCIBUS_PCICFG_BASE + (cfgoff & 0xfffc)) = data;
-
- REGVAL(OCTEON_PCIBUS_INTENSET) = imr;
- (void)REGVAL(OCTEON_PCIBUS_INTENSET);
- setsr(sr);
-#endif
+ REG_WRITE32(cfgoff, data);
}
+
/*
* PCI Interrupt handling
*/
-
int
octeon_pcibus_pci_intr_map(struct pci_attach_args *pa, pci_intr_handle_t *ihp)
{
+#if 0
struct octeon_pcibus_softc *sc = pa->pa_pc->pc_intr_v;
- const struct octeon_pcibus_config *oc = sc->sc_octeon_pcibus;
+#endif
int bus, dev, fn, pin;
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- DEBUG_PRINT(("pa->pa_domain_ %d\n",pa->pa_domain));
- DEBUG_PRINT(("pa->pa_bus %d\n",pa->pa_bus));
- DEBUG_PRINT(("pa->pa_device %d\n",pa->pa_device));
- DEBUG_PRINT(("pa->pa_function %d\n",pa->pa_function));
- DEBUG_PRINT(("pa->pa_id %d\n",pa->pa_id));
- DEBUG_PRINT(("pa->pa_class %d\n",pa->pa_class));
-
*ihp = (pci_intr_handle_t)-1;
-
+
if (pa->pa_intrpin == 0) /* no interrupt needed */
return 1;
- DEBUG_PRINT(("%s: interrupt pin %d\n", __func__, pa->pa_intrpin));
#ifdef DIAGNOSTIC
if (pa->pa_intrpin > 4) {
}
#endif
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
pci_decompose_tag(pa->pa_pc, pa->pa_tag, &bus, &dev, &fn);
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
if (pa->pa_bridgetag) {
-
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
pin = PPB_INTERRUPT_SWIZZLE(pa->pa_rawintrpin, dev);
*ihp = pa->pa_bridgeih[pin - 1];
} else {
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- DEBUG_PRINT(("oc_intr_map %p\n",oc->oc_intr_map));
if (bus == 0)
- *ihp = (*oc->oc_intr_map)(dev, fn, pa->pa_intrpin);
+ *ihp = octeon_pcibus_intr_map(dev, fn, pa->pa_intrpin);
if (*ihp == (pci_intr_handle_t)-1)
return 1;
const char *
octeon_pcibus_pci_intr_string(void *cookie, pci_intr_handle_t ih)
{
- static char irqstr[1 + 12];
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-
- if (OCTEON_PCIBUS_IRQ_IS_ISA(ih))
- snprintf(irqstr, sizeof irqstr, "isa irq %d",
- OCTEON_PCIBUS_IRQ_TO_ISA(ih));
- else
- snprintf(irqstr, sizeof irqstr, "irq %d", ih);
+ static char irqstr[sizeof("irq 0123456789")];
+
+ snprintf(irqstr, sizeof irqstr, "irq %d", ih);
return irqstr;
}
octeon_pcibus_pci_intr_establish(void *cookie, pci_intr_handle_t ih, int level,
int (*cb)(void *), void *cbarg, char *name)
{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- return octeon_pcibus_intr_establish(ih, IST_LEVEL, level, cb, cbarg, name);
+ struct octeon_pcibus_softc *sc;
+ struct obio_attach_args *oba;
+
+ sc = (struct octeon_pcibus_softc *)cookie;
+ oba = sc->sc_oba;
+
+ return obio_intr_establish(oba->oba_intr, level, cb, cbarg, name);
}
void
octeon_pcibus_pci_intr_disestablish(void *cookie, void *ihp)
{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- octeon_pcibus_intr_disestablish(ihp);
+ struct octeon_pcibus_softc *sc;
+ struct obio_attach_args *oba;
+
+ sc = (struct octeon_pcibus_softc *)cookie;
+ oba = sc->sc_oba;
+
+// XXX: this cause panic...
+// obio_intr_disestablish(ihp);
}
/*
* bus_space mapping routines.
*/
-
-/*
- * Legacy I/O access protection.
- * Since MI ISA code does not expect bus access to cause any failure when
- * accessing missing hardware, but only receive bogus data in return, we
- * force bus_space_map() to fail if there is no hardware there.
- */
-
int
octeon_pcibus_io_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- DEBUG_PRINT(("t->bus_base %p\n",t->bus_base));
- DEBUG_PRINT(("offs %p\n",offs));
- DEBUG_PRINT(("size %d\n",size));
- DEBUG_PRINT(("flags %x\n",flags));
-
-#if 0
- const struct legacy_io_range *r;
- if (offs < OCTEON_PCIBUS_PCIIO_LEGACY) {
- size--;
- for (r = sys_platform->legacy_io_ranges; r->start != 0; r++)
- if (offs >= r->start && offs + size <= r->end)
- break;
-
- if (r->end == 0)
- return ENXIO;
+ if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) {
+ offs +=
+ PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
}
-#endif
- uint64_t endianSwap=0x400000000;
- *bshp = (t->bus_base|endianSwap) + offs;
+ *bshp = t->bus_base + offs;
return 0;
}
-/*
- * PCI memory access.
- * Things are a bit complicated here, as we can either use one of the 64MB
- * windows in PCILO space (making sure ranges spanning multiple windows will
- * turn contiguous), or a direct access within the PCIHI space.
- * Note that, on 2F systems, only the PCIHI range for which CPU->PCI accesses
- * are enabled in the crossbar is usable.
- */
-
int
octeon_pcibus_mem_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, int flags,
bus_space_handle_t *bshp)
{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-#if 0
- uint32_t pcimap;
- bus_addr_t pcilo_w[3];
- bus_addr_t ws, we, w;
- bus_addr_t end = offs + size - 1;
- int pcilo_window;
-
- /*
- * Try a PCIHI mapping first.
- */
-
-
- if (loongson_ver == 0x2f) {
- if (offs >= LS2F_PCIHI_BASE && end <= LS2F_PCIHI_TOP) {
- *bshp = t->bus_base + offs;
- return 0;
- }
- } else {
- /*
- * Only try HI space if we do not have memory setup there.
- */
- if (physmem <= atop(OCTEON_PCIBUS_PCILO_BASE)) {
- /* PCI1.5 */
- if (offs >= OCTEON_PCIBUS_PCIHI_BASE &&
- end <= OCTEON_PCIBUS_PCIHI_TOP) {
- *bshp = t->bus_base + offs;
- return 0;
- }
-
- /* PCI2 */
- w = pcimap & OCTEON_PCIBUS_PCIMAP_PCIMAP_2 ? 0x80000000UL : 0;
- if (offs >= w && end < (w + 0x80000000UL)) {
- *bshp = t->bus_base + 0x80000000UL + (offs - w);
- return 0;
- }
- }
- }
-
- /*
- * No luck, try a PCILO mapping.
- */
-
- /*
- * Decode PCIMAP, and figure out what PCILO mappings are
- * possible.
- */
-
- DEBUG_PRINT(("%s:%d:\n",__FUNCTION__,__LINE__));
-#if 0
- pcimap = REGVAL(OCTEON_PCIBUS_PCIMAP);
- pcilo_w[0] = (pcimap & OCTEON_PCIBUS_PCIMAP_PCIMAP_LO0) >>
- OCTEON_PCIBUS_PCIMAP_PCIMAP_LO0_SHIFT;
- pcilo_w[1] = (pcimap & OCTEON_PCIBUS_PCIMAP_PCIMAP_LO1) >>
- OCTEON_PCIBUS_PCIMAP_PCIMAP_LO1_SHIFT;
- pcilo_w[2] = (pcimap & OCTEON_PCIBUS_PCIMAP_PCIMAP_LO2) >>
- OCTEON_PCIBUS_PCIMAP_PCIMAP_LO2_SHIFT;
-#endif
- /*
- * Check if the 64MB areas we want to span are all available as
- * contiguous PCILO mappings.
- */
-
- ws = offs >> 26;
- we = end >> 26;
-
- pcilo_window = -1;
- if (ws == pcilo_w[0])
- pcilo_window = 0;
- else if (ws == pcilo_w[1])
- pcilo_window = 1;
- else if (ws == pcilo_w[2])
- pcilo_window = 2;
-
- if (pcilo_window >= 0) {
- /* contiguous area test */
- for (w = ws + 1; w <= we; w++) {
- if (pcilo_window + (w - ws) > 2 ||
- w != pcilo_w[pcilo_window + (w - ws)]) {
- pcilo_window = -1;
- break;
- }
- }
+ if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) {
+ offs +=
+ PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC);
}
-
- if (pcilo_window >= 0) {
- *bshp = t->bus_base + OCTEON_PCIBUS_PCILO_BASE +
- OCTEON_PCIBUS_PCIMAP_WINBASE(pcilo_window) +
- OCTEON_PCIBUS_PCIMAP_WINOFFSET(offs);
- return 0;
- }
-
-#endif
- return EINVAL;
+ *bshp = t->bus_base + offs;
+ return 0;
}
/*
* PCI resource handling
*/
-
struct extent *
octeon_pcibus_get_resource_extent(pci_chipset_tag_t pc, int io)
{
struct octeon_pcibus_softc *sc = pc->pc_conf_v;
struct extent *ex;
char *exname;
- size_t exnamesz;
-// uint32_t reg;
+ int exnamesz;
int errors;
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
exnamesz = 1 + 16 + 4;
exname = (char *)malloc(exnamesz, M_DEVBUF, M_NOWAIT);
if (exname == NULL)
snprintf(exname, exnamesz, "%s%s", sc->sc_dev.dv_xname,
io ? "_io" : "_mem");
- ex = extent_create(exname, 0, 0xffffffff, M_DEVBUF, NULL, 0,
+ ex = extent_create(exname, 0, 0xffffffffffffffff, M_DEVBUF, NULL, 0,
EX_NOWAIT | EX_FILLED);
if (ex == NULL)
goto out;
+ exname = NULL;
errors = 0;
if (io) {
- /*
- * Reserve the low 16KB of I/O space to the legacy hardware,
- * if any.
- */
-/*
- if (extent_free(ex, OCTEON_PCIBUS_PCIIO_LEGACY, OCTEON_PCIBUS_PCIIO_SIZE,
+ if (extent_free(ex, _OCTEON_PCIBUS_PCIIO_BASE, _OCTEON_PCIBUS_PCIIO_SIZE,
EX_NOWAIT) != 0)
errors++;
-*/
} else {
- DEBUG_PRINT(("%s:%d:\n",__FUNCTION__,__LINE__));
-#if 0
- reg = REGVAL(OCTEON_PCIBUS_PCIMAP);
- if (extent_free(ex,
- OCTEON_PCIBUS_PCIMAP_WINBASE((reg & OCTEON_PCIBUS_PCIMAP_PCIMAP_LO0) >>
- OCTEON_PCIBUS_PCIMAP_PCIMAP_LO0_SHIFT),
- OCTEON_PCIBUS_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
- errors++;
- if (extent_free(ex,
- OCTEON_PCIBUS_PCIMAP_WINBASE((reg & OCTEON_PCIBUS_PCIMAP_PCIMAP_LO1) >>
- OCTEON_PCIBUS_PCIMAP_PCIMAP_LO1_SHIFT),
- OCTEON_PCIBUS_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
- errors++;
- if (extent_free(ex,
- OCTEON_PCIBUS_PCIMAP_WINBASE((reg & OCTEON_PCIBUS_PCIMAP_PCIMAP_LO2) >>
- OCTEON_PCIBUS_PCIMAP_PCIMAP_LO2_SHIFT),
- OCTEON_PCIBUS_PCIMAP_WINSIZE, EX_NOWAIT) != 0)
+ if (extent_free(ex, _OCTEON_PCIBUS_PCIMEM_BASE, _OCTEON_PCIBUS_PCIMEM_SIZE,
+ EX_NOWAIT) != 0)
errors++;
-
- if (sc->sc_compatible) {
- /* XXX make PCIMAP_HI available if PCIMAP_2 set */
- }
-#endif
}
if (errors != 0) {
if (exname != NULL)
free(exname, M_DEVBUF);
-
return ex;
}
/*
- * Functions used during early system configuration (before octeon_pcibus attaches).
- */
-
-pcitag_t
-pci_make_tag_early(int b, int d, int f)
-{
- return octeon_pcibus_make_tag(NULL, b, d, f);
-}
-
-pcireg_t
-pci_conf_read_early(pcitag_t tag, int reg)
-{
- return octeon_pcibus_conf_read_internal(sys_platform->octeon_pcibus_config, tag, reg);
-}
-
-/*
* PCI model specific routines
*/
-
void
octeon_pcibus_pci_attach_hook(pci_chipset_tag_t pc)
{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
-
-#if 0
- pcireg_t id;
- pcitag_t tag;
- int dev;
-
- /*
- * Check for a VIA 686 southbridge; if one is found, remember
- * its location, needed by generic2e_intr_map().
- */
-
- for (dev = pci_bus_maxdevs(pc, 0); dev >= 0; dev--) {
- tag = pci_make_tag(pc, 0, dev, 0);
- id = pci_conf_read(pc, tag, PCI_ID_REG);
- if (id == PCI_ID_CODE(PCI_VENDOR_VIATECH,
- PCI_PRODUCT_VIATECH_VT82C686A_ISA)) {
- generic2e_via686sb_dev = dev;
- break;
- }
- }
-
- if (generic2e_via686sb_dev != 0)
- via686sb_setup(pc, generic2e_via686sb_dev);
-#endif
}
int
octeon_pcibus_intr_map(int dev, int fn, int pin)
{
- DEBUG_PRINT(("%s:%s:%d:\n",__FILE__,__FUNCTION__,__LINE__));
- DEBUG_PRINT(("Dev %x fn %x pin %x\n",dev,fn,pin));
-#if 0
- if (dev == generic2e_via686sb_dev) {
- switch (fn) {
- case 1: /* PCIIDE */
- /* will use compat interrupt */
- break;
- case 2: /* USB */
- return BONITO_ISA_IRQ(VIA686_IRQ_PCIB);
- case 3: /* USB */
- return BONITO_ISA_IRQ(VIA686_IRQ_PCIC);
- case 4: /* power management, SMBus */
- break;
- case 5: /* Audio */
- return BONITO_ISA_IRQ(VIA686_IRQ_PCIA);
- case 6: /* Modem */
- break;
- default:
- break;
- }
- } else {
- return BONITO_DIRECT_IRQ(BONITO_INTR_GPIN +
- pin - PCI_INTERRUPT_PIN_A);
- }
-#endif
- return CIU_INT_PCI_INTA + pin - PCI_INTERRUPT_PIN_A;
-
+ return CIU_INT_PCI_INTA + ((pin - 1) & 3);
}