diff options
Diffstat (limited to 'sys/arch/alpha/pci')
42 files changed, 3635 insertions, 3082 deletions
diff --git a/sys/arch/alpha/pci/apecs.c b/sys/arch/alpha/pci/apecs.c index 76fd9fec019..ec858ee1bab 100644 --- a/sys/arch/alpha/pci/apecs.c +++ b/sys/arch/alpha/pci/apecs.c @@ -1,7 +1,7 @@ -/* $NetBSD: apecs.c,v 1.4 1995/11/23 02:37:11 cgd Exp $ */ +/* $NetBSD: apecs.c,v 1.7 1996/04/12 06:08:01 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -44,18 +44,20 @@ #include <dev/pci/pcivar.h> #include <alpha/pci/apecsreg.h> #include <alpha/pci/apecsvar.h> +#include <alpha/pci/pci_2100_a50.h> int apecsmatch __P((struct device *, void *, void *)); void apecsattach __P((struct device *, struct device *, void *)); -struct cfdriver apecscd = { - NULL, "apecs", apecsmatch, apecsattach, DV_DULL, - sizeof(struct apecs_softc) +struct cfattach apecs_ca = { + sizeof(struct apecs_softc), apecsmatch, apecsattach, }; -static int apecsprint __P((void *, char *pnp)); +struct cfdriver apecs_cd = { + NULL, "apecs", DV_DULL, +}; -#define REGVAL(r) (*(int32_t *)phystok0seg(r)) +static int apecsprint __P((void *, char *pnp)); /* There can be only one. */ int apecsfound; @@ -70,7 +72,7 @@ apecsmatch(parent, match, aux) struct confargs *ca = aux; /* Make sure that we're looking for an APECS. */ - if (strcmp(ca->ca_name, apecscd.cd_name) != 0) + if (strcmp(ca->ca_name, apecs_cd.cd_name) != 0) return (0); if (apecsfound) @@ -98,15 +100,9 @@ apecs_init(acp) * Can't set up SGMAP data here; can be called before malloc(). */ - acp->ac_conffns = &apecs_conf_fns; - acp->ac_confarg = acp; - acp->ac_dmafns = &apecs_dma_fns; - acp->ac_dmaarg = acp; - /* Interrupt routines set up in 'attach' */ - acp->ac_memfns = &apecs_mem_fns; - acp->ac_memarg = acp; - acp->ac_piofns = &apecs_pio_fns; - acp->ac_pioarg = acp; + apecs_lca_bus_io_init(&acp->ac_bc, acp); + apecs_lca_bus_mem_init(&acp->ac_bc, acp); + apecs_pci_init(&acp->ac_pc, acp); /* Turn off DMA window enables in PCI Base Reg 1. */ REGVAL(EPIC_PCI_BASE_1) = 0; @@ -120,10 +116,9 @@ apecsattach(parent, self, aux) struct device *parent, *self; void *aux; { - struct confargs *ca = aux; struct apecs_softc *sc = (struct apecs_softc *)self; struct apecs_config *acp; - struct pci_attach_args pa; + struct pcibus_attach_args pba; /* note that we've attached the chipset; can't have 2 APECSes. */ apecsfound = 1; @@ -151,31 +146,18 @@ apecsattach(parent, self, aux) switch (hwrpb->rpb_type) { #if defined(DEC_2100_A50) case ST_DEC_2100_A50: - pci_2100_a50_pickintr(acp->ac_conffns, acp->ac_confarg, - acp->ac_piofns, acp->ac_pioarg, - &acp->ac_intrfns, &acp->ac_intrarg); + pci_2100_a50_pickintr(acp); break; #endif default: panic("apecsattach: shouldn't be here, really..."); } - pa.pa_bus = 0; - pa.pa_maxdev = 32; - pa.pa_burstlog2 = 8; - - pa.pa_conffns = acp->ac_conffns; - pa.pa_confarg = acp->ac_confarg; - pa.pa_dmafns = acp->ac_dmafns; - pa.pa_dmaarg = acp->ac_dmaarg; - pa.pa_intrfns = acp->ac_intrfns; - pa.pa_intrarg = acp->ac_intrarg; - pa.pa_memfns = acp->ac_memfns; - pa.pa_memarg = acp->ac_memarg; - pa.pa_piofns = acp->ac_piofns; - pa.pa_pioarg = acp->ac_pioarg; - - config_found(self, &pa, apecsprint); + pba.pba_busname = "pci"; + pba.pba_bc = &acp->ac_bc; + pba.pba_pc = &acp->ac_pc; + pba.pba_bus = 0; + config_found(self, &pba, apecsprint); } static int @@ -183,11 +165,11 @@ apecsprint(aux, pnp) void *aux; char *pnp; { - register struct pci_attach_args *pa = aux; + register struct pcibus_attach_args *pba = aux; /* only PCIs can attach to APECSes; easy. */ if (pnp) - printf("pci at %s", pnp); - printf(" bus %d", pa->pa_bus); + printf("%s at %s", pba->pba_busname, pnp); + printf(" bus %d", pba->pba_bus); return (UNCONF); } diff --git a/sys/arch/alpha/pci/apecs_isa.c b/sys/arch/alpha/pci/apecs_isa.c deleted file mode 100644 index 1d2729475dc..00000000000 --- a/sys/arch/alpha/pci/apecs_isa.c +++ /dev/null @@ -1,346 +0,0 @@ -/* $NetBSD: apecs_isa.c,v 1.4 1995/11/23 02:37:13 cgd Exp $ */ - -/* - * Copyright (c) 1995 Carnegie-Mellon University. - * All rights reserved. - * - * Author: Chris G. Demetriou - * - * Permission to use, copy, modify and distribute this software and - * its documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND - * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <vm/vm.h> - -#include <dev/isa/isavar.h> - -#include <alpha/pci/apecsreg.h> -#include <alpha/pci/apecsvar.h> - -/* - * Allocation/deallocation functions. - */ -int apecs_pio_alloc __P((void *, isa_iooffset_t, isa_iosize_t)); -int apecs_pio_dealloc __P((void *, isa_iooffset_t, isa_iosize_t)); - -/* - * Byte functions. - */ -isa_byte_t apecs_inb __P((void *, isa_iooffset_t)); -#define apecs_insb 0 /* XXX */ -void apecs_outb __P((void *, isa_iooffset_t, isa_byte_t)); -#define apecs_outsb 0 /* XXX */ - -/* - * Word functions. - */ -isa_word_t apecs_inw __P((void *, isa_iooffset_t)); -#define apecs_insw 0 /* XXX */ -void apecs_outw __P((void *, isa_iooffset_t, isa_word_t)); -#define apecs_outsw 0 /* XXX */ - -/* - * Longword functions. - */ -isa_long_t apecs_inl __P((void *, isa_iooffset_t)); -#define apecs_insl 0 /* XXX */ -void apecs_outl __P((void *, isa_iooffset_t, isa_long_t)); -#define apecs_outsl 0 /* XXX */ - -__const struct pci_pio_fns apecs_pio_fns = { - /* Allocation/deallocation functions. */ - apecs_pio_alloc, apecs_pio_dealloc, - - /* Byte functions. */ - apecs_inb, apecs_insb, - apecs_outb, apecs_outsb, - - /* Word functions. */ - apecs_inw, apecs_insw, - apecs_outw, apecs_outsw, - - /* Longword functions. */ - apecs_inl, apecs_insl, - apecs_outl, apecs_outsl, -}; - -int -apecs_pio_alloc(ipfarg, start, size) - void *ipfarg; - isa_iooffset_t start; - isa_iosize_t size; -{ - - /* XXX should do something */ -} - -int -apecs_pio_dealloc(ipfarg, start, size) - void *ipfarg; - isa_iooffset_t start; - isa_iosize_t size; -{ - - /* XXX should do something */ -} - -isa_byte_t -apecs_inb(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_byte_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(APECS_PCI_SIO | 0 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xff; -/* rval = val & 0xff; */ - - return rval; -} - -void -apecs_outb(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_byte_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - nval = val << (8 * offset); - port = (int32_t *)phystok0seg(APECS_PCI_SIO | 0 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -isa_word_t -apecs_inw(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_word_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(APECS_PCI_SIO | 1 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xffff; - rval = val & 0xffff; - -panic("inw(0x%x) => 0x%x @ %p => 0x%x\n", ioaddr, val, port, rval); - - return rval; -} - -void -apecs_outw(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_word_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - port = (int32_t *)phystok0seg(APECS_PCI_SIO | 1 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -isa_long_t -apecs_inl(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_long_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(APECS_PCI_SIO | 3 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xffffffff; - rval = val & 0xffffffff; - - return rval; -} - -void -apecs_outl(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_long_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - port = (int32_t *)phystok0seg(APECS_PCI_SIO | 3 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -/* XXX XXX XXX */ - -#define pf(fn, args) fn args { panic(__STRING(fn)); } - -void pf(apecs_dma_cascade, (void *idfa, isa_drq_t chan)) -void pf(apecs_dma_copytobuf, ()) -void pf(apecs_dma_copyfrombuf, ()) -void pf(apecs_dma_start, (void *idfa, vm_offset_t addr, - isa_msize_t size, isa_drq_t chan, int flags)) -void pf(apecs_dma_abort, (void *idfa, isa_drq_t chan)) -void pf(apecs_dma_done, (void *idfa, isa_drq_t chan)) - -int apecs_dma_map __P((void *, vm_offset_t, isa_msize_t, - isa_moffset_t *, int)); -void apecs_dma_unmap __P((void *, vm_offset_t, isa_msize_t, int, - isa_moffset_t *)); - -__const struct isa_dma_fns apecs_dma_fns = { - apecs_dma_cascade, - apecs_dma_map, - apecs_dma_unmap, - apecs_dma_copytobuf, - apecs_dma_copyfrombuf, - apecs_dma_start, - apecs_dma_abort, - apecs_dma_done, -}; - -int -apecs_dma_map(idfa, va, isasize, mappingsp, flags) - void *idfa; - vm_offset_t va; - isa_msize_t isasize; - isa_moffset_t *mappingsp; - int flags; -{ - struct apecs_config *acp = idfa; - long todo; - int i; - - if (ISA_DMA_NEEDCONTIG(flags) && isasize > NBPG || - ISA_DMA_SIZEBOUND(flags) != ISA_DMA_SIZEBOUND_NONE || - ISA_DMA_ADDRBOUND(flags) != ISA_DMA_ADDRBOUND_NONE) - panic("apecs_dma_map: punt"); - - i = 0; - todo = isasize; - - while (todo > 0) { - mappingsp[i] = vtophys(va) | 0x40000000; -#if 0 - printf("a_pd_m mapping %d: %lx -> %lx -> %lx\n", i, va, - vtophys(va), mappingsp[i]); -#endif - i++; - todo -= PAGE_SIZE - (va - trunc_page(va)); - va += PAGE_SIZE - (va - trunc_page(va)); - } - return (i); -} - -void -apecs_dma_unmap(idfa, va, isasize, nmappings, mappingsp) - void *idfa; - vm_offset_t va; - isa_msize_t isasize; - int nmappings; - isa_moffset_t *mappingsp; -{ - - printf("apecs_dma_unmap: called\n"); -} - -vm_offset_t apecs_mem_map __P((void *, isa_moffset_t, isa_msize_t, int)); -void apecs_mem_unmap __P((void *, vm_offset_t, isa_msize_t)); - -#if 0 -void apecs_mem_copytoisa __P((void *, char *, vm_offset_t, - isa_moffset_t, isa_msize_t)); -void apecs_mem_copyfromisa __P((void *, char *, vm_offset_t, - isa_moffset_t, isa_msize_t)); -void apecs_mem_zero __P((void *, vm_offset_t, isa_moffset_t, - isa_msize_t)); -#else -void pf(apecs_mem_copytoisa, ()) -void pf(apecs_mem_copyfromisa, ()) -void pf(apecs_mem_zero, ()) -#endif - -__const struct isa_mem_fns apecs_mem_fns = { - apecs_mem_map, - apecs_mem_unmap, - apecs_mem_copytoisa, - apecs_mem_copyfromisa, - apecs_mem_zero, -}; - -vm_offset_t -apecs_mem_map(imfa, isapa, isasize, cacheable) - void *imfa; - isa_moffset_t isapa; - isa_msize_t isasize; - int cacheable; -{ - vm_offset_t sbpa; - - /* XXX sanity checks on sizes, use of windows, etc. */ - - /* XXX MAGIC NUMBERS */ - if (cacheable) - sbpa = (isapa & 0xffffffff) | APECS_PCI_DENSE; - else - sbpa = ((isapa & 0x7ffffff) << 5) | APECS_PCI_SPARSE; - - return phystok0seg(sbpa); -} - -void -apecs_mem_unmap(imfa, va, isasize) - void *imfa; - vm_offset_t va; - isa_msize_t isasize; -{ - - /* XXX sanity checks on va */ - - /* Nothing to do; mapping was done in direct-mapped segment. */ -} diff --git a/sys/arch/alpha/pci/apecs_lca_bus_io.c b/sys/arch/alpha/pci/apecs_lca_bus_io.c new file mode 100644 index 00000000000..22e1aa3f050 --- /dev/null +++ b/sys/arch/alpha/pci/apecs_lca_bus_io.c @@ -0,0 +1,59 @@ +/* $NetBSD: apecs_lca_bus_io.c,v 1.2.4.1 1996/06/13 18:14:55 cgd Exp $ */ + +/* + * Copyright (c) 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include <sys/param.h> +#include <sys/malloc.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <vm/vm.h> + +#include <machine/bus.h> + +#include <alpha/pci/apecsreg.h> +#include <alpha/pci/lcareg.h> + +#if (APECS_PCI_SIO != LCA_PCI_SIO) +#error Sparse I/O addresses do not match up? +#endif + +#define CHIP apecs_lca + +/* IO region 1 */ +#define CHIP_IO_W1_START(v) 0x00000000 +#define CHIP_IO_W1_END(v) 0x0003ffff +#define CHIP_IO_W1_BASE(v) APECS_PCI_SIO +#define CHIP_IO_W1_MASK(v) 0x00ffffff + +/* IO region 2 */ +#define CHIP_IO_W2_START(v) 0x00040000 /* XXX from HAXR2 */ +#define CHIP_IO_W2_END(v) 0xfffbffff /* XXX from HAXR2 */ +#define CHIP_IO_W2_BASE(v) APECS_PCI_SIO +#define CHIP_IO_W2_MASK(v) 0x00ffffff + +#include "pcs_bus_io_common.c" diff --git a/sys/arch/alpha/pci/apecs_lca_bus_mem.c b/sys/arch/alpha/pci/apecs_lca_bus_mem.c new file mode 100644 index 00000000000..72a892c37fe --- /dev/null +++ b/sys/arch/alpha/pci/apecs_lca_bus_mem.c @@ -0,0 +1,65 @@ +/* $NetBSD: apecs_lca_bus_mem.c,v 1.2.4.2 1996/06/13 18:14:58 cgd Exp $ */ + +/* + * Copyright (c) 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include <sys/param.h> +#include <sys/malloc.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <vm/vm.h> + +#include <machine/bus.h> + +#include <alpha/pci/apecsreg.h> +#include <alpha/pci/lcareg.h> + +#if (APECS_PCI_SPARSE != LCA_PCI_SPARSE) || (APECS_PCI_DENSE != LCA_PCI_DENSE) +#error Memory addresses do not match up? +#endif + +#define CHIP apecs_lca + +/* Dense region 1 */ +#define CHIP_D_MEM_W1_START(v) 0x00000000 +#define CHIP_D_MEM_W1_END(v) 0xffffffff +#define CHIP_D_MEM_W1_BASE(v) APECS_PCI_DENSE +#define CHIP_D_MEM_W1_MASK(v) 0xffffffff + +/* Sparse region 1 */ +#define CHIP_S_MEM_W1_START(v) 0x00000000 +#define CHIP_S_MEM_W1_END(v) 0x00ffffff +#define CHIP_S_MEM_W1_BASE(v) APECS_PCI_SPARSE +#define CHIP_S_MEM_W1_MASK(v) 0x07ffffff + +/* Sparse region 2 */ +#define CHIP_S_MEM_W2_START(v) 0x01000000 /* XXX from HAXR1 */ +#define CHIP_S_MEM_W2_END(v) 0xfeffffff /* XXX from HAXR1 */ +#define CHIP_S_MEM_W2_BASE(v) APECS_PCI_SPARSE +#define CHIP_S_MEM_W2_MASK(v) 0x07ffffff + +#include "pcs_bus_mem_common.c" diff --git a/sys/arch/alpha/pci/apecs_pci.c b/sys/arch/alpha/pci/apecs_pci.c index 42be1862efa..0c30c45ecba 100644 --- a/sys/arch/alpha/pci/apecs_pci.c +++ b/sys/arch/alpha/pci/apecs_pci.c @@ -1,7 +1,7 @@ -/* $NetBSD: apecs_pci.c,v 1.4 1995/11/23 02:37:16 cgd Exp $ */ +/* $NetBSD: apecs_pci.c,v 1.6 1996/04/12 06:08:09 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -38,33 +38,83 @@ #include <alpha/pci/apecsreg.h> #include <alpha/pci/apecsvar.h> -pci_confreg_t apecs_conf_read __P((void *, pci_conftag_t, pci_confoffset_t)); -void apecs_conf_write __P((void *, pci_conftag_t, - pci_confoffset_t, pci_confreg_t)); -int apecs_find_io __P((void *, pci_conftag_t, - pci_confoffset_t, pci_iooffset_t *, pci_iosize_t *)); -int apecs_find_mem __P((void *, pci_conftag_t, - pci_confoffset_t, pci_moffset_t *, pci_msize_t *, int *)); - -__const struct pci_conf_fns apecs_conf_fns = { - apecs_conf_read, - apecs_conf_write, - apecs_find_io, - apecs_find_mem, -}; - -pci_confreg_t +void apecs_attach_hook __P((struct device *, struct device *, + struct pcibus_attach_args *)); +int apecs_bus_maxdevs __P((void *, int)); +pcitag_t apecs_make_tag __P((void *, int, int, int)); +void apecs_decompose_tag __P((void *, pcitag_t, int *, int *, + int *)); +pcireg_t apecs_conf_read __P((void *, pcitag_t, int)); +void apecs_conf_write __P((void *, pcitag_t, int, pcireg_t)); + +void +apecs_pci_init(pc, v) + pci_chipset_tag_t pc; + void *v; +{ + + pc->pc_conf_v = v; + pc->pc_attach_hook = apecs_attach_hook; + pc->pc_bus_maxdevs = apecs_bus_maxdevs; + pc->pc_make_tag = apecs_make_tag; + pc->pc_decompose_tag = apecs_decompose_tag; + pc->pc_conf_read = apecs_conf_read; + pc->pc_conf_write = apecs_conf_write; +} + +void +apecs_attach_hook(parent, self, pba) + struct device *parent, *self; + struct pcibus_attach_args *pba; +{ +} + +int +apecs_bus_maxdevs(cpv, busno) + void *cpv; + int busno; +{ + + return 32; +} + +pcitag_t +apecs_make_tag(cpv, b, d, f) + void *cpv; + int b, d, f; +{ + + return (b << 16) | (d << 11) | (f << 8); +} + +void +apecs_decompose_tag(cpv, tag, bp, dp, fp) + void *cpv; + pcitag_t tag; + int *bp, *dp, *fp; +{ + + if (bp != NULL) + *bp = (tag >> 16) & 0xff; + if (dp != NULL) + *dp = (tag >> 11) & 0x1f; + if (fp != NULL) + *fp = (tag >> 8) & 0x7; +} + +pcireg_t apecs_conf_read(cpv, tag, offset) void *cpv; - pci_conftag_t tag; - pci_confoffset_t offset; + pcitag_t tag; + int offset; { struct apecs_config *acp = cpv; - pci_confreg_t *datap, data; + pcireg_t *datap, data; int s, secondary, ba; int32_t old_haxr2; /* XXX */ - secondary = PCI_TAG_BUS(tag) != 0; + /* secondary if bus # != 0 */ + pci_decompose_tag(&acp->ac_pc, tag, &secondary, 0, 0); if (secondary) { s = splhigh(); old_haxr2 = REGVAL(EPIC_HAXR2); @@ -73,12 +123,12 @@ apecs_conf_read(cpv, tag, offset) wbflush(); } - datap = (pci_confreg_t *)phystok0seg(APECS_PCI_CONF | + datap = (pcireg_t *)phystok0seg(APECS_PCI_CONF | tag << 5UL | /* XXX */ (offset & ~0x03) << 5 | /* XXX */ 0 << 5 | /* XXX */ 0x3 << 3); /* XXX */ - data = (pci_confreg_t)-1; + data = (pcireg_t)-1; if (!(ba = badaddr(datap, sizeof *datap))) data = *datap; @@ -100,16 +150,17 @@ apecs_conf_read(cpv, tag, offset) void apecs_conf_write(cpv, tag, offset, data) void *cpv; - pci_conftag_t tag; - pci_confoffset_t offset; - pci_confreg_t data; + pcitag_t tag; + int offset; + pcireg_t data; { struct apecs_config *acp = cpv; - pci_confreg_t *datap; + pcireg_t *datap; int s, secondary; int32_t old_haxr2; /* XXX */ - secondary = PCI_TAG_BUS(tag) != 0; + /* secondary if bus # != 0 */ + pci_decompose_tag(&acp->ac_pc, tag, &secondary, 0, 0); if (secondary) { s = splhigh(); old_haxr2 = REGVAL(EPIC_HAXR2); @@ -118,7 +169,7 @@ apecs_conf_write(cpv, tag, offset, data) wbflush(); } - datap = (pci_confreg_t *)phystok0seg(APECS_PCI_CONF | + datap = (pcireg_t *)phystok0seg(APECS_PCI_CONF | tag << 5UL | /* XXX */ (offset & ~0x03) << 5 | /* XXX */ 0 << 5 | /* XXX */ @@ -137,86 +188,3 @@ apecs_conf_write(cpv, tag, offset, data) reg, data, datap); #endif } - -int -apecs_find_io(cpv, tag, reg, iobasep, sizep) - void *cpv; - pci_conftag_t tag; - pci_confoffset_t reg; - pci_iooffset_t *iobasep; - pci_iosize_t *sizep; -{ - struct apecs_config *acp = cpv; - pci_confreg_t addrdata, sizedata; - pci_iooffset_t pci_iobase; - - if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) - panic("apecs_map_io: bad request"); - - addrdata = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, tag, reg); - - PCI_CONF_WRITE(acp->ac_conffns, acp->ac_confarg, tag, reg, 0xffffffff); - sizedata = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, tag, reg); - PCI_CONF_WRITE(acp->ac_conffns, acp->ac_confarg, tag, reg, addrdata); - - if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_MEM) - panic("apecs_map_io: attempt to I/O map an memory region"); - - if (iobasep != NULL) - *iobasep = PCI_MAPREG_IO_ADDRESS(addrdata); - if (sizep != NULL) - *sizep = ~PCI_MAPREG_IO_ADDRESS(sizedata) + 1; - - return (0); -} - -int -apecs_find_mem(cpv, tag, reg, paddrp, sizep, cacheablep) - void *cpv; - pci_conftag_t tag; - pci_confoffset_t reg; - pci_moffset_t *paddrp; - pci_msize_t *sizep; - int *cacheablep; -{ - struct apecs_config *acp = cpv; - pci_confreg_t addrdata, sizedata; - - if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) - panic("apecs_map_mem: bad request"); - - /* - * The PROM has mapped the device for us. We take the address - * that's been assigned to the register, and figure out what - * physical and virtual addresses go with it... - */ - addrdata = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, tag, reg); - - PCI_CONF_WRITE(acp->ac_conffns, acp->ac_confarg, tag, reg, 0xffffffff); - sizedata = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, tag, reg); - PCI_CONF_WRITE(acp->ac_conffns, acp->ac_confarg, tag, reg, addrdata); - - if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_IO) - panic("apecs_map_mem: attempt to memory map an I/O region"); - - switch (PCI_MAPREG_MEM_TYPE(addrdata)) { - case PCI_MAPREG_MEM_TYPE_32BIT: - case PCI_MAPREG_MEM_TYPE_32BIT_1M: - break; - case PCI_MAPREG_MEM_TYPE_64BIT: -/* XXX */ printf("apecs_map_mem: attempt to map 64-bit region\n"); -/* XXX */ break; - default: - printf("apecs_map_mem: reserved mapping type\n"); - return EINVAL; - } - - if (paddrp != NULL) - *paddrp = PCI_MAPREG_MEM_ADDRESS(addrdata); /* PCI addr */ - if (sizep != NULL) - *sizep = ~PCI_MAPREG_MEM_ADDRESS(sizedata) + 1; - if (cacheablep != NULL) - *cacheablep = PCI_MAPREG_MEM_CACHEABLE(addrdata); - - return 0; -} diff --git a/sys/arch/alpha/pci/apecsvar.h b/sys/arch/alpha/pci/apecsvar.h index a63cc275922..fe4cfdeba47 100644 --- a/sys/arch/alpha/pci/apecsvar.h +++ b/sys/arch/alpha/pci/apecsvar.h @@ -1,21 +1,21 @@ -/* $NetBSD: apecsvar.h,v 1.1 1995/11/23 02:37:21 cgd Exp $ */ +/* $NetBSD: apecsvar.h,v 1.3 1996/04/12 06:08:14 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou - * + * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * + * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU @@ -41,20 +41,8 @@ struct apecs_config { int ac_epic_pass2; int ac_memwidth; - __const struct pci_conf_fns *ac_conffns; - void *ac_confarg; - - __const struct pci_dma_fns *ac_dmafns; - void *ac_dmaarg; - - __const struct pci_intr_fns *ac_intrfns; - void *ac_intrarg; - - __const struct pci_mem_fns *ac_memfns; - void *ac_memarg; - - __const struct pci_pio_fns *ac_piofns; - void *ac_pioarg; + struct alpha_bus_chipset ac_bc; + struct alpha_pci_chipset ac_pc; }; struct apecs_softc { @@ -63,10 +51,5 @@ struct apecs_softc { struct apecs_config *sc_acp; }; -extern __const struct pci_conf_fns apecs_conf_fns; -extern __const struct pci_dma_fns apecs_dma_fns; -/* pci interrupt functions handled elsewhere */ -extern __const struct pci_mem_fns apecs_mem_fns; -extern __const struct pci_pio_fns apecs_pio_fns; - void apecs_init __P((struct apecs_config *)); +void apecs_pci_init __P((pci_chipset_tag_t, void *)); diff --git a/sys/arch/alpha/pci/bt485reg.h b/sys/arch/alpha/pci/bt485reg.h index 60623050e8a..6cd8a9258ae 100644 --- a/sys/arch/alpha/pci/bt485reg.h +++ b/sys/arch/alpha/pci/bt485reg.h @@ -1,7 +1,7 @@ -/* $NetBSD: bt485reg.h,v 1.2 1995/08/03 01:17:07 cgd Exp $ */ +/* $NetBSD: bt485reg.h,v 1.4 1996/04/12 06:08:17 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -55,3 +55,10 @@ #define BT485_REG_CURSOR_Y_HIGH 0x0f #define BT485_REG_MAX 0x0f + +#define BT485_IREG_STATUS 0x00 +#define BT485_IREG_COMMAND_3 0x01 +#define BT485_IREG_COMMAND_4 0x02 +#define BT485_IREG_RSA 0x20 +#define BT485_IREG_GSA 0x21 +#define BT485_IREG_BSA 0x22 diff --git a/sys/arch/alpha/pci/cia.c b/sys/arch/alpha/pci/cia.c index fa2f49fc6cc..942a5ed0cee 100644 --- a/sys/arch/alpha/pci/cia.c +++ b/sys/arch/alpha/pci/cia.c @@ -1,7 +1,7 @@ -/* $NetBSD: cia.c,v 1.1 1995/11/23 02:37:24 cgd Exp $ */ +/* $NetBSD: cia.c,v 1.5.4.1 1996/06/10 00:02:39 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -51,9 +51,12 @@ int ciamatch __P((struct device *, void *, void *)); void ciaattach __P((struct device *, struct device *, void *)); -struct cfdriver ciacd = { - NULL, "cia", ciamatch, ciaattach, DV_DULL, - sizeof(struct cia_softc) +struct cfattach cia_ca = { + sizeof(struct cia_softc), ciamatch, ciaattach, +}; + +struct cfdriver cia_cd = { + NULL, "cia", DV_DULL, }; static int ciaprint __P((void *, char *pnp)); @@ -73,7 +76,7 @@ ciamatch(parent, match, aux) struct confargs *ca = aux; /* Make sure that we're looking for a CIA. */ - if (strcmp(ca->ca_name, ciacd.cd_name) != 0) + if (strcmp(ca->ca_name, cia_cd.cd_name) != 0) return (0); if (ciafound) @@ -94,15 +97,12 @@ cia_init(ccp) * Can't set up SGMAP data here; can be called before malloc(). */ - ccp->cc_conffns = &cia_conf_fns; - ccp->cc_confarg = ccp; - ccp->cc_dmafns = &cia_dma_fns; - ccp->cc_dmaarg = ccp; - /* Interrupt routines set up in 'attach' */ - ccp->cc_memfns = &cia_mem_fns; - ccp->cc_memarg = ccp; - ccp->cc_piofns = &cia_pio_fns; - ccp->cc_pioarg = ccp; + cia_bus_io_init(&ccp->cc_bc, ccp); + cia_bus_mem_init(&ccp->cc_bc, ccp); + cia_pci_init(&ccp->cc_pc, ccp); + + ccp->cc_hae_mem = REGVAL(CIA_CSR_HAE_MEM); + ccp->cc_hae_io = REGVAL(CIA_CSR_HAE_IO); } void @@ -113,7 +113,7 @@ ciaattach(parent, self, aux) struct confargs *ca = aux; struct cia_softc *sc = (struct cia_softc *)self; struct cia_config *ccp; - struct pci_attach_args pa; + struct pcibus_attach_args pba; /* note that we've attached the chipset; can't have 2 CIAs. */ ciafound = 1; @@ -131,9 +131,7 @@ ciaattach(parent, self, aux) switch (hwrpb->rpb_type) { #if defined(DEC_KN20AA) case ST_DEC_KN20AA: - pci_kn20aa_pickintr(ccp->cc_conffns, ccp->cc_confarg, - ccp->cc_piofns, ccp->cc_pioarg, - &ccp->cc_intrfns, &ccp->cc_intrarg); + pci_kn20aa_pickintr(ccp); #ifdef EVCNT_COUNTERS evcnt_attach(self, "intr", &kn20aa_intr_evcnt); #endif @@ -143,22 +141,11 @@ ciaattach(parent, self, aux) panic("ciaattach: shouldn't be here, really..."); } - pa.pa_bus = 0; - pa.pa_maxdev = 32; - pa.pa_burstlog2 = 8; - - pa.pa_conffns = ccp->cc_conffns; - pa.pa_confarg = ccp->cc_confarg; - pa.pa_dmafns = ccp->cc_dmafns; - pa.pa_dmaarg = ccp->cc_dmaarg; - pa.pa_intrfns = ccp->cc_intrfns; - pa.pa_intrarg = ccp->cc_intrarg; - pa.pa_memfns = ccp->cc_memfns; - pa.pa_memarg = ccp->cc_memarg; - pa.pa_piofns = ccp->cc_piofns; - pa.pa_pioarg = ccp->cc_pioarg; - - config_found(self, &pa, ciaprint); + pba.pba_busname = "pci"; + pba.pba_bc = &ccp->cc_bc; + pba.pba_pc = &ccp->cc_pc; + pba.pba_bus = 0; + config_found(self, &pba, ciaprint); } static int @@ -166,11 +153,11 @@ ciaprint(aux, pnp) void *aux; char *pnp; { - register struct pci_attach_args *pa = aux; + register struct pcibus_attach_args *pba = aux; /* only PCIs can attach to CIAs; easy. */ if (pnp) - printf("pci at %s", pnp); - printf(" bus %d", pa->pa_bus); + printf("%s at %s", pba->pba_busname, pnp); + printf(" bus %d", pba->pba_bus); return (UNCONF); } diff --git a/sys/arch/alpha/pci/cia_bus_io.c b/sys/arch/alpha/pci/cia_bus_io.c new file mode 100644 index 00000000000..12934b17687 --- /dev/null +++ b/sys/arch/alpha/pci/cia_bus_io.c @@ -0,0 +1,63 @@ +/* $NetBSD: cia_bus_io.c,v 1.2.4.2 1996/06/13 18:14:59 cgd Exp $ */ + +/* + * Copyright (c) 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include <sys/param.h> +#include <sys/malloc.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <vm/vm.h> + +#include <machine/bus.h> + +#include <alpha/pci/ciareg.h> +#include <alpha/pci/ciavar.h> + +#define CHIP cia + +/* IO region 1 */ +#define CHIP_IO_W1_START(v) \ + HAE_IO_REG1_START(((struct cia_config *)(v))->cc_hae_io) +#define CHIP_IO_W1_END(v) \ + (CHIP_IO_W1_START(v) + HAE_IO_REG1_MASK) +#define CHIP_IO_W1_BASE(v) \ + CIA_PCI_SIO1 +#define CHIP_IO_W1_MASK(v) \ + HAE_IO_REG1_MASK + +/* IO region 2 */ +#define CHIP_IO_W2_START(v) \ + HAE_IO_REG2_START(((struct cia_config *)(v))->cc_hae_io) +#define CHIP_IO_W2_END(v) \ + (CHIP_IO_W2_START(v) + HAE_IO_REG2_MASK) +#define CHIP_IO_W2_BASE(v) \ + CIA_PCI_SIO2 +#define CHIP_IO_W2_MASK(v) \ + HAE_IO_REG2_MASK + +#include "pcs_bus_io_common.c" diff --git a/sys/arch/alpha/pci/cia_bus_mem.c b/sys/arch/alpha/pci/cia_bus_mem.c new file mode 100644 index 00000000000..47413db910a --- /dev/null +++ b/sys/arch/alpha/pci/cia_bus_mem.c @@ -0,0 +1,79 @@ +/* $NetBSD: cia_bus_mem.c,v 1.2.4.2 1996/06/13 18:15:01 cgd Exp $ */ + +/* + * Copyright (c) 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include <sys/param.h> +#include <sys/malloc.h> +#include <sys/syslog.h> +#include <sys/device.h> +#include <vm/vm.h> + +#include <machine/bus.h> + +#include <alpha/pci/ciareg.h> +#include <alpha/pci/ciavar.h> + +#define CHIP cia + +/* Dense region 1 */ +#define CHIP_D_MEM_W1_START(v) 0x00000000 +#define CHIP_D_MEM_W1_END(v) 0xffffffff +#define CHIP_D_MEM_W1_BASE(v) CIA_PCI_DENSE +#define CHIP_D_MEM_W1_MASK(v) 0xffffffff + +/* Sparse region 1 */ +#define CHIP_S_MEM_W1_START(v) \ + HAE_MEM_REG1_START(((struct cia_config *)(v))->cc_hae_mem) +#define CHIP_S_MEM_W1_END(v) \ + (CHIP_S_MEM_W1_START(v) + HAE_MEM_REG1_MASK) +#define CHIP_S_MEM_W1_BASE(v) \ + CIA_PCI_SMEM1 +#define CHIP_S_MEM_W1_MASK(v) \ + HAE_MEM_REG1_MASK + +/* Sparse region 2 */ +#define CHIP_S_MEM_W2_START(v) \ + HAE_MEM_REG2_START(((struct cia_config *)(v))->cc_hae_mem) +#define CHIP_S_MEM_W2_END(v) \ + (CHIP_S_MEM_W2_START(v) + HAE_MEM_REG2_MASK) +#define CHIP_S_MEM_W2_BASE(v) \ + CIA_PCI_SMEM2 +#define CHIP_S_MEM_W2_MASK(v) \ + HAE_MEM_REG2_MASK + +/* Sparse region 3 */ +#define CHIP_S_MEM_W3_START(v) \ + HAE_MEM_REG3_START(((struct cia_config *)(v))->cc_hae_mem) +#define CHIP_S_MEM_W3_END(v) \ + (CHIP_S_MEM_W3_START(v) + HAE_MEM_REG3_MASK) +#define CHIP_S_MEM_W3_BASE(v) \ + CIA_PCI_SMEM3 +#define CHIP_S_MEM_W3_MASK(v) \ + HAE_MEM_REG3_MASK + +#include "pcs_bus_mem_common.c" diff --git a/sys/arch/alpha/pci/cia_isa.c b/sys/arch/alpha/pci/cia_isa.c deleted file mode 100644 index 6ccb0ae4a3e..00000000000 --- a/sys/arch/alpha/pci/cia_isa.c +++ /dev/null @@ -1,346 +0,0 @@ -/* $NetBSD: cia_isa.c,v 1.1 1995/11/23 02:37:26 cgd Exp $ */ - -/* - * Copyright (c) 1995 Carnegie-Mellon University. - * All rights reserved. - * - * Author: Chris G. Demetriou - * - * Permission to use, copy, modify and distribute this software and - * its documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND - * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <vm/vm.h> - -#include <dev/isa/isavar.h> - -#include <alpha/pci/ciareg.h> -#include <alpha/pci/ciavar.h> - -/* - * Allocation/deallocation functions. - */ -int cia_pio_alloc __P((void *, isa_iooffset_t, isa_iosize_t)); -int cia_pio_dealloc __P((void *, isa_iooffset_t, isa_iosize_t)); - -/* - * Byte functions. - */ -isa_byte_t cia_inb __P((void *, isa_iooffset_t)); -#define cia_insb 0 /* XXX */ -void cia_outb __P((void *, isa_iooffset_t, isa_byte_t)); -#define cia_outsb 0 /* XXX */ - -/* - * Word functions. - */ -isa_word_t cia_inw __P((void *, isa_iooffset_t)); -#define cia_insw 0 /* XXX */ -void cia_outw __P((void *, isa_iooffset_t, isa_word_t)); -#define cia_outsw 0 /* XXX */ - -/* - * Longword functions. - */ -isa_long_t cia_inl __P((void *, isa_iooffset_t)); -#define cia_insl 0 /* XXX */ -void cia_outl __P((void *, isa_iooffset_t, isa_long_t)); -#define cia_outsl 0 /* XXX */ - -__const struct pci_pio_fns cia_pio_fns = { - /* Allocation/deallocation functions. */ - cia_pio_alloc, cia_pio_dealloc, - - /* Byte functions. */ - cia_inb, cia_insb, - cia_outb, cia_outsb, - - /* Word functions. */ - cia_inw, cia_insw, - cia_outw, cia_outsw, - - /* Longword functions. */ - cia_inl, cia_insl, - cia_outl, cia_outsl, -}; - -int -cia_pio_alloc(ipfarg, start, size) - void *ipfarg; - isa_iooffset_t start; - isa_iosize_t size; -{ - - /* XXX should do something */ -} - -int -cia_pio_dealloc(ipfarg, start, size) - void *ipfarg; - isa_iooffset_t start; - isa_iosize_t size; -{ - - /* XXX should do something */ -} - -isa_byte_t -cia_inb(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_byte_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 0 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xff; -/* rval = val & 0xff; */ - - return rval; -} - -void -cia_outb(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_byte_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - nval = val << (8 * offset); - port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 0 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -isa_word_t -cia_inw(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_word_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 1 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xffff; - rval = val & 0xffff; - -panic("inw(0x%x) => 0x%x @ %p => 0x%x\n", ioaddr, val, port, rval); - - return rval; -} - -void -cia_outw(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_word_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 1 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -isa_long_t -cia_inl(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_long_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 3 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xffffffff; - rval = val & 0xffffffff; - - return rval; -} - -void -cia_outl(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_long_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - port = (int32_t *)phystok0seg(CIA_PCI_SIO0 | 3 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -/* XXX XXX XXX */ - -#define pf(fn, args) fn args { panic(__STRING(fn)); } - -void pf(cia_dma_cascade, (void *idfa, isa_drq_t chan)) -void pf(cia_dma_copytobuf, ()) -void pf(cia_dma_copyfrombuf, ()) -void pf(cia_dma_start, (void *idfa, vm_offset_t addr, - isa_msize_t size, isa_drq_t chan, int flags)) -void pf(cia_dma_abort, (void *idfa, isa_drq_t chan)) -void pf(cia_dma_done, (void *idfa, isa_drq_t chan)) - -int cia_dma_map __P((void *, vm_offset_t, isa_msize_t, - isa_moffset_t *, int)); -void cia_dma_unmap __P((void *, vm_offset_t, isa_msize_t, int, - isa_moffset_t *)); - -__const struct isa_dma_fns cia_dma_fns = { - cia_dma_cascade, - cia_dma_map, - cia_dma_unmap, - cia_dma_copytobuf, - cia_dma_copyfrombuf, - cia_dma_start, - cia_dma_abort, - cia_dma_done, -}; - -int -cia_dma_map(idfa, va, isasize, mappingsp, flags) - void *idfa; - vm_offset_t va; - isa_msize_t isasize; - isa_moffset_t *mappingsp; - int flags; -{ - struct apecs_config *acp = idfa; - long todo; - int i; - - if (ISA_DMA_NEEDCONTIG(flags) && isasize > NBPG || - ISA_DMA_SIZEBOUND(flags) != ISA_DMA_SIZEBOUND_NONE || - ISA_DMA_ADDRBOUND(flags) != ISA_DMA_ADDRBOUND_NONE) - panic("cia_dma_map: punt"); - - i = 0; - todo = isasize; - - while (todo > 0) { - mappingsp[i] = vtophys(va) | 0x40000000; -#if 0 - printf("a_pd_m mapping %d: %lx -> %lx -> %lx\n", i, va, - vtophys(va), mappingsp[i]); -#endif - i++; - todo -= PAGE_SIZE - (va - trunc_page(va)); - va += PAGE_SIZE - (va - trunc_page(va)); - } - return (i); -} - -void -cia_dma_unmap(idfa, va, isasize, nmappings, mappingsp) - void *idfa; - vm_offset_t va; - isa_msize_t isasize; - int nmappings; - isa_moffset_t *mappingsp; -{ - - printf("cia_dma_unmap: called\n"); -} - -vm_offset_t cia_mem_map __P((void *, isa_moffset_t, isa_msize_t, int)); -void cia_mem_unmap __P((void *, vm_offset_t, isa_msize_t)); - -#if 0 -void cia_mem_copytoisa __P((void *, char *, vm_offset_t, - isa_moffset_t, isa_msize_t)); -void cia_mem_copyfromisa __P((void *, char *, vm_offset_t, - isa_moffset_t, isa_msize_t)); -void cia_mem_zero __P((void *, vm_offset_t, isa_moffset_t, - isa_msize_t)); -#else -void pf(cia_mem_copytoisa, ()) -void pf(cia_mem_copyfromisa, ()) -void pf(cia_mem_zero, ()) -#endif - -__const struct isa_mem_fns cia_mem_fns = { - cia_mem_map, - cia_mem_unmap, - cia_mem_copytoisa, - cia_mem_copyfromisa, - cia_mem_zero, -}; - -vm_offset_t -cia_mem_map(imfa, isapa, isasize, cacheable) - void *imfa; - isa_moffset_t isapa; - isa_msize_t isasize; - int cacheable; -{ - vm_offset_t sbpa; - - /* XXX sanity checks on sizes, use of windows, etc. */ - - /* XXX MAGIC NUMBERS */ - if (cacheable) - sbpa = (isapa & 0xffffffff) | CIA_PCI_DENSE; - else - sbpa = ((isapa & 0x7ffffff) << 5) | CIA_PCI_SPARSE0; - - return phystok0seg(sbpa); -} - -void -cia_mem_unmap(imfa, va, isasize) - void *imfa; - vm_offset_t va; - isa_msize_t isasize; -{ - - /* XXX sanity checks on va */ - - /* Nothing to do; mapping was done in direct-mapped segment. */ -} diff --git a/sys/arch/alpha/pci/cia_pci.c b/sys/arch/alpha/pci/cia_pci.c index ef918cd84d6..4d9b592502b 100644 --- a/sys/arch/alpha/pci/cia_pci.c +++ b/sys/arch/alpha/pci/cia_pci.c @@ -1,7 +1,7 @@ -/* $NetBSD: cia_pci.c,v 1.1 1995/11/23 02:37:29 cgd Exp $ */ +/* $NetBSD: cia_pci.c,v 1.2 1996/04/12 23:37:10 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -38,33 +38,83 @@ #include <alpha/pci/ciareg.h> #include <alpha/pci/ciavar.h> -pci_confreg_t cia_conf_read __P((void *, pci_conftag_t, pci_confoffset_t)); -void cia_conf_write __P((void *, pci_conftag_t, - pci_confoffset_t, pci_confreg_t)); -int cia_find_io __P((void *, pci_conftag_t, - pci_confoffset_t, pci_iooffset_t *, pci_iosize_t *)); -int cia_find_mem __P((void *, pci_conftag_t, - pci_confoffset_t, pci_moffset_t *, pci_msize_t *, int *)); - -__const struct pci_conf_fns cia_conf_fns = { - cia_conf_read, - cia_conf_write, - cia_find_io, - cia_find_mem, -}; - -pci_confreg_t +void cia_attach_hook __P((struct device *, struct device *, + struct pcibus_attach_args *)); +int cia_bus_maxdevs __P((void *, int)); +pcitag_t cia_make_tag __P((void *, int, int, int)); +void cia_decompose_tag __P((void *, pcitag_t, int *, int *, + int *)); +pcireg_t cia_conf_read __P((void *, pcitag_t, int)); +void cia_conf_write __P((void *, pcitag_t, int, pcireg_t)); + +void +cia_pci_init(pc, v) + pci_chipset_tag_t pc; + void *v; +{ + + pc->pc_conf_v = v; + pc->pc_attach_hook = cia_attach_hook; + pc->pc_bus_maxdevs = cia_bus_maxdevs; + pc->pc_make_tag = cia_make_tag; + pc->pc_decompose_tag = cia_decompose_tag; + pc->pc_conf_read = cia_conf_read; + pc->pc_conf_write = cia_conf_write; +} + +void +cia_attach_hook(parent, self, pba) + struct device *parent, *self; + struct pcibus_attach_args *pba; +{ +} + +int +cia_bus_maxdevs(cpv, busno) + void *cpv; + int busno; +{ + + return 32; +} + +pcitag_t +cia_make_tag(cpv, b, d, f) + void *cpv; + int b, d, f; +{ + + return (b << 16) | (d << 11) | (f << 8); +} + +void +cia_decompose_tag(cpv, tag, bp, dp, fp) + void *cpv; + pcitag_t tag; + int *bp, *dp, *fp; +{ + + if (bp != NULL) + *bp = (tag >> 16) & 0xff; + if (dp != NULL) + *dp = (tag >> 11) & 0x1f; + if (fp != NULL) + *fp = (tag >> 8) & 0x7; +} + +pcireg_t cia_conf_read(cpv, tag, offset) void *cpv; - pci_conftag_t tag; - pci_confoffset_t offset; + pcitag_t tag; + int offset; { - struct cia_config *acp = cpv; - pci_confreg_t *datap, data; + struct cia_config *ccp = cpv; + pcireg_t *datap, data; int s, secondary, ba; int32_t old_haxr2; /* XXX */ - secondary = PCI_TAG_BUS(tag) != 0; + /* secondary if bus # != 0 */ + pci_decompose_tag(&ccp->cc_pc, tag, &secondary, 0, 0); if (secondary) { s = splhigh(); old_haxr2 = REGVAL(CIA_CSRS + 0x480); /* XXX */ @@ -73,12 +123,12 @@ cia_conf_read(cpv, tag, offset) wbflush(); } - datap = (pci_confreg_t *)phystok0seg(CIA_PCI_CONF | + datap = (pcireg_t *)phystok0seg(CIA_PCI_CONF | tag << 5UL | /* XXX */ (offset & ~0x03) << 5 | /* XXX */ 0 << 5 | /* XXX */ 0x3 << 3); /* XXX */ - data = (pci_confreg_t)-1; + data = (pcireg_t)-1; if (!(ba = badaddr(datap, sizeof *datap))) data = *datap; @@ -100,16 +150,17 @@ cia_conf_read(cpv, tag, offset) void cia_conf_write(cpv, tag, offset, data) void *cpv; - pci_conftag_t tag; - pci_confoffset_t offset; - pci_confreg_t data; + pcitag_t tag; + int offset; + pcireg_t data; { - struct cia_config *acp = cpv; - pci_confreg_t *datap; + struct cia_config *ccp = cpv; + pcireg_t *datap; int s, secondary; int32_t old_haxr2; /* XXX */ - secondary = PCI_TAG_BUS(tag) != 0; + /* secondary if bus # != 0 */ + pci_decompose_tag(&ccp->cc_pc, tag, &secondary, 0, 0); if (secondary) { s = splhigh(); old_haxr2 = REGVAL(CIA_CSRS + 0x480); /* XXX */ @@ -118,7 +169,7 @@ cia_conf_write(cpv, tag, offset, data) wbflush(); } - datap = (pci_confreg_t *)phystok0seg(CIA_PCI_CONF | + datap = (pcireg_t *)phystok0seg(CIA_PCI_CONF | tag << 5UL | /* XXX */ (offset & ~0x03) << 5 | /* XXX */ 0 << 5 | /* XXX */ @@ -137,86 +188,3 @@ cia_conf_write(cpv, tag, offset, data) reg, data, datap); #endif } - -int -cia_find_io(cpv, tag, reg, iobasep, sizep) - void *cpv; - pci_conftag_t tag; - pci_confoffset_t reg; - pci_iooffset_t *iobasep; - pci_iosize_t *sizep; -{ - struct cia_config *acp = cpv; - pci_confreg_t addrdata, sizedata; - pci_iooffset_t pci_iobase; - - if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) - panic("cia_map_io: bad request"); - - addrdata = PCI_CONF_READ(acp->cc_conffns, acp->cc_confarg, tag, reg); - - PCI_CONF_WRITE(acp->cc_conffns, acp->cc_confarg, tag, reg, 0xffffffff); - sizedata = PCI_CONF_READ(acp->cc_conffns, acp->cc_confarg, tag, reg); - PCI_CONF_WRITE(acp->cc_conffns, acp->cc_confarg, tag, reg, addrdata); - - if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_MEM) - panic("cia_map_io: attempt to I/O map an memory region"); - - if (iobasep != NULL) - *iobasep = PCI_MAPREG_IO_ADDRESS(addrdata); - if (sizep != NULL) - *sizep = ~PCI_MAPREG_IO_ADDRESS(sizedata) + 1; - - return (0); -} - -int -cia_find_mem(cpv, tag, reg, paddrp, sizep, cacheablep) - void *cpv; - pci_conftag_t tag; - pci_confoffset_t reg; - pci_moffset_t *paddrp; - pci_msize_t *sizep; - int *cacheablep; -{ - struct cia_config *acp = cpv; - pci_confreg_t addrdata, sizedata; - - if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) - panic("cia_map_mem: bad request"); - - /* - * The PROM has mapped the device for us. We take the address - * that's been assigned to the register, and figure out what - * physical and virtual addresses go with it... - */ - addrdata = PCI_CONF_READ(acp->cc_conffns, acp->cc_confarg, tag, reg); - - PCI_CONF_WRITE(acp->cc_conffns, acp->cc_confarg, tag, reg, 0xffffffff); - sizedata = PCI_CONF_READ(acp->cc_conffns, acp->cc_confarg, tag, reg); - PCI_CONF_WRITE(acp->cc_conffns, acp->cc_confarg, tag, reg, addrdata); - - if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_IO) - panic("cia_map_mem: attempt to memory map an I/O region"); - - switch (PCI_MAPREG_MEM_TYPE(addrdata)) { - case PCI_MAPREG_MEM_TYPE_32BIT: - case PCI_MAPREG_MEM_TYPE_32BIT_1M: - break; - case PCI_MAPREG_MEM_TYPE_64BIT: -/* XXX */ printf("cia_map_mem: attempt to map 64-bit region\n"); -/* XXX */ break; - default: - printf("cia_map_mem: reserved mapping type\n"); - return EINVAL; - } - - if (paddrp != NULL) - *paddrp = PCI_MAPREG_MEM_ADDRESS(addrdata); /* PCI addr */ - if (sizep != NULL) - *sizep = ~PCI_MAPREG_MEM_ADDRESS(sizedata) + 1; - if (cacheablep != NULL) - *cacheablep = PCI_MAPREG_MEM_CACHEABLE(addrdata); - - return 0; -} diff --git a/sys/arch/alpha/pci/ciareg.h b/sys/arch/alpha/pci/ciareg.h index 5fc6ae9435a..403afa6e3de 100644 --- a/sys/arch/alpha/pci/ciareg.h +++ b/sys/arch/alpha/pci/ciareg.h @@ -1,7 +1,7 @@ -/* $NetBSD: ciareg.h,v 1.1 1995/11/23 02:37:31 cgd Exp $ */ +/* $NetBSD: ciareg.h,v 1.1.4.3 1996/06/13 18:35:27 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -38,14 +38,34 @@ /* * Base addresses */ -#define CIA_PCI_SPARSE0 0x8000000000L -#define CIA_PCI_SPARSE1 0x8400000000L -#define CIA_PCI_SPARSE2 0x8500000000L -#define CIA_PCI_SIO0 0x8580000000L -#define CIA_PCI_SIO1 0x85c0000000L +#define CIA_PCI_SMEM1 0x8000000000L +#define CIA_PCI_SMEM2 0x8400000000L +#define CIA_PCI_SMEM3 0x8500000000L +#define CIA_PCI_SIO1 0x8580000000L +#define CIA_PCI_SIO2 0x85c0000000L #define CIA_PCI_DENSE 0x8600000000L #define CIA_PCI_CONF 0x8700000000L #define CIA_PCI_IACK 0x8720000000L #define CIA_CSRS 0x8740000000L #define CIA_PCI_MC_CSRS 0x8750000000L #define CIA_PCI_ATRANS 0x8760000000L + +/* + * General CSRs + */ + +#define CIA_CSR_HAE_MEM (CIA_CSRS + 0x400) + +#define HAE_MEM_REG1_START(x) (((u_int32_t)(x) & 0xe0000000) << 0) +#define HAE_MEM_REG1_MASK 0x1fffffff +#define HAE_MEM_REG2_START(x) (((u_int32_t)(x) & 0x0000f800) << 16) +#define HAE_MEM_REG2_MASK 0x07ffffff +#define HAE_MEM_REG3_START(x) (((u_int32_t)(x) & 0x000000fc) << 16) +#define HAE_MEM_REG3_MASK 0x03ffffff + +#define CIA_CSR_HAE_IO (CIA_CSRS + 0x440) + +#define HAE_IO_REG1_START(x) 0 +#define HAE_IO_REG1_MASK 0x01ffffff +#define HAE_IO_REG2_START(x) (((u_int32_t)(x) & 0xfe000000) << 0) +#define HAE_IO_REG2_MASK 0x01ffffff diff --git a/sys/arch/alpha/pci/ciavar.h b/sys/arch/alpha/pci/ciavar.h index d9241010d89..0a96fe7347b 100644 --- a/sys/arch/alpha/pci/ciavar.h +++ b/sys/arch/alpha/pci/ciavar.h @@ -1,7 +1,7 @@ -/* $NetBSD: ciavar.h,v 1.1 1995/11/23 02:37:35 cgd Exp $ */ +/* $NetBSD: ciavar.h,v 1.3.4.1 1996/06/10 00:04:12 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -37,20 +37,11 @@ * do their dirty work (and more!). */ struct cia_config { - __const struct pci_conf_fns *cc_conffns; - void *cc_confarg; + struct alpha_bus_chipset cc_bc; + struct alpha_pci_chipset cc_pc; - __const struct pci_dma_fns *cc_dmafns; - void *cc_dmaarg; - - __const struct pci_intr_fns *cc_intrfns; - void *cc_intrarg; - - __const struct pci_mem_fns *cc_memfns; - void *cc_memarg; - - __const struct pci_pio_fns *cc_piofns; - void *cc_pioarg; + u_int32_t cc_hae_mem; + u_int32_t cc_hae_io; }; struct cia_softc { @@ -60,10 +51,8 @@ struct cia_softc { /* XXX SGMAP info */ }; -extern __const struct pci_conf_fns cia_conf_fns; -extern __const struct pci_dma_fns cia_dma_fns; -/* pci interrupt functions handled elsewhere */ -extern __const struct pci_mem_fns cia_mem_fns; -extern __const struct pci_pio_fns cia_pio_fns; - void cia_init __P((struct cia_config *)); +void cia_pci_init __P((pci_chipset_tag_t, void *)); + +void cia_bus_mem_init __P((bus_chipset_tag_t bc, void *memv)); +void cia_bus_io_init __P((bus_chipset_tag_t bc, void *iov)); diff --git a/sys/arch/alpha/pci/lca.c b/sys/arch/alpha/pci/lca.c index ac6514fee99..164dd0714be 100644 --- a/sys/arch/alpha/pci/lca.c +++ b/sys/arch/alpha/pci/lca.c @@ -1,10 +1,10 @@ -/* $NetBSD: lca.c,v 1.1 1995/11/23 02:37:38 cgd Exp $ */ +/* $NetBSD: lca.c,v 1.5 1996/04/23 14:00:53 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * - * Author: Jeffrey Hsu + * Authors: Jeffrey Hsu and Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright @@ -48,9 +48,12 @@ int lcamatch __P((struct device *, void *, void *)); void lcaattach __P((struct device *, struct device *, void *)); -struct cfdriver lcacd = { - NULL, "lca", lcamatch, lcaattach, DV_DULL, - sizeof(struct lca_softc) +struct cfattach lca_ca = { + sizeof(struct lca_softc), lcamatch, lcaattach, +}; + +struct cfdriver lca_cd = { + NULL, "lca", DV_DULL, }; static int lcaprint __P((void *, char *pnp)); @@ -68,7 +71,7 @@ lcamatch(parent, match, aux) struct confargs *ca = aux; /* Make sure that we're looking for a LCA. */ - if (strcmp(ca->ca_name, lcacd.cd_name) != 0) + if (strcmp(ca->ca_name, lca_cd.cd_name) != 0) return (0); if (lcafound) @@ -89,20 +92,33 @@ lca_init(lcp) * Can't set up SGMAP data here; can be called before malloc(). */ - lcp->lc_conffns = &lca_conf_fns; - lcp->lc_confarg = lcp; - lcp->lc_dmafns = &lca_dma_fns; - lcp->lc_dmaarg = lcp; - /* Interrupt routines set up in 'attach' */ - lcp->lc_memfns = &lca_mem_fns; - lcp->lc_memarg = lcp; - lcp->lc_piofns = &lca_pio_fns; - lcp->lc_pioarg = lcp; + apecs_lca_bus_io_init(&lcp->lc_bc, lcp); + apecs_lca_bus_mem_init(&lcp->lc_bc, lcp); + lca_pci_init(&lcp->lc_pc, lcp); -/* -printf("lca_init: before IOC_HAE=0x%x\n", REGVAL(LCA_IOC_HAE)); - REGVAL(LCA_IOC_HAE) = 0; */ + /* + * Refer to ``DECchip 21066 and DECchip 21068 Alpha AXP Microprocessors + * Hardware Reference Manual''. + * ... + */ + /* + * According to section 6.4.1, all bits of the IOC_HAE register are + * undefined after reset. Bits <31:27> are write-only. However, we + * cannot blindly set it to zero. The serial ROM code that initializes + * the PCI devices' address spaces, allocates sparse memory blocks in + * the range that must use the IOC_HAE register for address translation, + * and sets this register accordingly (see section 6.4.14). + * + * IOC_HAE left AS IS. + */ + + /* According to section 6.4.2, all bits of the IOC_CONF register are + * undefined after reset. Bits <1:0> are write-only. Set them to + * 0x00 for PCI Type 0 configuration access. + * + * IOC_CONF set to ZERO. + */ REGVAL(LCA_IOC_CONF) = 0; /* Turn off DMA window enables in Window Base Registers */ @@ -142,10 +158,9 @@ lcaattach(parent, self, aux) struct device *parent, *self; void *aux; { - struct confargs *ca = aux; struct lca_softc *sc = (struct lca_softc *)self; struct lca_config *lcp; - struct pci_attach_args pa; + struct pcibus_attach_args pba; /* note that we've attached the chipset; can't have 2 LCAs. */ /* Um, not sure about this. XXX JH */ @@ -167,31 +182,18 @@ lcaattach(parent, self, aux) switch (hwrpb->rpb_type) { #if defined(DEC_AXPPCI_33) case ST_DEC_AXPPCI_33: - pci_axppci_33_pickintr(lcp->lc_conffns, lcp->lc_confarg, - lcp->lc_piofns, lcp->lc_pioarg, - &lcp->lc_intrfns, &lcp->lc_intrarg); + pci_axppci_33_pickintr(lcp); break; #endif default: panic("lcaattach: shouldn't be here, really..."); } - pa.pa_bus = 0; - pa.pa_maxdev = 13; - pa.pa_burstlog2 = 8; - - pa.pa_conffns = lcp->lc_conffns; - pa.pa_confarg = lcp->lc_confarg; - pa.pa_dmafns = lcp->lc_dmafns; - pa.pa_dmaarg = lcp->lc_dmaarg; - pa.pa_intrfns = lcp->lc_intrfns; - pa.pa_intrarg = lcp->lc_intrarg; - pa.pa_memfns = lcp->lc_memfns; - pa.pa_memarg = lcp->lc_memarg; - pa.pa_piofns = lcp->lc_piofns; - pa.pa_pioarg = lcp->lc_pioarg; - - config_found(self, &pa, lcaprint); + pba.pba_busname = "pci"; + pba.pba_bc = &lcp->lc_bc; + pba.pba_pc = &lcp->lc_pc; + pba.pba_bus = 0; + config_found(self, &pba, lcaprint); } static int @@ -199,12 +201,11 @@ lcaprint(aux, pnp) void *aux; char *pnp; { - register struct pci_attach_args *pa = aux; + register struct pcibus_attach_args *pba = aux; - /* what does this do? XXX JH */ /* only PCIs can attach to LCAes; easy. */ if (pnp) - printf("pci at %s", pnp); - printf(" bus %d", pa->pa_bus); + printf("%s at %s", pba->pba_busname, pnp); + printf(" bus %d", pba->pba_bus); return (UNCONF); } diff --git a/sys/arch/alpha/pci/lca_isa.c b/sys/arch/alpha/pci/lca_isa.c deleted file mode 100644 index 205d8708663..00000000000 --- a/sys/arch/alpha/pci/lca_isa.c +++ /dev/null @@ -1,346 +0,0 @@ -/* $NetBSD: lca_isa.c,v 1.1 1995/11/23 02:37:40 cgd Exp $ */ - -/* - * Copyright (c) 1995 Carnegie-Mellon University. - * All rights reserved. - * - * Author: Jeffrey Hsu - * - * Permission to use, copy, modify and distribute this software and - * its documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND - * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -#include <sys/param.h> -#include <sys/malloc.h> -#include <sys/syslog.h> -#include <sys/device.h> -#include <vm/vm.h> - -#include <dev/isa/isavar.h> - -#include <alpha/pci/lcareg.h> -#include <alpha/pci/lcavar.h> - -/* - * Allocation/deallocation functions. - */ -int lca_pio_alloc __P((void *, isa_iooffset_t, isa_iosize_t)); -int lca_pio_dealloc __P((void *, isa_iooffset_t, isa_iosize_t)); - -/* - * Byte functions. - */ -isa_byte_t lca_inb __P((void *, isa_iooffset_t)); -#define lca_insb 0 /* XXX */ -void lca_outb __P((void *, isa_iooffset_t, isa_byte_t)); -#define lca_outsb 0 /* XXX */ - -/* - * Word functions. - */ -isa_word_t lca_inw __P((void *, isa_iooffset_t)); -#define lca_insw 0 /* XXX */ -void lca_outw __P((void *, isa_iooffset_t, isa_word_t)); -#define lca_outsw 0 /* XXX */ - -/* - * Longword functions. - */ -isa_long_t lca_inl __P((void *, isa_iooffset_t)); -#define lca_insl 0 /* XXX */ -void lca_outl __P((void *, isa_iooffset_t, isa_long_t)); -#define lca_outsl 0 /* XXX */ - -__const struct pci_pio_fns lca_pio_fns = { - /* Allocation/deallocation functions. */ - lca_pio_alloc, lca_pio_dealloc, - - /* Byte functions. */ - lca_inb, lca_insb, - lca_outb, lca_outsb, - - /* Word functions. */ - lca_inw, lca_insw, - lca_outw, lca_outsw, - - /* Longword functions. */ - lca_inl, lca_insl, - lca_outl, lca_outsl, -}; - -int -lca_pio_alloc(ipfarg, start, size) - void *ipfarg; - isa_iooffset_t start; - isa_iosize_t size; -{ - - /* XXX should do something */ -} - -int -lca_pio_dealloc(ipfarg, start, size) - void *ipfarg; - isa_iooffset_t start; - isa_iosize_t size; -{ - - /* XXX should do something */ -} - -isa_byte_t -lca_inb(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_byte_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(LCA_PCI_SIO | 0 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xff; -/* rval = val & 0xff; */ - - return rval; -} - -void -lca_outb(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_byte_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - nval = val << (8 * offset); - port = (int32_t *)phystok0seg(LCA_PCI_SIO | 0 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -isa_word_t -lca_inw(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_word_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(LCA_PCI_SIO | 1 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xffff; - rval = val & 0xffff; - -panic("inw(0x%x) => 0x%x @ %p => 0x%x\n", ioaddr, val, port, rval); - - return rval; -} - -void -lca_outw(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_word_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - port = (int32_t *)phystok0seg(LCA_PCI_SIO | 1 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -isa_long_t -lca_inl(ipfa, ioaddr) - void *ipfa; - isa_iooffset_t ioaddr; -{ - u_int32_t *port, val; - isa_long_t rval; - int offset; - - wbflush(); - offset = ioaddr & 3; - port = (int32_t *)phystok0seg(LCA_PCI_SIO | 3 << 3 | ioaddr << 5); - val = *port; - rval = ((val) >> (8 * offset)) & 0xffffffff; - rval = val & 0xffffffff; - - return rval; -} - -void -lca_outl(ipfa, ioaddr, val) - void *ipfa; - isa_iooffset_t ioaddr; - isa_long_t val; -{ - u_int32_t *port, nval; - int offset; - - offset = ioaddr & 3; - nval = val /*<< (8 * offset)*/; - port = (int32_t *)phystok0seg(LCA_PCI_SIO | 3 << 3 | ioaddr << 5); - - *port = nval; - wbflush(); -} - -/* XXX XXX XXX */ - -#define pf(fn, args) fn args { panic(__STRING(fn)); } - -void pf(lca_dma_cascade, (void *idfa, isa_drq_t chan)) -void pf(lca_dma_copytobuf, ()) -void pf(lca_dma_copyfrombuf, ()) -void pf(lca_dma_start, (void *idfa, vm_offset_t addr, - isa_msize_t size, isa_drq_t chan, int flags)) -void pf(lca_dma_abort, (void *idfa, isa_drq_t chan)) -void pf(lca_dma_done, (void *idfa, isa_drq_t chan)) - -int lca_dma_map __P((void *, vm_offset_t, isa_msize_t, - isa_moffset_t *, int)); -void lca_dma_unmap __P((void *, vm_offset_t, isa_msize_t, int, - isa_moffset_t *)); - -__const struct isa_dma_fns lca_dma_fns = { - lca_dma_cascade, - lca_dma_map, - lca_dma_unmap, - lca_dma_copytobuf, - lca_dma_copyfrombuf, - lca_dma_start, - lca_dma_abort, - lca_dma_done, -}; - -int -lca_dma_map(idfa, va, isasize, mappingsp, flags) - void *idfa; - vm_offset_t va; - isa_msize_t isasize; - isa_moffset_t *mappingsp; - int flags; -{ - struct lca_config *acp = idfa; - long todo; - int i; - - if (ISA_DMA_NEEDCONTIG(flags) && isasize > NBPG || - ISA_DMA_SIZEBOUND(flags) != ISA_DMA_SIZEBOUND_NONE || - ISA_DMA_ADDRBOUND(flags) != ISA_DMA_ADDRBOUND_NONE) - panic("lca_dma_map: punt"); - - i = 0; - todo = isasize; - - while (todo > 0) { - mappingsp[i] = vtophys(va) | 0x40000000; -#if 0 - printf("a_pd_m mapping %d: %lx -> %lx -> %lx\n", i, va, - vtophys(va), mappingsp[i]); -#endif - i++; - todo -= PAGE_SIZE - (va - trunc_page(va)); - va += PAGE_SIZE - (va - trunc_page(va)); - } - return (i); -} - -void -lca_dma_unmap(idfa, va, isasize, nmappings, mappingsp) - void *idfa; - vm_offset_t va; - isa_msize_t isasize; - int nmappings; - isa_moffset_t *mappingsp; -{ - - printf("lca_dma_unmap: called\n"); -} - -vm_offset_t lca_mem_map __P((void *, isa_moffset_t, isa_msize_t, int)); -void lca_mem_unmap __P((void *, vm_offset_t, isa_msize_t)); - -#if 0 -void lca_mem_copytoisa __P((void *, char *, vm_offset_t, - isa_moffset_t, isa_msize_t)); -void lca_mem_copyfromisa __P((void *, char *, vm_offset_t, - isa_moffset_t, isa_msize_t)); -void lca_mem_zero __P((void *, vm_offset_t, isa_moffset_t, - isa_msize_t)); -#else -void pf(lca_mem_copytoisa, ()) -void pf(lca_mem_copyfromisa, ()) -void pf(lca_mem_zero, ()) -#endif - -__const struct isa_mem_fns lca_mem_fns = { - lca_mem_map, - lca_mem_unmap, - lca_mem_copytoisa, - lca_mem_copyfromisa, - lca_mem_zero, -}; - -vm_offset_t -lca_mem_map(imfa, isapa, isasize, cacheable) - void *imfa; - isa_moffset_t isapa; - isa_msize_t isasize; - int cacheable; -{ - vm_offset_t sbpa; - - /* XXX sanity checks on sizes, use of windows, etc. */ - - /* XXX MAGIC NUMBERS */ - if (cacheable) - sbpa = (isapa & 0xffffffff) | LCA_PCI_DENSE; - else - sbpa = ((isapa & 0x7ffffff) << 5) | LCA_PCI_SPARSE; - - return phystok0seg(sbpa); -} - -void -lca_mem_unmap(imfa, va, isasize) - void *imfa; - vm_offset_t va; - isa_msize_t isasize; -{ - - /* XXX sanity checks on va */ - - /* Nothing to do; mapping was done in direct-mapped segment. */ -} diff --git a/sys/arch/alpha/pci/lca_pci.c b/sys/arch/alpha/pci/lca_pci.c index 1b151dcefb9..8d11ddd5ff3 100644 --- a/sys/arch/alpha/pci/lca_pci.c +++ b/sys/arch/alpha/pci/lca_pci.c @@ -1,10 +1,10 @@ -/* $NetBSD: lca_pci.c,v 1.1 1995/11/23 02:37:42 cgd Exp $ */ +/* $NetBSD: lca_pci.c,v 1.3 1996/04/23 14:01:00 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * - * Author: Jeffrey Hsu + * Author: Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright @@ -38,62 +38,119 @@ #include <alpha/pci/lcareg.h> #include <alpha/pci/lcavar.h> -pci_confreg_t lca_conf_read __P((void *, pci_conftag_t, pci_confoffset_t)); -void lca_conf_write __P((void *, pci_conftag_t, - pci_confoffset_t, pci_confreg_t)); -int lca_find_io __P((void *, pci_conftag_t, - pci_confoffset_t, pci_iooffset_t *, pci_iosize_t *)); -int lca_find_mem __P((void *, pci_conftag_t, - pci_confoffset_t, pci_moffset_t *, pci_msize_t *, int *)); - -__const struct pci_conf_fns lca_conf_fns = { - lca_conf_read, - lca_conf_write, - lca_find_io, - lca_find_mem, -}; - -pci_confreg_t -lca_conf_read(cpv, tag, offset) +void lca_attach_hook __P((struct device *, struct device *, + struct pcibus_attach_args *)); +int lca_bus_maxdevs __P((void *, int)); +pcitag_t lca_make_tag __P((void *, int, int, int)); +void lca_decompose_tag __P((void *, pcitag_t, int *, int *, + int *)); +pcireg_t lca_conf_read __P((void *, pcitag_t, int)); +void lca_conf_write __P((void *, pcitag_t, int, pcireg_t)); + +void +lca_pci_init(pc, v) + pci_chipset_tag_t pc; + void *v; +{ + + pc->pc_conf_v = v; + pc->pc_attach_hook = lca_attach_hook; + pc->pc_bus_maxdevs = lca_bus_maxdevs; + pc->pc_make_tag = lca_make_tag; + pc->pc_decompose_tag = lca_decompose_tag; + pc->pc_conf_read = lca_conf_read; + pc->pc_conf_write = lca_conf_write; +} + +void +lca_attach_hook(parent, self, pba) + struct device *parent, *self; + struct pcibus_attach_args *pba; +{ +} + +int +lca_bus_maxdevs(cpv, busno) + void *cpv; + int busno; +{ + + if (busno == 0) + return 16; + else + return 32; +} + +pcitag_t +lca_make_tag(cpv, b, d, f) void *cpv; - pci_conftag_t tag; - pci_confoffset_t offset; + int b, d, f; { - pci_confreg_t *datap, data; - int s, secondary, ba; - int32_t old_ioc_conf; /* XXX */ - u_int64_t dev_sel; - dev_sel = 1 << PCI_TAG_DEVICE(tag) + 11; + return (b << 16) | (d << 11) | (f << 8); +} + +void +lca_decompose_tag(cpv, tag, bp, dp, fp) + void *cpv; + pcitag_t tag; + int *bp, *dp, *fp; +{ + + if (bp != NULL) + *bp = (tag >> 16) & 0xff; + if (dp != NULL) + *dp = (tag >> 11) & 0x1f; + if (fp != NULL) + *fp = (tag >> 8) & 0x7; +} + +pcireg_t +lca_conf_read(cpv, tag, offset) + void *cpv; + pcitag_t tag; + int offset; +{ + struct lca_config *lcp = cpv; + pcireg_t *datap, data; + int s, secondary, device, ba; - secondary = PCI_TAG_BUS(tag) != 0; + /* secondary if bus # != 0 */ + pci_decompose_tag(&lcp->lc_pc, tag, &secondary, &device, 0); if (secondary) { s = splhigh(); - old_ioc_conf = REGVAL(LCA_IOC_CONF); wbflush(); - REGVAL(LCA_IOC_CONF) = old_ioc_conf | 0x1; + REGVAL(LCA_IOC_CONF) = 0x01; wbflush(); + } else { + /* + * on the LCA, must frob the tag used for + * devices on the primary bus, in the same ways + * as is used by type 1 configuration cycles + * on PCs. + */ + tag = (1 << (device + 11)) | (tag & 0x7ff); } - datap = (pci_confreg_t *)phystok0seg(LCA_PCI_CONF | - dev_sel << 5UL | /* XXX */ + datap = (pcireg_t *)phystok0seg(LCA_PCI_CONF | + tag << 5UL | /* XXX */ (offset & ~0x03) << 5 | /* XXX */ 0 << 5 | /* XXX */ 0x3 << 3); /* XXX */ - data = (pci_confreg_t)-1; + data = (pcireg_t)-1; if (!(ba = badaddr(datap, sizeof *datap))) data = *datap; if (secondary) { wbflush(); - REGVAL(LCA_IOC_CONF) = old_ioc_conf; + REGVAL(LCA_IOC_CONF) = 0x00; wbflush(); splx(s); } #if 0 - printf("lca_conf_read: tag 0x%x, offset 0x%x -> %x @ %p%s\n", tag, - offset, data, datap, ba ? " (badaddr)" : ""); + printf("lca_conf_read: tag 0x%lx, reg 0x%lx -> %x @ %p%s\n", tag, reg, + data, datap, ba ? " (badaddr)" : ""); #endif return data; @@ -102,28 +159,33 @@ lca_conf_read(cpv, tag, offset) void lca_conf_write(cpv, tag, offset, data) void *cpv; - pci_conftag_t tag; - pci_confoffset_t offset; - pci_confreg_t data; + pcitag_t tag; + int offset; + pcireg_t data; { - pci_confreg_t *datap; - int s, secondary; - int32_t old_ioc_conf; /* XXX */ - int32_t dev_sel; - - dev_sel = 1 << PCI_TAG_DEVICE(tag) + 11; + struct lca_config *lcp = cpv; + pcireg_t *datap; + int s, secondary, device; - secondary = PCI_TAG_BUS(tag) != 0; + /* secondary if bus # != 0 */ + pci_decompose_tag(&lcp->lc_pc, tag, &secondary, &device, 0); if (secondary) { s = splhigh(); - old_ioc_conf = REGVAL(LCA_IOC_CONF); wbflush(); - REGVAL(LCA_IOC_CONF) = old_ioc_conf | 0x1; + REGVAL(LCA_IOC_CONF) = 0x01; wbflush(); + } else { + /* + * on the LCA, must frob the tag used for + * devices on the primary bus, in the same ways + * as is used by type 1 configuration cycles + * on PCs. + */ + tag = (1 << (device + 11)) | (tag & 0x7ff); } - datap = (pci_confreg_t *)phystok0seg(LCA_PCI_CONF | - dev_sel << 5UL | /* XXX */ + datap = (pcireg_t *)phystok0seg(LCA_PCI_CONF | + tag << 5UL | /* XXX */ (offset & ~0x03) << 5 | /* XXX */ 0 << 5 | /* XXX */ 0x3 << 3); /* XXX */ @@ -131,96 +193,13 @@ lca_conf_write(cpv, tag, offset, data) if (secondary) { wbflush(); - REGVAL(LCA_IOC_CONF) = old_ioc_conf; + REGVAL(LCA_IOC_CONF) = 0x00; wbflush(); splx(s); } #if 0 - printf("lca_conf_write: tag 0x%x, offset 0x%x -> 0x%x @ %p\n", tag, - offset, data, datap); + printf("lca_conf_write: tag 0x%lx, reg 0x%lx -> 0x%x @ %p\n", tag, + reg, data, datap); #endif } - -int -lca_find_io(cpv, tag, reg, iobasep, sizep) - void *cpv; - pci_conftag_t tag; - pci_confoffset_t reg; - pci_iooffset_t *iobasep; - pci_iosize_t *sizep; -{ - struct lca_config *lcp = cpv; - pci_confreg_t addrdata, sizedata; - pci_iooffset_t pci_iobase; - - if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) - panic("lca_map_io: bad request"); - - addrdata = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, tag, reg); - - PCI_CONF_WRITE(lcp->lc_conffns, lcp->lc_confarg, tag, reg, 0xffffffff); - sizedata = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, tag, reg); - PCI_CONF_WRITE(lcp->lc_conffns, lcp->lc_confarg, tag, reg, addrdata); - - if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_MEM) - panic("lca_map_io: attempt to I/O map an memory region"); - - if (iobasep != NULL) - *iobasep = PCI_MAPREG_IO_ADDRESS(addrdata); - if (sizep != NULL) - *sizep = ~PCI_MAPREG_IO_ADDRESS(sizedata) + 1; - - return (0); -} - -int -lca_find_mem(cpv, tag, reg, paddrp, sizep, cacheablep) - void *cpv; - pci_conftag_t tag; - pci_confoffset_t reg; - pci_moffset_t *paddrp; - pci_msize_t *sizep; - int *cacheablep; -{ - struct lca_config *lcp = cpv; - pci_confreg_t addrdata, sizedata; - - if (reg < PCI_MAPREG_START || reg >= PCI_MAPREG_END || (reg & 3)) - panic("lca_map_mem: bad request"); - - /* - * The PROM has mapped the device for us. We take the address - * that's been assigned to the register, and figure out what - * physical and virtual addresses go with it... - */ - addrdata = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, tag, reg); - - PCI_CONF_WRITE(lcp->lc_conffns, lcp->lc_confarg, tag, reg, 0xffffffff); - sizedata = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, tag, reg); - PCI_CONF_WRITE(lcp->lc_conffns, lcp->lc_confarg, tag, reg, addrdata); - - if (PCI_MAPREG_TYPE(addrdata) == PCI_MAPREG_TYPE_IO) - panic("lca_map_mem: attempt to memory map an I/O region"); - - switch (PCI_MAPREG_MEM_TYPE(addrdata)) { - case PCI_MAPREG_MEM_TYPE_32BIT: - case PCI_MAPREG_MEM_TYPE_32BIT_1M: - break; - case PCI_MAPREG_MEM_TYPE_64BIT: -/* XXX */ printf("lca_map_mem: attempt to map 64-bit region\n"); -/* XXX */ break; - default: - printf("lca_map_mem: reserved mapping type\n"); - return EINVAL; - } - - if (paddrp != NULL) - *paddrp = PCI_MAPREG_MEM_ADDRESS(addrdata); /* PCI addr */ - if (sizep != NULL) - *sizep = ~PCI_MAPREG_MEM_ADDRESS(sizedata) + 1; - if (cacheablep != NULL) - *cacheablep = PCI_MAPREG_MEM_CACHEABLE(addrdata); - - return 0; -} diff --git a/sys/arch/alpha/pci/lcareg.h b/sys/arch/alpha/pci/lcareg.h index ac876e3110d..2a36401be8d 100644 --- a/sys/arch/alpha/pci/lcareg.h +++ b/sys/arch/alpha/pci/lcareg.h @@ -1,4 +1,4 @@ -/* $NetBSD: lcareg.h,v 1.1 1995/11/23 02:37:44 cgd Exp $ */ +/* $NetBSD: lcareg.h,v 1.2 1996/04/23 14:03:46 cgd Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -45,6 +45,8 @@ #define LCA_IOC_HAE LCA_IOC_BASE /* Host Address Extension */ #define LCA_IOC_CONF (LCA_IOC_BASE + 0x020) /* Configuration Cycle Type */ +#define LCA_IOC_STAT0 (LCA_IOC_BASE + 0x040) /* Status 0 */ +#define LCA_IOC_STAT1 (LCA_IOC_BASE + 0x060) /* Status 1 */ #define LCA_IOC_W_BASE0 (LCA_IOC_BASE + 0x100) /* Window Base */ #define LCA_IOC_W_MASK0 (LCA_IOC_BASE + 0x140) /* Window Mask */ diff --git a/sys/arch/alpha/pci/lcavar.h b/sys/arch/alpha/pci/lcavar.h index 80c70807172..1b2cf4bf816 100644 --- a/sys/arch/alpha/pci/lcavar.h +++ b/sys/arch/alpha/pci/lcavar.h @@ -1,7 +1,7 @@ -/* $NetBSD: lcavar.h,v 1.1 1995/11/23 02:37:47 cgd Exp $ */ +/* $NetBSD: lcavar.h,v 1.3 1996/04/12 06:08:35 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Jeffrey Hsu @@ -37,20 +37,8 @@ * do their dirty work (and more!). */ struct lca_config { - __const struct pci_conf_fns *lc_conffns; - void *lc_confarg; - - __const struct pci_dma_fns *lc_dmafns; - void *lc_dmaarg; - - __const struct pci_intr_fns *lc_intrfns; - void *lc_intrarg; - - __const struct pci_mem_fns *lc_memfns; - void *lc_memarg; - - __const struct pci_pio_fns *lc_piofns; - void *lc_pioarg; + struct alpha_bus_chipset lc_bc; + struct alpha_pci_chipset lc_pc; }; struct lca_softc { @@ -59,10 +47,5 @@ struct lca_softc { struct lca_config *sc_lcp; }; -extern __const struct pci_conf_fns lca_conf_fns; -extern __const struct pci_dma_fns lca_dma_fns; -/* pci interrupt functions handled elsewhere */ -extern __const struct pci_mem_fns lca_mem_fns; -extern __const struct pci_pio_fns lca_pio_fns; - void lca_init __P((struct lca_config *)); +void lca_pci_init __P((pci_chipset_tag_t, void *)); diff --git a/sys/arch/alpha/pci/pci_2100_a50.c b/sys/arch/alpha/pci/pci_2100_a50.c index 06fbc924b02..b9420c5ce01 100644 --- a/sys/arch/alpha/pci/pci_2100_a50.c +++ b/sys/arch/alpha/pci/pci_2100_a50.c @@ -1,7 +1,7 @@ -/* $NetBSD: pci_2100_a50.c,v 1.4 1995/12/24 02:29:42 mycroft Exp $ */ +/* $NetBSD: pci_2100_a50.c,v 1.7 1996/04/23 14:15:55 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -35,6 +35,9 @@ #include <sys/device.h> #include <vm/vm.h> +#include <machine/bus.h> +#include <machine/intr.h> + #include <dev/isa/isavar.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> @@ -43,45 +46,72 @@ #include <alpha/pci/pci_2100_a50.h> #include <alpha/pci/siovar.h> +#include <alpha/pci/sioreg.h> #include "sio.h" -void *dec_2100_a50_pci_map_int __P((void *, pci_conftag_t, - pci_intr_pin_t, pci_intr_line_t, int, - int (*func)(void *), void *, char *)); -void dec_2100_a50_pci_unmap_int __P((void *, void *)); +int dec_2100_a50_intr_map __P((void *, pcitag_t, int, int, + pci_intr_handle_t *)); +const char *dec_2100_a50_intr_string __P((void *, pci_intr_handle_t)); +void *dec_2100_a50_intr_establish __P((void *, pci_intr_handle_t, + int, int (*func)(void *), void *)); +void dec_2100_a50_intr_disestablish __P((void *, void *)); -__const struct pci_intr_fns dec_2100_a50_pci_intr_fns = { - dec_2100_a50_pci_map_int, - dec_2100_a50_pci_unmap_int, -}; +#define APECS_SIO_DEVICE 7 /* XXX */ -void * -dec_2100_a50_pci_map_int(acv, tag, pin, line, level, func, arg, what) +void +pci_2100_a50_pickintr(acp) + struct apecs_config *acp; +{ + bus_chipset_tag_t bc = &acp->ac_bc; + pci_chipset_tag_t pc = &acp->ac_pc; + pcireg_t sioclass; + int sioII; + + /* XXX MAGIC NUMBER */ + sioclass = pci_conf_read(pc, pci_make_tag(pc, 0, 7, 0), PCI_CLASS_REG); + sioII = (sioclass & 0xff) >= 3; + + if (!sioII) + printf("WARNING: SIO NOT SIO II... NO BETS...\n"); + + pc->pc_intr_v = acp; + pc->pc_intr_map = dec_2100_a50_intr_map; + pc->pc_intr_string = dec_2100_a50_intr_string; + pc->pc_intr_establish = dec_2100_a50_intr_establish; + pc->pc_intr_disestablish = dec_2100_a50_intr_disestablish; + +#if NSIO + sio_intr_setup(bc); + set_iointr(&sio_iointr); +#else + panic("pci_2100_a50_pickintr: no I/O interrupt handler (no sio)"); +#endif +} + +int +dec_2100_a50_intr_map(acv, bustag, buspin, line, ihp) void *acv; - pci_conftag_t tag; - pci_intr_pin_t pin; - pci_intr_line_t line; - int level; - int (*func) __P((void *)); - void *arg; - char *what; + pcitag_t bustag; + int buspin, line; + pci_intr_handle_t *ihp; { struct apecs_config *acp = acv; - int bus, device, pirq; - pci_confreg_t irreg, pirqreg; + pci_chipset_tag_t pc = &acp->ac_pc; + int device, pirq; + pcireg_t pirqreg; u_int8_t pirqline; - if (pin == 0) { + if (buspin == 0) { /* No IRQ used. */ - return 0; + return 1; } - if (pin > 4) { - printf("pci_map_int: bad interrupt pin %d\n", pin); - return NULL; + if (buspin > 4) { + printf("pci_map_int: bad interrupt pin %d\n", buspin); + return 1; } - device = PCI_TAG_DEVICE(tag); + pci_decompose_tag(pc, bustag, NULL, &device, NULL); switch (device) { case 6: /* NCR SCSI */ @@ -89,7 +119,8 @@ dec_2100_a50_pci_map_int(acv, tag, pin, line, level, func, arg, what) break; case 11: /* slot 1 */ - switch (pin) { + case 14: /* slot 3 */ + switch (buspin) { case PCI_INTERRUPT_PIN_A: case PCI_INTERRUPT_PIN_D: pirq = 0; @@ -104,7 +135,7 @@ dec_2100_a50_pci_map_int(acv, tag, pin, line, level, func, arg, what) break; case 12: /* slot 2 */ - switch (pin) { + switch (buspin) { case PCI_INTERRUPT_PIN_A: case PCI_INTERRUPT_PIN_D: pirq = 1; @@ -119,7 +150,7 @@ dec_2100_a50_pci_map_int(acv, tag, pin, line, level, func, arg, what) break; case 13: /* slot 3 */ - switch (pin) { + switch (buspin) { case PCI_INTERRUPT_PIN_A: case PCI_INTERRUPT_PIN_D: pirq = 2; @@ -134,64 +165,54 @@ dec_2100_a50_pci_map_int(acv, tag, pin, line, level, func, arg, what) break; } - pirqreg = PCI_CONF_READ(acp->ac_conffns, acp->ac_confarg, - PCI_MAKE_TAG(0, 7, 0), 0x60); /* XXX */ + pirqreg = pci_conf_read(pc, pci_make_tag(pc, 0, APECS_SIO_DEVICE, 0), + SIO_PCIREG_PIRQ_RTCTRL); #if 0 printf("pci_2100_a50_map_int: device %d pin %c: pirq %d, reg = %x\n", - device, '@' + pin, pirq, pirqreg); + device, '@' + buspin, pirq, pirqreg); #endif pirqline = (pirqreg >> (pirq * 8)) & 0xff; if ((pirqline & 0x80) != 0) - return 0; /* not routed? */ + return 1; pirqline &= 0xf; #if 0 printf("pci_2100_a50_map_int: device %d pin %c: mapped to line %d\n", - device, '@' + pin, pirqline); + device, '@' + buspin, pirqline); #endif -#if NSIO - return ISA_INTR_ESTABLISH(&sio_isa_intr_fns, NULL, /* XXX */ - pirqline, IST_LEVEL, level, func, arg); -#else - panic("dec_2100_a50_pci_map_int: no sio!"); -#endif + *ihp = pirqline; + return (0); } -void -dec_2100_a50_pci_unmap_int(pifa, cookie) - void *pifa; - void *cookie; +const char * +dec_2100_a50_intr_string(acv, ih) + void *acv; + pci_intr_handle_t ih; { + struct apecs_config *acp = acv; - panic("dec_2100_a50_pci_unmap_int not implemented"); /* XXX */ + return sio_intr_string(NULL /*XXX*/, ih); } -void -pci_2100_a50_pickintr(pcf, pcfa, ppf, ppfa, pifp, pifap) - __const struct pci_conf_fns *pcf; - __const struct pci_pio_fns *ppf; - void *pcfa, *ppfa; - __const struct pci_intr_fns **pifp; - void **pifap; +void * +dec_2100_a50_intr_establish(acv, ih, level, func, arg) + void *acv, *arg; + pci_intr_handle_t ih; + int level; + int (*func) __P((void *)); { - pci_confreg_t sioclass; - int sioII; + struct apecs_config *acp = acv; - /* XXX MAGIC NUMBER */ - sioclass = PCI_CONF_READ(pcf, pcfa, PCI_MAKE_TAG(0, 7, 0), - PCI_CLASS_REG); - sioII = (sioclass & 0xff) >= 3; + return sio_intr_establish(NULL /*XXX*/, ih, IST_LEVEL, level, func, + arg); +} - if (!sioII) - printf("WARNING: SIO NOT SIO II... NO BETS...\n"); +void +dec_2100_a50_intr_disestablish(acv, cookie) + void *acv, *cookie; +{ + struct apecs_config *acp = acv; - *pifp = &dec_2100_a50_pci_intr_fns; - *pifap = pcfa; /* XXX assumes apecs_config ptr */ -#if NSIO - sio_intr_setup(ppf, ppfa); - set_iointr(&sio_iointr); -#else - panic("pci_2100_a50_pickintr: no I/O interrupt handler (no sio)"); -#endif + sio_intr_disestablish(NULL /*XXX*/, cookie); } diff --git a/sys/arch/alpha/pci/pci_2100_a50.h b/sys/arch/alpha/pci/pci_2100_a50.h index 08c22aef089..ed450aa2f97 100644 --- a/sys/arch/alpha/pci/pci_2100_a50.h +++ b/sys/arch/alpha/pci/pci_2100_a50.h @@ -1,7 +1,7 @@ -/* $NetBSD: pci_2100_a50.h,v 1.1 1995/11/23 02:37:51 cgd Exp $ */ +/* $NetBSD: pci_2100_a50.h,v 1.3 1996/04/12 06:08:42 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -27,6 +27,4 @@ * rights to redistribute these changes. */ -void pci_2100_a50_pickintr __P((__const struct pci_conf_fns *, void *, - __const struct pci_pio_fns *, void *, - __const struct pci_intr_fns **, void **)); +void pci_2100_a50_pickintr __P((struct apecs_config *)); diff --git a/sys/arch/alpha/pci/pci_axppci_33.c b/sys/arch/alpha/pci/pci_axppci_33.c index 2cfb453226b..008f5111636 100644 --- a/sys/arch/alpha/pci/pci_axppci_33.c +++ b/sys/arch/alpha/pci/pci_axppci_33.c @@ -1,10 +1,10 @@ -/* $NetBSD: pci_axppci_33.c,v 1.2 1995/12/24 02:29:43 mycroft Exp $ */ +/* $NetBSD: pci_axppci_33.c,v 1.5 1996/04/23 14:15:28 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * - * Author: Jeffrey Hsu + * Authors: Jeffrey Hsu and Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright @@ -35,6 +35,9 @@ #include <sys/device.h> #include <vm/vm.h> +#include <machine/bus.h> +#include <machine/intr.h> + #include <dev/isa/isavar.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> @@ -42,47 +45,74 @@ #include <alpha/pci/lcavar.h> #include <alpha/pci/pci_axppci_33.h> - #include <alpha/pci/siovar.h> +#include <alpha/pci/sioreg.h> #include "sio.h" -void *dec_axppci_33_pci_map_int __P((void *, pci_conftag_t, - pci_intr_pin_t, pci_intr_line_t, int, - int (*func)(void *), void *, char *)); -void dec_axppci_33_pci_unmap_int __P((void *, void *)); +int dec_axppci_33_intr_map __P((void *, pcitag_t, int, int, + pci_intr_handle_t *)); +const char *dec_axppci_33_intr_string __P((void *, pci_intr_handle_t)); +void *dec_axppci_33_intr_establish __P((void *, pci_intr_handle_t, + int, int (*func)(void *), void *)); +void dec_axppci_33_intr_disestablish __P((void *, void *)); -__const struct pci_intr_fns dec_axppci_33_pci_intr_fns = { - dec_axppci_33_pci_map_int, - dec_axppci_33_pci_unmap_int, -}; +#define LCA_SIO_DEVICE 7 /* XXX */ -void * -dec_axppci_33_pci_map_int(lcv, tag, pin, line, level, func, arg, what) +void +pci_axppci_33_pickintr(lcp) + struct lca_config *lcp; +{ + bus_chipset_tag_t bc = &lcp->lc_bc; + pci_chipset_tag_t pc = &lcp->lc_pc; + pcireg_t sioclass; + int sioII; + + /* XXX MAGIC NUMBER */ + sioclass = pci_conf_read(pc, pci_make_tag(pc, 0, LCA_SIO_DEVICE, 0), + PCI_CLASS_REG); + sioII = (sioclass & 0xff) >= 3; + + if (!sioII) + printf("WARNING: SIO NOT SIO II... NO BETS...\n"); + + pc->pc_intr_v = lcp; + pc->pc_intr_map = dec_axppci_33_intr_map; + pc->pc_intr_string = dec_axppci_33_intr_string; + pc->pc_intr_establish = dec_axppci_33_intr_establish; + pc->pc_intr_disestablish = dec_axppci_33_intr_disestablish; + +#if NSIO + sio_intr_setup(bc); + set_iointr(&sio_iointr); +#else + panic("pci_axppci_33_pickintr: no I/O interrupt handler (no sio)"); +#endif +} + +int +dec_axppci_33_intr_map(lcv, bustag, buspin, line, ihp) void *lcv; - pci_conftag_t tag; - pci_intr_pin_t pin; - pci_intr_line_t line; - int level; - int (*func) __P((void *)); - void *arg; - char *what; + pcitag_t bustag; + int buspin, line; + pci_intr_handle_t *ihp; { struct lca_config *lcp = lcv; - int bus, device, pirq; - pci_confreg_t irreg, pirqreg; + pci_chipset_tag_t pc = &lcp->lc_pc; + int device, pirq; + pcireg_t pirqreg; u_int8_t pirqline; - if (pin == 0) { + if (buspin == 0) { /* No IRQ used. */ - return 0; + return 1; } - if (pin > 4) { - printf("dec_axppci_33_map_int: bad interrupt pin %d\n", pin); - return NULL; + if (buspin > 4) { + printf("pci_map_int: bad interrupt pin %d\n", buspin); + return 1; } - device = PCI_TAG_DEVICE(tag); + pci_decompose_tag(pc, bustag, NULL, &device, NULL); switch (device) { case 6: /* NCR SCSI */ @@ -90,7 +120,7 @@ dec_axppci_33_pci_map_int(lcv, tag, pin, line, level, func, arg, what) break; case 11: /* slot 1 */ - switch (pin) { + switch (buspin) { case PCI_INTERRUPT_PIN_A: case PCI_INTERRUPT_PIN_D: pirq = 0; @@ -105,7 +135,7 @@ dec_axppci_33_pci_map_int(lcv, tag, pin, line, level, func, arg, what) break; case 12: /* slot 2 */ - switch (pin) { + switch (buspin) { case PCI_INTERRUPT_PIN_A: case PCI_INTERRUPT_PIN_D: pirq = 1; @@ -120,7 +150,7 @@ dec_axppci_33_pci_map_int(lcv, tag, pin, line, level, func, arg, what) break; case 8: /* slot 3 */ - switch (pin) { + switch (buspin) { case PCI_INTERRUPT_PIN_A: case PCI_INTERRUPT_PIN_D: pirq = 2; @@ -139,66 +169,54 @@ dec_axppci_33_pci_map_int(lcv, tag, pin, line, level, func, arg, what) panic("dec_axppci_33_pci_map_int: bad device number"); } -#define LCA_SIO_DEVICE 7 /* XXX */ - - pirqreg = PCI_CONF_READ(lcp->lc_conffns, lcp->lc_confarg, - PCI_MAKE_TAG(0, LCA_SIO_DEVICE, 0), 0x60); /* XXX */ + pirqreg = pci_conf_read(pc, pci_make_tag(pc, 0, LCA_SIO_DEVICE, 0), + SIO_PCIREG_PIRQ_RTCTRL); #if 0 - printf("dec_pci_axppci_33_map_int: device %d pin %c: pirq %d, reg = %x\n", - device, '@' + pin, pirq, pirqreg); + printf("pci_axppci_33_map_int: device %d pin %c: pirq %d, reg = %x\n", + device, '@' + buspin, pirq, pirqreg); #endif pirqline = (pirqreg >> (pirq * 8)) & 0xff; if ((pirqline & 0x80) != 0) - return 0; /* not routed? */ + return 1; /* not routed? */ pirqline &= 0xf; #if 0 - printf("dec_pci_axppci_33_map_int: device %d pin %c: mapped to line %d\n", - device, '@' + pin, pirqline); + printf("pci_axppci_33_map_int: device %d pin %c: mapped to line %d\n", + device, '@' + buspin, pirqline); #endif -#if NSIO - return ISA_INTR_ESTABLISH(&sio_isa_intr_fns, NULL, /* XXX */ - pirqline, IST_LEVEL, level, func, arg); -#else - panic("dec_axppci_33_pci_map_int: no sio!"); -#endif + *ihp = pirqline; + return (0); } -void -dec_axppci_33_pci_unmap_int(pifa, cookie) - void *pifa; - void *cookie; +const char * +dec_axppci_33_intr_string(lcv, ih) + void *lcv; + pci_intr_handle_t ih; { + struct lca_config *lcp = lcv; - panic("dec_axppci_33_pci_unmap_int not implemented"); /* XXX */ + return sio_intr_string(NULL /*XXX*/, ih); } -void -pci_axppci_33_pickintr(pcf, pcfa, ppf, ppfa, pifp, pifap) - __const struct pci_conf_fns *pcf; - __const struct pci_pio_fns *ppf; - void *pcfa, *ppfa; - __const struct pci_intr_fns **pifp; - void **pifap; +void * +dec_axppci_33_intr_establish(lcv, ih, level, func, arg) + void *lcv, *arg; + pci_intr_handle_t ih; + int level; + int (*func) __P((void *)); { - pci_confreg_t sioclass; - int sioII; + struct lca_config *lcp = lcv; - /* XXX MAGIC NUMBER */ - sioclass = PCI_CONF_READ(pcf, pcfa, PCI_MAKE_TAG(0, LCA_SIO_DEVICE, 0), - PCI_CLASS_REG); - sioII = (sioclass & 0xff) >= 3; + return sio_intr_establish(NULL /*XXX*/, ih, IST_LEVEL, level, func, + arg); +} - if (!sioII) - printf("WARNING: SIO NOT SIO II... NO BETS...\n"); +void +dec_axppci_33_intr_disestablish(lcv, cookie) + void *lcv, *cookie; +{ + struct lca_config *lcp = lcv; - *pifp = &dec_axppci_33_pci_intr_fns; - *pifap = pcfa; /* XXX assumes apecs_config ptr */ -#if NSIO - sio_intr_setup(ppf, ppfa); - set_iointr(&sio_iointr); -#else - panic("pci_axppci_33_pickintr: no I/O interrupt handler (no sio)"); -#endif + sio_intr_disestablish(NULL /*XXX*/, cookie); } diff --git a/sys/arch/alpha/pci/pci_axppci_33.h b/sys/arch/alpha/pci/pci_axppci_33.h index 342eb0dfd71..27dfa1f4b04 100644 --- a/sys/arch/alpha/pci/pci_axppci_33.h +++ b/sys/arch/alpha/pci/pci_axppci_33.h @@ -1,10 +1,10 @@ -/* $NetBSD: pci_axppci_33.h,v 1.1 1995/11/23 02:37:56 cgd Exp $ */ +/* $NetBSD: pci_axppci_33.h,v 1.3 1996/04/12 06:08:47 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * - * Author: Jeffrey Hsu + * Author: Chris G. Demetriou * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright @@ -27,6 +27,4 @@ * rights to redistribute these changes. */ -void pci_axppci_33_pickintr __P((__const struct pci_conf_fns *, void *, - __const struct pci_pio_fns *, void *, - __const struct pci_intr_fns **, void **)); +void pci_axppci_33_pickintr __P((struct lca_config *)); diff --git a/sys/arch/alpha/pci/pci_kn20aa.c b/sys/arch/alpha/pci/pci_kn20aa.c index f8cff214e01..6a5582c7cd3 100644 --- a/sys/arch/alpha/pci/pci_kn20aa.c +++ b/sys/arch/alpha/pci/pci_kn20aa.c @@ -1,7 +1,7 @@ -/* $NetBSD: pci_kn20aa.c,v 1.2 1995/12/24 02:29:45 mycroft Exp $ */ +/* $NetBSD: pci_kn20aa.c,v 1.3.4.2 1996/06/13 18:35:31 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -55,14 +55,12 @@ #include <alpha/pci/siovar.h> #endif -void *kn20aa_pci_map_int __P((void *, pci_conftag_t, pci_intr_pin_t, - pci_intr_line_t, int, int (*func)(void *), void *, char *)); -void kn20aa_pci_unmap_int __P((void *, void *)); - -__const struct pci_intr_fns kn20aa_pci_intr_fns = { - kn20aa_pci_map_int, - kn20aa_pci_unmap_int, -}; +int dec_kn20aa_intr_map __P((void *, pcitag_t, int, int, + pci_intr_handle_t *)); +const char *dec_kn20aa_intr_string __P((void *, pci_intr_handle_t)); +void *dec_kn20aa_intr_establish __P((void *, pci_intr_handle_t, + int, int (*func)(void *), void *)); +void dec_kn20aa_intr_disestablish __P((void *, void *)); #define KN20AA_PCEB_IRQ 31 #define KN20AA_MAX_IRQ 32 @@ -90,25 +88,25 @@ struct kn20aa_intrhand *kn20aa_attach_intr __P((struct kn20aa_intrchain *, int, int (*) (void *), void *)); void -pci_kn20aa_pickintr(pcf, pcfa, ppf, ppfa, pifp, pifap) - __const struct pci_conf_fns *pcf; - __const struct pci_pio_fns *ppf; - void *pcfa, *ppfa; - __const struct pci_intr_fns **pifp; - void **pifap; +pci_kn20aa_pickintr(ccp) + struct cia_config *ccp; { int i; struct kn20aa_intrhand *nintrhand; - + bus_chipset_tag_t bc = &ccp->cc_bc; + pci_chipset_tag_t pc = &ccp->cc_pc; for (i = 0; i < KN20AA_MAX_IRQ; i++) TAILQ_INIT(&kn20aa_pci_intrs[i]); - *pifp = &kn20aa_pci_intr_fns; - *pifap = NULL; /* XXX ? */ + pc->pc_intr_v = ccp; + pc->pc_intr_map = dec_kn20aa_intr_map; + pc->pc_intr_string = dec_kn20aa_intr_string; + pc->pc_intr_establish = dec_kn20aa_intr_establish; + pc->pc_intr_disestablish = dec_kn20aa_intr_disestablish; #if NSIO - sio_intr_setup(ppf, ppfa); + sio_intr_setup(bc); #endif set_iointr(kn20aa_iointr); @@ -121,27 +119,25 @@ pci_kn20aa_pickintr(pcf, pcfa, ppf, ppfa, pifp, pifap) #endif } -void * -kn20aa_pci_map_int(ccv, tag, pin, line, level, func, arg, what) - void *ccv; - pci_conftag_t tag; - pci_intr_pin_t pin; - pci_intr_line_t line; - int level; - int (*func) __P((void *)); - void *arg; - char *what; +int +dec_kn20aa_intr_map(ccv, bustag, buspin, line, ihp) + void *ccv; + pcitag_t bustag; + int buspin, line; + pci_intr_handle_t *ihp; { + struct cia_config *ccp = ccv; + pci_chipset_tag_t pc = &ccp->cc_pc; int device; int kn20aa_slot, kn20aa_irq; void *ih; - if (pin == 0) { + if (buspin == 0) { /* No IRQ used. */ return 0; } - if (pin > 4) { - printf("pci_map_int: bad interrupt pin %d\n", pin); + if (buspin > 4) { + printf("pci_map_int: bad interrupt pin %d\n", buspin); return NULL; } @@ -152,7 +148,8 @@ kn20aa_pci_map_int(ccv, tag, pin, line, level, func, arg, what) * The DEC engineers who did this hardware obviously engaged * in random drug testing. */ - switch (device = PCI_TAG_DEVICE(tag)) { + pci_decompose_tag(pc, bustag, NULL, &device, NULL); + switch (device) { case 11: case 12: kn20aa_slot = (device - 11) + 0; @@ -175,29 +172,56 @@ kn20aa_pci_map_int(ccv, tag, pin, line, level, func, arg, what) device); } - kn20aa_irq = (kn20aa_slot * 4) + pin - 1; + kn20aa_irq = (kn20aa_slot * 4) + buspin - 1; if (kn20aa_irq > KN20AA_MAX_IRQ) panic("pci_kn20aa_map_int: kn20aa_irq too large (%d)\n", kn20aa_irq); -#if 0 - printf("kn20aa_attach_intr: func 0x%lx, arg 0x%lx, level %d, irq %d\n", - func, arg, level, kn20aa_irq); -#endif + *ihp = kn20aa_irq; +} - ih = kn20aa_attach_intr(&kn20aa_pci_intrs[kn20aa_irq], level, - func, arg); - kn20aa_enable_intr(kn20aa_irq); - return (ih); +const char * +dec_kn20aa_intr_string(ccv, ih) + void *ccv; + pci_intr_handle_t ih; +{ + struct cia_config *ccp = ccv; + static char irqstr[15]; /* 11 + 2 + NULL + sanity */ + + if (ih > KN20AA_MAX_IRQ) + panic("dec_kn20aa_a50_intr_string: bogus kn20aa IRQ 0x%x\n", + ih); + + sprintf(irqstr, "kn20aa irq %d", ih); + return (irqstr); } -void -kn20aa_pci_unmap_int(pifa, cookie) - void *pifa; +void * +dec_kn20aa_intr_establish(ccv, ih, level, func, arg) + void *ccv, *arg; + pci_intr_handle_t ih; + int level; + int (*func) __P((void *)); +{ + struct cia_config *ccp = ccv; void *cookie; + + if (ih > KN20AA_MAX_IRQ) + panic("dec_kn20aa_intr_establish: bogus kn20aa IRQ 0x%x\n", + ih); + + cookie = kn20aa_attach_intr(&kn20aa_pci_intrs[ih], level, func, arg); + kn20aa_enable_intr(ih); + return (cookie); +} + +void +dec_kn20aa_intr_disestablish(ccv, cookie) + void *ccv, *cookie; { + struct cia_config *ccp = ccv; - panic("kn20aa_pci_unmap_int not implemented"); /* XXX */ + panic("dec_kn20aa_intr_disestablish not implemented"); /* XXX */ } /* diff --git a/sys/arch/alpha/pci/pci_kn20aa.h b/sys/arch/alpha/pci/pci_kn20aa.h index 4e499317ea0..dfbd89e3f05 100644 --- a/sys/arch/alpha/pci/pci_kn20aa.h +++ b/sys/arch/alpha/pci/pci_kn20aa.h @@ -1,4 +1,4 @@ -/* $NetBSD: pci_kn20aa.h,v 1.1 1995/11/23 02:38:05 cgd Exp $ */ +/* $NetBSD: pci_kn20aa.h,v 1.2 1996/04/13 00:24:35 cgd Exp $ */ /* * Copyright (c) 1995 Carnegie-Mellon University. @@ -27,9 +27,7 @@ * rights to redistribute these changes. */ -void pci_kn20aa_pickintr __P((__const struct pci_conf_fns *, void *, - __const struct pci_pio_fns *, void *, - __const struct pci_intr_fns **, void **)); +void pci_kn20aa_pickintr __P((struct cia_config *)); #ifdef EVCNT_COUNTERS extern struct evcnt kn20aa_intr_evcnt; diff --git a/sys/arch/alpha/pci/pci_machdep.c b/sys/arch/alpha/pci/pci_machdep.c index 02eb57caeaa..b0a8e04c6d3 100644 --- a/sys/arch/alpha/pci/pci_machdep.c +++ b/sys/arch/alpha/pci/pci_machdep.c @@ -1,7 +1,7 @@ -/* $NetBSD: pci_machdep.c,v 1.3 1995/11/23 02:38:07 cgd Exp $ */ +/* $NetBSD: pci_machdep.c,v 1.5 1996/04/12 06:08:49 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -37,7 +37,6 @@ #include <sys/systm.h> #include <sys/errno.h> #include <sys/device.h> - #include <vm/vm.h> #include <dev/isa/isavar.h> @@ -56,41 +55,44 @@ #endif void -pci_display_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, device, function) - __const struct pci_conf_fns *pcf; - __const struct pci_mem_fns *pmf; - __const struct pci_pio_fns *ppf; - void *pcfa, *pmfa, *ppfa; - pci_bus_t bus; - pci_device_t device; - pci_function_t function; +pci_display_console(bc, pc, bus, device, function) + bus_chipset_tag_t bc; + pci_chipset_tag_t pc; + int bus, device, function; { - pci_conftag_t tag; - pci_confreg_t id, class; + pcitag_t tag; + pcireg_t id, class; + int match, nmatch; + void (*fn) __P((bus_chipset_tag_t, pci_chipset_tag_t, int, int, int)); - tag = PCI_MAKE_TAG(bus, device, function); - id = PCI_CONF_READ(pcf, pcfa, tag, PCI_ID_REG); + tag = pci_make_tag(pc, bus, device, function); + id = pci_conf_read(pc, tag, PCI_ID_REG); if (id == 0 || id == 0xffffffff) panic("pci_display_console: no device at %d/%d/%d", bus, device, function); - class = PCI_CONF_READ(pcf, pcfa, tag, PCI_CLASS_REG); + class = pci_conf_read(pc, tag, PCI_CLASS_REG); + + match = 0; + fn = NULL; #if NPCIVGA - if (DEVICE_IS_PCIVGA(class, id)) { - pcivga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, - device, function); - return; + nmatch = DEVICE_IS_PCIVGA(class, id); + if (nmatch > match) { + match = nmatch; + fn = pcivga_console; } #endif - #if NTGA - if (DEVICE_IS_TGA(class, id)) { - tga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, - device, function); - return; + nmatch = DEVICE_IS_TGA(class, id); + if (nmatch > match) { + match = nmatch; + fn = tga_console; } #endif - panic("pci_display_console: unconfigured device at %d/%d/%d", + if (fn != NULL) + (*fn)(bc, pc, bus, device, function); + else + panic("pci_display_console: unconfigured device at %d/%d/%d", bus, device, function); } diff --git a/sys/arch/alpha/pci/pci_machdep.h b/sys/arch/alpha/pci/pci_machdep.h new file mode 100644 index 00000000000..1a4c5074fcb --- /dev/null +++ b/sys/arch/alpha/pci/pci_machdep.h @@ -0,0 +1,87 @@ +/* $NetBSD: pci_machdep.h,v 1.4 1996/04/12 06:08:52 cgd Exp $ */ + +/* + * Copyright (c) 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +/* + * Machine-specific definitions for PCI autoconfiguration. + */ + +/* + * Types provided to machine-independent PCI code + */ +typedef struct alpha_pci_chipset *pci_chipset_tag_t; +typedef u_long pcitag_t; +typedef u_long pci_intr_handle_t; + +/* + * alpha-specific PCI structure and type definitions. + * NOT TO BE USED DIRECTLY BY MACHINE INDEPENDENT CODE. + */ +struct alpha_pci_chipset { + void *pc_conf_v; + void (*pc_attach_hook) __P((struct device *, + struct device *, struct pcibus_attach_args *)); + int (*pc_bus_maxdevs) __P((void *, int)); + pcitag_t (*pc_make_tag) __P((void *, int, int, int)); + void (*pc_decompose_tag) __P((void *, pcitag_t, int *, + int *, int *)); + pcireg_t (*pc_conf_read) __P((void *, pcitag_t, int)); + void (*pc_conf_write) __P((void *, pcitag_t, int, pcireg_t)); + + void *pc_intr_v; + int (*pc_intr_map) __P((void *, pcitag_t, int, int, + pci_intr_handle_t *)); + const char *(*pc_intr_string) __P((void *, pci_intr_handle_t)); + void *(*pc_intr_establish) __P((void *, pci_intr_handle_t, + int, int (*)(void *), void *)); + void (*pc_intr_disestablish) __P((void *, void *)); +}; + +/* + * Functions provided to machine-independent PCI code. + */ +#define pci_attach_hook(p, s, pba) \ + (*(pba)->pba_pc->pc_attach_hook)((p), (s), (pba)) +#define pci_bus_maxdevs(c, b) \ + (*(c)->pc_bus_maxdevs)((c)->pc_conf_v, (b)) +#define pci_make_tag(c, b, d, f) \ + (*(c)->pc_make_tag)((c)->pc_conf_v, (b), (d), (f)) +#define pci_decompose_tag(c, t, bp, dp, fp) \ + (*(c)->pc_decompose_tag)((c)->pc_conf_v, (t), (bp), (dp), (fp)) +#define pci_conf_read(c, t, r) \ + (*(c)->pc_conf_read)((c)->pc_conf_v, (t), (r)) +#define pci_conf_write(c, t, r, v) \ + (*(c)->pc_conf_write)((c)->pc_conf_v, (t), (r), (v)) +#define pci_intr_map(c, it, ip, il, ihp) \ + (*(c)->pc_intr_map)((c)->pc_intr_v, (it), (ip), (il), (ihp)) +#define pci_intr_string(c, ih) \ + (*(c)->pc_intr_string)((c)->pc_intr_v, (ih)) +#define pci_intr_establish(c, ih, l, h, a) \ + (*(c)->pc_intr_establish)((c)->pc_intr_v, (ih), (l), (h), (a)) +#define pci_intr_disestablish(c, iv) \ + (*(c)->pc_intr_disestablish)((c)->pc_intr_v, (iv)) diff --git a/sys/arch/alpha/pci/pcivga.c b/sys/arch/alpha/pci/pcivga.c index 5f62ab3fa73..96c3cfdadf9 100644 --- a/sys/arch/alpha/pci/pcivga.c +++ b/sys/arch/alpha/pci/pcivga.c @@ -1,7 +1,7 @@ -/* $NetBSD: pcivga.c,v 1.4 1995/12/24 02:29:47 mycroft Exp $ */ +/* $NetBSD: pcivga.c,v 1.8 1996/04/17 21:49:58 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -36,39 +36,41 @@ #include <machine/autoconf.h> #include <machine/pte.h> -#include <dev/pseudo/ansicons.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcidevs.h> #include <alpha/pci/pcivgavar.h> -#include <alpha/pci/wsconsvar.h> +#include <alpha/wscons/wsconsvar.h> + +#define PCIVGA_6845_ADDR 0x24 +#define PCIVGA_6845_DATA 0x25 int pcivgamatch __P((struct device *, void *, void *)); void pcivgaattach __P((struct device *, struct device *, void *)); +int pcivgaprint __P((void *, char *)); + +struct cfattach pcivga_ca = { + sizeof(struct pcivga_softc), pcivgamatch, pcivgaattach, +}; -struct cfdriver pcivgacd = { - NULL, "pcivga", pcivgamatch, pcivgaattach, DV_DULL, - sizeof(struct pcivga_softc) +struct cfdriver pcivga_cd = { + NULL, "pcivga", DV_DULL, }; -void pcivga_getdevconfig __P((__const struct pci_conf_fns *, void *, - __const struct pci_mem_fns *, void *, - __const struct pci_pio_fns *, void *, - pci_conftag_t tag, struct pcivga_devconfig *dc)); +void pcivga_getdevconfig __P((bus_chipset_tag_t, pci_chipset_tag_t, + pcitag_t, struct pcivga_devconfig *dc)); struct pcivga_devconfig pcivga_console_dc; -void pcivga_cursor __P((void *, int, int)); +void pcivga_cursor __P((void *, int, int, int)); void pcivga_putstr __P((void *, int, int, char *, int)); void pcivga_copycols __P((void *, int, int, int,int)); void pcivga_erasecols __P((void *, int, int, int)); void pcivga_copyrows __P((void *, int, int, int)); void pcivga_eraserows __P((void *, int, int)); -void pcivga_bell __P((void *)); /* XXX */ -struct ansicons_functions pcivga_acf = { - pcivga_bell, +struct wscons_emulfuncs pcivga_emulfuncs = { pcivga_cursor, pcivga_putstr, pcivga_copycols, @@ -77,7 +79,9 @@ struct ansicons_functions pcivga_acf = { pcivga_eraserows, }; -#define PCIVGAUNIT(dev) minor(dev) +int pcivgaioctl __P((struct device *, u_long, caddr_t, int, + struct proc *)); +int pcivgammap __P((struct device *, off_t, int)); int pcivgamatch(parent, match, aux) @@ -85,55 +89,71 @@ pcivgamatch(parent, match, aux) void *match, *aux; { struct cfdata *cf = match; - struct pcidev_attach_args *pda = aux; + struct pci_attach_args *pa = aux; /* * If it's prehistoric/vga or display/vga, we match. */ - if (PCI_CLASS(pda->pda_class) == PCI_CLASS_PREHISTORIC && - PCI_SUBCLASS(pda->pda_class) == PCI_SUBCLASS_PREHISTORIC_VGA) + if (PCI_CLASS(pa->pa_class) == PCI_CLASS_PREHISTORIC && + PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_PREHISTORIC_VGA) return (1); - if (PCI_CLASS(pda->pda_class) == PCI_CLASS_DISPLAY && - PCI_SUBCLASS(pda->pda_class) == PCI_SUBCLASS_DISPLAY_VGA) + if (PCI_CLASS(pa->pa_class) == PCI_CLASS_DISPLAY && + PCI_SUBCLASS(pa->pa_class) == PCI_SUBCLASS_DISPLAY_VGA) return (1); return (0); } void -pcivga_getdevconfig(pcf, pcfa, pmf, pmfa, ppf, ppfa, tag, dc) - __const struct pci_conf_fns *pcf; - __const struct pci_mem_fns *pmf; - __const struct pci_pio_fns *ppf; - void *pcfa, *pmfa, *ppfa; - pci_conftag_t tag; +pcivga_getdevconfig(bc, pc, tag, dc) + bus_chipset_tag_t bc; + pci_chipset_tag_t pc; + pcitag_t tag; struct pcivga_devconfig *dc; { + bus_io_handle_t ioh; + int cpos; - dc->dc_pcf = pcf; - dc->dc_pcfa = pcfa; - dc->dc_pmf = pmf; - dc->dc_pmfa = pmfa; - dc->dc_ppf = ppf; - dc->dc_ppfa = ppfa; + dc->dc_bc = bc; + dc->dc_pc = pc; dc->dc_pcitag = tag; /* XXX deal with mapping foo */ - /* XXX */ - dc->dc_crtat = (u_short *)PCI_MEM_MAP(pmf, pmfa, 0xb8000, 0x8000, 1); - dc->dc_iobase = 0x3d4; /* XXX */ + if (bus_mem_map(bc, 0xb8000, 0x8000, 0, &dc->dc_memh)) + panic("pcivga_getdevconfig: couldn't map memory"); + if (bus_io_map(bc, 0x3b0, 0x30, &ioh)) + panic("pcivga_getdevconfig: couldn't map io"); + dc->dc_ioh = ioh; dc->dc_nrow = 25; dc->dc_ncol = 80; + dc->dc_ccol = dc->dc_crow = 0; + bus_io_write_1(bc, ioh, PCIVGA_6845_ADDR, 14); + cpos = bus_io_read_1(bc, ioh, PCIVGA_6845_DATA) << 8; + bus_io_write_1(bc, ioh, PCIVGA_6845_ADDR, 15); + cpos |= bus_io_read_1(bc, ioh, PCIVGA_6845_DATA); + + dc->dc_crow = cpos / dc->dc_ncol; + dc->dc_ccol = cpos % dc->dc_ncol; + dc->dc_so = 0; +#if 0 dc->dc_at = 0x00 | 0xf; /* black bg | white fg */ dc->dc_so_at = 0x00 | 0xf | 0x80; /* black bg | white fg | blink */ /* clear screen, frob cursor, etc.? */ pcivga_eraserows(dc, 0, dc->dc_nrow); +#endif + /* + * XXX DEC HAS SWITCHED THE CODES FOR BLUE AND RED!!! + * XXX Therefore, though the comments say "blue bg", the code uses + * XXX the value for a red background! + */ + dc->dc_at = 0x40 | 0x0f; /* blue bg | white fg */ + dc->dc_so_at = 0x40 | 0x0f | 0x80; /* blue bg | white fg | blink */ } void @@ -141,29 +161,26 @@ pcivgaattach(parent, self, aux) struct device *parent, *self; void *aux; { - struct pcidev_attach_args *pda = aux; + struct pci_attach_args *pa = aux; struct pcivga_softc *sc = (struct pcivga_softc *)self; + struct wscons_attach_args waa; + struct wscons_odev_spec *wo; char devinfo[256]; int console; - console = (pda->pda_tag == pcivga_console_dc.dc_pcitag); + console = (pa->pa_tag == pcivga_console_dc.dc_pcitag); if (console) sc->sc_dc = &pcivga_console_dc; else { sc->sc_dc = (struct pcivga_devconfig *) malloc(sizeof(struct pcivga_devconfig), M_DEVBUF, M_WAITOK); - pcivga_getdevconfig(pda->pda_conffns, pda->pda_confarg, - pda->pda_memfns, pda->pda_memarg, pda->pda_piofns, - pda->pda_memarg, pda->pda_tag, sc->sc_dc); - } - if (sc->sc_dc->dc_crtat == NULL) { - printf(": couldn't map memory space; punt!\n"); - return; + pcivga_getdevconfig(pa->pa_bc, pa->pa_pc, pa->pa_tag, + sc->sc_dc); } - pci_devinfo(pda->pda_id, pda->pda_class, 0, devinfo); + pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); printf(": %s (rev. 0x%02x)\n", devinfo, - PCI_REVISION(pda->pda_class)); + PCI_REVISION(pa->pa_class)); #if 0 if (sc->sc_dc->dc_tgaconf == NULL) { @@ -180,94 +197,120 @@ pcivgaattach(parent, self, aux) #if 0 pci_intrdata = pci_conf_read(sc->sc_pcitag, PCI_INTERRUPT_REG); if (PCI_INTERRUPT_PIN(pci_intrdata) != PCI_INTERRUPT_PIN_NONE) { - sc->sc_intr = pci_map_int(sc->sc_pcitag, IPL_TTY, tgaintr, sc, - sc->sc_dev.dv_xname); + sc->sc_intr = pci_map_int(sc->sc_pcitag, IPL_TTY, tgaintr, sc); if (sc->sc_intr == NULL) printf("%s: WARNING: couldn't map interrupt\n", sc->sc_dev.dv_xname); } #endif - if (!wscattach_output(self, console, &sc->sc_dc->dc_ansicons, - &pcivga_acf, sc->sc_dc, sc->sc_dc->dc_nrow, sc->sc_dc->dc_ncol, - 0, 0)) { - panic("pcivgaattach: wscattach failed"); - /* NOTREACHED */ - } + waa.waa_isconsole = console; + wo = &waa.waa_odev_spec; + wo->wo_ef = &pcivga_emulfuncs; + wo->wo_efa = sc->sc_dc; + wo->wo_nrows = sc->sc_dc->dc_nrow; + wo->wo_ncols = sc->sc_dc->dc_ncol; + wo->wo_crow = sc->sc_dc->dc_crow; + wo->wo_ccol = sc->sc_dc->dc_ccol; + wo->wo_ioctl = pcivgaioctl; + wo->wo_mmap = pcivgammap; + + config_found(self, &waa, pcivgaprint); } -#if 0 int -tgammap(dev, offset, nprot) - dev_t dev; - int offset; - int nprot; +pcivgaprint(aux, pnp) + void *aux; + char *pnp; { - struct pcivga_softc *sc = pcivgacd.cd_devs[TGAUNIT(dev)]; - if (offset > sc->sc_dc->dc_pcivgaconf->pcivgac_cspace_size) - return -1; - return alpha_btop(sc->sc_dc->dc_paddr + offset); + if (pnp) + printf("wscons at %s", pnp); + return (UNCONF); } + +int +pcivgaioctl(dev, cmd, data, flag, p) + struct device *dev; + u_long cmd; + caddr_t data; + int flag; + struct proc *p; +{ + + return -1; /* XXX */ +} + +int +pcivgammap(dev, offset, prot) + struct device *dev; + off_t offset; + int prot; +{ + struct pcivga_softc *sc = (struct pcivga_softc *)dev; + int rv; + + rv = -1; +#if 0 /* XXX */ + if (offset >= 0 && offset < 0x100000) { /* 1MB */ + /* Deal with mapping the VGA memory */ + if (offset >= 0xb8000 && offset < 0xc0000) { + offset -= 0xb8000; + rv = alpha_btop(k0segtophys(sc->sc_dc->dc_crtat) + + offset); + } + } else { + /* XXX should do something with PCI memory */ + rv = -1; + } #endif + return rv; +} void -pcivga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, device, function) - __const struct pci_conf_fns *pcf; - __const struct pci_mem_fns *pmf; - __const struct pci_pio_fns *ppf; - void *pcfa, *pmfa, *ppfa; - pci_bus_t bus; - pci_device_t device; - pci_function_t function; +pcivga_console(bc, pc, bus, device, function) + bus_chipset_tag_t bc; + pci_chipset_tag_t pc; + int bus, device, function; { struct pcivga_devconfig *dcp = &pcivga_console_dc; + struct wscons_odev_spec wo; - pcivga_getdevconfig(pcf, pcfa, pmf, pmfa, ppf, ppfa, - PCI_MAKE_TAG(bus, device, function), dcp); + pcivga_getdevconfig(bc, pc, + pci_make_tag(pc, bus, device, function), dcp); - /* sanity checks */ - if (dcp->dc_crtat == NULL) - panic("pcivga_console(%d, %d): couldn't map memory space", - device, function); -#if 0 - if (dcp->dc_pcivgaconf == NULL) - panic("pcivga_console(%d, %d): unknown board configuration", - device, function); -#endif + wo.wo_ef = &pcivga_emulfuncs; + wo.wo_efa = dcp; + wo.wo_nrows = dcp->dc_nrow; + wo.wo_ncols = dcp->dc_ncol; + wo.wo_crow = dcp->dc_crow; + wo.wo_ccol = dcp->dc_ccol; + /* ioctl and mmap are unused until real attachment. */ - wsc_console(&dcp->dc_ansicons, &pcivga_acf, dcp, - dcp->dc_nrow, dcp->dc_ncol, 0, 0); + wscons_attach_console(&wo); } /* * The following functions implement the MI ANSI terminal emulation on * a VGA display. */ -void /* XXX */ -pcivga_bell(id) /* XXX */ - void *id; /* XXX */ -{ /* XXX */ - /* XXX */ - printf("pcivga_bell: unimplemented\n"); /* XXX */ -} /* XXX */ - void -pcivga_cursor(id, row, col) +pcivga_cursor(id, on, row, col) void *id; - int row, col; + int on, row, col; { struct pcivga_devconfig *dc = id; + bus_chipset_tag_t bc = dc->dc_bc; + bus_io_handle_t ioh = dc->dc_ioh; int pos; #if 0 printf("pcivga_cursor: %d %d\n", row, col); #endif /* turn the cursor off */ - if (row == -1 || col == -1) { - dc->dc_crow = dc->dc_ccol = PCIVGA_CURSOR_OFF; - - /* XXX disable cursor??? */ + if (!on) { + /* XXX disable cursor how??? */ + dc->dc_crow = dc->dc_ccol = -1; } else { dc->dc_crow = row; dc->dc_ccol = col; @@ -275,10 +318,10 @@ pcivga_cursor(id, row, col) pos = row * dc->dc_ncol + col; - OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase, 14); - OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase+1, pos >> 8); - OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase, 15); - OUTB(dc->dc_ppf, dc->dc_ppfa, dc->dc_iobase+1, pos); + bus_io_write_1(bc, ioh, PCIVGA_6845_ADDR, 14); + bus_io_write_1(bc, ioh, PCIVGA_6845_DATA, pos >> 8); + bus_io_write_1(bc, ioh, PCIVGA_6845_ADDR, 15); + bus_io_write_1(bc, ioh, PCIVGA_6845_DATA, pos); } void @@ -289,20 +332,16 @@ pcivga_putstr(id, row, col, cp, len) int len; { struct pcivga_devconfig *dc = id; + bus_chipset_tag_t bc = dc->dc_bc; + bus_mem_handle_t memh = dc->dc_memh; char *dcp; - int i; + int i, off; - for (i = 0; i < len; i++, cp++) { - dcp = (char *)&dc->dc_crtat[row * dc->dc_ncol + col]; -#if 0 -printf("*cp = %c, attr = 0x%x\n", *cp, dc->dc_so ? dc->dc_so_at : dc->dc_at); -printf("was: %c/", *dcp); -#endif - *dcp++ = *cp; -#if 0 -printf("0x%x\n", *dcp); -#endif - *dcp++ = dc->dc_so ? dc->dc_so_at : dc->dc_at; + off = (row * dc->dc_ncol + col) * 2; + for (i = 0; i < len; i++, cp++, off += 2) { + bus_mem_write_1(bc, memh, off, *cp); + bus_mem_write_1(bc, memh, off + 1, + dc->dc_so ? dc->dc_so_at : dc->dc_at); } } @@ -312,16 +351,20 @@ pcivga_copycols(id, row, srccol, dstcol, ncols) int row, srccol, dstcol, ncols; { struct pcivga_devconfig *dc = id; - u_short *ssp, *dsp; - int nclr; + bus_chipset_tag_t bc = dc->dc_bc; + bus_mem_handle_t memh = dc->dc_memh; + bus_mem_size_t srcoff, srcend, dstoff; -#if 0 - printf("pcivga_copycols: row %d: %d, %d -> %d\n", row, srccol, ncols, - dstcol); -#endif - ssp = &dc->dc_crtat[row * dc->dc_ncol + srccol]; - dsp = &dc->dc_crtat[row * dc->dc_ncol + dstcol]; - bcopy(ssp, dsp, ncols * sizeof(u_short)); + /* + * YUCK. Need bus copy functions. + */ + srcoff = (row * dc->dc_ncol + srccol) * 2; + srcend = srcoff + ncols * 2; + dstoff = (row * dc->dc_ncol + dstcol) * 2; + + for (; srcoff < srcend; srcoff += 2, dstoff += 2) + bus_mem_write_2(bc, memh, dstoff, + bus_mem_read_2(bc, memh, srcoff)); } void @@ -330,15 +373,20 @@ pcivga_erasecols(id, row, startcol, ncols) int row, startcol, ncols; { struct pcivga_devconfig *dc = id; - u_short *ssp; - int i; + bus_chipset_tag_t bc = dc->dc_bc; + bus_mem_handle_t memh = dc->dc_memh; + bus_mem_size_t off, endoff; + u_int16_t val; -#if 0 - printf("pcivga_erasecols: row %d: %d, %d\n", row, startcol, ncols); -#endif - ssp = &dc->dc_crtat[row * dc->dc_ncol + startcol]; - for (i = 0; i < ncols; i++) - *ssp++ = (dc->dc_at << 8) | ' '; + /* + * YUCK. Need bus 'set' functions. + */ + off = (row * dc->dc_ncol + startcol) * 2; + endoff = off + ncols * 2; + val = (dc->dc_at << 8) | ' '; + + for (; off < endoff; off += 2) + bus_mem_write_2(bc, memh, off, val); } void @@ -347,15 +395,20 @@ pcivga_copyrows(id, srcrow, dstrow, nrows) int srcrow, dstrow, nrows; { struct pcivga_devconfig *dc = id; - u_short *ssp, *dsp; - int nclr; + bus_chipset_tag_t bc = dc->dc_bc; + bus_mem_handle_t memh = dc->dc_memh; + bus_mem_size_t srcoff, srcend, dstoff; -#if 0 - printf("pcivga_copyrows: %d, %d -> %d\n", srcrow, nrows, dstrow); -#endif - ssp = &dc->dc_crtat[srcrow * dc->dc_ncol + 0]; - dsp = &dc->dc_crtat[dstrow * dc->dc_ncol + 0]; - bcopy(ssp, dsp, nrows * dc->dc_ncol * sizeof(u_short)); + /* + * YUCK. Need bus copy functions. + */ + srcoff = (srcrow * dc->dc_ncol + 0) * 2; + srcend = srcoff + (nrows * dc->dc_ncol * 2); + dstoff = (dstrow * dc->dc_ncol + 0) * 2; + + for (; srcoff < srcend; srcoff += 2, dstoff += 2) + bus_mem_write_2(bc, memh, dstoff, + bus_mem_read_2(bc, memh, srcoff)); } void @@ -364,13 +417,18 @@ pcivga_eraserows(id, startrow, nrows) int startrow, nrows; { struct pcivga_devconfig *dc = id; - u_short *ssp; - int i; + bus_chipset_tag_t bc = dc->dc_bc; + bus_mem_handle_t memh = dc->dc_memh; + bus_mem_size_t off, endoff; + u_int16_t val; -#if 0 - printf("pcivga_eraserows: %d, %d\n", startrow, nrows); -#endif - ssp = &dc->dc_crtat[startrow * dc->dc_ncol + 0]; - for (i = 0; i < nrows * dc->dc_ncol; i++) - *ssp++ = (dc->dc_at << 8) | ' '; + /* + * YUCK. Need bus 'set' functions. + */ + off = (startrow * dc->dc_ncol + 0) * 2; + endoff = off + (nrows * dc->dc_ncol) * 2; + val = (dc->dc_at << 8) | ' '; + + for (; off < endoff; off += 2) + bus_mem_write_2(bc, memh, off, val); } diff --git a/sys/arch/alpha/pci/pcivgavar.h b/sys/arch/alpha/pci/pcivgavar.h index 579ad4ca0a4..da42958de3f 100644 --- a/sys/arch/alpha/pci/pcivgavar.h +++ b/sys/arch/alpha/pci/pcivgavar.h @@ -1,7 +1,7 @@ -/* $NetBSD: pcivgavar.h,v 1.3 1995/11/23 02:38:13 cgd Exp $ */ +/* $NetBSD: pcivgavar.h,v 1.5 1996/04/12 06:08:58 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -27,20 +27,14 @@ * rights to redistribute these changes. */ -#include <dev/pseudo/ansicons.h> - struct pcivga_devconfig { - __const struct pci_conf_fns *dc_pcf; - void *dc_pcfa; - __const struct pci_mem_fns *dc_pmf; - void *dc_pmfa; - __const struct pci_pio_fns *dc_ppf; - void *dc_ppfa; + bus_chipset_tag_t dc_bc; + pci_chipset_tag_t dc_pc; - pci_tag_t dc_pcitag; /* PCI tag */ + pcitag_t dc_pcitag; /* PCI tag */ - u_int16_t *dc_crtat; /* VGA screen memory */ - int dc_iobase; /* VGA I/O address */ + bus_io_handle_t dc_ioh; + bus_mem_handle_t dc_memh; int dc_ncol, dc_nrow; /* screen width & height */ int dc_ccol, dc_crow; /* current cursor position */ @@ -48,8 +42,6 @@ struct pcivga_devconfig { char dc_so; /* in standout mode? */ char dc_at; /* normal attributes */ char dc_so_at; /* standout attributes */ - - struct ansicons dc_ansicons; /* ansi console emulator info XXX */ }; struct pcivga_softc { @@ -59,15 +51,11 @@ struct pcivga_softc { void *sc_intr; /* interrupt handler info */ }; -#define PCIVGA_CURSOR_OFF -1 /* pass to pcivga_cpos to disable */ - #define DEVICE_IS_PCIVGA(class, id) \ - ((PCI_CLASS(class) == PCI_CLASS_DISPLAY && \ + (((PCI_CLASS(class) == PCI_CLASS_DISPLAY && \ PCI_SUBCLASS(class) == PCI_SUBCLASS_DISPLAY_VGA) || \ (PCI_CLASS(class) == PCI_CLASS_PREHISTORIC && \ - PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) + PCI_SUBCLASS(class) == PCI_SUBCLASS_PREHISTORIC_VGA)) ? 1 : 0) -void pcivga_console __P((__const struct pci_conf_fns *, void *, - __const struct pci_mem_fns *, void *, - __const struct pci_pio_fns *, void *, - pci_bus_t, pci_device_t, pci_function_t)); +void pcivga_console __P((bus_chipset_tag_t, pci_chipset_tag_t, int, int, + int)); diff --git a/sys/arch/alpha/pci/pcs_bus_io_common.c b/sys/arch/alpha/pci/pcs_bus_io_common.c new file mode 100644 index 00000000000..3d1e904467b --- /dev/null +++ b/sys/arch/alpha/pci/pcs_bus_io_common.c @@ -0,0 +1,488 @@ +/* $NetBSD: pcs_bus_io_common.c,v 1.2.4.2 1996/06/13 18:16:59 cgd Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +/* + * Common PCI Chipset "bus I/O" functions, for chipsets which have to + * deal with only a single PCI interface chip in a machine. + * + * uses: + * CHIP name of the 'chip' it's being compiled for. + * CHIP_IO_BASE Sparse I/O space base to use. + */ + +#define __C(A,B) __CONCAT(A,B) +#define __S(S) __STRING(S) + +int __C(CHIP,_io_map) __P((void *, bus_io_addr_t, bus_io_size_t, + bus_io_handle_t *)); +void __C(CHIP,_io_unmap) __P((void *, bus_io_handle_t, + bus_io_size_t)); +int __C(CHIP,_io_subregion) __P((void *, bus_io_handle_t, + bus_io_size_t, bus_io_size_t, bus_io_handle_t *)); +u_int8_t __C(CHIP,_io_read_1) __P((void *, bus_io_handle_t, + bus_io_size_t)); +u_int16_t __C(CHIP,_io_read_2) __P((void *, bus_io_handle_t, + bus_io_size_t)); +u_int32_t __C(CHIP,_io_read_4) __P((void *, bus_io_handle_t, + bus_io_size_t)); +u_int64_t __C(CHIP,_io_read_8) __P((void *, bus_io_handle_t, + bus_io_size_t)); +void __C(CHIP,_io_read_multi_1) __P((void *, bus_io_handle_t, + bus_io_size_t, u_int8_t *, bus_io_size_t)); +void __C(CHIP,_io_read_multi_2) __P((void *, bus_io_handle_t, + bus_io_size_t, u_int16_t *, bus_io_size_t)); +void __C(CHIP,_io_read_multi_4) __P((void *, bus_io_handle_t, + bus_io_size_t, u_int32_t *, bus_io_size_t)); +void __C(CHIP,_io_read_multi_8) __P((void *, bus_io_handle_t, + bus_io_size_t, u_int64_t *, bus_io_size_t)); +void __C(CHIP,_io_write_1) __P((void *, bus_io_handle_t, + bus_io_size_t, u_int8_t)); +void __C(CHIP,_io_write_2) __P((void *, bus_io_handle_t, + bus_io_size_t, u_int16_t)); +void __C(CHIP,_io_write_4) __P((void *, bus_io_handle_t, + bus_io_size_t, u_int32_t)); +void __C(CHIP,_io_write_8) __P((void *, bus_io_handle_t, + bus_io_size_t, u_int64_t)); +void __C(CHIP,_io_write_multi_1) __P((void *, bus_io_handle_t, + bus_io_size_t, const u_int8_t *, bus_io_size_t)); +void __C(CHIP,_io_write_multi_2) __P((void *, bus_io_handle_t, + bus_io_size_t, const u_int16_t *, bus_io_size_t)); +void __C(CHIP,_io_write_multi_4) __P((void *, bus_io_handle_t, + bus_io_size_t, const u_int32_t *, bus_io_size_t)); +void __C(CHIP,_io_write_multi_8) __P((void *, bus_io_handle_t, + bus_io_size_t, const u_int64_t *, bus_io_size_t)); + +void +__C(CHIP,_bus_io_init)(bc, iov) + bus_chipset_tag_t bc; + void *iov; +{ + + bc->bc_i_v = iov; + + bc->bc_i_map = __C(CHIP,_io_map); + bc->bc_i_unmap = __C(CHIP,_io_unmap); + bc->bc_i_subregion = __C(CHIP,_io_subregion); + + bc->bc_ir1 = __C(CHIP,_io_read_1); + bc->bc_ir2 = __C(CHIP,_io_read_2); + bc->bc_ir4 = __C(CHIP,_io_read_4); + bc->bc_ir8 = __C(CHIP,_io_read_8); + + bc->bc_irm1 = __C(CHIP,_io_read_multi_1); + bc->bc_irm2 = __C(CHIP,_io_read_multi_2); + bc->bc_irm4 = __C(CHIP,_io_read_multi_4); + bc->bc_irm8 = __C(CHIP,_io_read_multi_8); + + bc->bc_iw1 = __C(CHIP,_io_write_1); + bc->bc_iw2 = __C(CHIP,_io_write_2); + bc->bc_iw4 = __C(CHIP,_io_write_4); + bc->bc_iw8 = __C(CHIP,_io_write_8); + + bc->bc_iwm1 = __C(CHIP,_io_write_multi_1); + bc->bc_iwm2 = __C(CHIP,_io_write_multi_2); + bc->bc_iwm4 = __C(CHIP,_io_write_multi_4); + bc->bc_iwm8 = __C(CHIP,_io_write_multi_8); +} + +int +__C(CHIP,_io_map)(v, ioaddr, iosize, iohp) + void *v; + bus_io_addr_t ioaddr; + bus_io_size_t iosize; + bus_io_handle_t *iohp; +{ + +#ifdef CHIP_IO_W1_START + if (ioaddr >= CHIP_IO_W1_START(v) && + ioaddr <= CHIP_IO_W1_END(v)) { + *iohp = (phystok0seg(CHIP_IO_W1_BASE(v)) >> 5) + + (ioaddr & CHIP_IO_W1_MASK(v)); + } else +#endif +#ifdef CHIP_IO_W2_START + if (ioaddr >= CHIP_IO_W2_START(v) && + ioaddr <= CHIP_IO_W2_END(v)) { + *iohp = (phystok0seg(CHIP_IO_W2_BASE(v)) >> 5) + + (ioaddr & CHIP_IO_W2_MASK(v)); + } else +#endif + { + printf("\n"); +#ifdef CHIP_IO_W1_START + printf("%s: window[1]=0x%lx-0x%lx\n", + __S(__C(CHIP,_io_map)), CHIP_IO_W1_START(v), + CHIP_IO_W1_END(v)-1); +#endif +#ifdef CHIP_IO_W2_START + printf("%s: window[2]=0x%lx-0x%lx\n", + __S(__C(CHIP,_io_map)), CHIP_IO_W2_START(v), + CHIP_IO_W2_END(v)-1); +#endif + panic("%s: don't know how to map %lx non-cacheable\n", + __S(__C(CHIP,_io_map)), ioaddr); + } + + return (0); +} + +void +__C(CHIP,_io_unmap)(v, ioh, iosize) + void *v; + bus_io_handle_t ioh; + bus_io_size_t iosize; +{ + + /* XXX nothing to do. */ +} + +int +__C(CHIP,_io_subregion)(v, ioh, offset, size, nioh) + void *v; + bus_io_handle_t ioh, *nioh; + bus_io_size_t offset, size; +{ + + *nioh = ioh + offset; + return (0); +} + +u_int8_t +__C(CHIP,_io_read_1)(v, ioh, off) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, val; + register u_int8_t rval; + register int offset; + + wbflush(); + + tmpioh = ioh + off; + offset = tmpioh & 3; + port = (u_int32_t *)((tmpioh << 5) | (0 << 3)); + val = *port; + rval = ((val) >> (8 * offset)) & 0xff; + + return rval; +} + +u_int16_t +__C(CHIP,_io_read_2)(v, ioh, off) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, val; + register u_int16_t rval; + register int offset; + + wbflush(); + + tmpioh = ioh + off; + offset = tmpioh & 3; + port = (u_int32_t *)((tmpioh << 5) | (1 << 3)); + val = *port; + rval = ((val) >> (8 * offset)) & 0xffff; + + return rval; +} + +u_int32_t +__C(CHIP,_io_read_4)(v, ioh, off) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, val; + register u_int32_t rval; + register int offset; + + wbflush(); + + tmpioh = ioh + off; + offset = tmpioh & 3; + port = (u_int32_t *)((tmpioh << 5) | (3 << 3)); + val = *port; +#if 0 + rval = ((val) >> (8 * offset)) & 0xffffffff; +#else + rval = val; +#endif + + return rval; +} + +u_int64_t +__C(CHIP,_io_read_8)(v, ioh, off) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off; +{ + + /* XXX XXX XXX */ + panic("%s not implemented\n", __S(__C(CHIP,_io_read_8))); +} + +void +__C(CHIP,_io_read_multi_1)(v, ioh, off, addr, count) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off, count; + u_int8_t *addr; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, val; + register int offset; + + wbflush(); + + while (count--) { + tmpioh = ioh + off; + offset = tmpioh & 3; + port = (u_int32_t *)((tmpioh << 5) | (0 << 3)); + val = *port; + *addr++ = ((val) >> (8 * offset)) & 0xff; + off++; + } +} + +void +__C(CHIP,_io_read_multi_2)(v, ioh, off, addr, count) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off, count; + u_int16_t *addr; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, val; + register int offset; + + wbflush(); + + while (count--) { + tmpioh = ioh + off; + offset = tmpioh & 3; + port = (u_int32_t *)((tmpioh << 5) | (1 << 3)); + val = *port; + *addr++ = ((val) >> (8 * offset)) & 0xffff; + off++; + } +} + +void +__C(CHIP,_io_read_multi_4)(v, ioh, off, addr, count) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off, count; + u_int32_t *addr; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, val; + register int offset; + + wbflush(); + + while (count--) { + tmpioh = ioh + off; + offset = tmpioh & 3; + port = (u_int32_t *)((tmpioh << 5) | (3 << 3)); + val = *port; +#if 0 + *addr++ = ((val) >> (8 * offset)) & 0xffffffff; +#else + *addr++ = val; +#endif + off++; + } +} + +void +__C(CHIP,_io_read_multi_8)(v, ioh, off, addr, count) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off, count; + u_int64_t *addr; +{ + + /* XXX XXX XXX */ + panic("%s not implemented\n", __S(__C(CHIP,_io_read_multi_8))); +} + +void +__C(CHIP,_io_write_1)(v, ioh, off, val) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off; + u_int8_t val; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, nval; + register int offset; + + tmpioh = ioh + off; + offset = tmpioh & 3; + nval = val << (8 * offset); + port = (u_int32_t *)((tmpioh << 5) | (0 << 3)); + *port = nval; + wbflush(); +} + +void +__C(CHIP,_io_write_2)(v, ioh, off, val) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off; + u_int16_t val; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, nval; + register int offset; + + tmpioh = ioh + off; + offset = tmpioh & 3; + nval = val << (8 * offset); + port = (u_int32_t *)((tmpioh << 5) | (1 << 3)); + *port = nval; + wbflush(); +} + +void +__C(CHIP,_io_write_4)(v, ioh, off, val) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off; + u_int32_t val; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, nval; + register int offset; + + tmpioh = ioh + off; + offset = tmpioh & 3; + nval = val /*<< (8 * offset)*/; + port = (u_int32_t *)((tmpioh << 5) | (3 << 3)); + *port = nval; + wbflush(); +} + +void +__C(CHIP,_io_write_8)(v, ioh, off, val) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off; + u_int64_t val; +{ + + /* XXX XXX XXX */ + panic("%s not implemented\n", __S(__C(CHIP,_io_write_8))); + wbflush(); +} + +void +__C(CHIP,_io_write_multi_1)(v, ioh, off, addr, count) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off, count; + const u_int8_t *addr; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, nval; + register int offset; + + while (count--) { + tmpioh = ioh + off; + offset = tmpioh & 3; + nval = (*addr++) << (8 * offset); + port = (u_int32_t *)((tmpioh << 5) | (0 << 3)); + *port = nval; + off++; + } + wbflush(); +} + +void +__C(CHIP,_io_write_multi_2)(v, ioh, off, addr, count) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off, count; + const u_int16_t *addr; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, nval; + register int offset; + + while (count--) { + tmpioh = ioh + off; + offset = tmpioh & 3; + nval = (*addr++) << (8 * offset); + port = (u_int32_t *)((tmpioh << 5) | (1 << 3)); + *port = nval; + off++; + } + wbflush(); +} + +void +__C(CHIP,_io_write_multi_4)(v, ioh, off, addr, count) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off, count; + const u_int32_t *addr; +{ + register bus_io_handle_t tmpioh; + register u_int32_t *port, nval; + register int offset; + + while (count--) { + tmpioh = ioh + off; + offset = tmpioh & 3; + nval = (*addr++) /*<< (8 * offset)*/; + port = (u_int32_t *)((tmpioh << 5) | (3 << 3)); + *port = nval; + off++; + } + wbflush(); +} + +void +__C(CHIP,_io_write_multi_8)(v, ioh, off, addr, count) + void *v; + bus_io_handle_t ioh; + bus_io_size_t off, count; + const u_int64_t *addr; +{ + + /* XXX XXX XXX */ + panic("%s not implemented\n", __S(__C(CHIP,_io_write_multi_8))); +} diff --git a/sys/arch/alpha/pci/pcs_bus_mem_common.c b/sys/arch/alpha/pci/pcs_bus_mem_common.c new file mode 100644 index 00000000000..3697a497a15 --- /dev/null +++ b/sys/arch/alpha/pci/pcs_bus_mem_common.c @@ -0,0 +1,378 @@ +/* $NetBSD: pcs_bus_mem_common.c,v 1.1.4.4 1996/06/13 18:17:01 cgd Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +/* + * Common PCI Chipset "bus I/O" functions, for chipsets which have to + * deal with only a single PCI interface chip in a machine. + * + * uses: + * CHIP name of the 'chip' it's being compiled for. + * CHIP_D_MEM_BASE Dense Mem space base to use. + * CHIP_S_MEM_BASE Sparse Mem space base to use. + */ + +#define __C(A,B) __CONCAT(A,B) +#define __S(S) __STRING(S) + +int __C(CHIP,_mem_map) __P((void *, bus_mem_addr_t, bus_mem_size_t, + int, bus_mem_handle_t *)); +void __C(CHIP,_mem_unmap) __P((void *, bus_mem_handle_t, + bus_mem_size_t)); +int __C(CHIP,_mem_subregion) __P((void *, bus_mem_handle_t, + bus_mem_size_t, bus_mem_size_t, bus_mem_handle_t *)); +u_int8_t __C(CHIP,_mem_read_1) __P((void *, bus_mem_handle_t, + bus_mem_size_t)); +u_int16_t __C(CHIP,_mem_read_2) __P((void *, bus_mem_handle_t, + bus_mem_size_t)); +u_int32_t __C(CHIP,_mem_read_4) __P((void *, bus_mem_handle_t, + bus_mem_size_t)); +u_int64_t __C(CHIP,_mem_read_8) __P((void *, bus_mem_handle_t, + bus_mem_size_t)); +void __C(CHIP,_mem_write_1) __P((void *, bus_mem_handle_t, + bus_mem_size_t, u_int8_t)); +void __C(CHIP,_mem_write_2) __P((void *, bus_mem_handle_t, + bus_mem_size_t, u_int16_t)); +void __C(CHIP,_mem_write_4) __P((void *, bus_mem_handle_t, + bus_mem_size_t, u_int32_t)); +void __C(CHIP,_mem_write_8) __P((void *, bus_mem_handle_t, + bus_mem_size_t, u_int64_t)); + +/* XXX DOES NOT BELONG */ +vm_offset_t __C(CHIP,_XXX_dmamap) __P((void *)); + +void +__C(CHIP,_bus_mem_init)(bc, memv) + bus_chipset_tag_t bc; + void *memv; +{ + + bc->bc_m_v = memv; + + bc->bc_m_map = __C(CHIP,_mem_map); + bc->bc_m_unmap = __C(CHIP,_mem_unmap); + bc->bc_m_subregion = __C(CHIP,_mem_subregion); + + bc->bc_mr1 = __C(CHIP,_mem_read_1); + bc->bc_mr2 = __C(CHIP,_mem_read_2); + bc->bc_mr4 = __C(CHIP,_mem_read_4); + bc->bc_mr8 = __C(CHIP,_mem_read_8); + + bc->bc_mw1 = __C(CHIP,_mem_write_1); + bc->bc_mw2 = __C(CHIP,_mem_write_2); + bc->bc_mw4 = __C(CHIP,_mem_write_4); + bc->bc_mw8 = __C(CHIP,_mem_write_8); + + /* XXX DOES NOT BELONG */ + bc->bc_XXX_dmamap = __C(CHIP,_XXX_dmamap); +} + +int +__C(CHIP,_mem_map)(v, memaddr, memsize, cacheable, memhp) + void *v; + bus_mem_addr_t memaddr; + bus_mem_size_t memsize; + int cacheable; + bus_mem_handle_t *memhp; +{ + + if (cacheable) { +#ifdef CHIP_D_MEM_W1_START + if (memaddr >= CHIP_D_MEM_W1_START(v) && + memaddr <= CHIP_D_MEM_W1_END(v)) { + *memhp = phystok0seg(CHIP_D_MEM_W1_BASE(v)) + + (memaddr & CHIP_D_MEM_W1_MASK(v)); + } else +#endif + { + printf("\n"); +#ifdef CHIP_D_MEM_W1_START + printf("%s: window[1]=0x%lx-0x%lx\n", + __S(__C(CHIP,_mem_map)), CHIP_D_MEM_W1_START(v), + CHIP_D_MEM_W1_END(v)-1); +#endif + panic("%s: don't know how to map %lx cacheable\n", + __S(__C(CHIP,_mem_map)), memaddr); + } + } else { +#ifdef CHIP_S_MEM_W1_START + if (memaddr >= CHIP_S_MEM_W1_START(v) && + memaddr <= CHIP_S_MEM_W1_END(v)) { + *memhp = (phystok0seg(CHIP_S_MEM_W1_BASE(v)) >> 5) + + (memaddr & CHIP_S_MEM_W1_MASK(v)); + } else +#endif +#ifdef CHIP_S_MEM_W2_START + if (memaddr >= CHIP_S_MEM_W2_START(v) && + memaddr <= CHIP_S_MEM_W2_END(v)) { + *memhp = (phystok0seg(CHIP_S_MEM_W2_BASE(v)) >> 5) + + (memaddr & CHIP_S_MEM_W2_MASK(v)); + } else +#endif +#ifdef CHIP_S_MEM_W3_START + if (memaddr >= CHIP_S_MEM_W3_START(v) && + memaddr <= CHIP_S_MEM_W3_END(v)) { + *memhp = (phystok0seg(CHIP_S_MEM_W3_BASE(v)) >> 5) + + (memaddr & CHIP_S_MEM_W3_MASK(v)); + } else +#endif + { + printf("\n"); +#ifdef CHIP_S_MEM_W1_START + printf("%s: window[1]=0x%lx-0x%lx\n", + __S(__C(CHIP,_mem_map)), CHIP_S_MEM_W1_START(v), + CHIP_S_MEM_W1_END(v)-1); +#endif +#ifdef CHIP_S_MEM_W2_START + printf("%s: window[2]=0x%lx-0x%lx\n", + __S(__C(CHIP,_mem_map)), CHIP_S_MEM_W2_START(v), + CHIP_S_MEM_W2_END(v)-1); +#endif +#ifdef CHIP_S_MEM_W3_START + printf("%s: window[3]=0x%lx-0x%lx\n", + __S(__C(CHIP,_mem_map)), CHIP_S_MEM_W3_START(v), + CHIP_S_MEM_W3_END(v)-1); +#endif + panic("%s: don't know how to map %lx non-cacheable\n", + __S(__C(CHIP,_mem_map)), memaddr); + } + } + + return (0); +} + +void +__C(CHIP,_mem_unmap)(v, memh, memsize) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t memsize; +{ + + /* XXX nothing to do. */ +} + +int +__C(CHIP,_mem_subregion)(v, memh, offset, size, nmemh) + void *v; + bus_mem_handle_t memh, *nmemh; + bus_mem_size_t offset, size; +{ + + *nmemh = memh + offset; + return (0); +} + +u_int8_t +__C(CHIP,_mem_read_1)(v, memh, off) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t off; +{ + register bus_mem_handle_t tmpmemh; + register u_int32_t *port, val; + register u_int8_t rval; + register int offset; + + wbflush(); + + if ((memh >> 63) != 0) + return (*(u_int8_t *)(memh + off)); + + tmpmemh = memh + off; + offset = tmpmemh & 3; + port = (u_int32_t *)((tmpmemh << 5) | (0 << 3)); + val = *port; + rval = ((val) >> (8 * offset)) & 0xff; + + return rval; +} + +u_int16_t +__C(CHIP,_mem_read_2)(v, memh, off) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t off; +{ + register bus_mem_handle_t tmpmemh; + register u_int32_t *port, val; + register u_int16_t rval; + register int offset; + + wbflush(); + + if ((memh >> 63) != 0) + return (*(u_int16_t *)(memh + off)); + + tmpmemh = memh + off; + offset = tmpmemh & 3; + port = (u_int32_t *)((tmpmemh << 5) | (1 << 3)); + val = *port; + rval = ((val) >> (8 * offset)) & 0xffff; + + return rval; +} + +u_int32_t +__C(CHIP,_mem_read_4)(v, memh, off) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t off; +{ + register bus_mem_handle_t tmpmemh; + register u_int32_t *port, val; + register u_int32_t rval; + register int offset; + + wbflush(); + + if ((memh >> 63) != 0) + return (*(u_int32_t *)(memh + off)); + + tmpmemh = memh + off; + offset = tmpmemh & 3; + port = (u_int32_t *)((tmpmemh << 5) | (3 << 3)); + val = *port; +#if 0 + rval = ((val) >> (8 * offset)) & 0xffffffff; +#else + rval = val; +#endif + + return rval; +} + +u_int64_t +__C(CHIP,_mem_read_8)(v, memh, off) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t off; +{ + + wbflush(); + + if ((memh >> 63) != 0) + return (*(u_int64_t *)(memh + off)); + + /* XXX XXX XXX */ + panic("%s not implemented\n", __S(__C(CHIP,_mem_read_8))); +} + +void +__C(CHIP,_mem_write_1)(v, memh, off, val) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t off; + u_int8_t val; +{ + register bus_mem_handle_t tmpmemh; + register u_int32_t *port, nval; + register int offset; + + if ((memh >> 63) != 0) + (*(u_int8_t *)(memh + off)) = val; + else { + tmpmemh = memh + off; + offset = tmpmemh & 3; + nval = val << (8 * offset); + port = (u_int32_t *)((tmpmemh << 5) | (0 << 3)); + *port = nval; + } + wbflush(); +} + +void +__C(CHIP,_mem_write_2)(v, memh, off, val) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t off; + u_int16_t val; +{ + register bus_mem_handle_t tmpmemh; + register u_int32_t *port, nval; + register int offset; + + if ((memh >> 63) != 0) + (*(u_int16_t *)(memh + off)) = val; + else { + tmpmemh = memh + off; + offset = tmpmemh & 3; + nval = val << (8 * offset); + port = (u_int32_t *)((tmpmemh << 5) | (1 << 3)); + *port = nval; + } + wbflush(); +} + +void +__C(CHIP,_mem_write_4)(v, memh, off, val) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t off; + u_int32_t val; +{ + register bus_mem_handle_t tmpmemh; + register u_int32_t *port, nval; + register int offset; + + if ((memh >> 63) != 0) + (*(u_int32_t *)(memh + off)) = val; + else { + tmpmemh = memh + off; + offset = tmpmemh & 3; + nval = val /*<< (8 * offset)*/; + port = (u_int32_t *)((tmpmemh << 5) | (3 << 3)); + *port = nval; + } + wbflush(); +} + +void +__C(CHIP,_mem_write_8)(v, memh, off, val) + void *v; + bus_mem_handle_t memh; + bus_mem_size_t off; + u_int64_t val; +{ + + if ((memh >> 63) != 0) + (*(u_int64_t *)(memh + off)) = val; + else { + /* XXX XXX XXX */ + panic("%s not implemented\n", + __S(__C(CHIP,_mem_write_8))); + } + wbflush(); +} + +vm_offset_t +__C(CHIP,_XXX_dmamap)(addr) + void *addr; +{ + + return (vtophys(addr) | 0x40000000); +} diff --git a/sys/arch/alpha/pci/sio.c b/sys/arch/alpha/pci/sio.c index a8b6b8a0a24..a43bcef227d 100644 --- a/sys/arch/alpha/pci/sio.c +++ b/sys/arch/alpha/pci/sio.c @@ -1,7 +1,7 @@ -/* $NetBSD: sio.c,v 1.3 1995/11/23 02:38:16 cgd Exp $ */ +/* $NetBSD: sio.c,v 1.8 1996/04/13 00:23:34 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -32,6 +32,9 @@ #include <sys/kernel.h> #include <sys/device.h> +#include <machine/intr.h> +#include <machine/bus.h> + #include <dev/isa/isavar.h> #include <dev/eisa/eisavar.h> @@ -44,17 +47,37 @@ int siomatch __P((struct device *, void *, void *)); void sioattach __P((struct device *, struct device *, void *)); -struct cfdriver siocd = { - NULL, "sio", siomatch, sioattach, DV_DULL, sizeof(struct device) +struct cfattach sio_ca = { + sizeof(struct device), siomatch, sioattach, +}; + +struct cfdriver sio_cd = { + NULL, "sio", DV_DULL, }; int pcebmatch __P((struct device *, void *, void *)); -struct cfdriver pcebcd = { - NULL, "pceb", pcebmatch, sioattach, DV_DULL, sizeof(struct device) +struct cfattach pceb_ca = { + sizeof(struct device), pcebmatch, sioattach, +}; + +struct cfdriver pceb_cd = { + NULL, "pceb", DV_DULL, }; -static int sioprint __P((void *, char *pnp)); +union sio_attach_args { + const char *sa_name; /* XXX should be common */ + struct isabus_attach_args sa_iba; + struct eisabus_attach_args sa_eba; +}; + +int sioprint __P((void *, char *pnp)); +void sio_isa_attach_hook __P((struct device *, struct device *, + struct isabus_attach_args *)); +void sio_eisa_attach_hook __P((struct device *, struct device *, + struct eisabus_attach_args *)); +int sio_eisa_maxslots __P((void *)); +int sio_eisa_intr_map __P((void *, u_int, eisa_intr_handle_t *)); int siomatch(parent, match, aux) @@ -62,10 +85,10 @@ siomatch(parent, match, aux) void *match, *aux; { struct cfdata *cf = match; - struct pcidev_attach_args *pda = aux; + struct pci_attach_args *pa = aux; - if (PCI_VENDOR(pda->pda_id) != PCI_VENDOR_INTEL || - PCI_PRODUCT(pda->pda_id) != PCI_PRODUCT_INTEL_SIO) + if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL || + PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_SIO) return (0); return (1); @@ -77,10 +100,10 @@ pcebmatch(parent, match, aux) void *match, *aux; { struct cfdata *cf = match; - struct pcidev_attach_args *pda = aux; + struct pci_attach_args *pa = aux; - if (PCI_VENDOR(pda->pda_id) != PCI_VENDOR_INTEL || - PCI_PRODUCT(pda->pda_id) != PCI_PRODUCT_INTEL_PCEB) + if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_INTEL || + PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_INTEL_PCEB) return (0); return (1); @@ -91,23 +114,24 @@ sioattach(parent, self, aux) struct device *parent, *self; void *aux; { - struct pcidev_attach_args *pda = aux; - struct isa_attach_args ia; - struct eisa_attach_args ea; + struct pci_attach_args *pa = aux; + struct alpha_isa_chipset ic; + struct alpha_eisa_chipset ec; + union sio_attach_args sa; int sio, haseisa; char devinfo[256]; - sio = (PCI_PRODUCT(pda->pda_id) == PCI_PRODUCT_INTEL_SIO); - haseisa = (PCI_PRODUCT(pda->pda_id) == PCI_PRODUCT_INTEL_PCEB); + sio = (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_SIO); + haseisa = (PCI_PRODUCT(pa->pa_id) == PCI_PRODUCT_INTEL_PCEB); - pci_devinfo(pda->pda_id, pda->pda_class, 0, devinfo); + pci_devinfo(pa->pa_id, pa->pa_class, 0, devinfo); printf(": %s (rev. 0x%02x)\n", devinfo, - PCI_REVISION(pda->pda_class)); + PCI_REVISION(pa->pa_class)); if (sio) { pci_revision_t rev; - rev = PCI_REVISION(pda->pda_class); + rev = PCI_REVISION(pa->pa_class); if (rev < 3) printf("%s: WARNING: SIO I SUPPORT UNTESTED\n", @@ -118,44 +142,89 @@ sioattach(parent, self, aux) evcnt_attach(self, "intr", &sio_intr_evcnt); #endif - ia.ia_bus = BUS_ISA; - ia.ia_dmafns = pda->pda_dmafns; - ia.ia_dmaarg = pda->pda_dmaarg; - ia.ia_intrfns = &sio_isa_intr_fns; - ia.ia_intrarg = NULL; /* XXX needs nothing */ - ia.ia_memfns = pda->pda_memfns; - ia.ia_memarg = pda->pda_memarg; - ia.ia_piofns = pda->pda_piofns; - ia.ia_pioarg = pda->pda_pioarg; - config_found(self, &ia, sioprint); - if (haseisa) { - ea.ea_bus = BUS_EISA; - ea.ea_dmafns = pda->pda_dmafns; - ea.ea_dmaarg = pda->pda_dmaarg; - ea.ea_intrfns = &sio_isa_intr_fns; - ea.ea_intrarg = NULL; /* XXX needs nothing */ - ea.ea_memfns = pda->pda_memfns; - ea.ea_memarg = pda->pda_memarg; - ea.ea_piofns = pda->pda_piofns; - ea.ea_pioarg = pda->pda_pioarg; - config_found(self, &ea, sioprint); + ec.ec_v = NULL; + ec.ec_attach_hook = sio_eisa_attach_hook; + ec.ec_maxslots = sio_eisa_maxslots; + ec.ec_intr_map = sio_eisa_intr_map; + ec.ec_intr_string = sio_intr_string; + ec.ec_intr_establish = sio_intr_establish; + ec.ec_intr_disestablish = sio_intr_disestablish; + + sa.sa_eba.eba_busname = "eisa"; + sa.sa_eba.eba_bc = pa->pa_bc; + sa.sa_eba.eba_ec = &ec; + config_found(self, &sa.sa_eba, sioprint); } + + ic.ic_v = NULL; + ic.ic_attach_hook = sio_isa_attach_hook; + ic.ic_intr_establish = sio_intr_establish; + ic.ic_intr_disestablish = sio_intr_disestablish; + + sa.sa_iba.iba_busname = "isa"; + sa.sa_iba.iba_bc = pa->pa_bc; + sa.sa_iba.iba_ic = ⁣ + config_found(self, &sa.sa_iba, sioprint); } -static int +int sioprint(aux, pnp) void *aux; char *pnp; { - register struct isa_attach_args *ia = aux; - - /* - * XXX Assumes that the first fields of 'struct isa_attach_args' - * XXX and 'struct eisa_attach_args' are the same. - */ + register union sio_attach_args *sa = aux; if (pnp) - printf("%s at %s", isa_bustype_name(ia->ia_bus), pnp); + printf("%s at %s", sa->sa_name, pnp); return (UNCONF); } + +void +sio_isa_attach_hook(parent, self, iba) + struct device *parent, *self; + struct isabus_attach_args *iba; +{ + + /* Nothing to do. */ +} + +void +sio_eisa_attach_hook(parent, self, eba) + struct device *parent, *self; + struct eisabus_attach_args *eba; +{ + + /* Nothing to do. */ +} + +int +sio_eisa_maxslots(v) + void *v; +{ + + return 16; /* as good a number as any. only 8, maybe? */ +} + +int +sio_eisa_intr_map(v, irq, ihp) + void *v; + u_int irq; + eisa_intr_handle_t *ihp; +{ + +#define ICU_LEN 16 /* number of ISA IRQs (XXX) */ + + if (irq >= ICU_LEN) { + printf("sio_eisa_intr_map: bad IRQ %d\n", irq); + *ihp = -1; + return 1; + } + if (irq == 2) { + printf("sio_eisa_intr_map: changed IRQ 2 to IRQ 9\n"); + irq = 9; + } + + *ihp = irq; + return 0; +} diff --git a/sys/arch/alpha/pci/sio_pic.c b/sys/arch/alpha/pci/sio_pic.c index b7d7af43858..6ad39660d5f 100644 --- a/sys/arch/alpha/pci/sio_pic.c +++ b/sys/arch/alpha/pci/sio_pic.c @@ -1,7 +1,7 @@ -/* $NetBSD: sio_pic.c,v 1.3 1995/12/24 02:29:49 mycroft Exp $ */ +/* $NetBSD: sio_pic.c,v 1.7.4.3 1996/06/05 22:50:23 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -33,6 +33,9 @@ #include <sys/malloc.h> #include <sys/syslog.h> +#include <machine/intr.h> +#include <machine/bus.h> + #include <dev/isa/isareg.h> #include <dev/isa/isavar.h> #include <alpha/pci/siovar.h> @@ -56,21 +59,10 @@ /* * Private functions and variables. */ -static void *sio_intr_establish __P((void *, isa_irq_t, - int, int, int (*)(void *), void *)); -static void sio_intr_disestablish __P((void *, void *)); -static void sio_strayintr __P((isa_irq_t)); - -static __const struct isa_pio_fns *sio_ipf; /* XXX */ -static void *sio_ipfa; /* XXX */ - -void sio_intr_setup __P((__const struct isa_pio_fns *, void *)); -void sio_iointr __P((void *framep, int vec)); +static void sio_strayintr __P((int)); -struct isa_intr_fns sio_isa_intr_fns = { - sio_intr_establish, - sio_intr_disestablish, -}; +bus_chipset_tag_t sio_bc; +bus_io_handle_t sio_ioh_icu1, sio_ioh_icu2, sio_ioh_elcr; /* * Interrupt handler chains. sio_intr_establish() inserts a handler into @@ -131,7 +123,7 @@ sio_setirqstat(irq, enabled, type) int icu, bit; #if 0 - printf("sio_setirqstat: irq %d, %s, %s\n", irq, + printf("sio_setirqstat: irq %d: %s, %s\n", irq, enabled ? "enabled" : "disabled", isa_intr_typename(type)); #endif @@ -140,10 +132,10 @@ sio_setirqstat(irq, enabled, type) icu = irq / 8; bit = irq % 8; - ocw1[0] = INB(sio_ipf, sio_ipfa, IO_ICU1 + 1); - ocw1[1] = INB(sio_ipf, sio_ipfa, IO_ICU2 + 1); - elcr[0] = INB(sio_ipf, sio_ipfa, 0x4d0); /* XXX */ - elcr[1] = INB(sio_ipf, sio_ipfa, 0x4d1); /* XXX */ + ocw1[0] = bus_io_read_1(sio_bc, sio_ioh_icu1, 1); + ocw1[1] = bus_io_read_1(sio_bc, sio_ioh_icu2, 1); + elcr[0] = bus_io_read_1(sio_bc, sio_ioh_elcr, 0); /* XXX */ + elcr[1] = bus_io_read_1(sio_bc, sio_ioh_elcr, 1); /* XXX */ /* * interrupt enable: set bit to mask (disable) interrupt. @@ -178,39 +170,42 @@ sio_setirqstat(irq, enabled, type) (ocw1[1] & ~initial_ocw1[1]) != 0 || (elcr[0] & initial_elcr[0]) != initial_elcr[0] || (elcr[1] & initial_elcr[1]) != initial_elcr[1]) { - printf("sio_sis: initial: ocw = (%2x,%2x), elcr = (%2x,%2X)\n", + printf("sio_sis: initial: ocw = (%2x,%2x), elcr = (%2x,%2x)\n", initial_ocw1[0], initial_ocw1[1], initial_elcr[0], initial_elcr[1]); - printf(" current: ocw = (%2x,%2x), elcr = (%2x,%2X)\n", + printf(" current: ocw = (%2x,%2x), elcr = (%2x,%2x)\n", ocw1[0], ocw1[1], elcr[0], elcr[1]); panic("sio_setirqstat: hosed"); } #endif - OUTB(sio_ipf, sio_ipfa, IO_ICU1 + 1, ocw1[0]); - OUTB(sio_ipf, sio_ipfa, IO_ICU2 + 1, ocw1[1]); - OUTB(sio_ipf, sio_ipfa, 0x4d0, elcr[0]); /* XXX */ - OUTB(sio_ipf, sio_ipfa, 0x4d1, elcr[1]); /* XXX */ + bus_io_write_1(sio_bc, sio_ioh_icu1, 1, ocw1[0]); + bus_io_write_1(sio_bc, sio_ioh_icu2, 1, ocw1[1]); + bus_io_write_1(sio_bc, sio_ioh_elcr, 0, elcr[0]); /* XXX */ + bus_io_write_1(sio_bc, sio_ioh_elcr, 1, elcr[1]); /* XXX */ } void -sio_intr_setup(ipf, ipfa) - __const struct isa_pio_fns *ipf; - void *ipfa; +sio_intr_setup(bc) + bus_chipset_tag_t bc; { int i; - sio_ipf = ipf; - sio_ipfa = ipfa; + sio_bc = bc; + + if (bus_io_map(sio_bc, IO_ICU1, IO_ICUSIZE, &sio_ioh_icu1) || + bus_io_map(sio_bc, IO_ICU2, IO_ICUSIZE, &sio_ioh_icu2) || + bus_io_map(sio_bc, 0x4d0, 2, &sio_ioh_elcr)) + panic("sio_intr_setup: can't map I/O ports"); #ifdef BROKEN_PROM_CONSOLE /* * Remember the initial values, because the prom is stupid. */ - initial_ocw1[0] = INB(sio_ipf, sio_ipfa, IO_ICU1 + 1); - initial_ocw1[1] = INB(sio_ipf, sio_ipfa, IO_ICU2 + 1); - initial_elcr[0] = INB(sio_ipf, sio_ipfa, 0x4d0); /* XXX */ - initial_elcr[1] = INB(sio_ipf, sio_ipfa, 0x4d1); /* XXX */ + initial_ocw1[0] = bus_io_read_1(sio_bc, sio_ioh_icu1, 1); + initial_ocw1[1] = bus_io_read_1(sio_bc, sio_ioh_icu2, 1); + initial_elcr[0] = bus_io_read_1(sio_bc, sio_ioh_elcr, 0); /* XXX */ + initial_elcr[1] = bus_io_read_1(sio_bc, sio_ioh_elcr, 1); /* XXX */ #if 0 printf("initial_ocw1[0] = 0x%x\n", initial_ocw1[0]); printf("initial_ocw1[1] = 0x%x\n", initial_ocw1[1]); @@ -262,14 +257,27 @@ sio_intr_setup(ipf, ipfa) } } +const char * +sio_intr_string(v, irq) + void *v; + int irq; +{ + static char irqstr[12]; /* 8 + 2 + NULL + sanity */ + + if (irq == 0 || irq >= ICU_LEN || irq == 2) + panic("sio_intr_string: bogus IRQ 0x%x\n", irq); + + sprintf(irqstr, "isa irq %d", irq); + return (irqstr); +} + void * -sio_intr_establish(siifa, irq, type, level, ih_fun, ih_arg) - void *siifa; - isa_irq_t irq; +sio_intr_establish(v, irq, type, level, ih_fun, ih_arg) + void *v, *ih_arg; + int irq; int type; int level; int (*ih_fun)(void *); - void *ih_arg; { struct intrhand **p, *c, *ih; extern int cold; @@ -288,10 +296,18 @@ sio_intr_establish(siifa, irq, type, level, ih_fun, ih_arg) if (type == sio_intrsharetype[irq]) break; case IST_PULSE: - if (type != IST_NONE) - panic("intr_establish: can't share %s with %s", - isa_intrsharetype_name(sio_intrsharetype[irq]), - isa_intrsharetype_name(type)); + if (type != IST_NONE) { + if (sio_intrhand[irq] == NULL) { + printf("sio_intr_establish: irq %d: warning: using %s on %s\n", + irq, isa_intr_typename(type), + isa_intr_typename(sio_intrsharetype[irq])); + type = sio_intrsharetype[irq]; + } else { + panic("sio_intr_establish: irq %d: can't share %s with %s", + irq, isa_intr_typename(type), + isa_intr_typename(sio_intrsharetype[irq])); + } + } break; } @@ -320,12 +336,12 @@ sio_intr_establish(siifa, irq, type, level, ih_fun, ih_arg) } void -sio_intr_disestablish(siifa, handler) - void *siifa; - void *handler; +sio_intr_disestablish(v, cookie) + void *v; + void *cookie; { - printf("sio_intr_disestablish(%lx)\n", handler); + printf("sio_intr_disestablish(%lx)\n", cookie); /* XXX */ /* XXX NEVER ALLOW AN INITIALLY-ENABLED INTERRUPT TO BE DISABLED */ @@ -337,7 +353,7 @@ sio_intr_disestablish(siifa, handler) */ void sio_strayintr(irq) - isa_irq_t irq; + int irq; { if (++sio_strayintrcnt[irq] <= STRAY_MAX) @@ -401,8 +417,8 @@ sio_iointr(framep, vec) * by the interrupt handler. */ if (irq > 7) - OUTB(sio_ipf, sio_ipfa, - IO_ICU2 + 0, 0x20 | (irq & 0x07)); /* XXX */ - OUTB(sio_ipf, sio_ipfa, - IO_ICU1 + 0, 0x20 | (irq > 7 ? 2 : irq)); /* XXX */ + bus_io_write_1(sio_bc, + sio_ioh_icu2, 0, 0x20 | (irq & 0x07)); /* XXX */ + bus_io_write_1(sio_bc, + sio_ioh_icu1, 0, 0x20 | (irq > 7 ? 2 : irq)); /* XXX */ } diff --git a/sys/arch/alpha/pci/sioreg.h b/sys/arch/alpha/pci/sioreg.h new file mode 100644 index 00000000000..3be1f87288f --- /dev/null +++ b/sys/arch/alpha/pci/sioreg.h @@ -0,0 +1,129 @@ +/* $NetBSD: sioreg.h,v 1.1 1996/04/23 14:10:53 cgd Exp $ */ + +/* + * Copyright (c) 1996 BBN Corporation. + * BBN Systems and Technologies Division + * 10 Moulton Street + * Cambridge, Ma. 02138 + * 617-873-3000 + * + * Permission to use, copy, modify, distribute, and sell this software and its + * documentation for any purpose is hereby granted without fee, provided that + * the above copyright notice and this permission appear in all copies and in + * supporting documentation, and that the name of BBN Corporation not be used + * in advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. BBN makes no representations + * about the suitability of this software for any purposes. It is provided + * "AS IS" without express or implied warranties. + */ + +/* + * Intel 82378 System I/O (SIO) Chip + * + * Taken from the Intel "Peripheral Components" manual, 1995 Edition. + */ + + +/* + * Device-specific PCI Configuration Registers + */ + +/* + * PCI Control Registers + */ +#define SIO_PCIREG_PCICON 0x40 /* PCI Control */ +#define SIO_PCIREG_PAC 0x41 /* PCI Arbiter Control */ +#define SIO_PCIREG_PAPC 0x42 /* PCI Arbiter Priority Control */ +#define SIO_PCIREG_ARBPRIX 0x43 /* PCI Arbiter Priority Control Ext. */ + +/* + * Memory Chip Select Registers + */ +#define SIO_PCIREG_MEMCSCON 0x44 /* MEMCS# Control */ +#define SIO_PCIREG_MEMCSBOH 0x45 /* MEMCS# Bottom of Hole */ +#define SIO_PCIREG_MEMCSTOH 0x46 /* MEMCS# Top of Hole */ +#define SIO_PCIREG_MEMCSTOM 0x47 /* MEMCS# Top of Memory */ + +#define SIO_PCIREG_MAR1 0x54 /* MEMCS# Attribute 1 */ +#define SIO_PCIREG_MAR2 0x55 /* MEMCS# Attribute 2 */ +#define SIO_PCIREG_MAR3 0x56 /* MEMCS# Attribute 3 */ +#define SIO_PCIREG_DMASGRB 0x57 /* DMA Scatter/Gather Rel. Base Addr. */ + +/* + * ISA Address Decoder Registers + */ +#define SIO_PCIREG_IADCON 0x48 /* ISA Address Decoder Control */ +#define SIO_PCIREG_IADRBE 0x49 /* ISA Addr. Decoder ROM Block Enable */ +#define SIO_PCIREG_IADBOH 0x4A /* ISA Addr. Decoder Bottom of Hole */ +#define SIO_PCIREG_IADTOH 0x4B /* ISA Addr. Decoder Top of Hole */ + +/* + * Clocks and Timers + */ +#define SIO_PCIREG_ICRT 0x4C /* ISA Controller Recovery Timer */ +#define SIO_PCIREG_ICD 0x4D /* ISA Clock Divisor */ + +#define SIO_PCIREG_ 0x80 /* BIOS Timer Base Address */ + +#define SIO_PCIREG_CTLTMRL 0xAC /* Clock Throttle STPCLK# Low Timer */ +#define SIO_PCIREG_CTLTMRH 0xAE /* Clock Throttle STPCLK# High Timer */ + +/* + * Miscellaneous + */ +#define SIO_PCIREG_UBCSA 0x4E /* Utility Bus Chip Select A */ +#define SIO_PCIREG_UBCSB 0x4F /* Utility Bus Chip Select B */ + +/* + * PIRQ# Route Control + */ +#define SIO_PCIREG_PIRQ0 0x60 /* PIRQ0 Route Control */ +#define SIO_PCIREG_PIRQ1 0x61 /* PIRQ1 Route Control */ +#define SIO_PCIREG_PIRQ2 0x62 /* PIRQ2 Route Control */ +#define SIO_PCIREG_PIRQ3 0x63 /* PIRQ3 Route Control */ +#define SIO_PCIREG_PIRQ_RTCTRL SIO_PCIREG_PIRQ0 + +/* + * System Management Interrupt (SMI) + */ +#define SIO_PCIREG_SMICNTL 0xA0 /* SMI Control */ +#define SIO_PCIREG_SMIEN 0xA2 /* SMI Enable */ +#define SIO_PCIREG_SEE 0xA4 /* System Event Enable */ +#define SIO_PCIREG_FTMR 0xA8 /* Fast Off Timer */ +#define SIO_PCIREG_SMIREQ 0xAA /* SMI Request */ + + +/* + * Non-Configuration Registers + */ + +/* + * Control + */ +#define SIO_REG_RSTUB 0x060 /* Reset UBus */ +#define SIO_REG_NMICTRL 0x061 /* NMI Status and Control */ +#define SIO_REG_CMOSRAM 0x070 /* CMOS RAM Address and NMI Mask */ +#define SIO_REG_NMIMASK 0x070 /* CMOS RAM Address and NMI Mask */ +#define SIO_REG_PORT92 0x092 /* Port 92 */ +#define SIO_REG_CPERR 0x0F0 /* Coprocessor Error */ + +/* + * Interrupt + */ +#define SIO_REG_ICU1 0x020 /* Intr. Controller #1 Control */ +#define SIO_REG_ICU1MASK 0x021 /* Intr. Controller #1 Mask */ +#define SIO_REG_ICU2 0x0A0 /* Intr. Controller #2 Control */ +#define SIO_REG_ICU2MASK 0x0A1 /* Intr. Controller #2 Mask */ +#define SIO_REG_ICU1ELC 0x4D0 /* #1's Edge/Level Control */ +#define SIO_REG_ICU2ELC 0x4D1 /* #2's Edge/Level Control */ +#define SIO_ICUSIZE 16 /* I/O Port Sizes */ + +/* + * Timer + */ +/* XXX need Timer definitions */ + +/* + * DMA + */ +/* XXX need DMA definitions */ diff --git a/sys/arch/alpha/pci/siovar.h b/sys/arch/alpha/pci/siovar.h index 746b9a89abb..84bcfabcedd 100644 --- a/sys/arch/alpha/pci/siovar.h +++ b/sys/arch/alpha/pci/siovar.h @@ -1,7 +1,7 @@ -/* $NetBSD: siovar.h,v 1.1 1995/11/23 02:38:22 cgd Exp $ */ +/* $NetBSD: siovar.h,v 1.3 1996/04/12 06:09:06 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -27,10 +27,14 @@ * rights to redistribute these changes. */ -void sio_intr_setup __P((__const struct isa_pio_fns *, void *)); +void sio_intr_setup __P((bus_chipset_tag_t)); void sio_iointr __P((void *framep, int vec)); +const char *sio_intr_string __P((void *, int)); +void *sio_intr_establish __P((void *, int, int, int, int (*)(void *), + void *)); +void sio_intr_disestablish __P((void *, void *)); + #ifdef EVCNT_COUNTERS extern struct evcnt sio_intr_evcnt; #endif -extern __const struct isa_intr_fns sio_isa_intr_fns; diff --git a/sys/arch/alpha/pci/tga.c b/sys/arch/alpha/pci/tga.c index 739c0d812c1..efec7a02a81 100644 --- a/sys/arch/alpha/pci/tga.c +++ b/sys/arch/alpha/pci/tga.c @@ -1,7 +1,7 @@ -/* $NetBSD: tga.c,v 1.3 1995/11/23 02:38:25 cgd Exp $ */ +/* $NetBSD: tga.c,v 1.6 1996/04/12 06:09:08 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -32,48 +32,49 @@ #include <sys/kernel.h> #include <sys/device.h> #include <sys/malloc.h> +#include <sys/buf.h> #include <sys/conf.h> +#include <sys/ioctl.h> -#include <dev/rcons/raster.h> -#include <dev/pseudo/rcons.h> -#include <dev/pseudo/ansicons.h> +#include <machine/bus.h> +#include <machine/intr.h> #include <dev/pci/pcireg.h> #include <dev/pci/pcivar.h> #include <dev/pci/pcidevs.h> -#include <alpha/pci/tgareg.h> +#include <machine/tgareg.h> #include <alpha/pci/tgavar.h> #include <alpha/pci/bt485reg.h> -#include <alpha/pci/wsconsvar.h> + +#include <dev/rcons/raster.h> +#include <alpha/wscons/wscons_raster.h> +#include <alpha/wscons/wsconsvar.h> +#include <machine/fbio.h> #include <machine/autoconf.h> #include <machine/pte.h> int tgamatch __P((struct device *, void *, void *)); void tgaattach __P((struct device *, struct device *, void *)); +int tgaprint __P((void *, char *)); -struct cfdriver tgacd = { - NULL, "tga", tgamatch, tgaattach, DV_DULL, sizeof(struct tga_softc) +struct cfattach tga_ca = { + sizeof(struct tga_softc), tgamatch, tgaattach, }; -int tga_identify __P((tga_reg_t *)); -__const struct tga_conf *tga_getconf __P((int)); -void tga_getdevconfig __P((__const struct pci_conf_fns *, void *, - __const struct pci_mem_fns *, void *, - pci_conftag_t tag, struct tga_devconfig *dc)); +struct cfdriver tga_cd = { + NULL, "tga", DV_DULL, +}; -void tga_bell __P((void *)); /* XXX */ +int tga_identify __P((tga_reg_t *)); +const struct tga_conf *tga_getconf __P((int)); +void tga_getdevconfig __P((bus_chipset_tag_t bc, pci_chipset_tag_t pc, + pcitag_t tag, struct tga_devconfig *dc)); struct tga_devconfig tga_console_dc; -#if 0 -dev_decl(tga, mmap); -dev_decl(tga, ioctl); -#endif - -struct ansicons_functions tga_acf = { - tga_bell, - rcons_cursor, /* could use hardware cursor; who cares? */ +struct wscons_emulfuncs tga_emulfuncs = { + rcons_cursor, /* could use hardware cursor; punt */ rcons_putstr, rcons_copycols, rcons_erasecols, @@ -81,110 +82,11 @@ struct ansicons_functions tga_acf = { rcons_eraserows, }; -#define TGAUNIT(dev) minor(dev) +int tgaioctl __P((struct device *, u_long, caddr_t, int, struct proc *)); +int tgammap __P((struct device *, off_t, int)); -void tga_builtin_set_cpos __P((struct tga_devconfig *, int, int)); -void tga_builtin_get_cpos __P((struct tga_devconfig *, int *, int *)); - -__const struct tga_ramdac_conf tga_ramdac_bt463 = { - "Bt463", - tga_builtin_set_cpos, - tga_builtin_get_cpos, - /* XXX */ -}; - -void tga_bt485_wr_reg __P((volatile tga_reg_t *, u_int, u_int8_t)); -u_int8_t tga_bt485_rd_reg __P((volatile tga_reg_t *, u_int)); - -void tga_bt485_set_cpos __P((struct tga_devconfig *, int, int)); -void tga_bt485_get_cpos __P((struct tga_devconfig *, int *, int *)); - -__const struct tga_ramdac_conf tga_ramdac_bt485 = { - "Bt485", - tga_bt485_set_cpos, - tga_bt485_get_cpos, - /* XXX */ -}; - -#undef KB -#define KB * 1024 -#undef MB -#define MB * 1024 * 1024 - -__const struct tga_conf tga_configs[TGA_TYPE_UNKNOWN] = { - /* TGA_TYPE_T8_01 */ - { - "T8-01", - &tga_ramdac_bt485, - 8, - 4 MB, - 2 KB, - 1, { 2 MB, 0 }, { 1 MB, 0 }, - 0, { 0, 0 }, { 0, 0 }, - }, - /* TGA_TYPE_T8_02 */ - { - "T8-02", - &tga_ramdac_bt485, - 8, - 4 MB, - 4 KB, - 1, { 2 MB, 0 }, { 2 MB, 0 }, - 0, { 0, 0 }, { 0, 0 }, - }, - /* TGA_TYPE_T8_22 */ - { - "T8-22", - &tga_ramdac_bt485, - 8, - 8 MB, - 4 KB, - 1, { 4 MB, 0 }, { 2 MB, 0 }, - 1, { 6 MB, 0 }, { 2 MB, 0 }, - }, - /* TGA_TYPE_T8_44 */ - { - "T8-44", - &tga_ramdac_bt485, - 8, - 16 MB, - 4 KB, - 2, { 8 MB, 12 MB }, { 2 MB, 2 MB }, - 2, { 10 MB, 14 MB }, { 2 MB, 2 MB }, - }, - /* TGA_TYPE_T32_04 */ - { - "T32-04", - &tga_ramdac_bt463, - 32, - 16 MB, - 8 KB, - 1, { 8 MB, 0 }, { 4 MB, 0 }, - 0, { 0, 0 }, { 0, 0 }, - }, - /* TGA_TYPE_T32_08 */ - { - "T32-08", - &tga_ramdac_bt463, - 32, - 16 MB, - 16 KB, - 1, { 8 MB, 0 }, { 8 MB, 0 }, - 0, { 0, 0 }, { 0, 0 }, - }, - /* TGA_TYPE_T32_88 */ - { - "T32-88", - &tga_ramdac_bt463, - 32, - 32 MB, - 16 KB, - 1, { 16 MB, 0 }, { 8 MB, 0 }, - 1, { 24 MB, 0 }, { 8 MB, 0 }, - }, -}; -#undef KB -#undef MB +void tga_blank __P((struct tga_devconfig *)); +void tga_unblank __P((struct tga_devconfig *)); int tgamatch(parent, match, aux) @@ -192,113 +94,43 @@ tgamatch(parent, match, aux) void *match, *aux; { struct cfdata *cf = match; - struct pcidev_attach_args *pda = aux; + struct pci_attach_args *pa = aux; - if (PCI_VENDOR(pda->pda_id) != PCI_VENDOR_DEC || - PCI_PRODUCT(pda->pda_id) != PCI_PRODUCT_DEC_21030) + if (PCI_VENDOR(pa->pa_id) != PCI_VENDOR_DEC || + PCI_PRODUCT(pa->pa_id) != PCI_PRODUCT_DEC_21030) return (0); - return (1); -} - -int -tga_identify(regs) - tga_reg_t *regs; -{ - int type; - int deep, addrmask, wide; - - deep = (regs[TGA_REG_GDER] & 0x1) != 0; /* XXX */ - addrmask = ((regs[TGA_REG_GDER] >> 2) & 0x7); /* XXX */ - wide = (regs[TGA_REG_GDER] & 0x200) == 0; /* XXX */ - - type = TGA_TYPE_UNKNOWN; - - if (!deep) { - /* 8bpp frame buffer */ - - if (addrmask == 0x0) { - /* 4MB core map; T8-01 or T8-02 */ - - if (!wide) - type = TGA_TYPE_T8_01; - else - type = TGA_TYPE_T8_02; - } else if (addrmask == 0x1) { - /* 8MB core map; T8-22 */ - - if (wide) /* sanity */ - type = TGA_TYPE_T8_22; - } else if (addrmask == 0x3) { - /* 16MB core map; T8-44 */ - - if (wide) /* sanity */ - type = TGA_TYPE_T8_44; - } - } else { - /* 32bpp frame buffer */ - - if (addrmask == 0x3) { - /* 16MB core map; T32-04 or T32-08 */ - - if (!wide) - type = TGA_TYPE_T32_04; - else - type = TGA_TYPE_T32_08; - } else if (addrmask == 0x7) { - /* 32MB core map; T32-88 */ - - if (wide) /* sanity */ - type = TGA_TYPE_T32_88; - } - } - - return (type); -} - -__const struct tga_conf * -tga_getconf(type) - int type; -{ - - if (type >= 0 && type < TGA_TYPE_UNKNOWN) - return &tga_configs[type]; - - return (NULL); + return (10); } void -tga_getdevconfig(pcf, pcfa, pmf, pmfa, tag, dc) - __const struct pci_conf_fns *pcf; - __const struct pci_mem_fns *pmf; - void *pcfa, *pmfa; - pci_conftag_t tag; +tga_getdevconfig(bc, pc, tag, dc) + bus_chipset_tag_t bc; + pci_chipset_tag_t pc; + pcitag_t tag; struct tga_devconfig *dc; { - __const struct tga_conf *tgac; - __const struct tga_ramdac_conf *tgar; + const struct tga_conf *tgac; + const struct tga_ramdac_conf *tgar; struct raster *rap; struct rcons *rcp; - pci_msize_t pcisize; + bus_mem_size_t pcisize; int i, cacheable; - dc->dc_pcf = pcf; - dc->dc_pcfa = pcfa; - dc->dc_pmf = pmf; - dc->dc_pmfa = pmfa; + dc->dc_bc = bc; + dc->dc_pc = pc; dc->dc_pcitag = tag; /* XXX MAGIC NUMBER */ - PCI_FIND_MEM(pcf, pcfa, tag, 0x10, &dc->dc_pcipaddr, &pcisize, + pci_mem_find(pc, tag, 0x10, &dc->dc_pcipaddr, &pcisize, &cacheable); if (!cacheable) /* sanity */ panic("tga_getdevconfig: memory not cacheable?"); - dc->dc_vaddr = PCI_MEM_MAP(pmf, pmfa, dc->dc_pcipaddr, pcisize, 1); - if (dc->dc_vaddr == 0) + /* XXX XXX XXX */ + if (bus_mem_map(bc, dc->dc_pcipaddr, pcisize, 1, &dc->dc_vaddr)) return; - dc->dc_paddr = k0segtophys(dc->dc_vaddr); /* XXX */ dc->dc_regs = (tga_reg_t *)(dc->dc_vaddr + TGA_MEM_CREGS); @@ -332,15 +164,26 @@ tga_getdevconfig(pcf, pcfa, pmf, pmfa, tag, dc) dc->dc_rowbytes = dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8); if ((dc->dc_regs[TGA_REG_VHCR] & 0x00000001) != 0 && /* XXX */ - (dc->dc_regs[TGA_REG_VHCR] & 0x80000000) != 0) /* XXX */ + (dc->dc_regs[TGA_REG_VHCR] & 0x80000000) != 0) { /* XXX */ dc->dc_wid -= 4; + /* + * XXX XXX turning off 'odd' shouldn't be necesssary, + * XXX XXX but i can't make X work with the weird size. + */ + dc->dc_regs[TGA_REG_VHCR] &= ~0x80000001; + dc->dc_rowbytes = + dc->dc_wid * (dc->dc_tgaconf->tgac_phys_depth / 8); + } dc->dc_ht = (dc->dc_regs[TGA_REG_VVCR] & 0x7ff); /* XXX */ /* XXX this seems to be what DEC does */ + dc->dc_regs[TGA_REG_CCBR] = 0; dc->dc_regs[TGA_REG_VVBR] = 1; dc->dc_videobase = dc->dc_vaddr + tgac->tgac_dbuf[0] + 1 * tgac->tgac_vvbr_units; + dc->dc_blanked = 1; + tga_unblank(dc); /* * Set all bits in the pixel mask, to enable writes to all pixels. @@ -349,15 +192,6 @@ tga_getdevconfig(pcf, pcfa, pmf, pmfa, tag, dc) */ dc->dc_regs[TGA_REG_GPXR_P] = 0xffffffff; - /* disable the cursor */ - (*tgar->tgar_set_cpos)(dc, TGA_CURSOR_OFF, 0); - - /* init black and white color map entries to 'sane' values. */ -#if 0 - (*tgar->tga_set_cmap)(dc, 0, 0, 0, 0); - (*tgar->tga_set_cmap)(dc, 255, 0xff, 0xff, 0xff); -#endif - /* clear the screen */ for (i = 0; i < dc->dc_ht * dc->dc_rowbytes; i += sizeof(u_int32_t)) *(u_int32_t *)(dc->dc_videobase + i) = 0; @@ -384,27 +218,56 @@ tgaattach(parent, self, aux) struct device *parent, *self; void *aux; { - struct pcidev_attach_args *pda = aux; + struct pci_attach_args *pa = aux; struct tga_softc *sc = (struct tga_softc *)self; - pci_revision_t rev; + struct wscons_attach_args waa; + struct wscons_odev_spec *wo; + pci_intr_handle_t intrh; + const char *intrstr; + u_int8_t rev; int console; - console = (pda->pda_tag == tga_console_dc.dc_pcitag); + console = (pa->pa_tag == tga_console_dc.dc_pcitag); if (console) sc->sc_dc = &tga_console_dc; else { sc->sc_dc = (struct tga_devconfig *) malloc(sizeof(struct tga_devconfig), M_DEVBUF, M_WAITOK); - tga_getdevconfig(pda->pda_conffns, pda->pda_confarg, - pda->pda_memfns, pda->pda_memarg, pda->pda_tag, sc->sc_dc); + tga_getdevconfig(pa->pa_bc, pa->pa_pc, pa->pa_tag, sc->sc_dc); } if (sc->sc_dc->dc_vaddr == NULL) { printf(": couldn't map memory space; punt!\n"); return; } + /* XXX say what's going on. */ + if (sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_intr != NULL) { + if (pci_intr_map(pa->pa_pc, pa->pa_intrtag, pa->pa_intrpin, + pa->pa_intrline, &intrh)) { + printf(": couldn't map interrupt"); + return; + } + intrstr = pci_intr_string(pa->pa_pc, intrh); + sc->sc_intr = pci_intr_establish(pa->pa_pc, intrh, IPL_TTY, + sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_intr, sc->sc_dc); + if (sc->sc_intr == NULL) { + printf(": couldn't establish interrupt"); + if (intrstr != NULL) + printf("at %s", intrstr); + printf("\n"); + return; + } + } + + /* + * Initialize the RAMDAC and allocate any private storage it needs. + * Initialization includes disabling cursor, setting a sane + * colormap, etc. + */ + (*sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_init)(sc->sc_dc, 1); + printf(": DC21030 "); - rev = PCI_REVISION(pda->pda_class); + rev = PCI_REVISION(pa->pa_class); switch (rev) { case 1: case 2: case 3: printf("step %c", 'A' + rev - 1); @@ -426,216 +289,276 @@ tgaattach(parent, self, aux) sc->sc_dc->dc_tgaconf->tgac_phys_depth, sc->sc_dc->dc_tgaconf->tgac_ramdac->tgar_name); -#if 0 - /* XXX intr foo? */ -#endif + if (intrstr != NULL) + printf("%s: interrupting at %s\n", sc->sc_dev.dv_xname, + intrstr); + + waa.waa_isconsole = console; + wo = &waa.waa_odev_spec; + wo->wo_ef = &tga_emulfuncs; + wo->wo_efa = &sc->sc_dc->dc_rcons; + wo->wo_nrows = sc->sc_dc->dc_rcons.rc_maxrow; + wo->wo_ncols = sc->sc_dc->dc_rcons.rc_maxcol; + wo->wo_crow = 0; + wo->wo_ccol = 0; + wo->wo_ioctl = tgaioctl; + wo->wo_mmap = tgammap; + + config_found(self, &waa, tgaprint); +} - if (!wscattach_output(self, console, &sc->sc_dc->dc_ansicons, &tga_acf, - &sc->sc_dc->dc_rcons, sc->sc_dc->dc_rcons.rc_maxrow, - sc->sc_dc->dc_rcons.rc_maxcol, 0, 0)) { - panic("tgaattach: wscattach failed"); - /* NOTREACHED */ - } +int +tgaprint(aux, pnp) + void *aux; + char *pnp; +{ + + if (pnp) + printf("wscons at %s", pnp); + return (UNCONF); } -#if 0 int tgaioctl(dev, cmd, data, flag, p) - dev_t dev; + struct device *dev; u_long cmd; caddr_t data; int flag; struct proc *p; { - struct tga_softc *sc = tgacd.cd_devs[TGAUNIT(dev)]; + struct tga_softc *sc = (struct tga_softc *)dev; + struct tga_devconfig *dc = sc->sc_dc; + const struct tga_ramdac_conf *tgar = dc->dc_tgaconf->tgac_ramdac; + + switch (cmd) { + case FBIOGTYPE: +#define fbt ((struct fbtype *)data) + fbt->fb_type = FBTYPE_TGA; + fbt->fb_height = sc->sc_dc->dc_ht; + fbt->fb_width = sc->sc_dc->dc_wid; + fbt->fb_depth = sc->sc_dc->dc_tgaconf->tgac_phys_depth; + fbt->fb_cmsize = 256; /* XXX ??? */ + fbt->fb_size = sc->sc_dc->dc_tgaconf->tgac_cspace_size; +#undef fbt + return (0); + + case FBIOPUTCMAP: + return (*tgar->tgar_set_cmap)(dc, (struct fbcmap *)data); + + case FBIOGETCMAP: + return (*tgar->tgar_get_cmap)(dc, (struct fbcmap *)data); + + case FBIOGATTR: + return (ENOTTY); /* XXX ? */ - return (ENOTTY); + case FBIOSVIDEO: + if (*(int *)data == FBVIDEO_OFF) + tga_blank(sc->sc_dc); + else + tga_unblank(sc->sc_dc); + return (0); + + case FBIOGVIDEO: + *(int *)data = dc->dc_blanked ? FBVIDEO_OFF : FBVIDEO_ON; + return (0); + + case FBIOSCURSOR: + return (*tgar->tgar_set_cursor)(dc, (struct fbcursor *)data); + + case FBIOGCURSOR: + return (*tgar->tgar_get_cursor)(dc, (struct fbcursor *)data); + + case FBIOSCURPOS: + return (*tgar->tgar_set_curpos)(dc, (struct fbcurpos *)data); + + case FBIOGCURPOS: + return (*tgar->tgar_get_curpos)(dc, (struct fbcurpos *)data); + + case FBIOGCURMAX: + return (*tgar->tgar_get_curmax)(dc, (struct fbcurpos *)data); + } + return (-1); } int -tgammap(dev, offset, nprot) - dev_t dev; - int offset; - int nprot; +tgammap(dev, offset, prot) + struct device *dev; + off_t offset; + int prot; { - struct tga_softc *sc = tgacd.cd_devs[TGAUNIT(dev)]; + struct tga_softc *sc = (struct tga_softc *)dev; if (offset > sc->sc_dc->dc_tgaconf->tgac_cspace_size) return -1; return alpha_btop(sc->sc_dc->dc_paddr + offset); } -#endif void -tga_bell(id) - void *id; +tga_console(bc, pc, bus, device, function) + bus_chipset_tag_t bc; + pci_chipset_tag_t pc; + int bus, device, function; { + struct tga_devconfig *dcp = &tga_console_dc; + struct wscons_odev_spec wo; + + tga_getdevconfig(bc, pc, pci_make_tag(pc, bus, device, function), dcp); - /* XXX */ - printf("tga_bell: not implemented\n"); + /* sanity checks */ + if (dcp->dc_vaddr == NULL) + panic("tga_console(%d, %d): couldn't map memory space", + device, function); + if (dcp->dc_tgaconf == NULL) + panic("tga_console(%d, %d): unknown board configuration", + device, function); + + /* + * Initialize the RAMDAC but DO NOT allocate any private storage. + * Initialization includes disabling cursor, setting a sane + * colormap, etc. It will be reinitialized in tgaattach(). + */ + (*dcp->dc_tgaconf->tgac_ramdac->tgar_init)(dcp, 0); + + wo.wo_ef = &tga_emulfuncs; + wo.wo_efa = &dcp->dc_rcons; + wo.wo_nrows = dcp->dc_rcons.rc_maxrow; + wo.wo_ncols = dcp->dc_rcons.rc_maxcol; + wo.wo_crow = 0; + wo.wo_ccol = 0; + /* ioctl and mmap are unused until real attachment. */ + + wscons_attach_console(&wo); } +/* + * Functions to blank and unblank the display. + */ void -tga_builtin_set_cpos(dc, x, y) +tga_blank(dc) struct tga_devconfig *dc; - int x, y; { - if (x == TGA_CURSOR_OFF || y == TGA_CURSOR_OFF) { - - dc->dc_regs[TGA_REG_VVVR] &= ~0x04; /* XXX */ - wbflush(); - return; + if (!dc->dc_blanked) { + dc->dc_blanked = 1; + dc->dc_regs[TGA_REG_VVVR] |= 0x02; /* XXX */ } - - /* - * TGA builtin cursor is 0-based, and position is top-left corner. - */ - dc->dc_regs[TGA_REG_CXYR] = - (x & 0xfff) | ((y & 0xfff) << 12); /* XXX */ - wbflush(); } void -tga_builtin_get_cpos(dc, xp, yp) +tga_unblank(dc) struct tga_devconfig *dc; - int *xp, *yp; { - tga_reg_t regval; - if ((dc->dc_regs[TGA_REG_VVVR] & 0x04) == 0) { /* XXX */ - *xp = *yp = TGA_CURSOR_OFF; - return; + if (dc->dc_blanked) { + dc->dc_blanked = 0; + dc->dc_regs[TGA_REG_VVVR] &= ~0x02; /* XXX */ } - - regval = dc->dc_regs[TGA_REG_CXYR]; - *xp = regval & 0xfff; /* XXX */ - *yp = (regval >> 12) & 0xfff; /* XXX */ } /* - * Bt485-specific functions. + * Functions to manipulate the built-in cursor handing hardware. */ - -void -tga_bt485_wr_reg(tgaregs, btreg, val) - volatile tga_reg_t *tgaregs; - u_int btreg; - u_int8_t val; +int +tga_builtin_set_cursor(dc, fbc) + struct tga_devconfig *dc; + struct fbcursor *fbc; { + int v, count; - if (btreg > BT485_REG_MAX) - panic("tga_bt485_wr_reg: reg %d out of range\n", btreg); + v = fbc->set; +#if 0 + if (v & FB_CUR_SETCMAP) /* XXX should be supported */ + return EINVAL; + if (v & FB_CUR_SETSHAPE) { + if ((u_int)fbc->size.x != 64 || (u_int)fbc->size.y > 64) + return (EINVAL); + /* The cursor is 2 bits deep, and there is no mask */ + count = (fbc->size.y * 64 * 2) / NBBY; + if (!useracc(fbc->image, count, B_READ)) + return (EFAULT); + } + if (v & FB_CUR_SETHOT) /* not supported */ + return EINVAL; +#endif - tgaregs[TGA_REG_EPDR] = (btreg << 9) | (0 << 8 ) | val; /* XXX */ - wbflush(); + /* parameters are OK; do it */ + if (v & FB_CUR_SETCUR) { + if (fbc->enable) + dc->dc_regs[TGA_REG_VVVR] |= 0x04; /* XXX */ + else + dc->dc_regs[TGA_REG_VVVR] &= ~0x04; /* XXX */ + } +#if 0 + if (v & FB_CUR_SETPOS) { + dc->dc_regs[TGA_REG_CXYR] = + ((fbc->pos.y & 0xfff) << 12) | (fbc->pos.x & 0xfff); + } + if (v & FB_CUR_SETCMAP) { + /* XXX */ + } + if (v & FB_CUR_SETSHAPE) { + dc->dc_regs[TGA_REG_CCBR] = + (dc->dc_regs[TGA_REG_CCBR] & ~0xfc00) | (fbc->size.y << 10); + copyin(fbc->image, (char *)(dc->dc_vaddr + + (dc->dc_regs[TGA_REG_CCBR] & 0x3ff)), + count); /* can't fail. */ + } +#endif + return (0); } -u_int8_t -tga_bt485_rd_reg(tgaregs, btreg) - volatile tga_reg_t *tgaregs; - u_int btreg; +int +tga_builtin_get_cursor(dc, fbc) + struct tga_devconfig *dc; + struct fbcursor *fbc; { - tga_reg_t rdval; - - if (btreg > BT485_REG_MAX) - panic("tga_bt485_rd_reg: reg %d out of range\n", btreg); - - tgaregs[TGA_REG_EPSR] = (btreg << 1) | 0x1; /* XXX */ - wbflush(); - - rdval = tgaregs[TGA_REG_EPDR]; - return (rdval >> 16) & 0xff; /* XXX */ + int count, error; + + fbc->set = FB_CUR_SETALL & ~(FB_CUR_SETHOT | FB_CUR_SETCMAP); + fbc->enable = (dc->dc_regs[TGA_REG_VVVR] & 0x04) != 0; + fbc->pos.x = dc->dc_regs[TGA_REG_CXYR] & 0xfff; + fbc->pos.y = (dc->dc_regs[TGA_REG_CXYR] >> 12) & 0xfff; + fbc->size.x = 64; + fbc->size.y = (dc->dc_regs[TGA_REG_CCBR] >> 10) & 0x3f; + + if (fbc->image != NULL) { + count = (fbc->size.y * 64 * 2) / NBBY; + error = copyout((char *)(dc->dc_vaddr + + (dc->dc_regs[TGA_REG_CCBR] & 0x3ff)), + fbc->image, count); + if (error) + return (error); + /* No mask */ + } + /* XXX No color map */ + return (0); } -void -tga_bt485_set_cpos(dc, x, y) +int +tga_builtin_set_curpos(dc, fbp) struct tga_devconfig *dc; - int x, y; + struct fbcurpos *fbp; { - if (x == TGA_CURSOR_OFF || y == TGA_CURSOR_OFF) { - u_int8_t regval; - - regval = tga_bt485_rd_reg(dc->dc_regs, BT485_REG_COMMAND_2); - regval &= ~0x03; /* XXX */ - regval |= 0x00; /* XXX */ - tga_bt485_wr_reg(dc->dc_regs, BT485_REG_COMMAND_2, regval); - return; - } - - /* - * RAMDAC cursors are 1-based, and position is bottom-right - * of displayed cursor! - */ - x += 64; - y += 64; - - /* XXX CONSTANTS */ - tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_X_LOW/*, - x & 0xff*/); - tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_X_HIGH/*, - (x >> 8) & 0x0f*/); - tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_Y_LOW/*, - y & 0xff*/); - tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_Y_HIGH/*, - (y >> 8) & 0x0f*/); + dc->dc_regs[TGA_REG_CXYR] = + ((fbp->y & 0xfff) << 12) | (fbp->x & 0xfff); } -void -tga_bt485_get_cpos(dc, xp, yp) +int +tga_builtin_get_curpos(dc, fbp) struct tga_devconfig *dc; - int *xp, *yp; + struct fbcurpos *fbp; { - u_int8_t regval; - regval = tga_bt485_rd_reg(dc->dc_regs, BT485_REG_COMMAND_2); - if ((regval & 0x03) == 0x00) { /* XXX */ - *xp = *yp = TGA_CURSOR_OFF; - return; - } - - regval = tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_X_LOW); - *xp = regval; - regval = tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_X_HIGH); - *xp |= regval << 8; /* XXX */ - - regval = tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_Y_LOW); - *yp = regval; - regval = tga_bt485_rd_reg(dc->dc_regs, BT485_REG_CURSOR_Y_HIGH); - *yp |= regval << 8; /* XXX */ - - /* - * RAMDAC cursors are 1-based, and position is bottom-right - * of displayed cursor! - */ - (*xp) -= 64; - (*yp) -= 64; + fbp->x = dc->dc_regs[TGA_REG_CXYR] & 0xfff; + fbp->y = (dc->dc_regs[TGA_REG_CXYR] >> 12) & 0xfff; } -void -tga_console(pcf, pcfa, pmf, pmfa, ppf, ppfa, bus, device, function) - __const struct pci_conf_fns *pcf; - __const struct pci_mem_fns *pmf; - __const struct pci_pio_fns *ppf; - void *pcfa, *pmfa, *ppfa; - pci_bus_t bus; - pci_device_t device; - pci_function_t function; +int +tga_builtin_get_curmax(dc, fbp) + struct tga_devconfig *dc; + struct fbcurpos *fbp; { - struct tga_devconfig *dcp = &tga_console_dc; - - tga_getdevconfig(pcf, pcfa, pmf, pmfa, - PCI_MAKE_TAG(bus, device, function), dcp); - - /* sanity checks */ - if (dcp->dc_vaddr == NULL) - panic("tga_console(%d, %d): couldn't map memory space", - device, function); - if (dcp->dc_tgaconf == NULL) - panic("tga_console(%d, %d): unknown board configuration", - device, function); - wsc_console(&dcp->dc_ansicons, &tga_acf, &dcp->dc_rcons, - dcp->dc_rcons.rc_maxrow, dcp->dc_rcons.rc_maxcol, 0, 0); + fbp->x = fbp->y = 64; } diff --git a/sys/arch/alpha/pci/wsconsvar.h b/sys/arch/alpha/pci/tga_bt463.c index 77347e07faa..8d581be2ffa 100644 --- a/sys/arch/alpha/pci/wsconsvar.h +++ b/sys/arch/alpha/pci/tga_bt463.c @@ -1,21 +1,21 @@ -/* $NetBSD: wsconsvar.h,v 1.1 1995/11/23 02:38:39 cgd Exp $ */ +/* $NetBSD: tga_bt463.c,v 1.2 1996/04/12 06:09:13 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou - * + * * Permission to use, copy, modify and distribute this software and * its documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * + * * Carnegie Mellon requests users of this software to return to * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU @@ -27,14 +27,25 @@ * rights to redistribute these changes. */ -struct device; -struct ansicons; -struct ansicons_functions; +#include <sys/param.h> +#include <sys/device.h> + +#include <dev/pci/pcivar.h> +#include <machine/tgareg.h> +#include <alpha/pci/tgavar.h> +#include <alpha/pci/bt485reg.h> + +#include <machine/fbio.h> -int wscattach_output __P((struct device *, int, struct ansicons *, - struct ansicons_functions *, void *, int, int, int, int)); -void wscattach_input __P((struct device *, void *, int (*)(void *), - void (*)(void *, int))); -void wscons_kbdinput __P((char *)); -void wsc_console __P((struct ansicons *, struct ansicons_functions *, - void *, int, int, int, int)); +const struct tga_ramdac_conf tga_ramdac_bt463 = { + "Bt463", +#if 0 + NULL, /* XXX SET CMAP */ + NULL, /* XXX GET CMAP */ + tga_builtin_set_cursor, + tga_builtin_get_cursor, + tga_builtin_set_curpos, + tga_builtin_get_curpos, + tga_builtin_get_curmax, +#endif +}; diff --git a/sys/arch/alpha/pci/tga_bt485.c b/sys/arch/alpha/pci/tga_bt485.c new file mode 100644 index 00000000000..45fb5f65b7e --- /dev/null +++ b/sys/arch/alpha/pci/tga_bt485.c @@ -0,0 +1,586 @@ +/* $NetBSD: tga_bt485.c,v 1.2 1996/04/12 06:09:16 cgd Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include <sys/param.h> +#include <sys/device.h> +#include <sys/buf.h> +#include <sys/kernel.h> +#include <sys/malloc.h> + +#include <dev/pci/pcivar.h> +#include <machine/tgareg.h> +#include <alpha/pci/tgavar.h> +#include <alpha/pci/bt485reg.h> + +#include <machine/fbio.h> + +/* + * Functions exported via the RAMDAC configuration table. + */ +void tga_bt485_init __P((struct tga_devconfig *, int)); +int tga_bt485_intr __P((void *)); +int tga_bt485_set_cmap __P((struct tga_devconfig *, struct fbcmap *)); +int tga_bt485_get_cmap __P((struct tga_devconfig *, struct fbcmap *)); +int tga_bt485_set_cursor __P((struct tga_devconfig *, struct fbcursor *)); +int tga_bt485_get_cursor __P((struct tga_devconfig *, struct fbcursor *)); +int tga_bt485_set_curpos __P((struct tga_devconfig *, struct fbcurpos *)); +int tga_bt485_get_curpos __P((struct tga_devconfig *, struct fbcurpos *)); +int tga_bt485_get_curmax __P((struct tga_devconfig *, struct fbcurpos *)); + +const struct tga_ramdac_conf tga_ramdac_bt485 = { + "Bt485", + tga_bt485_init, + tga_bt485_intr, + tga_bt485_set_cmap, + tga_bt485_get_cmap, + tga_bt485_set_cursor, + tga_bt485_get_cursor, + tga_bt485_set_curpos, + tga_bt485_get_curpos, + tga_bt485_get_curmax, +}; + +/* + * Private data. + */ +struct bt485data { + int changed; /* what changed; see below */ + int curenb; /* cursor enabled */ + struct fbcurpos curpos; /* current cursor position */ + struct fbcurpos curhot; /* cursor hotspot */ + char curcmap_r[2]; /* cursor colormap */ + char curcmap_g[2]; + char curcmap_b[2]; + struct fbcurpos cursize; /* current cursor size */ + char curimage[512]; /* cursor image data */ + char curmask[512]; /* cursor mask data */ + char cmap_r[256]; /* colormap */ + char cmap_g[256]; + char cmap_b[256]; +}; + +#define DATA_ENB_CHANGED 0x01 /* cursor enable changed */ +#define DATA_CURCMAP_CHANGED 0x02 /* cursor colormap changed */ +#define DATA_CURSHAPE_CHANGED 0x04 /* cursor size, image, mask changed */ +#define DATA_CMAP_CHANGED 0x08 /* colormap changed */ +#define DATA_ALL_CHANGED 0x0f + +#define CURSOR_MAX_SIZE 64 + +/* + * Internal functions. + */ +inline void tga_bt485_wr_d __P((volatile tga_reg_t *, u_int, u_int8_t)); +inline u_int8_t tga_bt485_rd_d __P((volatile tga_reg_t *, u_int)); +inline void tga_bt485_wr_i __P((volatile tga_reg_t *, u_int8_t, u_int8_t)); +inline u_int8_t tga_bt485_rd_i __P((volatile tga_reg_t *, u_int8_t)); +void tga_bt485_update __P((struct tga_devconfig *, struct bt485data *)); +void tga_bt485_update_curpos __P((struct tga_devconfig *, struct bt485data *)); + +#define tga_bt485_sched_update(dc) \ + ((dc)->dc_regs[TGA_REG_SISR] = 0x00010000) /* XXX */ + +/*****************************************************************************/ + +/* + * Functions exported via the RAMDAC configuration table. + */ + +void +tga_bt485_init(dc, alloc) + struct tga_devconfig *dc; + int alloc; +{ + u_int8_t regval; + struct bt485data tmp, *data; + int i; + + /* + * Init the BT485 for normal operation. + */ + + /* + * Allow indirect register access. (Actually, this is + * already enabled. In fact, if it is _disabled_, for + * some reason the monitor appears to lose sync!!! (?!?!) + */ + regval = tga_bt485_rd_d(dc->dc_regs, BT485_REG_COMMAND_0); + regval |= 0x80; + tga_bt485_wr_d(dc->dc_regs, BT485_REG_COMMAND_0, regval); + + /* Set the RAMDAC to 8BPP (no interestion options). */ + tga_bt485_wr_d(dc->dc_regs, BT485_REG_COMMAND_1, 0x40); + + /* Disable the cursor (for now) */ + regval = tga_bt485_rd_d(dc->dc_regs, BT485_REG_COMMAND_2); + regval &= ~0x03; + tga_bt485_wr_d(dc->dc_regs, BT485_REG_COMMAND_2, regval); + + /* Use a 64x64x2 cursor */ + regval = tga_bt485_rd_d(dc->dc_regs, BT485_IREG_COMMAND_3); + regval |= 0x04; + tga_bt485_wr_d(dc->dc_regs, BT485_IREG_COMMAND_3, regval); + + /* + * If we should allocate a new private info struct, do so. + * Otherwise, use the one we have (if it's there), or + * use the temporary one on the stack. + */ + if (alloc) { + if (dc->dc_ramdac_private != NULL) + panic("tga_bt485_init: already have private struct"); + dc->dc_ramdac_private = malloc(sizeof *data, M_DEVBUF, + M_WAITOK); + } + if (dc->dc_ramdac_private != NULL) + data = dc->dc_ramdac_private; + else + data = &tmp; + + /* + * Initalize the RAMDAC info struct to hold all of our + * data, and fill it in. + */ + data->changed = DATA_ALL_CHANGED; + + data->curenb = 0; /* cursor disabled */ + data->curpos.x = data->curpos.y = 0; /* right now at 0,0 */ + data->curhot.x = data->curhot.y = 0; /* hot spot at 0,0 */ + + /* initial cursor colormap: 0 is black, 1 is white */ + data->curcmap_r[0] = data->curcmap_g[0] = data->curcmap_b[0] = 0; + data->curcmap_r[1] = data->curcmap_g[1] = data->curcmap_b[1] = 0xff; + + /* initial cursor data: 64x64 block of white. */ + data->cursize.x = data->cursize.y = 64; + for (i = 0; i < 512; i++) + data->curimage[i] = data->curmask[i] = 0xff; + + /* Initial colormap: 0 is black, everything else is white */ + data->cmap_r[0] = data->cmap_g[0] = data->cmap_b[0] = 0; + for (i = 1; i < 256; i++) + data->cmap_r[i] = data->cmap_g[i] = data->cmap_b[i] = 255; + + tga_bt485_update(dc, data); + + dc->dc_regs[TGA_REG_SISR] = 0x00000001; /* XXX */ +} + +int +tga_bt485_set_cmap(dc, fbc) + struct tga_devconfig *dc; + struct fbcmap *fbc; +{ + struct bt485data *data = dc->dc_ramdac_private; + int error, count, index, s; + + if ((u_int)fbc->index >= 256 || + ((u_int)fbc->index + (u_int)fbc->count) > 256) + return (EINVAL); + if (!useracc(fbc->red, fbc->count, B_READ) || + !useracc(fbc->green, fbc->count, B_READ) || + !useracc(fbc->blue, fbc->count, B_READ)) + return (EFAULT); + + s = spltty(); + + index = fbc->index; + count = fbc->count; + copyin(fbc->red, &data->cmap_r[index], count); + copyin(fbc->green, &data->cmap_g[index], count); + copyin(fbc->blue, &data->cmap_b[index], count); + + data->changed |= DATA_CMAP_CHANGED; + + tga_bt485_sched_update(dc); + splx(s); + + return (0); +} + +int +tga_bt485_get_cmap(dc, fbc) + struct tga_devconfig *dc; + struct fbcmap *fbc; +{ + struct bt485data *data = dc->dc_ramdac_private; + int error, count, index; + + if ((u_int)fbc->index >= 256 || + ((u_int)fbc->index + (u_int)fbc->count) > 256) + return (EINVAL); + + count = fbc->count; + index = fbc->index; + + error = copyout(&data->cmap_r[index], fbc->red, count); + if (error) + return (error); + error = copyout(&data->cmap_g[index], fbc->green, count); + if (error) + return (error); + error = copyout(&data->cmap_b[index], fbc->blue, count); + return (error); +} + +int +tga_bt485_set_cursor(dc, fbc) + struct tga_devconfig *dc; + struct fbcursor *fbc; +{ + struct bt485data *data = dc->dc_ramdac_private; + int error, count, index, v, s; + + v = fbc->set; + + /* + * For SETCMAP and SETSHAPE, verify that parameters are OK + * before we do anything that we can't recover from. + */ + if (v & FB_CUR_SETCMAP) { + if ((u_int)fbc->cmap.index > 2 || + ((u_int)fbc->cmap.index + (u_int)fbc->cmap.count) > 2) + return (EINVAL); + count = fbc->cmap.count; + if (!useracc(fbc->cmap.red, count, B_READ) || + !useracc(fbc->cmap.green, count, B_READ) || + !useracc(fbc->cmap.blue, count, B_READ)) + return (EFAULT); + } + if (v & FB_CUR_SETSHAPE) { + if ((u_int)fbc->size.x > CURSOR_MAX_SIZE || + (u_int)fbc->size.y > CURSOR_MAX_SIZE) + return (EINVAL); + count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y; + if (!useracc(fbc->image, count, B_READ) || + !useracc(fbc->mask, count, B_READ)) + return (EFAULT); + } + + if (v & (FB_CUR_SETPOS | FB_CUR_SETCUR)) { + if (v & FB_CUR_SETPOS) + data->curpos = fbc->pos; + if (v & FB_CUR_SETCUR) + data->curhot = fbc->hot; + tga_bt485_update_curpos(dc, data); + } + + s = spltty(); + + /* Parameters are OK; perform the requested operations. */ + if (v & FB_CUR_SETCUR) { + data->curenb = fbc->enable; + data->changed |= DATA_ENB_CHANGED; + } + if (v & FB_CUR_SETCMAP) { + count = fbc->cmap.count; + index = fbc->cmap.index; + copyin(fbc->cmap.red, &data->cmap_r[index], count); + copyin(fbc->cmap.green, &data->cmap_g[index], count); + copyin(fbc->cmap.blue, &data->cmap_b[index], count); + data->changed |= DATA_CURCMAP_CHANGED; + } + if (v & FB_CUR_SETSHAPE) { + data->cursize = fbc->size; + count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y; + bzero(data->curimage, sizeof data->curimage); + bzero(data->curmask, sizeof data->curmask); + copyin(fbc->image, data->curimage, count); /* can't fail */ + copyin(fbc->mask, data->curmask, count); /* can't fail */ + data->changed |= DATA_CURSHAPE_CHANGED; + } + + if (data->changed) + tga_bt485_sched_update(dc); + splx(s); + + return (0); +} + +int +tga_bt485_get_cursor(dc, fbc) + struct tga_devconfig *dc; + struct fbcursor *fbc; +{ + struct bt485data *data = dc->dc_ramdac_private; + int error, count; + + fbc->set = FB_CUR_SETALL; /* we return everything they want */ + fbc->enable = data->curenb; /* SETCUR */ + fbc->pos = data->curpos; /* SETPOS */ + fbc->hot = data->curhot; /* SETHOT */ + + fbc->cmap.index = 0; /* SETCMAP */ + fbc->cmap.count = 2; + if (fbc->cmap.red != NULL) { + error = copyout(data->curcmap_r, fbc->cmap.red, 2); + if (error) + return (error); + } + if (fbc->cmap.green != NULL) { + error = copyout(data->curcmap_g, fbc->cmap.green, 2); + if (error) + return (error); + } + if (fbc->cmap.blue != NULL) { + error = copyout(data->curcmap_b, fbc->cmap.blue, 2); + if (error) + return (error); + } + + fbc->size = data->cursize; /* SETSHAPE */ + if (fbc->image != NULL) { + count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y; + error = copyout(data->curimage, fbc->image, count); + if (error) + return (error); + error = copyout(data->curmask, fbc->mask, count); + if (error) + return (error); + } + + return (0); +} + +int +tga_bt485_set_curpos(dc, fbp) + struct tga_devconfig *dc; + struct fbcurpos *fbp; +{ + struct bt485data *data = dc->dc_ramdac_private; + + data->curpos = *fbp; + tga_bt485_update_curpos(dc, data); + + return (0); +} + +int +tga_bt485_get_curpos(dc, fbp) + struct tga_devconfig *dc; + struct fbcurpos *fbp; +{ + struct bt485data *data = dc->dc_ramdac_private; + + *fbp = data->curpos; + return (0); +} + +int +tga_bt485_get_curmax(dc, fbp) + struct tga_devconfig *dc; + struct fbcurpos *fbp; +{ + struct bt485data *data = dc->dc_ramdac_private; + + fbp->x = fbp->y = CURSOR_MAX_SIZE; + return (0); +} + +int +tga_bt485_intr(v) + void *v; +{ + struct tga_devconfig *dc = v; + + if ((dc->dc_regs[TGA_REG_SISR] & 0x00010001) != 0x00010001) + return 0; + tga_bt485_update(dc, dc->dc_ramdac_private); + dc->dc_regs[TGA_REG_SISR] = 0x00000001; + return (1); +} + +/*****************************************************************************/ + +/* + * Internal functions. + */ + +inline void +tga_bt485_wr_d(tgaregs, btreg, val) + volatile tga_reg_t *tgaregs; + u_int btreg; + u_int8_t val; +{ + + if (btreg > BT485_REG_MAX) + panic("tga_bt485_wr_d: reg %d out of range\n", btreg); + + tgaregs[TGA_REG_EPDR] = (btreg << 9) | (0 << 8 ) | val; /* XXX */ + wbflush(); +} + +inline u_int8_t +tga_bt485_rd_d(tgaregs, btreg) + volatile tga_reg_t *tgaregs; + u_int btreg; +{ + tga_reg_t rdval; + + if (btreg > BT485_REG_MAX) + panic("tga_bt485_rd_d: reg %d out of range\n", btreg); + + tgaregs[TGA_REG_EPSR] = (btreg << 1) | 0x1; /* XXX */ + wbflush(); + + rdval = tgaregs[TGA_REG_EPDR]; + return (rdval >> 16) & 0xff; /* XXX */ +} + +inline void +tga_bt485_wr_i(tgaregs, ireg, val) + volatile tga_reg_t *tgaregs; + u_int8_t ireg; + u_int8_t val; +{ + tga_bt485_wr_d(tgaregs, BT485_REG_PCRAM_WRADDR, ireg); + tga_bt485_wr_d(tgaregs, BT485_REG_EXTENDED, val); +} + +inline u_int8_t +tga_bt485_rd_i(tgaregs, ireg) + volatile tga_reg_t *tgaregs; + u_int8_t ireg; +{ + tga_bt485_wr_d(tgaregs, BT485_REG_PCRAM_WRADDR, ireg); + return (tga_bt485_rd_d(tgaregs, BT485_REG_EXTENDED)); +} + +void +tga_bt485_update(dc, data) + struct tga_devconfig *dc; + struct bt485data *data; +{ + u_int8_t regval; + int count, i, v; + + v = data->changed; + data->changed = 0; + + if (v & DATA_ENB_CHANGED) { + regval = tga_bt485_rd_d(dc->dc_regs, BT485_REG_COMMAND_2); + if (data->curenb) + regval |= 0x01; + else + regval &= ~0x03; + tga_bt485_wr_d(dc->dc_regs, BT485_REG_COMMAND_2, regval); + } + + if (v & DATA_CURCMAP_CHANGED) { + /* addr[9:0] assumed to be 0 */ + /* set addr[7:0] to 1 */ + tga_bt485_wr_d(dc->dc_regs, BT485_REG_COC_WRADDR, 0x01); + + /* spit out the cursor data */ + for (i = 0; i < 2; i++) { + tga_bt485_wr_d(dc->dc_regs, BT485_REG_COCDATA, + data->curcmap_r[i]); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_COCDATA, + data->curcmap_g[i]); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_COCDATA, + data->curcmap_b[i]); + } + } + + if (v & DATA_CURSHAPE_CHANGED) { + count = (CURSOR_MAX_SIZE / NBBY) * data->cursize.y; + + /* + * Write the cursor image data: + * set addr[9:8] to 0, + * set addr[7:0] to 0, + * spit it all out. + */ + regval = tga_bt485_rd_i(dc->dc_regs, + BT485_IREG_COMMAND_3); + regval &= ~0x03; + tga_bt485_wr_i(dc->dc_regs, BT485_IREG_COMMAND_3, + regval); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_PCRAM_WRADDR, 0); + for (i = 0; i < count; i++) + tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_RAM, + data->curimage[i]); + + /* + * Write the cursor mask data: + * set addr[9:8] to 2, + * set addr[7:0] to 0, + * spit it all out. + */ + regval = tga_bt485_rd_i(dc->dc_regs, + BT485_IREG_COMMAND_3); + regval &= ~0x03; regval |= 0x02; + tga_bt485_wr_i(dc->dc_regs, BT485_IREG_COMMAND_3, + regval); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_PCRAM_WRADDR, 0); + for (i = 0; i < count; i++) + tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_RAM, + data->curmask[i]); + + /* set addr[9:0] back to 0 */ + regval = tga_bt485_rd_i(dc->dc_regs, BT485_IREG_COMMAND_3); + regval &= ~0x03; + tga_bt485_wr_i(dc->dc_regs, BT485_IREG_COMMAND_3, regval); + } + + if (v & DATA_CMAP_CHANGED) { + /* addr[9:0] assumed to be 0 */ + /* set addr[7:0] to 0 */ + tga_bt485_wr_d(dc->dc_regs, BT485_REG_PCRAM_WRADDR, 0x00); + + /* spit out the cursor data */ + for (i = 0; i < 256; i++) { + tga_bt485_wr_d(dc->dc_regs, BT485_REG_PALETTE, + data->cmap_r[i]); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_PALETTE, + data->cmap_g[i]); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_PALETTE, + data->cmap_b[i]); + } + } +} + +void +tga_bt485_update_curpos(dc, data) + struct tga_devconfig *dc; + struct bt485data *data; +{ + int s, x, y; + + s = spltty(); + + x = data->curpos.x + CURSOR_MAX_SIZE - data->curhot.x; + y = data->curpos.y + CURSOR_MAX_SIZE - data->curhot.y; + tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_X_LOW, x & 0xff); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_X_HIGH, (x >> 8) & 0x0f); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_Y_LOW, y & 0xff); + tga_bt485_wr_d(dc->dc_regs, BT485_REG_CURSOR_Y_HIGH, (y >> 8) & 0x0f); + + splx(s); +} diff --git a/sys/arch/alpha/pci/tga_conf.c b/sys/arch/alpha/pci/tga_conf.c new file mode 100644 index 00000000000..114e6964789 --- /dev/null +++ b/sys/arch/alpha/pci/tga_conf.c @@ -0,0 +1,183 @@ +/* $NetBSD: tga_conf.c,v 1.2 1996/04/12 06:09:18 cgd Exp $ */ + +/* + * Copyright (c) 1995, 1996 Carnegie-Mellon University. + * All rights reserved. + * + * Author: Chris G. Demetriou + * + * Permission to use, copy, modify and distribute this software and + * its documentation is hereby granted, provided that both the copyright + * notice and this permission notice appear in all copies of the + * software, derivative works or modified versions, and any portions + * thereof, and that both notices appear in supporting documentation. + * + * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" + * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND + * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. + * + * Carnegie Mellon requests users of this software to return to + * + * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU + * School of Computer Science + * Carnegie Mellon University + * Pittsburgh PA 15213-3890 + * + * any improvements or extensions that they make and grant Carnegie the + * rights to redistribute these changes. + */ + +#include <sys/param.h> +#include <sys/device.h> + +#include <dev/pci/pcivar.h> +#include <machine/tgareg.h> +#include <alpha/pci/tgavar.h> + +#undef KB +#define KB * 1024 +#undef MB +#define MB * 1024 * 1024 + +static const struct tga_conf tga_configs[TGA_TYPE_UNKNOWN] = { + /* TGA_TYPE_T8_01 */ + { + "T8-01", + &tga_ramdac_bt485, + 8, + 4 MB, + 2 KB, + 1, { 2 MB, 0 }, { 1 MB, 0 }, + 0, { 0, 0 }, { 0, 0 }, + }, + /* TGA_TYPE_T8_02 */ + { + "T8-02", + &tga_ramdac_bt485, + 8, + 4 MB, + 4 KB, + 1, { 2 MB, 0 }, { 2 MB, 0 }, + 0, { 0, 0 }, { 0, 0 }, + }, + /* TGA_TYPE_T8_22 */ + { + "T8-22", + &tga_ramdac_bt485, + 8, + 8 MB, + 4 KB, + 1, { 4 MB, 0 }, { 2 MB, 0 }, + 1, { 6 MB, 0 }, { 2 MB, 0 }, + }, + /* TGA_TYPE_T8_44 */ + { + "T8-44", + &tga_ramdac_bt485, + 8, + 16 MB, + 4 KB, + 2, { 8 MB, 12 MB }, { 2 MB, 2 MB }, + 2, { 10 MB, 14 MB }, { 2 MB, 2 MB }, + }, + /* TGA_TYPE_T32_04 */ + { + "T32-04", + &tga_ramdac_bt463, + 32, + 16 MB, + 8 KB, + 1, { 8 MB, 0 }, { 4 MB, 0 }, + 0, { 0, 0 }, { 0, 0 }, + }, + /* TGA_TYPE_T32_08 */ + { + "T32-08", + &tga_ramdac_bt463, + 32, + 16 MB, + 16 KB, + 1, { 8 MB, 0 }, { 8 MB, 0 }, + 0, { 0, 0 }, { 0, 0 }, + }, + /* TGA_TYPE_T32_88 */ + { + "T32-88", + &tga_ramdac_bt463, + 32, + 32 MB, + 16 KB, + 1, { 16 MB, 0 }, { 8 MB, 0 }, + 1, { 24 MB, 0 }, { 8 MB, 0 }, + }, +}; + +#undef KB +#undef MB + +int +tga_identify(regs) + tga_reg_t *regs; +{ + int type; + int deep, addrmask, wide; + + deep = (regs[TGA_REG_GDER] & 0x1) != 0; /* XXX */ + addrmask = ((regs[TGA_REG_GDER] >> 2) & 0x7); /* XXX */ + wide = (regs[TGA_REG_GDER] & 0x200) == 0; /* XXX */ + + type = TGA_TYPE_UNKNOWN; + + if (!deep) { + /* 8bpp frame buffer */ + + if (addrmask == 0x0) { + /* 4MB core map; T8-01 or T8-02 */ + + if (!wide) + type = TGA_TYPE_T8_01; + else + type = TGA_TYPE_T8_02; + } else if (addrmask == 0x1) { + /* 8MB core map; T8-22 */ + + if (wide) /* sanity */ + type = TGA_TYPE_T8_22; + } else if (addrmask == 0x3) { + /* 16MB core map; T8-44 */ + + if (wide) /* sanity */ + type = TGA_TYPE_T8_44; + } + } else { + /* 32bpp frame buffer */ + + if (addrmask == 0x3) { + /* 16MB core map; T32-04 or T32-08 */ + + if (!wide) + type = TGA_TYPE_T32_04; + else + type = TGA_TYPE_T32_08; + } else if (addrmask == 0x7) { + /* 32MB core map; T32-88 */ + + if (wide) /* sanity */ + type = TGA_TYPE_T32_88; + } + } + + return (type); +} + +const struct tga_conf * +tga_getconf(type) + int type; +{ + + if (type >= 0 && type < TGA_TYPE_UNKNOWN) + return &tga_configs[type]; + + return (NULL); +} + diff --git a/sys/arch/alpha/pci/tgareg.h b/sys/arch/alpha/pci/tgareg.h deleted file mode 100644 index 6c335cf9a28..00000000000 --- a/sys/arch/alpha/pci/tgareg.h +++ /dev/null @@ -1,159 +0,0 @@ -/* $NetBSD: tgareg.h,v 1.3 1995/11/23 02:38:28 cgd Exp $ */ - -/* - * Copyright (c) 1995 Carnegie-Mellon University. - * All rights reserved. - * - * Author: Chris G. Demetriou - * - * Permission to use, copy, modify and distribute this software and - * its documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND - * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -#ifndef _ALPHA_PCI_TGAREG_H_ -#define _ALPHA_PCI_TGAREG_H_ - -/* - * Device-specific PCI register offsets and contents. - */ - -#define TGA_PCIREG_PVRR 0x40 /* PCI Address Extension Register */ - -#define TGA_PCIREG_PAER 0x44 /* PCI VGA Redirect Register */ - -/* - * TGA Memory Space offsets - */ - -#define TGA_MEM_ALTROM 0x0000000 /* 0MB -- Alternate ROM space */ -#define TGA_MEM_CREGS 0x0100000 /* 1MB -- Core Registers */ -/* Display and Back Buffers mapped at config-dependent addresses */ - -/* - * TGA Core Space register numbers and contents. - */ - -typedef int32_t tga_reg_t; - -#define TGA_REG_GCBR0 0x000 /* Copy buffer 0 */ -#define TGA_REG_GCBR1 0x001 /* Copy buffer 1 */ -#define TGA_REG_GCBR2 0x002 /* Copy buffer 2 */ -#define TGA_REG_GCBR3 0x003 /* Copy buffer 3 */ -#define TGA_REG_GCBR4 0x004 /* Copy buffer 4 */ -#define TGA_REG_GCBR5 0x005 /* Copy buffer 5 */ -#define TGA_REG_GCBR6 0x006 /* Copy buffer 6 */ -#define TGA_REG_GCBR7 0x007 /* Copy buffer 7 */ - -#define TGA_REG_GFGR 0x008 /* Foreground */ -#define TGA_REG_GBGR 0x009 /* Background */ -#define TGA_REG_GPMR 0x00a /* Plane Mask */ -#define TGA_REG_GPXR_S 0x00b /* Pixel Mask (one-shot) */ -#define TGA_REG_GMOR 0x00c /* Mode */ -#define TGA_REG_GOPR 0x00d /* Raster Operation */ -#define TGA_REG_GPSR 0x00e /* Pixel Shift */ -#define TGA_REG_GADR 0x00f /* Address */ - -#define TGA_REG_GB1R 0x010 /* Bresenham 1 */ -#define TGA_REG_GB2R 0x011 /* Bresenham 2 */ -#define TGA_REG_GB3R 0x012 /* Bresenham 3 */ - -#define TGA_REG_GCTR 0x013 /* Continue */ -#define TGA_REG_GDER 0x014 /* Deep */ -/* reserved 0x015 */ -#define TGA_REG_GSMR 0x016 /* Stencil Mode */ -#define TGA_REG_GPXR_P 0x017 /* Pixel Mask (persistent) */ -#define TGA_REG_CCBR 0x018 /* Cursor Base Address */ -#define TGA_REG_VHCR 0x019 /* Horizontal Control */ -#define TGA_REG_VVCR 0x01a /* Vertical Control */ -#define TGA_REG_VVBR 0x01b /* Video Base Address */ -#define TGA_REG_VVVR 0x01c /* Video Valid */ -#define TGA_REG_CXYR 0x01d /* Cursor XY */ -#define TGA_REG_VSAR 0x01e /* Video Shift Address */ -#define TGA_REG_SISR 0x01f /* Interrupt Status */ -#define TGA_REG_GDAR 0x020 /* Data */ -#define TGA_REG_GRIR 0x021 /* Red Increment */ -#define TGA_REG_GGIR 0x022 /* Green Increment */ -#define TGA_REG_GBIR 0x023 /* Blue Increment */ -#define TGA_REG_GZIR_L 0x024 /* Z-increment Low */ -#define TGA_REG_GZIR_H 0x025 /* Z-Increment High */ -#define TGA_REG_GDBR 0x026 /* DMA Base Address */ -#define TGA_REG_GBWR 0x027 /* Bresenham Width */ -#define TGA_REG_GZVR_L 0x028 /* Z-value Low */ -#define TGA_REG_GZVR_H 0x029 /* Z-value High */ -#define TGA_REG_GZBR 0x02a /* Z-base address */ -/* GADR alias 0x02b */ -#define TGA_REG_GRVR 0x02c /* Red Value */ -#define TGA_REG_GGVR 0x02d /* Green Value */ -#define TGA_REG_GBVR 0x02e /* Blue Value */ -#define TGA_REG_GSWR 0x02f /* Span Width */ -#define TGA_REG_EPSR 0x030 /* Pallete and DAC Setup */ - -/* reserved 0x031 - 0x3f */ - -#define TGA_REG_GSNR0 0x040 /* Slope-no-go 0 */ -#define TGA_REG_GSNR1 0x041 /* Slope-no-go 1 */ -#define TGA_REG_GSNR2 0x042 /* Slope-no-go 2 */ -#define TGA_REG_GSNR3 0x043 /* Slope-no-go 3 */ -#define TGA_REG_GSNR4 0x044 /* Slope-no-go 4 */ -#define TGA_REG_GSNR5 0x045 /* Slope-no-go 5 */ -#define TGA_REG_GSNR6 0x046 /* Slope-no-go 6 */ -#define TGA_REG_GSNR7 0x047 /* Slope-no-go 7 */ - -#define TGA_REG_GSLR0 0x048 /* Slope 0 */ -#define TGA_REG_GSLR1 0x049 /* Slope 1 */ -#define TGA_REG_GSLR2 0x04a /* Slope 2 */ -#define TGA_REG_GSLR3 0x04b /* Slope 3 */ -#define TGA_REG_GSLR4 0x04c /* Slope 4 */ -#define TGA_REG_GSLR5 0x04d /* Slope 5 */ -#define TGA_REG_GSLR6 0x04e /* Slope 6 */ -#define TGA_REG_GSLR7 0x04f /* Slope 7 */ - -#define TGA_REG_GBCR0 0x050 /* Block Color 0 */ -#define TGA_REG_GBCR1 0x051 /* Block Color 1 */ -#define TGA_REG_GBCR2 0x052 /* Block Color 2 */ -#define TGA_REG_GBCR3 0x053 /* Block Color 3 */ -#define TGA_REG_GBCR4 0x054 /* Block Color 4 */ -#define TGA_REG_GBCR5 0x055 /* Block Color 5 */ -#define TGA_REG_GBCR6 0x056 /* Block Color 6 */ -#define TGA_REG_GBCR7 0x057 /* Block Color 7 */ - -#define TGA_REG_GCSR 0x058 /* Copy 64 Source */ -#define TGA_REG_GCDR 0x059 /* Copy 64 Destination */ -/* GC[SD]R aliases 0x05a - 0x05f */ - -/* reserved 0x060 - 0x077 */ - -#define TGA_REG_ERWR 0x078 /* EEPROM write */ - -/* reserved 0x079 */ - -#define TGA_REG_ECGR 0x07a /* Clock */ - -/* reserved 0x07b */ - -#define TGA_REG_EPDR 0x07c /* Pallete and DAC Data */ - -/* reserved 0x07d */ - -#define TGA_REG_SCSR 0x07e /* Command Status */ - -/* reserved 0x07f */ - -#endif /* _ALPHA_PCI_TGAREG_H_ */ diff --git a/sys/arch/alpha/pci/tgavar.h b/sys/arch/alpha/pci/tgavar.h index b1ab195c624..f4cad9b7777 100644 --- a/sys/arch/alpha/pci/tgavar.h +++ b/sys/arch/alpha/pci/tgavar.h @@ -1,7 +1,7 @@ -/* $NetBSD: tgavar.h,v 1.3 1995/11/23 02:38:31 cgd Exp $ */ +/* $NetBSD: tgavar.h,v 1.5 1996/04/12 06:09:21 cgd Exp $ */ /* - * Copyright (c) 1995 Carnegie-Mellon University. + * Copyright (c) 1995, 1996 Carnegie-Mellon University. * All rights reserved. * * Author: Chris G. Demetriou @@ -27,27 +27,40 @@ * rights to redistribute these changes. */ -#include <alpha/pci/tgareg.h> +#include <machine/tgareg.h> #include <dev/rcons/raster.h> -#include <dev/pseudo/rcons.h> -#include <dev/pseudo/ansicons.h> +#include <alpha/wscons/wsconsvar.h> +#include <alpha/wscons/wscons_raster.h> struct tga_devconfig; +struct fbcmap; +struct fbcursor; +struct fbcurpos; struct tga_ramdac_conf { char *tgar_name; - void (*tgar_set_cpos) __P((struct tga_devconfig *, int, int)); - void (*tgar_get_cpos) __P((struct tga_devconfig *, int *, int *)); - /* set cursor shape */ - /* set cursor location */ - /* set cursor colormap? */ - /* set colormap? */ + void (*tgar_init) __P((struct tga_devconfig *, int)); + int (*tgar_intr) __P((void *)); + int (*tgar_set_cmap) __P((struct tga_devconfig *, + struct fbcmap *)); + int (*tgar_get_cmap) __P((struct tga_devconfig *, + struct fbcmap *)); + int (*tgar_set_cursor) __P((struct tga_devconfig *, + struct fbcursor *)); + int (*tgar_get_cursor) __P((struct tga_devconfig *, + struct fbcursor *)); + int (*tgar_set_curpos) __P((struct tga_devconfig *, + struct fbcurpos *)); + int (*tgar_get_curpos) __P((struct tga_devconfig *, + struct fbcurpos *)); + int (*tgar_get_curmax) __P((struct tga_devconfig *, + struct fbcurpos *)); }; struct tga_conf { char *tgac_name; /* name for this board type */ - __const struct tga_ramdac_conf + const struct tga_ramdac_conf *tgac_ramdac; /* the RAMDAC type; see above */ int tgac_phys_depth; /* physical frame buffer depth */ vm_size_t tgac_cspace_size; /* core space size */ @@ -63,20 +76,16 @@ struct tga_conf { }; struct tga_devconfig { - __const struct pci_conf_fns *dc_pcf; - void *dc_pcfa; - __const struct pci_mem_fns *dc_pmf; - void *dc_pmfa; - __const struct pci_pio_fns *dc_ppf; - void *dc_ppfa; + bus_chipset_tag_t dc_bc; + pci_chipset_tag_t dc_pc; - pci_conftag_t dc_pcitag; /* PCI tag */ - pci_moffset_t dc_pcipaddr; /* PCI phys addr. */ + pcitag_t dc_pcitag; /* PCI tag */ + bus_mem_addr_t dc_pcipaddr; /* PCI phys addr. */ tga_reg_t *dc_regs; /* registers; XXX: need aliases */ int dc_tga_type; /* the device type; see below */ - __const struct tga_conf *dc_tgaconf; /* device buffer configuration */ + const struct tga_conf *dc_tgaconf; /* device buffer configuration */ vm_offset_t dc_vaddr; /* memory space virtual base address */ vm_offset_t dc_paddr; /* memory space physical base address */ @@ -89,7 +98,9 @@ struct tga_devconfig { struct raster dc_raster; /* raster description */ struct rcons dc_rcons; /* raster blitter control info */ - struct ansicons dc_ansicons; /* ansi console emulator info XXX */ + + int dc_blanked; /* currently had video disabled */ + void *dc_ramdac_private; /* RAMDAC private storage */ }; struct tga_softc { @@ -97,6 +108,7 @@ struct tga_softc { struct tga_devconfig *sc_dc; /* device configuration */ void *sc_intr; /* interrupt handler info */ + /* XXX should record intr fns/arg */ }; #define TGA_TYPE_T8_01 0 /* 8bpp, 1MB */ @@ -108,13 +120,20 @@ struct tga_softc { #define TGA_TYPE_T32_88 6 /* 32bpp, 16MB */ #define TGA_TYPE_UNKNOWN 7 /* unknown */ -#define TGA_CURSOR_OFF -1 /* pass to tgar_cpos to disable */ - #define DEVICE_IS_TGA(class, id) \ - (PCI_VENDOR(id) == PCI_VENDOR_DEC && \ - PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21030) + ((PCI_VENDOR(id) == PCI_VENDOR_DEC && \ + PCI_PRODUCT(id) == PCI_PRODUCT_DEC_21030) ? 10 : 0) + +void tga_console __P((bus_chipset_tag_t, pci_chipset_tag_t, int, int, int)); + +int tga_identify __P((tga_reg_t *)); +const struct tga_conf *tga_getconf __P((int)); + +extern const struct tga_ramdac_conf tga_ramdac_bt463; +extern const struct tga_ramdac_conf tga_ramdac_bt485; -void tga_console __P((__const struct pci_conf_fns *, void *, - __const struct pci_mem_fns *, void *, - __const struct pci_pio_fns *, void *, - pci_bus_t, pci_device_t, pci_function_t)); +int tga_builtin_set_cursor __P((struct tga_devconfig *, struct fbcursor *)); +int tga_builtin_get_cursor __P((struct tga_devconfig *, struct fbcursor *)); +int tga_builtin_set_curpos __P((struct tga_devconfig *, struct fbcurpos *)); +int tga_builtin_get_curpos __P((struct tga_devconfig *, struct fbcurpos *)); +int tga_builtin_get_curmax __P((struct tga_devconfig *, struct fbcurpos *)); diff --git a/sys/arch/alpha/pci/wscons.c b/sys/arch/alpha/pci/wscons.c deleted file mode 100644 index fa5a988cf09..00000000000 --- a/sys/arch/alpha/pci/wscons.c +++ /dev/null @@ -1,383 +0,0 @@ -/* $NetBSD: wscons.c,v 1.3 1995/11/23 02:38:36 cgd Exp $ */ - -/* - * Copyright (c) 1995 Carnegie-Mellon University. - * All rights reserved. - * - * Author: Chris G. Demetriou - * - * Permission to use, copy, modify and distribute this software and - * its documentation is hereby granted, provided that both the copyright - * notice and this permission notice appear in all copies of the - * software, derivative works or modified versions, and any portions - * thereof, and that both notices appear in supporting documentation. - * - * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" - * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND - * FOR ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * - * Carnegie Mellon requests users of this software to return to - * - * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU - * School of Computer Science - * Carnegie Mellon University - * Pittsburgh PA 15213-3890 - * - * any improvements or extensions that they make and grant Carnegie the - * rights to redistribute these changes. - */ - -#include <sys/param.h> -#include <sys/device.h> -#include <sys/kernel.h> -#include <sys/conf.h> -#include <sys/systm.h> -#include <sys/ioctl.h> -#include <sys/proc.h> -#include <sys/tty.h> -#include <sys/termios.h> - -#include <dev/cons.h> -#include <dev/pseudo/ansicons.h> -#include <alpha/pci/wsconsvar.h> - -#define NWSC 16 /* XXX XXX XXX */ - -#define WSCUNIT(dev) minor(dev) - -struct wsc_softc { - int sc_flags; - - struct device *sc_odev; - struct ansicons *sc_ansicons; - - struct tty *sc_tty; -}; - -#define WSC_INPUT 0x01 -#define WSC_OUTPUT 0x02 -#define WSC_ALIVE (WSC_INPUT | WSC_OUTPUT) - -struct wsc_softc wsc_sc[NWSC]; /* XXX XXX XXX */ -int nwsc = NWSC; -int nextiwsc; -int nextowsc; - -void wscstart __P((struct tty *)); -int wscparam __P((struct tty *, struct termios *)); - -int wsccngetc __P((dev_t)); -void wsccnputc __P((dev_t, int)); -void wsccnpollc __P((dev_t, int)); - -struct ansicons *wsc_console_ansicons; -void *wsc_input_arg; -int (*wsc_console_getc) __P((void *)) = NULL; -void (*wsc_console_pollc) __P((void *, int)) = NULL; -struct consdev wsccons = { NULL, NULL, wsccngetc, wsccnputc, - wsccnpollc, NODEV, 1 }; - -int wsc_kbdfocusunit = -1; /* XXX */ - -int -wscattach_output(dev, console, acp, acf, acfarg, mrow, mcol, crow, ccol) - struct device *dev; - int console; - struct ansicons *acp; - struct ansicons_functions *acf; - void *acfarg; - int mrow, mcol, crow, ccol; -{ - - if (nextowsc >= nwsc) - return 0; - - wsc_sc[nextowsc].sc_odev = dev; - wsc_sc[nextowsc].sc_ansicons = acp; - - if (wsc_kbdfocusunit == -1) - wsc_kbdfocusunit = nextowsc; - - if (!console) - ansicons_attach(acp, acf, acfarg, mrow, mcol, crow, ccol); - else { - wsc_kbdfocusunit = nextowsc; - wsccons.cn_dev = makedev(25, nextowsc); - } - - wsc_sc[nextowsc].sc_flags |= WSC_OUTPUT; - wsc_sc[nextowsc].sc_tty = ttymalloc(); - - printf("wsc%d: %s attached as output\n", nextowsc, dev->dv_xname); - if (console) - printf("wsc%d: console\n", nextowsc); - - nextowsc++; - return 1; -} - -void -wscattach_input(dev, cookie, getc, pollc) - struct device *dev; - void *cookie; - int (*getc) __P((void *)); - void (*pollc) __P((void *, int)); -{ - - printf("wsc: %s attached as input device\n", dev->dv_xname); - - wsc_input_arg = cookie; - wsc_console_getc = getc; - wsc_console_pollc = pollc; -} - -int -wscopen(dev, flag, mode, p) - dev_t dev; - int flag, mode; - struct proc *p; -{ - struct wsc_softc *sc; - int unit = WSCUNIT(dev); - struct tty *tp; - - if (unit >= nwsc) - return ENXIO; - sc = &wsc_sc[unit]; - if (sc == 0) - return ENXIO; - - if ((sc->sc_flags & WSC_ALIVE) == 0) - return ENXIO; - - if (!sc->sc_tty) - panic("wscopen: no tty!"); - tp = sc->sc_tty; - - tp->t_oproc = wscstart; - tp->t_param = wscparam; - tp->t_dev = dev; - if ((tp->t_state & TS_ISOPEN) == 0) { - tp->t_state |= TS_WOPEN; - ttychars(tp); - tp->t_iflag = TTYDEF_IFLAG; - tp->t_oflag = TTYDEF_OFLAG; - tp->t_cflag = TTYDEF_CFLAG; - tp->t_lflag = TTYDEF_LFLAG; - tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; - wscparam(tp, &tp->t_termios); - ttsetwater(tp); - } else if ((tp->t_state & TS_XCLUDE) != 0 && p->p_ucred->cr_uid != 0) - return EBUSY; - tp->t_state |= TS_CARR_ON; - - return ((*linesw[tp->t_line].l_open)(dev, tp)); -} - -int -wscclose(dev, flag, mode, p) - dev_t dev; - int flag, mode; - struct proc *p; -{ - struct wsc_softc *sc = &wsc_sc[WSCUNIT(dev)]; - struct tty *tp = sc->sc_tty; - - (*linesw[tp->t_line].l_close)(tp, flag); - ttyclose(tp); -#ifdef notyet /* XXX */ - ttyfree(tp); -#endif - return(0); -} - -int -wscread(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - struct wsc_softc *sc = &wsc_sc[WSCUNIT(dev)]; - struct tty *tp = sc->sc_tty; - - return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); -} - -int -wscwrite(dev, uio, flag) - dev_t dev; - struct uio *uio; - int flag; -{ - struct wsc_softc *sc = &wsc_sc[WSCUNIT(dev)]; - struct tty *tp = sc->sc_tty; - - return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); -} - -struct tty * -wsctty(dev) - dev_t dev; -{ - struct wsc_softc *sc = &wsc_sc[WSCUNIT(dev)]; - struct tty *tp = sc->sc_tty; - - return (tp); -} - -int -wscioctl(dev, cmd, data, flag, p) - dev_t dev; - u_long cmd; - caddr_t data; - int flag; - struct proc *p; -{ - struct wsc_softc *sc = &wsc_sc[WSCUNIT(dev)]; - struct tty *tp = sc->sc_tty; - int error; - - error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, data, flag, p); - if (error >= 0) - return error; - error = ttioctl(tp, cmd, data, flag, p); - if (error >= 0) - return error; - - switch (cmd) { - default: - return (ENOTTY); - } - -#ifdef DIAGNOSTIC - panic("wscioctl: impossible"); -#endif -} - -void -wscstart(tp) - register struct tty *tp; -{ - register int s, n, i; - char buf[OBUFSIZ]; - - s = spltty(); - if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP)) { - splx(s); - return; - } - tp->t_state |= TS_BUSY; - splx(s); - n = q_to_b(&tp->t_outq, buf, sizeof(buf)); - for (i = 0; i < n; ++i) - buf[i] &= 0177; /* strip parity (argh) */ - ansicons_input(wsc_sc[WSCUNIT(tp->t_dev)].sc_ansicons, buf, n); - - s = spltty(); - tp->t_state &= ~TS_BUSY; - /* Come back if there's more to do */ - if (tp->t_outq.c_cc) { - tp->t_state |= TS_TIMEOUT; - timeout(ttrstrt, tp, 1); - } - if (tp->t_outq.c_cc <= tp->t_lowat) { - if (tp->t_state&TS_ASLEEP) { - tp->t_state &= ~TS_ASLEEP; - wakeup((caddr_t)&tp->t_outq); - } - selwakeup(&tp->t_wsel); - } - splx(s); -} - -void -wscstop(tp, flag) - struct tty *tp; - int flag; -{ - -} - -/* - * Set line parameters. - */ -int -wscparam(tp, t) - struct tty *tp; - struct termios *t; -{ - - tp->t_ispeed = t->c_ispeed; - tp->t_ospeed = t->c_ospeed; - tp->t_cflag = t->c_cflag; - return 0; -} - -/* - * keyboard input! - */ -void -wscons_kbdinput(cp) - char *cp; -{ - struct wsc_softc *sc; - struct tty *tp; - - if (wsc_kbdfocusunit == -1) - return; - - sc = &wsc_sc[wsc_kbdfocusunit]; - tp = sc->sc_tty; - - while (*cp) - (*linesw[tp->t_line].l_rint)(*cp++, tp); -} - -/* - * XXX CONSOLE HANDLING GUNK. - */ - -void -wsc_console(acp, acf, acfarg, mrow, mcol, crow, ccol) - struct ansicons *acp; - struct ansicons_functions *acf; - void *acfarg; - int mrow, mcol, crow, ccol; -{ - - wsc_console_ansicons = acp; - ansicons_attach(acp, acf, acfarg, mrow, mcol, crow, ccol); - - cn_tab = &wsccons; -} - -void -wsccnputc(dev, ic) - dev_t dev; - int ic; -{ - char c = ic; - - ansicons_input(wsc_console_ansicons, &c, 1); -} - -int -wsccngetc(dev) - dev_t dev; -{ - - if (wsc_console_getc != NULL) - return (*wsc_console_getc)(wsc_input_arg); - else - return '\0'; -} - -void -wsccnpollc(dev, i) - dev_t dev; - int i; -{ - - if (wsc_console_pollc != NULL) - (*wsc_console_pollc)(wsc_input_arg, i); -} |