diff options
author | Takuya ASADA <syuu@cvs.openbsd.org> | 2011-05-08 13:24:56 +0000 |
---|---|---|
committer | Takuya ASADA <syuu@cvs.openbsd.org> | 2011-05-08 13:24:56 +0000 |
commit | b26609bbae04ffd505ecd0ec89bf2998e8dd00dd (patch) | |
tree | 2343bacdee14d4827b374ac6e4e08f0736481a6e /sys | |
parent | 5e6d68444563de018ac60e58c3cf114feee74501 (diff) |
obio renamed iobus, moved interrupt handler code to dev/octeon_intr.c
Diffstat (limited to 'sys')
-rw-r--r-- | sys/arch/octeon/conf/GENERIC | 8 | ||||
-rw-r--r-- | sys/arch/octeon/conf/RAMDISK | 8 | ||||
-rw-r--r-- | sys/arch/octeon/conf/files.octeon | 15 | ||||
-rw-r--r-- | sys/arch/octeon/dev/com_oct.c | 6 | ||||
-rw-r--r-- | sys/arch/octeon/dev/iobusvar.h (renamed from sys/arch/octeon/dev/obiovar.h) | 37 | ||||
-rw-r--r-- | sys/arch/octeon/dev/mainbus.c | 4 | ||||
-rw-r--r-- | sys/arch/octeon/dev/obio.c | 668 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octcf.c | 10 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octeon_intr.c | 323 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octeon_iobus.c | 264 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octeon_pcibus.c | 24 | ||||
-rw-r--r-- | sys/arch/octeon/dev/octeon_pcibusvar.h | 4 | ||||
-rw-r--r-- | sys/arch/octeon/include/intr.h | 8 | ||||
-rw-r--r-- | sys/arch/octeon/octeon/machdep.c | 26 |
14 files changed, 665 insertions, 740 deletions
diff --git a/sys/arch/octeon/conf/GENERIC b/sys/arch/octeon/conf/GENERIC index afc094eda72..5685efe1c74 100644 --- a/sys/arch/octeon/conf/GENERIC +++ b/sys/arch/octeon/conf/GENERIC @@ -1,4 +1,4 @@ -# $OpenBSD: GENERIC,v 1.5 2011/04/25 22:23:10 syuu Exp $ +# $OpenBSD: GENERIC,v 1.6 2011/05/08 13:24:55 syuu Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -28,15 +28,15 @@ config bsd swap generic mainbus0 at root cpu0 at mainbus0 clock0 at mainbus0 -obio0 at mainbus0 +iobus0 at mainbus0 combus0 at mainbus0 -octcf0 at obio0 +octcf0 at iobus0 com0 at combus0 com1 at combus0 -pcibus* at obio0 +pcibus* at iobus0 pci* at pcibus? # IDE Controller diff --git a/sys/arch/octeon/conf/RAMDISK b/sys/arch/octeon/conf/RAMDISK index ffe45016eed..e391dc0b2a2 100644 --- a/sys/arch/octeon/conf/RAMDISK +++ b/sys/arch/octeon/conf/RAMDISK @@ -1,4 +1,4 @@ -# $OpenBSD: RAMDISK,v 1.6 2011/04/25 22:23:10 syuu Exp $ +# $OpenBSD: RAMDISK,v 1.7 2011/05/08 13:24:55 syuu Exp $ # # For further information on compiling OpenBSD kernels, see the config(8) # man page. @@ -42,15 +42,15 @@ config bsd root on rd0a swap on rd0b mainbus0 at root cpu0 at mainbus0 clock0 at mainbus0 -obio0 at mainbus0 +iobus0 at mainbus0 combus0 at mainbus0 -octcf0 at obio0 +octcf0 at iobus0 com0 at combus0 com1 at combus0 -pcibus* at obio0 +pcibus* at iobus0 pci* at pcibus? # IDE Controller diff --git a/sys/arch/octeon/conf/files.octeon b/sys/arch/octeon/conf/files.octeon index 6e71787bad1..df5bce0c444 100644 --- a/sys/arch/octeon/conf/files.octeon +++ b/sys/arch/octeon/conf/files.octeon @@ -1,4 +1,4 @@ -# $OpenBSD: files.octeon,v 1.6 2010/10/28 22:50:49 syuu Exp $ +# $OpenBSD: files.octeon,v 1.7 2011/05/08 13:24:55 syuu Exp $ # Standard stanzas config(8) can't run without maxpartitions 16 @@ -49,14 +49,15 @@ attach cpu at mainbus device clock attach clock at mainbus -define obio {[base = -1]} -device obio -attach obio at mainbus -file arch/octeon/dev/obio.c mainbus +define iobus {[base = -1]} +device iobus +attach iobus at mainbus +file arch/octeon/dev/octeon_iobus.c iobus +file arch/octeon/dev/octeon_intr.c iobus # On-board CF device octcf: disk -attach octcf at obio +attach octcf at iobus file arch/octeon/dev/octcf.c octcf define combus {[base = -1]} @@ -68,7 +69,7 @@ attach com at combus with com_oct file arch/octeon/dev/com_oct.c com_oct device pcibus -attach pcibus at obio +attach pcibus at iobus file arch/octeon/dev/octeon_pcibus.c pcibus file arch/octeon/dev/octeon_bus_space.c diff --git a/sys/arch/octeon/dev/com_oct.c b/sys/arch/octeon/dev/com_oct.c index 49615e64301..36700d1f348 100644 --- a/sys/arch/octeon/dev/com_oct.c +++ b/sys/arch/octeon/dev/com_oct.c @@ -1,4 +1,4 @@ -/* $OpenBSD: com_oct.c,v 1.2 2010/10/01 16:13:59 syuu Exp $ */ +/* $OpenBSD: com_oct.c,v 1.3 2011/05/08 13:24:55 syuu Exp $ */ /* * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -34,12 +34,12 @@ #include <machine/autoconf.h> #include <machine/bus.h> +#include <machine/intr.h> #include <dev/ic/comreg.h> #include <dev/ic/comvar.h> #include <dev/cons.h> -#include <octeon/dev/obiovar.h> #include <octeon/dev/combusvar.h> #include <octeon/dev/octeonreg.h> @@ -134,7 +134,7 @@ com_oct_attach(struct device *parent, struct device *self, void *aux) com_attach_subr(sc); - obio_intr_establish(cba->cba_intr, IPL_TTY, comintr, + octeon_intr_establish(cba->cba_intr, IPL_TTY, comintr, (void *)sc, sc->sc_dev.dv_xname); } diff --git a/sys/arch/octeon/dev/obiovar.h b/sys/arch/octeon/dev/iobusvar.h index 1fae691e4ac..d0086fa5544 100644 --- a/sys/arch/octeon/dev/obiovar.h +++ b/sys/arch/octeon/dev/iobusvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: obiovar.h,v 1.2 2010/11/23 18:46:29 syuu Exp $ */ +/* $OpenBSD: iobusvar.h,v 1.1 2011/05/08 13:24:55 syuu Exp $ */ /* * Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -26,28 +26,27 @@ * */ -#ifndef _OBIOVAR_H_ -#define _OBIOVAR_H_ +#ifndef _IOBUSVAR_H_ +#define _IOBUSVAR_H_ #include <machine/bus.h> -extern bus_space_t obio_tag; -extern struct machine_bus_dma_tag obio_dma_tag; +extern bus_space_t iobus_tag; +extern struct machine_bus_dma_tag iobus_dma_tag; -struct obio_attach_args { - char *oba_name; - - bus_space_tag_t oba_iot; - bus_space_tag_t oba_memt; - bus_dma_tag_t oba_dmat; - bus_addr_t oba_baseaddr; - int oba_intr; +struct iobus_unit { + bus_addr_t addr; + int irq; }; -void obio_setintrmask(int); -void *obio_intr_establish(int, int, int (*)(void *), - void *, const char *); -void obio_intr_disestablish(void *); -void obio_intr_init(void); +struct iobus_attach_args { + char *aa_name; + int aa_unitno; + + const struct iobus_unit *aa_unit; + + bus_space_tag_t aa_bust; + bus_dma_tag_t aa_dmat; +}; -#endif /* _OBIOVAR_H_ */ +#endif /* _IOBUSVAR_H_ */ diff --git a/sys/arch/octeon/dev/mainbus.c b/sys/arch/octeon/dev/mainbus.c index 35db2b195b5..5028743f093 100644 --- a/sys/arch/octeon/dev/mainbus.c +++ b/sys/arch/octeon/dev/mainbus.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mainbus.c,v 1.2 2010/10/01 16:13:59 syuu Exp $ */ +/* $OpenBSD: mainbus.c,v 1.3 2011/05/08 13:24:55 syuu Exp $ */ /* * Copyright (c) 2001-2003 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -82,7 +82,7 @@ mainbus_attach(struct device *parent, struct device *self, void *aux) config_found(self, &caa.caa_maa, mainbus_print); /* on-board I/O */ - caa.caa_maa.maa_name = "obio"; + caa.caa_maa.maa_name = "iobus"; config_found(self, &caa.caa_maa, mainbus_print); } diff --git a/sys/arch/octeon/dev/obio.c b/sys/arch/octeon/dev/obio.c deleted file mode 100644 index a5d9a627213..00000000000 --- a/sys/arch/octeon/dev/obio.c +++ /dev/null @@ -1,668 +0,0 @@ -/* $OpenBSD: obio.c,v 1.6 2010/11/23 18:46:29 syuu Exp $ */ - -/* - * Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se) - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS - * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED - * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY - * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - */ - -/* - * This is a obio driver. - * It handles configuration of all devices on the processor bus except UART. - */ - -#include <sys/param.h> -#include <sys/systm.h> -#include <sys/kernel.h> -#include <sys/conf.h> -#include <sys/malloc.h> -#include <sys/device.h> -#include <sys/proc.h> - -#include <mips64/archtype.h> - -#include <machine/autoconf.h> -#include <machine/intr.h> -#include <machine/atomic.h> - -#include <octeon/dev/octeonreg.h> -#include <octeon/dev/obiovar.h> - -#define OBIO_NINTS 64 - -int obiomatch(struct device *, void *, void *); -void obioattach(struct device *, struct device *, void *); -int obioprint(void *, const char *); -int obiosubmatch(struct device *, void *, void *); - -void obio_intr_makemasks(void); -void obio_splx(int); -uint32_t obio_iointr(uint32_t, struct trap_frame *); -uint32_t obio_aux(uint32_t, struct trap_frame *); -int obio_iointr_skip(struct intrhand *, uint64_t, uint64_t); -void obio_setintrmask(int); - -u_int8_t obio_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t); -u_int16_t obio_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t); -u_int32_t obio_read_4(bus_space_tag_t, bus_space_handle_t, bus_size_t); -u_int64_t obio_read_8(bus_space_tag_t, bus_space_handle_t, bus_size_t); - -void obio_write_1(bus_space_tag_t, bus_space_handle_t, bus_size_t, - u_int8_t); -void obio_write_2(bus_space_tag_t, bus_space_handle_t, bus_size_t, - u_int16_t); -void obio_write_4(bus_space_tag_t, bus_space_handle_t, bus_size_t, - u_int32_t); -void obio_write_8(bus_space_tag_t, bus_space_handle_t, bus_size_t, - u_int64_t); - -void obio_read_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t, - u_int8_t *, bus_size_t); -void obio_write_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t, - const u_int8_t *, bus_size_t); -void obio_read_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t, - u_int8_t *, bus_size_t); -void obio_write_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t, - const u_int8_t *, bus_size_t); -void obio_read_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t, - u_int8_t *, bus_size_t); -void obio_write_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t, - const u_int8_t *, bus_size_t); - -int obio_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, - bus_space_handle_t *); -void obio_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t); -int obio_space_region(bus_space_tag_t, bus_space_handle_t, bus_size_t, - bus_size_t, bus_space_handle_t *); - -void *obio_space_vaddr(bus_space_tag_t, bus_space_handle_t); - -bus_addr_t obio_pa_to_device(paddr_t); -paddr_t obio_device_to_pa(bus_addr_t); - -struct cfattach obio_ca = { - sizeof(struct device), obiomatch, obioattach -}; - -struct cfdriver obio_cd = { - NULL, "obio", DV_DULL -}; - -bus_space_t obio_tag = { - PHYS_TO_XKPHYS(0, CCA_NC), - NULL, - obio_read_1, obio_write_1, - obio_read_2, obio_write_2, - obio_read_4, obio_write_4, - obio_read_8, obio_write_8, - obio_read_raw_2, obio_write_raw_2, - obio_read_raw_4, obio_write_raw_4, - obio_read_raw_8, obio_write_raw_8, - obio_space_map, obio_space_unmap, obio_space_region, - obio_space_vaddr -}; - -bus_space_handle_t obio_h; - -struct machine_bus_dma_tag obio_bus_dma_tag = { - NULL, /* _cookie */ - _dmamap_create, - _dmamap_destroy, - _dmamap_load, - _dmamap_load_mbuf, - _dmamap_load_uio, - _dmamap_load_raw, - _dmamap_load_buffer, - _dmamap_unload, - _dmamap_sync, - _dmamem_alloc, - _dmamem_free, - _dmamem_map, - _dmamem_unmap, - _dmamem_mmap, - obio_pa_to_device, - obio_device_to_pa, - 0 -}; - -struct intrhand *obio_intrhand[OBIO_NINTS]; - -#define INTPRI_CIU_0 (INTPRI_CLOCK + 1) - -uint64_t obio_intem[MAXCPUS]; -uint64_t obio_imask[MAXCPUS][NIPLS]; - -/* - * List of obio child devices. - */ - -#define OBIODEV(name, addr, i) \ - { name, &obio_tag, &obio_tag, &obio_bus_dma_tag, addr, i } -struct obio_attach_args obio_children[] = { - OBIODEV("octcf", OCTEON_CF_BASE, 0), - OBIODEV("pcibus", 0, 0), -}; -#undef OBIODEV - -/* - * Match bus only to targets which have this bus. - */ -int -obiomatch(struct device *parent, void *match, void *aux) -{ - return (1); -} - -int -obioprint(void *aux, const char *obio) -{ - struct obio_attach_args *oba = aux; - - if (obio != NULL) - printf("%s at %s", oba->oba_name, obio); - - if (oba->oba_baseaddr != 0) - printf(" base 0x%llx", oba->oba_baseaddr); - if (oba->oba_intr >= 0) - printf(" irq %d", oba->oba_intr); - - return (UNCONF); -} - -int -obiosubmatch(struct device *parent, void *vcf, void *args) -{ - struct cfdata *cf = vcf; - struct obio_attach_args *oba = args; - - if (strcmp(cf->cf_driver->cd_name, oba->oba_name) != 0) - return 0; - - if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != (int)oba->oba_baseaddr) - return 0; - - return (*cf->cf_attach->ca_match)(parent, cf, oba); -} - -void -obioattach(struct device *parent, struct device *self, void *aux) -{ - uint i; - - /* - * Map and setup CRIME control registers. - */ - if (bus_space_map(&obio_tag, OCTEON_CIU_BASE, OCTEON_CIU_SIZE, 0, - &obio_h)) { - printf(": can't map CIU control registers\n"); - return; - } - - printf("\n"); - - obio_intr_init(); - - set_intr(INTPRI_CIU_0, CR_INT_0, obio_iointr); - register_splx_handler(obio_splx); - - /* - * Attach subdevices. - */ - for (i = 0; i < nitems(obio_children); i++) - config_found_sm(self, obio_children + i, - obioprint, obiosubmatch); -} - -/* - * Bus access primitives. These are really ugly... - */ - -u_int8_t -obio_read_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) -{ - return (u_int8_t)*(volatile uint8_t *)(h + o); -} - -u_int16_t -obio_read_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) -{ - return (u_int16_t)*(volatile uint16_t *)(h + o); -} - -u_int32_t -obio_read_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) -{ - return (u_int32_t)*(volatile u_int32_t *)(h + o); -} - -u_int64_t -obio_read_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o) -{ - return *(volatile u_int64_t *)(h + o); -} - -void -obio_write_1(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int8_t v) -{ - *(volatile uint8_t *)(h + o) = (volatile uint8_t)v; -} - -void -obio_write_2(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int16_t v) -{ - *(volatile uint16_t *)(h + o) = (volatile uint16_t)v; -} - -void -obio_write_4(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int32_t v) -{ - *(volatile u_int32_t *)(h + o) = (volatile uint32_t)v; -} - -void -obio_write_8(bus_space_tag_t t, bus_space_handle_t h, bus_size_t o, u_int64_t v) -{ - *(volatile u_int64_t *)(h + o) = v; -} - -void -obio_read_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, - u_int8_t *buf, bus_size_t len) -{ - volatile uint16_t *addr = (volatile uint16_t *)(h + o); - len >>= 1; - while (len-- != 0) { - *(uint16_t *)buf = *addr; - buf += 2; - } -} - -void -obio_write_raw_2(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, - const u_int8_t *buf, bus_size_t len) -{ - volatile uint16_t *addr = (volatile uint16_t *)(h + o); - len >>= 1; - while (len-- != 0) { - *addr = *(uint16_t *)buf; - buf += 2; - } -} - -void -obio_read_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, - u_int8_t *buf, bus_size_t len) -{ - volatile uint32_t *addr = (volatile uint32_t *)(h + o); - len >>= 2; - while (len-- != 0) { - *(uint32_t *)buf = *addr; - buf += 4; - } -} - -void -obio_write_raw_4(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, - const u_int8_t *buf, bus_size_t len) -{ - volatile uint32_t *addr = (volatile uint32_t *)(h + o); - len >>= 2; - while (len-- != 0) { - *addr = *(uint32_t *)buf; - buf += 4; - } -} - -void -obio_read_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, - u_int8_t *buf, bus_size_t len) -{ - volatile uint64_t *addr = (volatile uint64_t *)(h + o); - len >>= 3; - while (len-- != 0) { - *(uint64_t *)buf = *addr; - buf += 8; - } -} - -void -obio_write_raw_8(bus_space_tag_t t, bus_space_handle_t h, bus_addr_t o, - const u_int8_t *buf, bus_size_t len) -{ - volatile uint64_t *addr = (volatile uint64_t *)(h + o); - len >>= 3; - while (len-- != 0) { - *addr = *(uint64_t *)buf; - buf += 8; - } -} - -int -obio_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, - int flags, bus_space_handle_t *bshp) -{ - if (ISSET(flags, BUS_SPACE_MAP_KSEG0)) { - *bshp = PHYS_TO_CKSEG0(offs); - return 0; - } - if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) - offs += - PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC); - *bshp = t->bus_base + offs; - return 0; -} - -void -obio_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) -{ -} - -int -obio_space_region(bus_space_tag_t t, bus_space_handle_t bsh, - bus_size_t offset, bus_size_t size, bus_space_handle_t *nbshp) -{ - *nbshp = bsh + offset; - return (0); -} - -void * -obio_space_vaddr(bus_space_tag_t t, bus_space_handle_t h) -{ - return (void *)h; -} - -/* - * Obio bus_dma helpers. - */ - -bus_addr_t -obio_pa_to_device(paddr_t pa) -{ - return (bus_addr_t)pa; -} - -paddr_t -obio_device_to_pa(bus_addr_t addr) -{ - return (paddr_t)addr; -} - -/* - * Obio interrupt handler driver. - */ - -void -obio_intr_init(void) -{ - int cpuid = cpu_number(); - bus_space_write_8(&obio_tag, obio_h, CIU_IP2_EN0(cpuid), 0); - bus_space_write_8(&obio_tag, obio_h, CIU_IP3_EN0(cpuid), 0); - bus_space_write_8(&obio_tag, obio_h, CIU_IP2_EN1(cpuid), 0); - bus_space_write_8(&obio_tag, obio_h, CIU_IP3_EN1(cpuid), 0); -} - -/* - * Establish an interrupt handler called from the dispatcher. - * The interrupt function established should return zero if there was nothing - * to serve (no int) and non-zero when an interrupt was serviced. - * - * Interrupts are numbered from 1 and up where 1 maps to HW int 0. - * XXX There is no reason to keep this... except for hardcoded interrupts - * XXX in kernel configuration files... - */ -void * -obio_intr_establish(int irq, int level, - int (*ih_fun)(void *), void *ih_arg, const char *ih_what) -{ - int cpuid = cpu_number(); - struct intrhand **p, *q, *ih; - int s; - -#ifdef DIAGNOSTIC - if (irq >= OBIO_NINTS || irq < 0) - panic("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 = ih_fun; - ih->ih_arg = ih_arg; - ih->ih_level = level; - ih->ih_irq = irq; - evcount_attach(&ih->ih_count, ih_what, (void *)&ih->ih_irq); - - 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 = &obio_intrhand[irq]; (q = *p) != NULL; - p = (struct intrhand **)&q->ih_next) - ; - *p = ih; - - obio_intem[cpuid] |= 1UL << irq; - obio_intr_makemasks(); - - splx(s); /* causes hw mask update */ - - return (ih); -} - -void -obio_intr_disestablish(void *ih) -{ - /* XXX */ - panic("%s not implemented", __func__); -} - -void -obio_splx(int newipl) -{ - struct cpu_info *ci = curcpu(); - - /* Update masks to new ipl. Order highly important! */ - __asm__ (".set noreorder\n"); - ci->ci_ipl = newipl; - __asm__ ("sync\n\t.set reorder\n"); - if (CPU_IS_PRIMARY(ci)) - obio_setintrmask(newipl); - /* If we still have softints pending trigger processing. */ - if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT) - setsoftintr0(); -} - -/* - * Recompute interrupt masks. - */ -void -obio_intr_makemasks() -{ - int cpuid = cpu_number(); - int irq, level; - struct intrhand *q; - uint intrlevel[OBIO_NINTS]; - - /* First, figure out which levels each IRQ uses. */ - for (irq = 0; irq < OBIO_NINTS; irq++) { - uint levels = 0; - for (q = (struct intrhand *)obio_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 < NIPLS; level++) { - uint64_t irqs = 0; - for (irq = 0; irq < OBIO_NINTS; irq++) - if (intrlevel[irq] & (1 << level)) - irqs |= 1UL << irq; - obio_imask[cpuid][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. - */ - obio_imask[cpuid][IPL_NET] |= obio_imask[cpuid][IPL_BIO]; - obio_imask[cpuid][IPL_TTY] |= obio_imask[cpuid][IPL_NET]; - obio_imask[cpuid][IPL_VM] |= obio_imask[cpuid][IPL_TTY]; - obio_imask[cpuid][IPL_CLOCK] |= obio_imask[cpuid][IPL_VM]; - obio_imask[cpuid][IPL_HIGH] |= obio_imask[cpuid][IPL_CLOCK]; - obio_imask[cpuid][IPL_IPI] |= obio_imask[cpuid][IPL_HIGH]; - - /* - * These are pseudo-levels. - */ - obio_imask[cpuid][IPL_NONE] = 0; -} - -/* - * Interrupt dispatcher. - */ -uint32_t -obio_iointr(uint32_t hwpend, struct trap_frame *frame) -{ - struct cpu_info *ci = curcpu(); - int cpuid = cpu_number(); - uint64_t imr, isr, mask; - int ipl; - int bit; - struct intrhand *ih; - int rc; - uint64_t sum0 = CIU_IP2_SUM0(cpuid); - uint64_t en0 = CIU_IP2_EN0(cpuid); - - isr = bus_space_read_8(&obio_tag, obio_h, sum0); - imr = bus_space_read_8(&obio_tag, obio_h, en0); - bit = 63; - - isr &= imr; - if (isr == 0) - return 0; /* not for us */ - - /* - * Mask all pending interrupts. - */ - bus_space_write_8(&obio_tag, obio_h, en0, imr & ~isr); - - /* - * If interrupts are spl-masked, mask them and wait for splx() - * to reenable them when necessary. - */ - if ((mask = isr & obio_imask[cpuid][frame->ipl]) != 0) { - isr &= ~mask; - imr &= ~mask; - } - - /* - * Now process allowed interrupts. - */ - if (isr != 0) { - int lvl, bitno; - uint64_t tmpisr; - - __asm__ (".set noreorder\n"); - ipl = ci->ci_ipl; - __asm__ ("sync\n\t.set reorder\n"); - - /* Service higher level interrupts first */ - for (lvl = NIPLS - 1; lvl != IPL_NONE; lvl--) { - tmpisr = isr & (obio_imask[cpuid][lvl] ^ obio_imask[cpuid][lvl - 1]); - if (tmpisr == 0) - continue; - for (bitno = bit, mask = 1UL << bitno; mask != 0; - bitno--, mask >>= 1) { - if ((tmpisr & mask) == 0) - continue; - - rc = 0; - for (ih = (struct intrhand *)obio_intrhand[bitno]; - ih != NULL; - ih = ih->ih_next) { -#ifdef MULTIPROCESSOR - u_int32_t sr; -#endif - splraise(ih->ih_level); -#ifdef MULTIPROCESSOR - if (ih->ih_level < IPL_IPI) { - sr = getsr(); - ENABLEIPI(); - if (ipl < IPL_SCHED) - __mp_lock(&kernel_lock); - } -#endif - if ((*ih->ih_fun)(ih->ih_arg) != 0) { - rc = 1; - atomic_add_uint64(&ih->ih_count.ec_count, 1); - } -#ifdef MULTIPROCESSOR - if (ih->ih_level < IPL_IPI) { - if (ipl < IPL_SCHED) - __mp_unlock(&kernel_lock); - setsr(sr); - } -#endif - __asm__ (".set noreorder\n"); - ci->ci_ipl = ipl; - __asm__ ("sync\n\t.set reorder\n"); - } - if (rc == 0) - printf("spurious crime interrupt %d\n", bitno); - - isr ^= mask; - if ((tmpisr ^= mask) == 0) - break; - } - } - - /* - * Reenable interrupts which have been serviced. - */ - bus_space_write_8(&obio_tag, obio_h, en0, imr); - } - - return hwpend; -} - -void -obio_setintrmask(int level) -{ - int cpuid = cpu_number(); - - bus_space_write_8(&obio_tag, obio_h, CIU_IP2_EN0(cpuid), - obio_intem[cpuid] & ~obio_imask[cpuid][level]); -} diff --git a/sys/arch/octeon/dev/octcf.c b/sys/arch/octeon/dev/octcf.c index 9b5acd67c13..c895aa15763 100644 --- a/sys/arch/octeon/dev/octcf.c +++ b/sys/arch/octeon/dev/octcf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: octcf.c,v 1.1 2010/10/26 00:02:01 syuu Exp $ */ +/* $OpenBSD: octcf.c,v 1.2 2011/05/08 13:24:55 syuu Exp $ */ /* $NetBSD: wd.c,v 1.193 1999/02/28 17:15:27 explorer Exp $ */ /* @@ -83,7 +83,7 @@ #include <dev/ic/wdcreg.h> #include <dev/ic/wdcvar.h> -#include <octeon/dev/obiovar.h> +#include <octeon/dev/iobusvar.h> #include <octeon/dev/octeonreg.h> #define OCTCF_REG_SIZE 8 @@ -173,15 +173,15 @@ void octcfattach(struct device *parent, struct device *self, void *aux) { struct octcf_softc *wd = (void *)self; - struct obio_attach_args *oba = aux; + struct iobus_attach_args *aa = aux; int i, blank; char buf[41], c, *p, *q; OCTCFDEBUG_PRINT(("octcfattach\n"), DEBUG_FUNCS | DEBUG_PROBE); uint8_t status; - wd->sc_iot = oba->oba_memt; + wd->sc_iot = aa->aa_bust; - if (bus_space_map(wd->sc_iot, oba->oba_baseaddr, + if (bus_space_map(wd->sc_iot, aa->aa_unit->addr, OCTCF_REG_SIZE, BUS_SPACE_MAP_KSEG0, &wd->sc_ioh)) { printf(": couldn't map registers\n"); return; diff --git a/sys/arch/octeon/dev/octeon_intr.c b/sys/arch/octeon/dev/octeon_intr.c new file mode 100644 index 00000000000..915982681bc --- /dev/null +++ b/sys/arch/octeon/dev/octeon_intr.c @@ -0,0 +1,323 @@ +/* + * Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * Interrupt support for Octeon Processor. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/conf.h> +#include <sys/malloc.h> +#include <sys/device.h> +#include <sys/proc.h> + +#include <mips64/archtype.h> + +#include <machine/autoconf.h> +#include <machine/atomic.h> +#include <machine/intr.h> + +#include <octeon/dev/octeonreg.h> +#include <octeon/dev/iobusvar.h> + +extern bus_space_handle_t iobus_h; + +#define OCTEON_NINTS 64 + +void octeon_intr_makemasks(void); +void octeon_splx(int); +uint32_t octeon_iointr(uint32_t, struct trap_frame *); +uint32_t octeon_aux(uint32_t, struct trap_frame *); +int octeon_iointr_skip(struct intrhand *, uint64_t, uint64_t); +void octeon_setintrmask(int); + +struct intrhand *octeon_intrhand[OCTEON_NINTS]; + +#define INTPRI_CIU_0 (INTPRI_CLOCK + 1) + +uint64_t octeon_intem[MAXCPUS]; +uint64_t octeon_imask[MAXCPUS][NIPLS]; + +void +octeon_intr_init(void) +{ + int cpuid = cpu_number(); + bus_space_write_8(&iobus_tag, iobus_h, CIU_IP2_EN0(cpuid), 0); + bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid), 0); + bus_space_write_8(&iobus_tag, iobus_h, CIU_IP2_EN1(cpuid), 0); + bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN1(cpuid), 0); + + set_intr(INTPRI_CIU_0, CR_INT_0, octeon_iointr); + register_splx_handler(octeon_splx); +} + +/* + * Establish an interrupt handler called from the dispatcher. + * The interrupt function established should return zero if there was nothing + * to serve (no int) and non-zero when an interrupt was serviced. + * + * Interrupts are numbered from 1 and up where 1 maps to HW int 0. + * XXX There is no reason to keep this... except for hardcoded interrupts + * XXX in kernel configuration files... + */ +void * +octeon_intr_establish(int irq, int level, + int (*ih_fun)(void *), void *ih_arg, const char *ih_what) +{ + int cpuid = cpu_number(); + struct intrhand **p, *q, *ih; + int s; + +#ifdef DIAGNOSTIC + if (irq >= OCTEON_NINTS || irq < 0) + panic("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 = ih_fun; + ih->ih_arg = ih_arg; + ih->ih_level = level; + ih->ih_irq = irq; + evcount_attach(&ih->ih_count, ih_what, (void *)&ih->ih_irq); + + 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_intrhand[irq]; (q = *p) != NULL; + p = (struct intrhand **)&q->ih_next) + ; + *p = ih; + + octeon_intem[cpuid] |= 1UL << irq; + octeon_intr_makemasks(); + + splx(s); /* causes hw mask update */ + + return (ih); +} + +void +octeon_intr_disestablish(void *ih) +{ + /* XXX */ + panic("%s not implemented", __func__); +} + +void +octeon_splx(int newipl) +{ + struct cpu_info *ci = curcpu(); + + /* Update masks to new ipl. Order highly important! */ + __asm__ (".set noreorder\n"); + ci->ci_ipl = newipl; + __asm__ ("sync\n\t.set reorder\n"); + if (CPU_IS_PRIMARY(ci)) + octeon_setintrmask(newipl); + /* If we still have softints pending trigger processing. */ + if (ci->ci_softpending != 0 && newipl < IPL_SOFTINT) + setsoftintr0(); +} + +/* + * Recompute interrupt masks. + */ +void +octeon_intr_makemasks() +{ + int cpuid = cpu_number(); + int irq, level; + struct intrhand *q; + uint intrlevel[OCTEON_NINTS]; + + /* First, figure out which levels each IRQ uses. */ + for (irq = 0; irq < OCTEON_NINTS; irq++) { + uint levels = 0; + for (q = (struct intrhand *)octeon_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 < NIPLS; level++) { + uint64_t irqs = 0; + for (irq = 0; irq < OCTEON_NINTS; irq++) + if (intrlevel[irq] & (1 << level)) + irqs |= 1UL << irq; + octeon_imask[cpuid][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_imask[cpuid][IPL_NET] |= octeon_imask[cpuid][IPL_BIO]; + octeon_imask[cpuid][IPL_TTY] |= octeon_imask[cpuid][IPL_NET]; + octeon_imask[cpuid][IPL_VM] |= octeon_imask[cpuid][IPL_TTY]; + octeon_imask[cpuid][IPL_CLOCK] |= octeon_imask[cpuid][IPL_VM]; + octeon_imask[cpuid][IPL_HIGH] |= octeon_imask[cpuid][IPL_CLOCK]; + octeon_imask[cpuid][IPL_IPI] |= octeon_imask[cpuid][IPL_HIGH]; + + /* + * These are pseudo-levels. + */ + octeon_imask[cpuid][IPL_NONE] = 0; +} + +/* + * Interrupt dispatcher. + */ +uint32_t +octeon_iointr(uint32_t hwpend, struct trap_frame *frame) +{ + struct cpu_info *ci = curcpu(); + int cpuid = cpu_number(); + uint64_t imr, isr, mask; + int ipl; + int bit; + struct intrhand *ih; + int rc; + uint64_t sum0 = CIU_IP2_SUM0(cpuid); + uint64_t en0 = CIU_IP2_EN0(cpuid); + + isr = bus_space_read_8(&iobus_tag, iobus_h, sum0); + imr = bus_space_read_8(&iobus_tag, iobus_h, en0); + bit = 63; + + isr &= imr; + if (isr == 0) + return 0; /* not for us */ + + /* + * Mask all pending interrupts. + */ + bus_space_write_8(&iobus_tag, iobus_h, en0, imr & ~isr); + + /* + * If interrupts are spl-masked, mask them and wait for splx() + * to reenable them when necessary. + */ + if ((mask = isr & octeon_imask[cpuid][frame->ipl]) != 0) { + isr &= ~mask; + imr &= ~mask; + } + + /* + * Now process allowed interrupts. + */ + if (isr != 0) { + int lvl, bitno; + uint64_t tmpisr; + + __asm__ (".set noreorder\n"); + ipl = ci->ci_ipl; + __asm__ ("sync\n\t.set reorder\n"); + + /* Service higher level interrupts first */ + for (lvl = NIPLS - 1; lvl != IPL_NONE; lvl--) { + tmpisr = isr & (octeon_imask[cpuid][lvl] ^ octeon_imask[cpuid][lvl - 1]); + if (tmpisr == 0) + continue; + for (bitno = bit, mask = 1UL << bitno; mask != 0; + bitno--, mask >>= 1) { + if ((tmpisr & mask) == 0) + continue; + + rc = 0; + for (ih = (struct intrhand *)octeon_intrhand[bitno]; + ih != NULL; + ih = ih->ih_next) { +#ifdef MULTIPROCESSOR + u_int32_t sr; +#endif + splraise(ih->ih_level); +#ifdef MULTIPROCESSOR + if (ih->ih_level < IPL_IPI) { + sr = getsr(); + ENABLEIPI(); + if (ipl < IPL_SCHED) + __mp_lock(&kernel_lock); + } +#endif + if ((*ih->ih_fun)(ih->ih_arg) != 0) { + rc = 1; + atomic_add_uint64(&ih->ih_count.ec_count, 1); + } +#ifdef MULTIPROCESSOR + if (ih->ih_level < IPL_IPI) { + if (ipl < IPL_SCHED) + __mp_unlock(&kernel_lock); + setsr(sr); + } +#endif + __asm__ (".set noreorder\n"); + ci->ci_ipl = ipl; + __asm__ ("sync\n\t.set reorder\n"); + } + if (rc == 0) + printf("spurious crime interrupt %d\n", bitno); + + isr ^= mask; + if ((tmpisr ^= mask) == 0) + break; + } + } + + /* + * Reenable interrupts which have been serviced. + */ + bus_space_write_8(&iobus_tag, iobus_h, en0, imr); + } + + return hwpend; +} + +void +octeon_setintrmask(int level) +{ + int cpuid = cpu_number(); + + bus_space_write_8(&iobus_tag, iobus_h, CIU_IP2_EN0(cpuid), + octeon_intem[cpuid] & ~octeon_imask[cpuid][level]); +} diff --git a/sys/arch/octeon/dev/octeon_iobus.c b/sys/arch/octeon/dev/octeon_iobus.c new file mode 100644 index 00000000000..f139f3349ff --- /dev/null +++ b/sys/arch/octeon/dev/octeon_iobus.c @@ -0,0 +1,264 @@ +/* $OpenBSD: octeon_iobus.c,v 1.1 2011/05/08 13:24:55 syuu Exp $ */ + +/* + * Copyright (c) 2000-2004 Opsycon AB (www.opsycon.se) + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS + * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS + * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY + * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF + * SUCH DAMAGE. + * + */ + +/* + * This is a iobus driver. + * It handles configuration of all devices on the processor bus except UART. + */ + +#include <sys/param.h> +#include <sys/systm.h> +#include <sys/kernel.h> +#include <sys/conf.h> +#include <sys/malloc.h> +#include <sys/device.h> +#include <sys/proc.h> + +#include <mips64/archtype.h> + +#include <machine/autoconf.h> +#include <machine/atomic.h> +#include <machine/intr.h> + +#include <octeon/dev/octeonreg.h> +#include <octeon/dev/iobusvar.h> + +int iobusmatch(struct device *, void *, void *); +void iobusattach(struct device *, struct device *, void *); +int iobusprint(void *, const char *); +int iobussubmatch(struct device *, void *, void *); + +u_int8_t iobus_read_1(bus_space_tag_t, bus_space_handle_t, bus_size_t); +u_int16_t iobus_read_2(bus_space_tag_t, bus_space_handle_t, bus_size_t); +u_int32_t iobus_read_4(bus_space_tag_t, bus_space_handle_t, bus_size_t); +u_int64_t iobus_read_8(bus_space_tag_t, bus_space_handle_t, bus_size_t); + +void iobus_write_1(bus_space_tag_t, bus_space_handle_t, bus_size_t, + u_int8_t); +void iobus_write_2(bus_space_tag_t, bus_space_handle_t, bus_size_t, + u_int16_t); +void iobus_write_4(bus_space_tag_t, bus_space_handle_t, bus_size_t, + u_int32_t); +void iobus_write_8(bus_space_tag_t, bus_space_handle_t, bus_size_t, + u_int64_t); + +void iobus_read_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t, + u_int8_t *, bus_size_t); +void iobus_write_raw_2(bus_space_tag_t, bus_space_handle_t, bus_addr_t, + const u_int8_t *, bus_size_t); +void iobus_read_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t, + u_int8_t *, bus_size_t); +void iobus_write_raw_4(bus_space_tag_t, bus_space_handle_t, bus_addr_t, + const u_int8_t *, bus_size_t); +void iobus_read_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t, + u_int8_t *, bus_size_t); +void iobus_write_raw_8(bus_space_tag_t, bus_space_handle_t, bus_addr_t, + const u_int8_t *, bus_size_t); + +int iobus_space_map(bus_space_tag_t, bus_addr_t, bus_size_t, int, + bus_space_handle_t *); +void iobus_space_unmap(bus_space_tag_t, bus_space_handle_t, bus_size_t); +int iobus_space_region(bus_space_tag_t, bus_space_handle_t, bus_size_t, + bus_size_t, bus_space_handle_t *); + +void *iobus_space_vaddr(bus_space_tag_t, bus_space_handle_t); + +bus_addr_t iobus_pa_to_device(paddr_t); +paddr_t iobus_device_to_pa(bus_addr_t); + +struct cfattach iobus_ca = { + sizeof(struct device), iobusmatch, iobusattach +}; + +struct cfdriver iobus_cd = { + NULL, "iobus", DV_DULL +}; + +bus_space_t iobus_tag = { + .bus_base = PHYS_TO_XKPHYS(0, 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 = iobus_space_map, + ._space_unmap = iobus_space_unmap, + ._space_subregion = generic_space_region, + ._space_vaddr = generic_space_vaddr +}; + +bus_space_handle_t iobus_h; + +struct machine_bus_dma_tag iobus_bus_dma_tag = { + NULL, /* _cookie */ + _dmamap_create, + _dmamap_destroy, + _dmamap_load, + _dmamap_load_mbuf, + _dmamap_load_uio, + _dmamap_load_raw, + _dmamap_load_buffer, + _dmamap_unload, + _dmamap_sync, + _dmamem_alloc, + _dmamem_free, + _dmamem_map, + _dmamem_unmap, + _dmamem_mmap, + iobus_pa_to_device, + iobus_device_to_pa, + 0 +}; + +/* + * List of iobus child devices. + */ + +#define IOBUSDEV(name, unitno, unit) \ + { name, unitno, unit, &iobus_tag, &iobus_bus_dma_tag } +const struct iobus_unit iobus_units[] = { + { OCTEON_CF_BASE, 0 }, /* octcf */ + { 0, 0 }, /* pcibus */ +}; +struct iobus_attach_args iobus_children[] = { + IOBUSDEV("octcf", 0, &iobus_units[0]), + IOBUSDEV("pcibus", 0, &iobus_units[1]), +}; +#undef IOBUSDEV + +/* + * Match bus only to targets which have this bus. + */ +int +iobusmatch(struct device *parent, void *match, void *aux) +{ + return (1); +} + +int +iobusprint(void *aux, const char *iobus) +{ + struct iobus_attach_args *aa = aux; + + if (iobus != NULL) + printf("%s at %s", aa->aa_name, iobus); + + if (aa->aa_unit->addr != 0) + printf(" base 0x%llx", aa->aa_unit->addr); + if (aa->aa_unit->irq >= 0) + printf(" irq %d", aa->aa_unit->irq); + + return (UNCONF); +} + +int +iobussubmatch(struct device *parent, void *vcf, void *args) +{ + struct cfdata *cf = vcf; + struct iobus_attach_args *aa = args; + + if (strcmp(cf->cf_driver->cd_name, aa->aa_name) != 0) + return 0; + + if (cf->cf_loc[0] != -1 && cf->cf_loc[0] != (int)aa->aa_unit->addr) + return 0; + + return (*cf->cf_attach->ca_match)(parent, cf, aa); +} + +void +iobusattach(struct device *parent, struct device *self, void *aux) +{ + uint i; + + /* + * Map and setup CRIME control registers. + */ + if (bus_space_map(&iobus_tag, OCTEON_CIU_BASE, OCTEON_CIU_SIZE, 0, + &iobus_h)) { + printf(": can't map CIU control registers\n"); + return; + } + + printf("\n"); + + octeon_intr_init(); + + /* + * Attach subdevices. + */ + for (i = 0; i < nitems(iobus_children); i++) + config_found_sm(self, iobus_children + i, + iobusprint, iobussubmatch); +} + +int +iobus_space_map(bus_space_tag_t t, bus_addr_t offs, bus_size_t size, + int flags, bus_space_handle_t *bshp) +{ + if (ISSET(flags, BUS_SPACE_MAP_KSEG0)) { + *bshp = PHYS_TO_CKSEG0(offs); + return 0; + } + if (ISSET(flags, BUS_SPACE_MAP_CACHEABLE)) + offs += + PHYS_TO_XKPHYS(0, CCA_CACHED) - PHYS_TO_XKPHYS(0, CCA_NC); + *bshp = t->bus_base + offs; + return 0; +} + +void +iobus_space_unmap(bus_space_tag_t t, bus_space_handle_t bsh, bus_size_t size) +{ +} + +/* + * Iobus bus_dma helpers. + */ + +bus_addr_t +iobus_pa_to_device(paddr_t pa) +{ + return (bus_addr_t)pa; +} + +paddr_t +iobus_device_to_pa(bus_addr_t addr) +{ + return (paddr_t)addr; +} diff --git a/sys/arch/octeon/dev/octeon_pcibus.c b/sys/arch/octeon/dev/octeon_pcibus.c index 3b0f36ffd44..97f2482895f 100644 --- a/sys/arch/octeon/dev/octeon_pcibus.c +++ b/sys/arch/octeon/dev/octeon_pcibus.c @@ -1,5 +1,5 @@ -/* $OpenBSD: octeon_pcibus.c,v 1.5 2010/12/04 20:01:05 syuu Exp $ */ -/* $OpenBSD: octeon_pcibus.c,v 1.5 2010/12/04 20:01:05 syuu Exp $ */ +/* $OpenBSD: octeon_pcibus.c,v 1.6 2011/05/08 13:24:55 syuu Exp $ */ +/* $OpenBSD: octeon_pcibus.c,v 1.6 2011/05/08 13:24:55 syuu Exp $ */ /* $NetBSD: bonito_mainbus.c,v 1.11 2008/04/28 20:23:10 martin Exp $ */ /* $NetBSD: bonito_pci.c,v 1.5 2008/04/28 20:23:28 martin Exp $ */ @@ -62,7 +62,7 @@ #include <dev/pci/pcivar.h> #include <dev/pci/ppbreg.h> -#include <octeon/dev/obiovar.h> +#include <octeon/dev/iobusvar.h> #include <octeon/dev/octeon_pcibus.h> #include <octeon/dev/octeon_pcibusvar.h> @@ -191,9 +191,9 @@ struct mips_bus_space octeon_pcibus_pci_mem_space_tag = { int octeon_pcibus_match(struct device *parent, void *vcf, void *aux) { - struct obio_attach_args *oba = aux; + struct iobus_attach_args *aa = aux; - if (strcmp(oba->oba_name, pcibus_cd.cd_name) == 0) + if (strcmp(aa->aa_name, pcibus_cd.cd_name) == 0) return 1; return 0; @@ -203,12 +203,12 @@ void octeon_pcibus_attach(struct device *parent, struct device *self, void *aux) { struct octeon_pcibus_softc *sc; - struct obio_attach_args *oba; + struct iobus_attach_args *aa; struct pcibus_attach_args pba; sc = (struct octeon_pcibus_softc *)self; - oba = aux; - sc->sc_oba = oba; + aa = aux; + sc->sc_aa = aa; /* * Attach PCI bus. @@ -413,20 +413,20 @@ void * octeon_pcibus_pci_intr_establish(void *cookie, pci_intr_handle_t ih, int level, int (*cb)(void *), void *cbarg, char *name) { - return obio_intr_establish(ih, level, cb, cbarg, name); + return octeon_intr_establish(ih, level, cb, cbarg, name); } void octeon_pcibus_pci_intr_disestablish(void *cookie, void *ihp) { struct octeon_pcibus_softc *sc; - struct obio_attach_args *oba; + struct iobus_attach_args *aa; sc = (struct octeon_pcibus_softc *)cookie; - oba = sc->sc_oba; + aa = sc->sc_aa; // XXX: this cause panic... -// obio_intr_disestablish(ihp); +// iobus_intr_disestablish(ihp); } /* diff --git a/sys/arch/octeon/dev/octeon_pcibusvar.h b/sys/arch/octeon/dev/octeon_pcibusvar.h index 85d5fc1865a..5e96db0071a 100644 --- a/sys/arch/octeon/dev/octeon_pcibusvar.h +++ b/sys/arch/octeon/dev/octeon_pcibusvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: octeon_pcibusvar.h,v 1.2 2010/12/04 16:46:35 miod Exp $ */ +/* $OpenBSD: octeon_pcibusvar.h,v 1.3 2011/05/08 13:24:55 syuu Exp $ */ /* $NetBSD: octeon_pcibusvar.h,v 1.4 2008/04/28 20:23:28 martin Exp $ */ /*- @@ -38,7 +38,7 @@ struct extent; struct octeon_pcibus_softc { struct device sc_dev; struct mips_pci_chipset sc_pc; - struct obio_attach_args *sc_oba; + struct iobus_attach_args *sc_aa; }; #ifdef _KERNEL diff --git a/sys/arch/octeon/include/intr.h b/sys/arch/octeon/include/intr.h index a73d1ecacda..d79c1b7d167 100644 --- a/sys/arch/octeon/include/intr.h +++ b/sys/arch/octeon/include/intr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: intr.h,v 1.1 2010/09/20 06:32:30 syuu Exp $ */ +/* $OpenBSD: intr.h,v 1.2 2011/05/08 13:24:55 syuu Exp $ */ /* * Copyright (c) 2001-2004 Opsycon AB (www.opsycon.se / www.opsycon.com) @@ -190,6 +190,12 @@ void dosoftint(void); #ifdef MULTIPROCESSOR #define ENABLEIPI() updateimask(~CR_INT_1) /* enable IPI interrupt level */ #endif +void octeon_intr_init(void); +void octeon_setintrmask(int); +void *octeon_intr_establish(int, int, int (*)(void *), + void *, const char *); +void octeon_intr_disestablish(void *); +void octeon_intr_init(void); #endif /* _LOCORE */ diff --git a/sys/arch/octeon/octeon/machdep.c b/sys/arch/octeon/octeon/machdep.c index 3842ccdc402..80d8e1ffb62 100644 --- a/sys/arch/octeon/octeon/machdep.c +++ b/sys/arch/octeon/octeon/machdep.c @@ -1,4 +1,4 @@ -/* $OpenBSD: machdep.c,v 1.7 2010/11/28 20:53:41 syuu Exp $ */ +/* $OpenBSD: machdep.c,v 1.8 2011/05/08 13:24:55 syuu Exp $ */ /* * Copyright (c) 2009, 2010 Miodrag Vallat. @@ -77,7 +77,7 @@ #include <mips64/archtype.h> -#include <octeon/dev/obiovar.h> +#include <octeon/dev/iobusvar.h> #include <octeon/dev/octeonreg.h> struct boot_desc { @@ -787,8 +787,8 @@ static int (*ipi_handler)(void *); uint32_t ipi_intr(uint32_t, struct trap_frame *); -extern bus_space_t obio_tag; -extern bus_space_handle_t obio_h; +extern bus_space_t iobus_tag; +extern bus_space_handle_t iobus_h; void hw_cpu_boot_secondary(struct cpu_info *ci) @@ -847,9 +847,9 @@ hw_cpu_hatch(struct cpu_info *ci) cpu_startclock(ci); ncpus++; cpuset_add(&cpus_running, ci); - obio_intr_init(); + octeon_intr_init(); mips64_ipi_init(); - obio_setintrmask(0); + octeon_setintrmask(0); spl0(); (void)updateimask(0); @@ -868,14 +868,14 @@ ipi_intr(uint32_t hwpend, struct trap_frame *frame) /* * Mask all pending interrupts. */ - bus_space_write_8(&obio_tag, obio_h, CIU_IP3_EN0(cpuid), 0); + bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid), 0); ipi_handler((void *)cpuid); /* * Reenable interrupts which have been serviced. */ - bus_space_write_8(&obio_tag, obio_h, CIU_IP3_EN0(cpuid), + bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid), (1ULL << CIU_INT_MBOX0)|(1ULL << CIU_INT_MBOX1)); return hwpend; } @@ -886,9 +886,9 @@ hw_ipi_intr_establish(int (*func)(void *), u_long cpuid) if (cpuid == 0) ipi_handler = func; - bus_space_write_8(&obio_tag, obio_h, CIU_MBOX_CLR(cpuid), + bus_space_write_8(&iobus_tag, iobus_h, CIU_MBOX_CLR(cpuid), 0xffffffff); - bus_space_write_8(&obio_tag, obio_h, CIU_IP3_EN0(cpuid), + bus_space_write_8(&iobus_tag, iobus_h, CIU_IP3_EN0(cpuid), (1ULL << CIU_INT_MBOX0)|(1ULL << CIU_INT_MBOX1)); set_intr(INTPRI_IPI, CR_INT_1, ipi_intr); @@ -898,15 +898,15 @@ hw_ipi_intr_establish(int (*func)(void *), u_long cpuid) void hw_ipi_intr_set(u_long cpuid) { - bus_space_write_8(&obio_tag, obio_h, CIU_MBOX_SET(cpuid), 1); + bus_space_write_8(&iobus_tag, iobus_h, CIU_MBOX_SET(cpuid), 1); } void hw_ipi_intr_clear(u_long cpuid) { uint64_t clr = - bus_space_read_8(&obio_tag, obio_h, CIU_MBOX_CLR(cpuid)); - bus_space_write_8(&obio_tag, obio_h, CIU_MBOX_CLR(cpuid), clr); + bus_space_read_8(&iobus_tag, iobus_h, CIU_MBOX_CLR(cpuid)); + bus_space_write_8(&iobus_tag, iobus_h, CIU_MBOX_CLR(cpuid), clr); } void |