summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKenji Aoyama <aoyama@cvs.openbsd.org>2015-03-03 23:50:38 +0000
committerKenji Aoyama <aoyama@cvs.openbsd.org>2015-03-03 23:50:38 +0000
commitef9a9578799ccdfca1e06e5ab4bc2b32cbd7da93 (patch)
tree44946957740d1a5f78cc44368e989652c35eb466
parent6470573f3a90a3c795eea22f4b415add107cddf7 (diff)
Add pcic(4) support on luna88k.
This is basically glue codes attaching pcic(4) at cbus(4/luna88k), based on src/sys/dev/isa/i82365_isa{,subr}.c. Tested on some ne(4) network interface cards, wdc(4) with a CF memory card, and com(4) with an old XJACK modem card. Currently wi(4) does not work yet. suggestions and ok miod@
-rw-r--r--sys/arch/luna88k/cbus/cbus.c6
-rw-r--r--sys/arch/luna88k/cbus/i82365_cbus.c537
-rw-r--r--sys/arch/luna88k/conf/files.luna88k27
-rw-r--r--sys/arch/luna88k/include/bus.h43
-rw-r--r--sys/arch/luna88k/include/conf.h9
-rw-r--r--sys/arch/luna88k/luna88k/conf.c10
-rw-r--r--sys/arch/m88k/m88k/softintr.c3
7 files changed, 613 insertions, 22 deletions
diff --git a/sys/arch/luna88k/cbus/cbus.c b/sys/arch/luna88k/cbus/cbus.c
index 82408c07366..5775d8d8e97 100644
--- a/sys/arch/luna88k/cbus/cbus.c
+++ b/sys/arch/luna88k/cbus/cbus.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: cbus.c,v 1.4 2015/02/18 22:42:04 aoyama Exp $ */
+/* $OpenBSD: cbus.c,v 1.5 2015/03/03 23:50:36 aoyama Exp $ */
/*
* Copyright (c) 2014 Kenji Aoyama.
@@ -37,11 +37,15 @@
#endif
#include "necsb.h"
+#include "pcic.h"
static struct cbus_attach_args cbus_devs[] = {
#if NNECSB > 0
{ "necsb", -1 }, /* PC-9801-86 sound board */
#endif
+#if NPCIC > 0
+ { "pcic", -1 }, /* PC-9801-102 & PC-9821X[AE]-01 PCMCIA board */
+#endif
{ "pcex", -1 } /* C-bus "generic" driver */
};
diff --git a/sys/arch/luna88k/cbus/i82365_cbus.c b/sys/arch/luna88k/cbus/i82365_cbus.c
new file mode 100644
index 00000000000..78da51ad2bf
--- /dev/null
+++ b/sys/arch/luna88k/cbus/i82365_cbus.c
@@ -0,0 +1,537 @@
+/* $OpenBSD: i82365_cbus.c,v 1.1 2015/03/03 23:50:36 aoyama Exp $ */
+/* $NetBSD: i82365_isa.c,v 1.11 1998/06/09 07:25:00 thorpej Exp $ */
+
+/*
+ * Copyright (c) 1997 Marc Horowitz. All rights reserved.
+ *
+ * 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.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by Marc Horowitz.
+ * 4. The name of the author may not be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * 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.
+ */
+
+/*
+ * Driver for PC-9801-102 & PC-9821X[AE]-E01 PC Card slot adapter
+ * based on OpenBSD:src/sys/dev/isa/i82365_isa{,subr}.c
+ */
+
+#include <sys/types.h>
+#include <sys/param.h>
+#include <sys/systm.h>
+#include <sys/kernel.h>
+#include <sys/device.h>
+#include <sys/extent.h>
+#include <sys/malloc.h>
+
+#include <machine/board.h> /* PC_BASE */
+#include <machine/bus.h>
+#include <machine/intr.h>
+
+#include <arch/luna88k/cbus/cbusvar.h>
+
+#include <dev/pcmcia/pcmciareg.h>
+#include <dev/pcmcia/pcmciavar.h>
+#include <dev/pcmcia/pcmciachip.h>
+
+#include <dev/ic/i82365reg.h>
+#include <dev/ic/i82365var.h>
+
+#ifdef PCICCBUSDEBUG
+#define DPRINTF(arg) printf arg;
+#else
+#define DPRINTF(arg)
+#endif
+
+/*
+ * XXX:
+ * The C-bus expects edge-triggered interrupts, but some PC Cards and
+ * the controller itself produce level-triggered interrupts. This causes
+ * spurious interrupts on C-bus.
+ * Then, we use CL-PD67XX 'pulse IRQ' feature in this driver. This seems
+ * to solve stray interrupts on C-bus.
+ * (BTW, all NEC genuine C-bus PC Card slot adapters use CL-PD67XX)
+ */
+
+/* Cirrus Logic CL-PD67XX Misc Control register */
+#define PCIC_CIRRUS_MISC_CTL_1 0x16
+#define PCIC_CIRRUS_MISC_CTL_1_PULSE_MGMT_INTR 0x04
+#define PCIC_CIRRUS_MISC_CTL_1_PULSE_SYS_IRQ 0x08
+
+/* XXX: should be passed by cbus_attach_args */
+#define PCIC_CBUS_IOBASE 0x3e0
+#define PCIC_CBUS_MEMBASE 0xd0000
+
+#define PCEXMEM_BASE PC_BASE
+#define PCEXIO_BASE PC_BASE + 0x1000000
+
+/* prototypes */
+void *pcic_cbus_chip_intr_establish(pcmcia_chipset_handle_t,
+ struct pcmcia_function *, int, int (*) (void *), void *, char *);
+void pcic_cbus_chip_intr_disestablish(pcmcia_chipset_handle_t, void *);
+const char *pcic_cbus_chip_intr_string(pcmcia_chipset_handle_t, void *);
+int pcic_cbus_intlevel_find(void);
+int pcic_cbus_chip_io_alloc(pcmcia_chipset_handle_t, bus_addr_t,
+ bus_size_t, bus_size_t, struct pcmcia_io_handle *);
+void pcic_cbus_chip_io_free(pcmcia_chipset_handle_t,
+ struct pcmcia_io_handle *);
+
+int pcic_cbus_probe(struct device *, void *, void *);
+void pcic_cbus_attach(struct device *, struct device *, void *);
+
+/* bus space tag for pcic_cbus */
+struct luna88k_bus_space_tag pcic_cbus_io_bst = {
+ .bs_stride_1 = 1,
+ .bs_stride_2 = 0, /* not used */
+ .bs_stride_4 = 0, /* not used */
+ .bs_stride_8 = 0, /* not used */
+ .bs_offset = PCEXIO_BASE,
+ .bs_flags = TAG_LITTLE_ENDIAN
+};
+
+struct luna88k_bus_space_tag pcic_cbus_mem_bst = {
+ .bs_stride_1 = 1,
+ .bs_stride_2 = 0, /* not used */
+ .bs_stride_4 = 0, /* not used */
+ .bs_stride_8 = 0, /* not used */
+ .bs_offset = PCEXMEM_BASE,
+ .bs_flags = TAG_LITTLE_ENDIAN
+};
+
+struct cfattach pcic_cbus_ca = {
+ sizeof(struct pcic_softc), pcic_cbus_probe, pcic_cbus_attach
+};
+
+static struct pcmcia_chip_functions pcic_cbus_functions = {
+ .mem_alloc = pcic_chip_mem_alloc,
+ .mem_free = pcic_chip_mem_free,
+ .mem_map = pcic_chip_mem_map,
+ .mem_unmap = pcic_chip_mem_unmap,
+
+ .io_alloc = pcic_cbus_chip_io_alloc,
+ .io_free = pcic_cbus_chip_io_free,
+ .io_map = pcic_chip_io_map,
+ .io_unmap = pcic_chip_io_unmap,
+
+ .intr_establish = pcic_cbus_chip_intr_establish,
+ .intr_disestablish = pcic_cbus_chip_intr_disestablish,
+ .intr_string = pcic_cbus_chip_intr_string,
+
+ .socket_enable = pcic_chip_socket_enable,
+ .socket_disable = pcic_chip_socket_disable,
+};
+
+/*
+ * NEC PC-9801 architecture uses different IRQ notation from PC-AT
+ * architecture, so-called INT. The MI pcic(4) driver internally uses
+ * IRQ, so here is a table to convert INT to IRQ.
+ */
+static const int pcic_cbus_int2irq[NCBUSISR] = {
+ PCIC_INTR_IRQ3, /* INT 0 */
+ PCIC_INTR_IRQ5, /* INT 1 */
+ PCIC_INTR_IRQ_RESERVED6, /* INT 2 */
+ PCIC_INTR_IRQ9, /* INT 3 */
+ PCIC_INTR_IRQ10, /* INT 4(41) */
+ PCIC_INTR_IRQ12, /* INT 5 */
+ PCIC_INTR_IRQ_RESERVED13 /* INT 6 */
+};
+
+/* And, a table to convert IRQ to INT */
+static const int pcic_cbus_irq2int[] = {
+ -1, -1, -1, 0, -1, 1, 2, -1, /* IRQ 0- 7 */
+ -1, 3, 4, -1, 5, 6, -1, -1 /* IRQ 8-15 */
+};
+
+struct pcic_ranges pcic_cbus_addr[] = {
+ { 0x340, 0x030 },
+ { 0x300, 0x030 },
+ { 0x390, 0x020 },
+ { 0x400, 0xbff },
+ { 0, 0}, /* terminator */
+};
+
+int
+pcic_cbus_probe(parent, match, aux)
+ struct device *parent;
+ void *match, *aux;
+{
+#if 0 /* should be use cbus_attach_args in the future */
+ struct cbus_attach_args *caa = aux;
+#endif
+ bus_space_tag_t iot = &pcic_cbus_io_bst;
+ bus_space_handle_t ioh;
+ int val, found;
+
+ SET_TAG_LITTLE_ENDIAN(iot);
+
+ if (bus_space_map(iot, PCIC_CBUS_IOBASE, PCIC_IOSIZE, 0, &ioh))
+ return (0);
+ found = 0;
+
+ /*
+ * this could be done with a loop, but it would violate the
+ * abstraction
+ */
+
+ bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SA + PCIC_IDENT);
+ val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
+ if (pcic_ident_ok(val))
+ found++;
+
+ bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C0SB + PCIC_IDENT);
+ val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
+ if (pcic_ident_ok(val))
+ found++;
+
+ bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SA + PCIC_IDENT);
+ val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
+ if (pcic_ident_ok(val))
+ found++;
+
+ bus_space_write_1(iot, ioh, PCIC_REG_INDEX, C1SB + PCIC_IDENT);
+ val = bus_space_read_1(iot, ioh, PCIC_REG_DATA);
+ if (pcic_ident_ok(val))
+ found++;
+
+ bus_space_unmap(iot, ioh, PCIC_IOSIZE);
+
+ if (!found)
+ return (0);
+
+ return (1);
+}
+
+void
+pcic_cbus_attach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+#if 0 /* should be use cbus_attach_args in the future */
+ struct cbus_attach_args *caa = aux;
+#endif
+ struct pcic_softc *sc = (void *)self;
+ struct pcic_handle *h;
+ bus_space_tag_t iot = &pcic_cbus_io_bst;
+ bus_space_tag_t memt = &pcic_cbus_mem_bst;
+ bus_space_handle_t ioh, memh;
+ int intlevel, irq, i, reg;
+
+ SET_TAG_LITTLE_ENDIAN(iot);
+ SET_TAG_LITTLE_ENDIAN(memt);
+
+ /* Map i/o space. */
+ if (bus_space_map(iot, PCIC_CBUS_IOBASE, PCIC_IOSIZE, 0, &ioh)) {
+ printf(": can't map i/o space\n");
+ return;
+ }
+
+ /* Map mem space. */
+ if (bus_space_map(memt, PCIC_CBUS_MEMBASE, PCIC_MEMSIZE, 0, &memh)) {
+ printf(": can't map mem space\n");
+ return;
+ }
+
+ sc->membase = PCIC_CBUS_MEMBASE;
+ sc->subregionmask = (1 << (PCIC_MEMSIZE / PCIC_MEM_PAGESIZE)) - 1;
+
+ sc->intr_est = NULL; /* not used on luna88k */
+ sc->pct = (pcmcia_chipset_tag_t)&pcic_cbus_functions;
+
+ sc->iot = iot;
+ sc->ioh = ioh;
+ sc->memt = memt;
+ sc->memh = memh;
+
+ printf("\n");
+
+ pcic_attach(sc);
+
+ sc->ranges = pcic_cbus_addr;
+ sc->iobase = 0x0000;
+ sc->iosize = 0x1000;
+ DPRINTF(("%s: bus_space_alloc range 0x%04lx-0x%04lx\n",
+ sc->dev.dv_xname, (long) sc->iobase,
+ (long) sc->iobase + sc->iosize));
+
+ pcic_attach_sockets(sc);
+
+ /*
+ * Allocate an INT. It will be used by both controllers. We could
+ * use two different interrupts, but interrupts are relatively
+ * scarce, shareable, and for PCIC controllers, very infrequent.
+ */
+ intlevel = pcic_cbus_intlevel_find();
+ if (intlevel == -1) {
+ printf("pcic_cbus_attach: no free INT found\n");
+ return;
+ }
+
+ irq = pcic_cbus_int2irq[intlevel];
+ cbus_isrlink(pcic_intr, sc, intlevel, IPL_TTY, sc->dev.dv_xname);
+ sc->ih = (void *)pcic_intr;
+ sc->irq = irq;
+
+ if (irq) {
+ printf("%s: INT%d (irq %d), ", sc->dev.dv_xname,
+ intlevel, irq);
+
+ /* Set up the pcic to interrupt on card detect. */
+ for (i = 0; i < PCIC_NSLOTS; i++) {
+ h = &sc->handle[i];
+ if (h->flags & PCIC_FLAG_SOCKETP) {
+ /* set 'pulse management interrupt' mode */
+ reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_1);
+ reg |= PCIC_CIRRUS_MISC_CTL_1_PULSE_MGMT_INTR;
+ pcic_write(h, PCIC_CIRRUS_MISC_CTL_1, reg);
+
+ pcic_write(h, PCIC_CSC_INTR,
+ (sc->irq << PCIC_CSC_INTR_IRQ_SHIFT) |
+ PCIC_CSC_INTR_CD_ENABLE);
+ }
+ }
+ } else
+ printf("%s: no irq, ", sc->dev.dv_xname);
+
+ printf("polling enabled\n");
+ if (sc->poll_established == 0) {
+ timeout_set(&sc->poll_timeout, pcic_poll_intr, sc);
+ timeout_add_msec(&sc->poll_timeout, 500);
+ sc->poll_established = 1;
+ }
+}
+
+void *
+pcic_cbus_chip_intr_establish(pcmcia_chipset_handle_t pch,
+ struct pcmcia_function *pf, int ipl, int (*fcl)(void *),
+ void *arg, char *xname)
+{
+ struct pcic_handle *h = (struct pcic_handle *)pch;
+#ifdef PCICCBUSDEBUG
+ struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
+#endif
+ int intlevel, irq, reg;
+
+#ifdef PCICCBUSDEBUG
+ char buf[16];
+ if (pf->cfe->flags & PCMCIA_CFE_IRQLEVEL)
+ strlcpy(buf, "LEVEL", sizeof(buf));
+ else if (pf->cfe->flags & PCMCIA_CFE_IRQPULSE)
+ strlcpy(buf, "PULSE", sizeof(buf));
+ else
+ strlcpy(buf, "EDGE", sizeof(buf));
+ printf("pcic_cbus_chip_intr_establish: IST_%s\n", buf);
+#endif
+
+ /*
+ * If the PC Card has level-triggered interrupt property,
+ * we use CL-PD67XX 'pulse IRQ' feature.
+ */
+ if (pf->cfe->flags & PCMCIA_CFE_IRQLEVEL) {
+ reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_1);
+ reg |= PCIC_CIRRUS_MISC_CTL_1_PULSE_SYS_IRQ;
+ pcic_write(h, PCIC_CIRRUS_MISC_CTL_1, reg);
+ }
+
+ intlevel = pcic_cbus_intlevel_find();
+
+ if (intlevel == -1) {
+ printf("pcic_cbus_chip_intr_establish: no INT found\n");
+ return (NULL);
+ }
+
+ irq = pcic_cbus_int2irq[intlevel];
+ h->ih_irq = irq;
+
+ DPRINTF(("%s: pcic_cbus_chip_intr_establish INT%d (irq %d)\n",
+ sc->dev.dv_xname, intlevel, h->ih_irq));
+
+ cbus_isrlink(fcl, arg, intlevel, ipl, h->pcmcia->dv_xname);
+
+ reg = pcic_read(h, PCIC_INTR);
+ reg &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE);
+ pcic_write(h, PCIC_INTR, reg | irq);
+
+ return (void *)fcl;
+}
+
+void
+pcic_cbus_chip_intr_disestablish(pcmcia_chipset_handle_t pch, void *ih)
+{
+ struct pcic_handle *h = (struct pcic_handle *)pch;
+#ifdef PCICCBUSDEBUG
+ struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
+#endif
+ int intlevel, reg;
+
+ intlevel = pcic_cbus_irq2int[h->ih_irq];
+
+ DPRINTF(("%s: pcic_cbus_chip_intr_disestablish INT%d (irq %d)\n",
+ sc->dev.dv_xname, intlevel, h->ih_irq));
+
+ if (intlevel == -1) {
+ printf("pcic_cbus_chip_intr_disestablish: "
+ "strange INT (irq = %d)\n", h->ih_irq);
+ return;
+ }
+
+ h->ih_irq = 0;
+
+ reg = pcic_read(h, PCIC_INTR);
+ reg &= ~(PCIC_INTR_IRQ_MASK | PCIC_INTR_ENABLE);
+ pcic_write(h, PCIC_INTR, reg);
+
+ cbus_isrunlink(ih, intlevel);
+
+ /* reset the 'pulse IRQ' mode */
+ reg = pcic_read(h, PCIC_CIRRUS_MISC_CTL_1);
+ reg &= ~PCIC_CIRRUS_MISC_CTL_1_PULSE_SYS_IRQ;
+ pcic_write(h, PCIC_CIRRUS_MISC_CTL_1, reg);
+}
+
+const char *
+pcic_cbus_chip_intr_string(pcmcia_chipset_handle_t pch, void *ih)
+{
+ struct pcic_handle *h = (struct pcic_handle *)pch;
+ static char irqstr[64];
+
+ if (ih == NULL)
+ snprintf(irqstr, sizeof(irqstr),
+ "couldn't establish interrupt");
+ else
+ snprintf(irqstr, sizeof(irqstr), "INT%d (irq %d)",
+ pcic_cbus_irq2int[h->ih_irq], h->ih_irq);
+ return(irqstr);
+}
+
+/*
+ * Find a free and pcic-compliant INT level; searching from highest
+ * (=small number) to lowest.
+ */
+int
+pcic_cbus_intlevel_find(void)
+{
+ int intlevel, irq;
+ u_int8_t cbus_not_used = ~cbus_intr_registered();
+
+ for (intlevel = 0; intlevel < NCBUSISR; intlevel++)
+ if (cbus_not_used & (1 << (6 - intlevel))) {
+ irq = pcic_cbus_int2irq[intlevel];
+ if ((1 << irq) & PCIC_INTR_IRQ_VALIDMASK)
+ break;
+ }
+
+ if (intlevel == NCBUSISR)
+ intlevel = -1; /* not found */
+
+ return intlevel;
+}
+
+/*
+ * LUNA specific pcic_cbus_chip_io_{alloc,free}
+ */
+int
+pcic_cbus_chip_io_alloc(pcmcia_chipset_handle_t pch, bus_addr_t start,
+ bus_size_t size, bus_size_t align, struct pcmcia_io_handle *pcihp)
+{
+ struct pcic_handle *h = (struct pcic_handle *) pch;
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ bus_addr_t ioaddr, beg, fin;
+ int flags = 0;
+ struct pcic_softc *sc = (struct pcic_softc *)(h->ph_parent);
+ struct pcic_ranges *range;
+
+ /*
+ * Allocate some arbitrary I/O space.
+ */
+
+ iot = sc->iot;
+
+ if (start) {
+ ioaddr = start;
+ if (bus_space_map(iot, start, size, 0, &ioh))
+ return (1);
+ DPRINTF(("pcic_chip_io_alloc map port %lx+%lx\n",
+ (u_long)ioaddr, (u_long)size));
+ } else if (sc->ranges) {
+ /*
+ * In this case, we know the "size" and "align" that
+ * we want. So we need to start walking down
+ * sc->ranges, searching for a similar space that
+ * is (1) large enough for the size and alignment
+ * (2) then we need to try to allocate
+ * (3) if it fails to allocate, we try next range.
+ *
+ * We must also check that the start/size of each
+ * allocation we are about to do is within the bounds
+ * of "sc->iobase" and "sc->iosize".
+ * (Some pcmcia controllers handle a 12 bits of addressing,
+ * but we want to use the same range structure)
+ */
+ for (range = sc->ranges; range->start; range++) {
+ /* Potentially trim the range because of bounds. */
+ beg = max(range->start, sc->iobase);
+ fin = min(range->start + range->len,
+ sc->iobase + sc->iosize);
+
+ /* Short-circuit easy cases. */
+ if (fin < beg || fin - beg < size)
+ continue;
+
+ DPRINTF(("pcic_chip_io_alloc beg-fin %lx-%lx\n",
+ (u_long)beg, (u_long)fin));
+ if (bus_space_map(iot, beg, size, 0, &ioh) == 0) {
+ ioaddr = beg;
+ break;
+ }
+ }
+ if (range->start == 0)
+ return (1);
+ DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
+ (u_long)ioaddr, (u_long)size));
+ } else {
+ if (bus_space_map(iot, sc->iobase, size, 0, &ioh))
+ return (1);
+ ioaddr = sc->iobase;
+ DPRINTF(("pcic_chip_io_alloc alloc port %lx+%lx\n",
+ (u_long)ioaddr, (u_long)size));
+ }
+
+ pcihp->iot = iot;
+ pcihp->ioh = ioh;
+ pcihp->addr = ioaddr;
+ pcihp->size = size;
+ pcihp->flags = flags;
+
+ return (0);
+}
+
+void
+pcic_cbus_chip_io_free(pcmcia_chipset_handle_t pch,
+ struct pcmcia_io_handle *pcihp)
+{
+ bus_space_tag_t iot = pcihp->iot;
+ bus_space_handle_t ioh = pcihp->ioh;
+ bus_size_t size = pcihp->size;
+
+ bus_space_unmap(iot, ioh, size);
+}
diff --git a/sys/arch/luna88k/conf/files.luna88k b/sys/arch/luna88k/conf/files.luna88k
index 6c73e88478f..837969ad6e3 100644
--- a/sys/arch/luna88k/conf/files.luna88k
+++ b/sys/arch/luna88k/conf/files.luna88k
@@ -1,4 +1,4 @@
-# $OpenBSD: files.luna88k,v 1.25 2015/01/17 08:26:10 aoyama Exp $
+# $OpenBSD: files.luna88k,v 1.26 2015/03/03 23:50:37 aoyama Exp $
#
maxpartitions 16
@@ -52,6 +52,7 @@ major {st = 5}
major {cd = 6}
major {rd = 7}
major {vnd = 8}
+major {wd = 9}
device spc: scsi
attach spc at mainbus
@@ -67,11 +68,25 @@ attach pcex at cbus
file arch/luna88k/cbus/pcex.c pcex needs-flag
# NEC PC-9801-86 sound board
-device necsb: audio, auconv, mulaw
-attach necsb at cbus
-file arch/luna88k/cbus/necsb.c necsb needs-flag
-file arch/luna88k/cbus/nec86.c necsb needs-flag
-file arch/luna88k/cbus/nec86hw.c necsb needs-flag
+device necsb: audio, auconv, mulaw
+attach necsb at cbus
+file arch/luna88k/cbus/necsb.c necsb needs-flag
+file arch/luna88k/cbus/nec86.c necsb needs-flag
+file arch/luna88k/cbus/nec86hw.c necsb needs-flag
+
+# PCMCIA devices via NEC PC-9801-102 / PC-9821X[AE]-E01
+device pcic: pcmciabus
+attach pcic at cbus with pcic_cbus
+file dev/ic/i82365.c pcic needs-flag
+file arch/luna88k/cbus/i82365_cbus.c pcic needs-flag
+include "dev/pcmcia/files.pcmcia"
+
+# Media Independent Interface (mii), used with PCMCIA
+include "dev/mii/files.mii"
+
+# Machine-independent ATAPI drivers, used with PCMCIA
+include "dev/atapiscsi/files.atapiscsi"
+include "dev/ata/files.ata"
# list of standard files
file arch/luna88k/luna88k/clock.c
diff --git a/sys/arch/luna88k/include/bus.h b/sys/arch/luna88k/include/bus.h
index 49afebd81d0..64ef603ccaf 100644
--- a/sys/arch/luna88k/include/bus.h
+++ b/sys/arch/luna88k/include/bus.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: bus.h,v 1.9 2015/02/14 14:54:13 aoyama Exp $ */
+/* $OpenBSD: bus.h,v 1.10 2015/03/03 23:50:37 aoyama Exp $ */
/* $NetBSD: bus.h,v 1.9 1998/01/13 18:32:15 scottr Exp $ */
/*-
@@ -79,8 +79,15 @@ struct luna88k_bus_space_tag {
uint8_t bs_stride_4;
uint8_t bs_stride_8;
bus_size_t bs_offset;
+ uint bs_flags;
+#define TAG_LITTLE_ENDIAN 0x01
};
+#define SET_TAG_BIG_ENDIAN(t) ((t))->bs_flags &= ~TAG_LITTLE_ENDIAN
+#define SET_TAG_LITTLE_ENDIAN(t) ((t))->bs_flags |= TAG_LITTLE_ENDIAN
+
+#define IS_TAG_LITTLE_ENDIAN(t) ((t)->bs_flags & TAG_LITTLE_ENDIAN)
+
/*
* int bus_space_map(bus_space_tag_t t, bus_addr_t addr,
* bus_size_t size, int flags, bus_space_handle_t *bshp);
@@ -171,12 +178,22 @@ bus_space_free(bus_space_tag_t tag, bus_space_handle_t handle, bus_size_t size)
#define bus_space_read_1(t, h, o) \
(*(volatile u_int8_t *)((h) + (t->bs_stride_1) * (o)))
-#define bus_space_read_2(t, h, o) \
+#define __bus_space_read_2(t, h, o) \
(*(volatile u_int16_t *)((h) + (t->bs_stride_2) * (o)))
-#define bus_space_read_4(t, h, o) \
+#define __bus_space_read_4(t, h, o) \
(*(volatile u_int32_t *)((h) + (t->bs_stride_4) * (o)))
+#define bus_space_read_2(t, h, o) \
+ ((IS_TAG_LITTLE_ENDIAN(t)) ? \
+ letoh16(__bus_space_read_2(t, h, o)) : \
+ __bus_space_read_2(t, h, o))
+
+#define bus_space_read_4(t, h, o) \
+ ((IS_TAG_LITTLE_ENDIAN(t)) ? \
+ letoh32(__bus_space_read_4(t, h, o)) : \
+ __bus_space_read_4(t, h, o))
+
#if 0 /* Cause a link error for bus_space_read_8 */
#define bus_space_read_8(t, h, o) !!! bus_space_read_8 unimplemented !!!
#endif
@@ -225,7 +242,7 @@ bus_space_read_raw_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
size >>= 1;
while ((int)--size >= 0) {
*(u_int16_t *)dest =
- bus_space_read_2(tag, handle, offset);
+ __bus_space_read_2(tag, handle, offset);
dest += 2;
}
}
@@ -237,7 +254,7 @@ bus_space_read_raw_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
size >>= 2;
while ((int)--size >= 0) {
*(u_int32_t *)dest =
- bus_space_read_4(tag, handle, offset);
+ __bus_space_read_4(tag, handle, offset);
dest += 4;
}
}
@@ -296,12 +313,20 @@ bus_space_read_region_4(bus_space_tag_t tag, bus_space_handle_t handle,
#define bus_space_write_1(t, h, o, v) \
((void)(*(volatile u_int8_t *)((h) + (t->bs_stride_1) * (o)) = (v)))
-#define bus_space_write_2(t, h, o, v) \
+#define __bus_space_write_2(t, h, o, v) \
((void)(*(volatile u_int16_t *)((h) + (t->bs_stride_2) * (o)) = (v)))
-#define bus_space_write_4(t, h, o, v) \
+#define __bus_space_write_4(t, h, o, v) \
((void)(*(volatile u_int32_t *)((h) + (t->bs_stride_4) * (o)) = (v)))
+#define bus_space_write_2(t, h, o, v) \
+ __bus_space_write_2(t, h, o, \
+ (IS_TAG_LITTLE_ENDIAN(t)) ? htole16(v) : (v))
+
+#define bus_space_write_4(t, h, o, v) \
+ __bus_space_write_4(t, h, o, \
+ (IS_TAG_LITTLE_ENDIAN(t)) ? htole32(v) : (v))
+
#if 0 /* Cause a link error for bus_space_write_8 */
#define bus_space_write_8 !!! bus_space_write_8 not implemented !!!
#endif
@@ -350,7 +375,7 @@ bus_space_write_raw_multi_2(bus_space_tag_t tag, bus_space_handle_t handle,
{
size >>= 1;
while ((int)--size >= 0) {
- bus_space_write_2(tag, handle, offset,*(u_int16_t *)dest);
+ __bus_space_write_2(tag, handle, offset,*(u_int16_t *)dest);
dest += 2;
}
}
@@ -361,7 +386,7 @@ bus_space_write_raw_multi_4(bus_space_tag_t tag, bus_space_handle_t handle,
{
size >>= 2;
while ((int)--size >= 0) {
- bus_space_write_4(tag, handle, offset, *(u_int32_t *)dest);
+ __bus_space_write_4(tag, handle, offset, *(u_int32_t *)dest);
dest += 4;
}
}
diff --git a/sys/arch/luna88k/include/conf.h b/sys/arch/luna88k/include/conf.h
index b7799146f87..d4cb26a62d4 100644
--- a/sys/arch/luna88k/include/conf.h
+++ b/sys/arch/luna88k/include/conf.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.h,v 1.3 2014/04/16 12:01:33 aoyama Exp $ */
+/* $OpenBSD: conf.h,v 1.4 2015/03/03 23:50:37 aoyama Exp $ */
/*
* Copyright (c) 2004, Miodrag Vallat.
* All rights reserved.
@@ -39,6 +39,13 @@ cdev_decl(lcd);
cdev_decl(pcex);
+/* devices on PCMCIA */
+/* block devices */
+bdev_decl(wd);
+/* character devices */
+cdev_decl(com);
+cdev_decl(wd);
+
/* open, close, write, ioctl */
#define cdev_lcd_init(c,n) { \
dev_init(c,n,open), dev_init(c,n,close), \
diff --git a/sys/arch/luna88k/luna88k/conf.c b/sys/arch/luna88k/luna88k/conf.c
index 5132b8632b6..c6d045d4636 100644
--- a/sys/arch/luna88k/luna88k/conf.c
+++ b/sys/arch/luna88k/luna88k/conf.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: conf.c,v 1.25 2014/12/28 13:03:18 aoyama Exp $ */
+/* $OpenBSD: conf.c,v 1.26 2015/03/03 23:50:37 aoyama Exp $ */
/*-
* Copyright (c) 1991 The Regents of the University of California.
@@ -51,10 +51,12 @@
#include "sd.h"
#include "st.h"
#include "uk.h"
+#include "wd.h"
#include "ksyms.h"
#include "audio.h"
+#include "com.h"
#include "lcd.h"
#include "pcex.h"
#include "siotty.h"
@@ -81,7 +83,7 @@ struct bdevsw bdevsw[] =
bdev_disk_init(NCD,cd), /* 6: SCSI CD-ROM */
bdev_disk_init(NRD,rd), /* 7: ramdisk */
bdev_disk_init(NVND,vnd), /* 8: vnode disk driver */
- bdev_notdef(), /* 9: was: concatenated disk driver */
+ bdev_disk_init(NWD,wd), /* 9: IDE disk (on PCMCIA) */
bdev_notdef(), /* 10 */
bdev_notdef(), /* 11 */
bdev_notdef(), /* 12 */
@@ -125,8 +127,8 @@ struct cdevsw cdevsw[] =
cdev_notdef(), /* 24 was LKM */
cdev_pcex_init(NPCEX, pcex), /* 25: PC-9801 extension board slot */
cdev_audio_init(NAUDIO, audio), /* 26: generic audio I/O */
- cdev_notdef(), /* 27 */
- cdev_notdef(), /* 28 */
+ cdev_tty_init(NCOM, com), /* 27: serial port (on PCMCIA) */
+ cdev_disk_init(NWD,wd), /* 28: IDE disk (on PCMCIA) */
cdev_notdef(), /* 29 */
cdev_notdef(), /* 30 */
cdev_notdef(), /* 31 */
diff --git a/sys/arch/m88k/m88k/softintr.c b/sys/arch/m88k/m88k/softintr.c
index fb466c67a2a..aec859a55d7 100644
--- a/sys/arch/m88k/m88k/softintr.c
+++ b/sys/arch/m88k/m88k/softintr.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: softintr.c,v 1.5 2014/12/24 22:48:27 miod Exp $ */
+/* $OpenBSD: softintr.c,v 1.6 2015/03/03 23:50:37 aoyama Exp $ */
/* $NetBSD: softintr.c,v 1.2 2003/07/15 00:24:39 lukem Exp $ */
/*
@@ -113,6 +113,7 @@ softintr_establish(int ipl, void (*func)(void *), void *arg)
case IPL_SOFTNET:
si = SI_SOFTNET;
break;
+ case IPL_TTY:
case IPL_SOFTTTY:
si = SI_SOFTTTY;
break;