summaryrefslogtreecommitdiffstats
path: root/sys/i386/pci/pci.c
diff options
context:
space:
mode:
Diffstat (limited to 'sys/i386/pci/pci.c')
-rw-r--r--sys/i386/pci/pci.c778
1 files changed, 0 insertions, 778 deletions
diff --git a/sys/i386/pci/pci.c b/sys/i386/pci/pci.c
deleted file mode 100644
index 6ef7163..0000000
--- a/sys/i386/pci/pci.c
+++ /dev/null
@@ -1,778 +0,0 @@
-/**************************************************************************
-**
-** $Id: pci.c,v 1.8 1994/10/25 23:09:08 se Exp $
-**
-** General subroutines for the PCI bus on 80*86 systems.
-** pci_configure ()
-**
-** 386bsd / FreeBSD
-**
-**-------------------------------------------------------------------------
-**
-** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved.
-**
-** Redistribution and use in source and binary forms, with or without
-** modification, are permitted provided that the following conditions
-** are met:
-** 1. Redistributions of source code must retain the above copyright
-** notice, this list of conditions and the following disclaimer.
-** 2. Redistributions in binary form must reproduce the above copyright
-** notice, this list of conditions and the following disclaimer in the
-** documentation and/or other materials provided with the distribution.
-** 3. The name of the author may not be used to endorse or promote products
-** derived from this software without specific prior written permission.
-**
-** THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
-** IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
-** OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
-** IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
-** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
-** NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-** DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-** THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
-** THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-**
-***************************************************************************
-*/
-
-#include <pci.h>
-#if NPCI > 0
-
-#ifndef __FreeBSD2__
-#if __FreeBSD__ >= 2
-#define __FreeBSD2__
-#endif
-#endif
-
-/*========================================================
-**
-** #includes and declarations
-**
-**========================================================
-*/
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/malloc.h>
-#include <sys/errno.h>
-
-#include <vm/vm.h>
-#include <vm/vm_param.h>
-
-#include <i386/isa/isa.h>
-#include <i386/isa/isa_device.h>
-#include <i386/isa/icu.h>
-#include <i386/pci/pcireg.h>
-
-#ifdef __FreeBSD2__
-#include <sys/devconf.h>
-
-struct pci_devconf {
- struct kern_devconf pdc_kdc;
- struct pci_info pdc_pi;
-};
-#endif
-
-/*
-** Function prototypes missing in system headers
-*/
-
-#ifndef __FreeBSD2__
-extern pmap_t pmap_kernel(void);
-static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize);
-
-/*
- * Type of the first (asm) part of an interrupt handler.
- */
-typedef void inthand_t __P((u_int cs, u_int ef, u_int esp, u_int ss));
-
-/*
- * Usual type of the second (C) part of an interrupt handler. Some bogus
- * ones need the arg to be the interrupt frame (and not a copy of it, which
- * is all that is possible in C).
- */
-typedef void inthand2_t __P((int unit));
-
-/*
-** XXX @FreeBSD2@
-**
-** Unfortunately, the mptr argument is _no_ pointer in 2.0 FreeBSD.
-** We would prefer a pointer because it enables us to install
-** new interrupt handlers at any time.
-** (This is just going to be changed ... <se> :)
-** In 2.0 FreeBSD later installed interrupt handlers may change
-** the xyz_imask, but this would not be recognized by handlers
-** which are installed before.
-*/
-
-static int
-register_intr __P((int intr, int device_id, unsigned int flags,
- inthand2_t *handler, unsigned int * mptr, int unit));
-extern unsigned intr_mask[ICU_LEN];
-
-#endif /* !__FreeBSD2__ */
-
-/*========================================================
-**
-** Autoconfiguration of pci devices.
-**
-** This is reverse to the isa configuration.
-** (1) find a pci device.
-** (2) look for a driver.
-**
-**========================================================
-*/
-
-/*--------------------------------------------------------
-**
-** The pci devices can be mapped to any address.
-** As default we start at the last gigabyte.
-**
-**--------------------------------------------------------
-*/
-
-#ifndef PCI_PMEM_START
-#define PCI_PMEM_START 0xc0000000
-#endif
-
-static vm_offset_t pci_paddr = PCI_PMEM_START;
-
-/*--------------------------------------------------------
-**
-** The pci device interrupt lines should have been
-** assigned by the bios. But if the bios failed to
-** to it, we set it.
-**
-**--------------------------------------------------------
-*/
-
-#ifndef PCI_IRQ
-#define PCI_IRQ 0
-#endif
-
-static u_long pci_irq = PCI_IRQ;
-
-/*---------------------------------------------------------
-**
-** pci_configure ()
-**
-** Probe all devices on pci bus and attach them.
-**
-** May be called more than once.
-** Any device is attached only once.
-** (Attached devices are remembered in pci_seen.)
-**
-**---------------------------------------------------------
-*/
-
-static void not_supported (pcici_t tag, u_long type);
-
-static unsigned long pci_seen[NPCI];
-
-static int pci_conf_count;
-
-#ifdef __FreeBSD2__
-static int
-pci_externalize (struct proc *, struct kern_devconf *, void *, size_t);
-
-static int
-pci_internalize (struct proc *, struct kern_devconf *, void *, size_t);
-
-#endif /* __FreeBSD2__ */
-
-void pci_configure()
-{
- u_char device,last_device;
- u_short bus;
- pcici_t tag;
- pcidi_t type;
- u_long data;
- int unit;
- int pci_mechanism;
- int pciint;
- int irq;
- char* name=0;
- vm_offset_t old_addr=pci_paddr;
-
- struct pci_driver *drp=0;
- struct pci_device *dvp;
-
-#ifdef __FreeBSD2__
- struct pci_devconf *pdcp;
-#endif
-
- /*
- ** check pci bus present
- */
-
- pci_mechanism = pci_conf_mode ();
- if (!pci_mechanism) return;
- last_device = pci_mechanism==1 ? 31 : 15;
-
- /*
- ** hello world ..
- */
-
-
- for (bus=0;bus<NPCI;bus++) {
-#ifndef PCI_QUIET
- printf ("pci%d: scanning device 0..%d, mechanism=%d.\n",
- bus, last_device, pci_mechanism);
-#endif
- for (device=0; device<=last_device; device ++) {
-
- if (pci_seen[bus] & (1ul << device))
- continue;
-
- tag = pcitag (bus, device, 0);
- type = pci_conf_read (tag, PCI_ID_REG);
-
- if ((!type) || (type==0xfffffffful)) continue;
-
- /*
- ** lookup device in ioconfiguration:
- */
-
- for (dvp = pci_devtab; dvp->pd_name; dvp++) {
- drp = dvp->pd_driver;
- if (!drp)
- continue;
- if ((name=(*drp->probe)(tag, type)))
- break;
- };
-
- if (!dvp->pd_name) {
-#ifndef PCI_QUIET
- if (pci_conf_count)
- continue;
- printf("pci%d:%d: ", bus, device);
- not_supported (tag, type);
-#endif
- continue;
- };
-
- pci_seen[bus] |= (1ul << device);
- /*
- ** Get and increment the unit.
- */
-
- unit = (*drp->count)++;
-
- /*
- ** ignore device ?
- */
-
- if (!*name) continue;
-
- /*
- ** Announce this device
- */
-
- printf ("%s%d <%s>", dvp->pd_name, unit, name);
-
- /*
- ** Get the int pin number (pci interrupt number a-d)
- ** from the pci configuration space.
- */
-
- data = pci_conf_read (tag, PCI_INTERRUPT_REG);
- pciint = PCI_INTERRUPT_PIN_EXTRACT(data);
-
- if (pciint) {
-
- printf (" int %c", 0x60+pciint);
-
- /*
- ** If the interrupt line register is not set,
- ** set it now from PCI_IRQ.
- */
-
- if (!(PCI_INTERRUPT_LINE_EXTRACT(data))) {
-
- irq = pci_irq & 0x0f;
- pci_irq >>= 4;
-
- data = PCI_INTERRUPT_LINE_INSERT(data, irq);
- printf (" (config)");
- pci_conf_write (tag, PCI_INTERRUPT_REG, data);
- };
-
- irq = PCI_INTERRUPT_LINE_EXTRACT(data);
-
- /*
- ** If it's zero, the isa irq number is unknown,
- ** and we cannot bind the pci interrupt to isa.
- */
-
- if (irq)
- printf (" irq %d", irq);
- else
- printf (" not bound");
- };
-
- /*
- ** enable memory access
- */
-
- data = (pci_conf_read (tag, PCI_COMMAND_STATUS_REG)
- & 0xffff) | PCI_COMMAND_MEM_ENABLE;
-
- pci_conf_write (tag, (u_char) PCI_COMMAND_STATUS_REG, data);
-
- /*
- ** show pci slot.
- */
-
- printf (" on pci%d:%d\n", bus, device);
-
-#ifdef __FreeBSD2__
-
- /*
- ** Allocate a devconf structure
- */
-
- pdcp = (struct pci_devconf *)
- malloc (sizeof (struct pci_devconf),M_DEVBUF,M_WAITOK);
-
- /*
- ** Fill in.
- **
- ** Sorry, this is not yet complete.
- ** We should, and eventually will, set the
- ** parent pointer to a pci bus devconf structure,
- ** and arrange to set the state field dynamically.
- **
- ** But I'll go to vacation today, and after all,
- ** wasn't there a new feature freeze on Oct 1.?
- */
-
- pdcp -> pdc_pi.pi_bus = bus;
- pdcp -> pdc_pi.pi_device = device;
-
- pdcp -> pdc_kdc.kdc_name = dvp->pd_name;
- pdcp -> pdc_kdc.kdc_unit = unit;
-
- pdcp -> pdc_kdc.kdc_md.mddc_devtype = MDDT_PCI;
-
- pdcp -> pdc_kdc.kdc_externalize = pci_externalize;
- pdcp -> pdc_kdc.kdc_internalize = pci_internalize;
-
- pdcp -> pdc_kdc.kdc_datalen = PCI_EXTERNAL_LEN;
- pdcp -> pdc_kdc.kdc_parentdata = &pdcp->pdc_pi;
- pdcp -> pdc_kdc.kdc_state = DC_UNKNOWN;
- pdcp -> pdc_kdc.kdc_description = name;
-
- /*
- ** And register this device
- */
-
- dev_attach (&pdcp->pdc_kdc);
-
-#endif /* __FreeBSD2__ */
-
-
- /*
- ** attach device
- ** may produce additional log messages,
- ** i.e. when installing subdevices.
- */
-
- (*drp->attach) (tag, unit);
- };
- };
-
-#ifndef PCI_QUIET
- if (pci_paddr != old_addr)
- printf ("pci uses physical addresses from 0x%lx to 0x%lx\n",
- (u_long)PCI_PMEM_START, (u_long)pci_paddr);
-#endif
- pci_conf_count++;
-}
-
-/*-----------------------------------------------------------------------
-**
-** Map device into port space.
-**
-** PCI-Specification: 6.2.5.1: address maps
-**
-**-----------------------------------------------------------------------
-*/
-
-int pci_map_port (pcici_t tag, u_long reg, u_short* pa)
-{
- /*
- ** @MAPIO@ not yet implemented.
- */
- printf ("pci_map_port failed: not yet implemented\n");
- return (0);
-}
-
-/*-----------------------------------------------------------------------
-**
-** Map device into virtual and physical space
-**
-** PCI-Specification: 6.2.5.1: address maps
-**
-**-----------------------------------------------------------------------
-*/
-
-int pci_map_mem (pcici_t tag, u_long reg, vm_offset_t* va, vm_offset_t* pa)
-{
- u_long data;
- vm_size_t vsize;
- vm_offset_t vaddr;
-
- /*
- ** sanity check
- */
-
- if (reg < PCI_MAP_REG_START || reg >= PCI_MAP_REG_END || (reg & 3)) {
- printf ("pci_map_mem failed: bad register=0x%x\n",
- (unsigned)reg);
- return (0);
- };
-
- /*
- ** get size and type of memory
- **
- ** type is in the lowest four bits.
- ** If device requires 2^n bytes, the next
- ** n-4 bits are read as 0.
- */
-
- pci_conf_write (tag, reg, 0xfffffffful);
- data = pci_conf_read (tag, reg);
-
- switch (data & 0x0f) {
-
- case PCI_MAP_MEMORY_TYPE_32BIT: /* 32 bit non cachable */
- break;
-
- default: /* unknown */
- printf ("pci_map_mem failed: bad memory type=0x%x\n",
- (unsigned) data);
- return (0);
- };
-
- /*
- ** mask out the type,
- ** and round up to a page size
- */
-
- vsize = round_page (-(data & PCI_MAP_MEMORY_ADDRESS_MASK));
-
- if (!vsize) return (0);
-
- /*
- ** align physical address to virtual size
- */
-
- if ((data = pci_paddr % vsize))
- pci_paddr += vsize - data;
-
- vaddr = (vm_offset_t) pmap_mapdev (pci_paddr, vsize);
-
-
- if (!vaddr) return (0);
-
-#ifndef PCI_QUIET
- /*
- ** display values.
- */
-
- printf ("\treg%d: virtual=0x%lx physical=0x%lx\n",
- (unsigned) reg, (u_long)vaddr, (u_long)pci_paddr);
-#endif
-
- /*
- ** return them to the driver
- */
-
- *va = vaddr;
- *pa = pci_paddr;
-
- /*
- ** set device address
- */
-
- pci_conf_write (tag, reg, pci_paddr);
-
- /*
- ** and don't forget to increment pci_paddr
- */
-
- pci_paddr += vsize;
-
- return (1);
-}
-
-/*------------------------------------------------------------
-**
-** Interface functions for the devconf module.
-**
-**------------------------------------------------------------
-*/
-
-static int
-pci_externalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t l)
-{
- struct pci_externalize_buffer buffer;
- struct pci_info * pip = kdcp->kdc_parentdata;
- pcici_t tag;
- int i;
-
- if (l < sizeof buffer) {
- return ENOMEM;
- };
-
- tag = pcitag (pip->pi_bus, pip->pi_device, 0);
-
- buffer.peb_pci_info = *pip;
-
- for (i=0; i<PCI_EXT_CONF_LEN; i++) {
- buffer.peb_config[i] = pci_conf_read (tag, i*4);
- };
-
- return copyout(&buffer, u, sizeof buffer);
-}
-
-
-static int
-pci_internalize (struct proc *p, struct kern_devconf *kdcp, void *u, size_t s)
-{
- return EOPNOTSUPP;
-}
-
-/*-----------------------------------------------------------------------
-**
-** Map pci interrupts to isa interrupts.
-**
-**-----------------------------------------------------------------------
-*/
-
-static unsigned int pci_int_mask [16];
-
-int pci_map_int (pcici_t tag, int(*func)(), void* arg, unsigned* maskptr)
-{
- int irq;
- unsigned mask;
-
- irq = PCI_INTERRUPT_LINE_EXTRACT(
- pci_conf_read (tag, PCI_INTERRUPT_REG));
-
- if (irq >= 16 || irq <= 0) {
- printf ("pci_map_int failed: no int line set.\n");
- return (0);
- }
-
- mask = 1ul << irq;
-
- if (!maskptr)
- maskptr = &pci_int_mask[irq];
-
- INTRMASK (*maskptr, mask);
-
- register_intr(
- irq, /* isa irq */
- 0, /* deviced?? */
- 0, /* flags? */
- (inthand2_t*) func, /* handler */
- maskptr, /* mask pointer */
- (int) arg); /* handler arg */
-
-#ifdef __FreeBSD2__
- /*
- ** XXX See comment at beginning of file.
- **
- ** Have to update all the interrupt masks ... Grrrrr!!!
- */
- {
- unsigned * mp = &intr_mask[0];
- /*
- ** update the isa interrupt masks.
- */
- for (mp=&intr_mask[0]; mp<&intr_mask[ICU_LEN]; mp++)
- if (*mp & *maskptr)
- *mp |= mask;
- /*
- ** update the pci interrupt masks.
- */
- for (mp=&pci_int_mask[0]; mp<&pci_int_mask[16]; mp++)
- if (*mp & *maskptr)
- *mp |= mask;
- };
-#endif
-
- INTREN (mask);
-
- return (1);
-}
-
-/*-----------------------------------------------------------
-**
-** Display of unknown devices.
-**
-**-----------------------------------------------------------
-*/
-struct vt {
- u_short ident;
- char* name;
-};
-
-static struct vt VendorTable[] = {
- {0x1002, "ATI TECHNOLOGIES INC"},
- {0x1011, "DIGITAL EQUIPMENT CORPORATION"},
- {0x101A, "NCR"},
- {0x102B, "MATROX"},
- {0x1045, "OPTI"},
- {0x5333, "S3 INC."},
- {0x8086, "INTEL CORPORATION"},
- {0,0}
-};
-
-static const char *const majclasses[] = {
- "old", "storage", "network", "display",
- "multimedia", "memory", "bridge"
-};
-
-void not_supported (pcici_t tag, u_long type)
-{
- u_char reg;
- u_long data;
- struct vt * vp;
-
- /*
- ** lookup the names.
- */
-
- for (vp=VendorTable; vp->ident; vp++)
- if (vp->ident == (type & 0xffff))
- break;
-
- /*
- ** and display them.
- */
-
- if (vp->ident) printf (vp->name);
- else printf ("vendor=0x%lx", type & 0xffff);
-
- printf (", device=0x%lx", type >> 16);
-
- data = (pci_conf_read(tag, PCI_CLASS_REG) >> 24) & 0xff;
- if (data < sizeof(majclasses) / sizeof(majclasses[0]))
- printf(", class=%s", majclasses[data]);
-
- printf (" [not supported]\n");
-
- for (reg=PCI_MAP_REG_START; reg<PCI_MAP_REG_END; reg+=4) {
- data = pci_conf_read (tag, reg);
- if (!data) continue;
- switch (data&7) {
-
- case 1:
- case 5:
- printf (" map(%x): io(%lx)\n",
- reg, data & ~3);
- break;
- case 0:
- printf (" map(%x): mem32(%lx)\n",
- reg, data & ~7);
- break;
- case 2:
- printf (" map(%x): mem20(%lx)\n",
- reg, data & ~7);
- break;
- case 4:
- printf (" map(%x): mem64(%lx)\n",
- reg, data & ~7);
- break;
- }
- }
-}
-
-#ifndef __FreeBSD2__
-/*-----------------------------------------------------------
-**
-** Mapping of physical to virtual memory
-**
-**-----------------------------------------------------------
-*/
-
-extern vm_map_t kernel_map;
-
-static vm_offset_t pmap_mapdev (vm_offset_t paddr, vm_size_t vsize)
-{
- vm_offset_t vaddr,value;
- u_long result;
-
- vaddr = vm_map_min (kernel_map);
-
- result = vm_map_find (kernel_map, (void*)0, (vm_offset_t) 0,
- &vaddr, vsize, TRUE);
-
- if (result != KERN_SUCCESS) {
- printf (" vm_map_find failed(%d)\n", result);
- return (0);
- };
-
- /*
- ** map physical
- */
-
- value = vaddr;
- while (vsize >= NBPG) {
- pmap_enter (pmap_kernel(), vaddr, paddr,
- VM_PROT_READ|VM_PROT_WRITE, TRUE);
- vaddr += NBPG;
- paddr += NBPG;
- vsize -= NBPG;
- };
- return (value);
-}
-
-/*------------------------------------------------------------
-**
-** Emulate the register_intr() function of FreeBSD 2.0
-**
-** requires a patch:
-** FreeBSD 2.0: "/sys/i386/isa/vector.s"
-** 386bsd0.1: "/sys/i386/isa/icu.s"
-** 386bsd1.0: Please ask Jesus Monroy Jr.
-**
-**------------------------------------------------------------
-*/
-
-#include <machine/segments.h>
-
-int pci_int_unit [16];
-inthand2_t* (pci_int_hdlr [16]);
-unsigned int * pci_int_mptr [16];
-unsigned int pci_int_count[16];
-
-extern void
- Vpci3(), Vpci4(), Vpci5(), Vpci6(), Vpci7(), Vpci8(), Vpci9(),
- Vpci10(), Vpci11(), Vpci12(), Vpci13(), Vpci14(), Vpci15();
-
-static inthand_t* pci_int_glue[16] = {
- 0, 0, 0, Vpci3, Vpci4, Vpci5, Vpci6, Vpci7, Vpci8,
- Vpci9, Vpci10, Vpci11, Vpci12, Vpci13, Vpci14, Vpci15 };
-
-static int
-register_intr __P((int intr, int device_id, unsigned int flags,
- inthand2_t *handler, unsigned int* mptr, int unit))
-{
- if (intr >= 16 || intr <= 2)
- return (EINVAL);
- if (pci_int_hdlr [intr])
- return (EBUSY);
-
- pci_int_hdlr [intr] = handler;
- pci_int_unit [intr] = unit;
- pci_int_mptr [intr] = mptr;
-
- setidt(NRSVIDT + intr, pci_int_glue[intr], SDT_SYS386IGT, SEL_KPL);
- return (0);
-}
-#endif /* __FreeBSD2__ */
-#endif /* NPCI */
OpenPOWER on IntegriCloud