summaryrefslogtreecommitdiff
path: root/2003
diff options
context:
space:
mode:
Diffstat (limited to '2003')
-rw-r--r--2003/i/buzz/src/kernel/pbus.c326
-rw-r--r--2003/i/buzz/src/kernel/pbus.h24
2 files changed, 350 insertions, 0 deletions
diff --git a/2003/i/buzz/src/kernel/pbus.c b/2003/i/buzz/src/kernel/pbus.c
new file mode 100644
index 0000000..277428a
--- /dev/null
+++ b/2003/i/buzz/src/kernel/pbus.c
@@ -0,0 +1,326 @@
+#include <sys/param.h>
+#include <sys/kernel.h>
+#include <sys/malloc.h>
+#include <sys/systm.h>
+#include <sys/buf.h>
+#include <sys/device.h>
+#include <sys/proc.h>
+#include <sys/conf.h>
+#include <sys/ioctl.h>
+
+#include <ioconf.h>
+#include <machine/bonito_io.h>
+#include <arch/bonito/dev/tests/pbus.h>
+
+
+/* autoconfig stuff... */
+
+#define BUFSZ (256<<10)
+#define DMASIZE (2*BUFSZ)
+
+struct pbus_softc {
+ struct device sc_dev; /* REQUIRED first entry */
+ void *sc_ih; /* interrupt handle */
+ bus_space_tag_t iot;
+ bus_space_handle_t ioh;
+ bus_dma_tag_t dmat;
+ unsigned long iobase;
+ bus_dmamap_t sc_dmam; /* bus dma map */
+ unsigned char *sc_cpudma; /* dma memory space from cpu space*/
+ unsigned long sc_bonitodma; /* dma memory space from pci space*/
+ unsigned long sc_dmasize; /* dma buffer size */
+ struct proc *cproc; /* Control process */
+ int csignal; /* Control signal */
+ int in_dma;
+ int buf_ok;
+ int framesize;
+ int buf_consumed;
+ int pbusinten;
+};
+
+static int pbusprobe(struct device *, struct cfdata *, void *);
+static void pbusattach(struct device *, struct device *, void *);
+
+struct cfattach pbus_ca = {
+ sizeof(struct pbus_softc), pbusprobe, pbusattach
+};
+
+#define BUFSYNC_PRE \
+ bus_dmamap_sync(sc->dmat,sc->sc_dmam,0,DMASIZE,BUS_DMASYNC_PREREAD)
+#define BUFSYNC_POST \
+ bus_dmamap_sync(sc->dmat,sc->sc_dmam,0,DMASIZE,BUS_DMASYNC_POSTREAD)
+
+#define PBUS_WRITE_4(reg, val) \
+ bus_space_write_4(sc->iot, sc->ioh, reg, val)
+#define PBUS_READ_4(reg) \
+ bus_space_read_4(sc->iot, sc->ioh, reg)
+
+static int
+pbusprobe(struct device *parent, struct cfdata *cf, void *aux)
+{
+ struct bonito_io_attach *bia = aux;
+ struct pbus_softc scp;
+ struct pbus_softc *sc=&scp;
+ sc->iobase=bia->base;
+
+ return 1;
+}
+
+int pbus_intr(void *p);
+
+static void
+pbusattach(parent, self, aux)
+ struct device *parent, *self;
+ void *aux;
+{
+ bus_dma_segment_t seg;
+ int rseg;
+ struct bonito_io_attach *bia = aux;
+ struct pbus_softc *sc = (struct pbus_softc *)self;
+
+ sc->iot=bia->iot;
+ sc->dmat=bia->dmat;
+ bus_space_map(sc->iot, bia->base, 12, 0, &(sc->ioh));
+
+ sc->iobase=(unsigned long)sc->ioh;
+ printf("\n");
+
+
+ PBUS_WRITE_4(0x08,PBUS_RnW|PBUS_CLK);
+ PBUS_WRITE_4(0x0,0);
+ sc->sc_dmasize=DMASIZE;
+ sc->in_dma=0;
+ sc->buf_ok=0;
+ sc->framesize=BUFSZ;
+ sc->csignal=SIGUSR1;
+ sc->pbusinten=0;
+ sc->buf_consumed=0;
+
+ /*
+ * Allocate a DMA area for the card.
+ */
+ if (bus_dmamem_alloc(sc->dmat, sc->sc_dmasize, NBPG, 0, &seg, 1,
+ &rseg, BUS_DMA_NOWAIT|BUS_DMA_DIRECT))
+ {
+ printf("%s: couldn't allocate DMA\n",
+ sc->sc_dev.dv_xname);
+ return;
+ }
+ if (bus_dmamem_map(sc->dmat, &seg, rseg, sc->sc_dmasize,
+ (caddr_t *)&sc->sc_cpudma,
+ BUS_DMA_NOWAIT|BUS_DMA_DIRECT))
+ {
+ printf("%s: couldn't map DMA\n",
+ sc->sc_dev.dv_xname);
+ return;
+ }
+
+ /*
+ * Create and load the DMA map for the DMA area.
+ */
+ if (bus_dmamap_create(sc->dmat, sc->sc_dmasize, 1,
+ sc->sc_dmasize, 0, BUS_DMA_NOWAIT|BUS_DMA_DIRECT, &sc->sc_dmam))
+ {
+ printf("%s: couldn't create DMA map\n",
+ sc->sc_dev.dv_xname);
+ bus_dmamem_free(sc->dmat, &seg, rseg);
+ return;
+ }
+ if (bus_dmamap_load(sc->dmat, sc->sc_dmam,
+ sc->sc_cpudma, sc->sc_dmasize, NULL, BUS_DMA_NOWAIT|BUS_DMA_DIRECT))
+ {
+ printf("%s: coundn't load DMA map\n",
+ sc->sc_dev.dv_xname);
+ bus_dmamem_free(sc->dmat, &seg, rseg);
+ return;
+ }
+
+ sc->sc_bonitodma = sc->sc_dmam->dm_segs[0].ds_addr;
+ bzero(sc->sc_cpudma,DMASIZE);
+
+ sc->sc_ih = bonito_intr_establish(bia->irq, IPL_NET, pbus_intr, sc);
+ if (sc->sc_ih == NULL)
+ {
+ printf("%s: couldn't establish interrupt at %d\n",
+ sc->sc_dev.dv_xname,bia->irq);
+ return;
+ }
+
+ printf("%s: DMA map:0x%08lx (PHYS:0x%08lx)\n", sc->sc_dev.dv_xname, (unsigned long) sc->sc_cpudma, sc->sc_bonitodma);
+ printf("%s: interrupting at %d\n", sc->sc_dev.dv_xname, bia->irq);
+
+}
+
+
+
+/*
+ * operational routines:
+ * open, close, read, write,
+ * ioctl, mmap
+ */
+
+dev_type_open(pbusopen);
+dev_type_close(pbusclose);
+dev_type_read(pbusread);
+dev_type_write(pbuswrite);
+dev_type_ioctl(pbusioctl);
+dev_type_mmap(pbusmmap);
+
+int
+pbusopen(dev, flag, fmt, proc)
+ dev_t dev;
+ int flag, fmt;
+ struct proc *proc;
+{
+ struct pbus_softc *sc= pbus_cd.cd_devs[0];
+
+ if (minor(dev)==1) /* PBUS */
+ sc->cproc=proc;
+ return 0;
+}
+
+int
+pbusclose(dev, flag, fmt, proc)
+ dev_t dev;
+ int flag, fmt;
+ struct proc *proc;
+{
+ struct pbus_softc *sc= pbus_cd.cd_devs[0];
+ if (minor(dev)==1) /* PBUS */
+ sc->cproc=NULL;
+ return 0;
+}
+
+int
+pbusread(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ int bufok,remain;
+ int resid=uio->uio_resid;
+ int s;
+ struct pbus_softc *sc= pbus_cd.cd_devs[0];
+ s=splhigh();
+ bufok=*((volatile int *)(&sc->buf_ok));
+ if ((!bufok)&&(!sc->in_dma))
+ {
+ BUFSYNC_PRE;
+ PBUS_WRITE_4(0x4,sc->sc_bonitodma);
+ sc->in_dma=1;
+ }
+ splx(s);
+ if (!bufok) return 0;
+ remain=sc->framesize-sc->buf_consumed;
+ if (resid>remain) resid=remain;
+
+ uiomove(sc->sc_cpudma+sc->buf_consumed,resid,uio);
+ sc->buf_consumed+=resid;
+ remain-=resid;
+ if (!remain)
+ {
+ sc->buf_consumed=0;
+ sc->buf_ok=0;
+ }
+ return 0;
+}
+
+int
+pbuswrite(dev, uio, flags)
+ dev_t dev;
+ struct uio *uio;
+ int flags;
+{
+ return ENODEV;
+}
+
+int pbus_intr(void *p)
+{
+ struct pbus_softc *sc = (struct pbus_softc *)p;
+ unsigned long status=PBUS_READ_4(0);
+ if (status&0x20000000)
+ {
+ PBUS_WRITE_4(8,PBUS_READ_4(8)&0x3FFF);
+ if (sc->cproc!=NULL) psignal(sc->cproc,sc->csignal);
+ }
+ else
+ {
+ if (status&0x40000000)
+ {
+ /* Frame Ok */
+ BUFSYNC_POST;
+ sc->buf_ok=1;
+ sc->in_dma=0;
+ }
+ else
+ {
+ /* Pointer slot avail */
+ }
+ }
+ return 0;
+}
+
+#define PBUS_WAIT \
+ tsleep(sc,PUSER | PCATCH,"pbusio",(HZ/10000)?(HZ/10000):1)
+
+int
+pbusioctl(dev, cmd, addr, flag, proc)
+ dev_t dev;
+ u_long cmd;
+ int flag;
+ caddr_t addr;
+ struct proc *proc;
+{
+ struct pbus_softc *sc= pbus_cd.cd_devs[0];
+ struct pbus_io *parm=(struct pbus_io *)addr;
+ unsigned long *fsize=(unsigned long *)addr;
+ /* PBUS IOctl */
+ if (minor(dev)==1) /* PBUS */
+ {
+ switch (cmd)
+ {
+ case PBUS_READ:
+ PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|PBUS_RnW|sc->pbusinten);
+ PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_RnW|sc->pbusinten);
+ PBUS_WAIT;
+ parm->data=PBUS_READ_4(8)&0xFF;
+ PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|PBUS_RnW|sc->pbusinten);
+ PBUS_WAIT;
+ break;
+ case PBUS_WRITE:
+ PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|(parm->data)|sc->pbusinten);
+ PBUS_WRITE_4(8,(parm->addr<<8)|(parm->data)|sc->pbusinten);
+ PBUS_WAIT;
+ PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|(parm->data)|sc->pbusinten);
+ PBUS_WAIT;
+ PBUS_WRITE_4(8,(parm->addr<<8)|PBUS_CLK|PBUS_RnW|sc->pbusinten);
+ break;
+ case PBUS_INTENABLE:
+ sc->pbusinten=1;
+ PBUS_WRITE_4(8,0|PBUS_CLK|PBUS_RnW|sc->pbusinten);
+ break;
+ }
+ parm->ints=(~(PBUS_READ_4(8)>>16))&0x1F;
+ }
+
+ if (minor(dev)==0) /* CAM */
+ {
+ switch (cmd)
+ {
+ case CAM_SETFRAMESIZE:
+ PBUS_WRITE_4(0x0,1);
+ sc->framesize=*fsize;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+paddr_t
+pbusmmap(dev_t dev, off_t offset, int nprot)
+{
+ return ENXIO;
+}
+
+
diff --git a/2003/i/buzz/src/kernel/pbus.h b/2003/i/buzz/src/kernel/pbus.h
new file mode 100644
index 0000000..7b11499
--- /dev/null
+++ b/2003/i/buzz/src/kernel/pbus.h
@@ -0,0 +1,24 @@
+#ifndef _PBUS_H_
+#define _PBUS_H_
+
+#include <sys/ioctl.h>
+
+struct pbus_io
+{
+ unsigned char addr; /* Address */
+ unsigned char data; /* Data */
+ unsigned char ints; /* IRQ lines */
+};
+
+#define PBUS_DATAMASK 0x00FF
+#define PBUS_ADDRMASK 0x0F00
+#define PBUS_RnW 0x1000
+#define PBUS_CLK 0x2000
+#define PBUS_INTEN 0x4000
+
+#define PBUS_READ _IOWR('R', 1, struct pbus_io)
+#define PBUS_WRITE _IOWR('R', 2, struct pbus_io)
+#define PBUS_INTENABLE _IO('R', 3)
+
+#define CAM_SETFRAMESIZE _IOW('R', 10, unsigned long)
+#endif