Completely new PCI code:
1) Supports PCI to PCI bridge devices (and tries to initialise them, even if the BIOS is brain dead). 2) Supports shared PCI interrupts. Interrupt handlers now MUST return '0' if they found nothing to do, '1' otherwise. New features tested with i486 systems based on the Intel Saturn and a DEC 4channel Ethernet card only, but expected to work on most systems. The option PCI_REMAP has been removed ! Submitted by: Wolfgang Stanglmeier <wolf@kintaro.cologne.de>
This commit is contained in:
parent
4f92854707
commit
6e667246cd
1585
sys/dev/pci/pci.c
1585
sys/dev/pci/pci.c
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcireg.h,v 1.3 1995/02/02 13:12:18 davidg Exp $
|
||||
** $Id: pcireg.h,v 1.4 1995/02/02 22:01:40 se Exp $
|
||||
**
|
||||
** Names for PCI configuration space registers.
|
||||
**
|
||||
@ -33,8 +33,7 @@
|
||||
*/
|
||||
|
||||
#ifndef __PCI_REG_H__
|
||||
#define __PCI_REG_H__
|
||||
|
||||
#define __PCI_REG_H__ "pl2 95/03/21"
|
||||
|
||||
/*
|
||||
** Device identification register; contains a vendor ID and a device ID.
|
||||
@ -146,6 +145,32 @@
|
||||
#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
|
||||
|
||||
#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
|
||||
/*
|
||||
** PCI-PCI bridge mapping registers
|
||||
*/
|
||||
#define PCI_PCI_BRIDGE_BUS_REG 0x18
|
||||
#define PCI_PCI_BRIDGE_IO_REG 0x1c
|
||||
#define PCI_PCI_BRIDGE_MEM_REG 0x20
|
||||
#define PCI_PCI_BRIDGE_PMEM_REG 0x24
|
||||
|
||||
|
||||
#define PCI_SUBORDINATE_BUS_MASK 0x00ff0000
|
||||
#define PCI_SECONDARY_BUS_MASK 0x0000ff00
|
||||
#define PCI_PRIMARY_BUS_MASK 0x000000ff
|
||||
|
||||
#define PCI_SUBORDINATE_BUS_EXTRACT(x) (((x) > 16) & 0xff)
|
||||
#define PCI_SECONDARY_BUS_EXTRACT(x) (((x) > 8) & 0xff)
|
||||
#define PCI_PRIMARY_BUS_EXTRACT(x) (((x) ) & 0xff)
|
||||
|
||||
#define PCI_PRIMARY_BUS_INSERT(x, y) (((x) & ~PCI_PRIMARY_BUS_MASK) | ((y) << 0))
|
||||
#define PCI_SECONDARY_BUS_INSERT(x, y) (((x) & ~PCI_SECONDARY_BUS_MASK) | ((y) << 8))
|
||||
#define PCI_SUBORDINATE_BUS_INSERT(x, y) (((x) & ~PCI_SUBORDINATE_BUS_MASK) | ((y) << 16))
|
||||
|
||||
#define PCI_PPB_IOBASE_EXTRACT(x) (((x) << 8) & 0xFF00)
|
||||
#define PCI_PPB_IOLIMIT_EXTRACT(x) (((x) << 0) & 0xFF00)
|
||||
|
||||
#define PCI_PPB_MEMBASE_EXTRACT(x) (((x) << 16) & 0xFFFF0000)
|
||||
#define PCI_PPB_MEMLIMIT_EXTRACT(x) (((x) << 0) & 0xFFFF0000)
|
||||
|
||||
/*
|
||||
** Interrupt configuration register
|
||||
|
@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcivar.h,v 1.2 1995/02/27 17:17:14 se Exp $
|
||||
** $Id: pcivar.h,v 1.3 1995/03/17 04:27:21 davidg Exp $
|
||||
**
|
||||
** Declarations for pci device drivers.
|
||||
**
|
||||
** 386bsd / FreeBSD
|
||||
** FreeBSD
|
||||
**
|
||||
**-------------------------------------------------------------------------
|
||||
**
|
||||
@ -36,10 +36,8 @@
|
||||
*/
|
||||
|
||||
#ifndef __PCI_VAR_H__
|
||||
#define __PCI_VAR_H__
|
||||
#define __PCI_VAR_H__ "pl2 95/03/21"
|
||||
|
||||
#define PCIVAR_H_PATCHLEVEL "pl1 95/02/27"
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** main pci initialization function.
|
||||
@ -60,13 +58,16 @@ void pci_configure (void);
|
||||
|
||||
typedef union {
|
||||
u_long cfg1;
|
||||
struct {
|
||||
struct {
|
||||
u_char enable;
|
||||
u_char forward;
|
||||
u_short port;
|
||||
} cfg2;
|
||||
unsigned tag;
|
||||
} pcici_t;
|
||||
|
||||
#define sametag(x,y) ((x).tag == (y).tag)
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** Each pci device has an unique device id.
|
||||
@ -98,7 +99,7 @@ typedef u_long pcidi_t;
|
||||
u_long pci_conf_read (pcici_t tag, u_long reg );
|
||||
|
||||
void pci_conf_write (pcici_t tag, u_long reg, u_long data);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** The pci driver structure.
|
||||
@ -141,7 +142,11 @@ struct pci_device {
|
||||
*/
|
||||
|
||||
extern struct linker_set pcidevice_set;
|
||||
|
||||
|
||||
extern unsigned pci_max_burst_len; /* log2 of safe burst transfer length */
|
||||
extern unsigned pci_mechanism;
|
||||
extern unsigned pci_maxdevice;
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** The pci-devconf interface.
|
||||
@ -150,8 +155,8 @@ extern struct linker_set pcidevice_set;
|
||||
*/
|
||||
|
||||
struct pci_info {
|
||||
u_short pi_bus;
|
||||
u_short pi_device;
|
||||
u_short pi_bus;
|
||||
u_short pi_device;
|
||||
};
|
||||
|
||||
#define PCI_EXT_CONF_LEN (16)
|
||||
@ -162,31 +167,18 @@ struct pci_externalize_buffer {
|
||||
u_long peb_config[PCI_EXT_CONF_LEN];
|
||||
};
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** Register an additional pci bus for probing.
|
||||
** Called by pci-pci bridge handlers.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int pci_map_bus (pcici_t tag, u_long bus);
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** Map a pci device to physical and virtual memory.
|
||||
**
|
||||
** The va and pa addresses are "in/out" parameters.
|
||||
** If they are 0 on entry, the function assigns an address.
|
||||
**
|
||||
** Entry selects the register in the pci configuration
|
||||
** Entry selects the register in the pci configuration
|
||||
** space, which supplies the size of the region, and
|
||||
** receives the physical address.
|
||||
**
|
||||
** If there is any error, a message is written, and
|
||||
** the function returns with zero.
|
||||
** Else it returns with a value different to zero.
|
||||
** In case of success the function sets the addresses
|
||||
** in *va and *pa, and returns 1.
|
||||
** In case of errors a message is written,
|
||||
** and the function returns 0.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
@ -197,59 +189,65 @@ int pci_map_mem (pcici_t tag, u_long entry, u_long * va, u_long * pa);
|
||||
**
|
||||
** Map a pci device to an io port area.
|
||||
**
|
||||
** *pa is an "in/out" parameter.
|
||||
** If it's 0 on entry, the function assigns an port number..
|
||||
**
|
||||
** Entry selects the register in the pci configuration
|
||||
** space, which supplies the size of the region, and
|
||||
** receives the port number.
|
||||
**
|
||||
** If there is any error, a message is written, and
|
||||
** the function returns with zero.
|
||||
** Else it returns with a value different to zero.
|
||||
** In case of success the function sets the port number in pa,
|
||||
** and returns 1.
|
||||
** In case of errors a message is written,
|
||||
** and the function returns 0.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int pci_map_port(pcici_t tag, u_long entry, u_short * pa);
|
||||
|
||||
int pci_map_port (pcici_t tag, u_long entry, u_short * pa);
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** Map a pci interrupt to an isa irq line,
|
||||
** and enable the interrupt.
|
||||
** Map a pci interrupt to an isa irq line, and enable the interrupt.
|
||||
**
|
||||
** func is the interrupt handler, arg is the argument
|
||||
** to this function.
|
||||
** -----------------
|
||||
**
|
||||
** The maskptr argument should be &bio_imask,
|
||||
** &net_imask etc. or NULL.
|
||||
** func is the interrupt handler, arg is the argument
|
||||
** to the handler (usually a pointer to a softc).
|
||||
**
|
||||
** If there is any error, a message is written, and
|
||||
** the function returns with zero.
|
||||
** Else it returns with a value different to zero.
|
||||
** The maskptr argument should be &bio_imask,
|
||||
** &net_imask etc. or NULL.
|
||||
**
|
||||
** A word of caution for FreeBSD 2.0:
|
||||
** If there is any error, a message is written, and
|
||||
** the function returns with zero.
|
||||
** Else it returns with a value different to zero.
|
||||
**
|
||||
** We use the register_intr() function.
|
||||
** -----------------
|
||||
**
|
||||
** The interrupt line of the selected device is included
|
||||
** into the supplied mask: after the corresponding splXXX
|
||||
** this drivers interrupts are blocked.
|
||||
** The irq number is read from the configuration space.
|
||||
** (Should have been set by the bios).
|
||||
**
|
||||
** But in the interrupt handlers startup code ONLY
|
||||
** the interrupt of the driver is blocked, and NOT
|
||||
** all interrupts of the spl group.
|
||||
** Supports multiple handlers per irq (shared interrupts).
|
||||
**
|
||||
** It may be required to additional block the group
|
||||
** interrupts by splXXX() inside the interrupt handler.
|
||||
** -----------------
|
||||
**
|
||||
** In pre 2.0 kernels we emulate the register_intr
|
||||
** function. The emulating function blocks all interrupts
|
||||
** of the group in the interrupt handler prefix code.
|
||||
** There is code to support shared edge triggered ints.
|
||||
** This relies on the cooperation of the interrupt handlers:
|
||||
** they have to return a value <>0 if and only if something
|
||||
** was done. Beware of the performance penalty.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
struct pci_int_desc {
|
||||
struct pci_int_desc * pcid_next;
|
||||
pcici_t pcid_tag;
|
||||
int (*pcid_handler)();
|
||||
void* pcid_argument;
|
||||
unsigned * pcid_maskptr;
|
||||
unsigned pcid_tally;
|
||||
unsigned pcid_mask;
|
||||
};
|
||||
|
||||
int pci_map_int (pcici_t tag, int (*func)(), void* arg, unsigned * maskptr);
|
||||
|
||||
int pci_unmap_int (pcici_t tag);
|
||||
|
||||
#endif
|
||||
|
1585
sys/pci/pci.c
1585
sys/pci/pci.c
File diff suppressed because it is too large
Load Diff
@ -1,14 +1,14 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcibus.h,v 1.2 1994/11/02 23:47:14 se Exp $
|
||||
** $Id: pcibus.h,v 1.1 1995/02/01 22:56:47 se Exp $
|
||||
**
|
||||
** Declarations for pci bus driver.
|
||||
**
|
||||
** 386bsd / FreeBSD
|
||||
** FreeBSD
|
||||
**
|
||||
**-------------------------------------------------------------------------
|
||||
**
|
||||
** Copyright (c) 1994 Wolfgang Stanglmeier. All rights reserved.
|
||||
** Copyright (c) 1995 Wolfgang Stanglmeier. All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
@ -36,51 +36,58 @@
|
||||
*/
|
||||
|
||||
#ifndef __PCI_BUS_H__
|
||||
#define __PCI_BUS_H__
|
||||
|
||||
#define __PCI_BUS_H__ "pl1 95/03/13"
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** The following functions are provided by the pci bios.
|
||||
** They are used only by the pci configuration.
|
||||
**
|
||||
** pb_mode():
|
||||
** pcibus_setup():
|
||||
** Probes for a pci system.
|
||||
** Returns 1 or 2 for pci configuration mechanism.
|
||||
** Returns 0 if no pci system.
|
||||
** Sets pci_maxdevice and pci_mechanism.
|
||||
**
|
||||
** pb_tag():
|
||||
** Gets a handle for accessing the pci configuration
|
||||
** space.
|
||||
** This handle is given to the mapping functions (see
|
||||
** above) or to the read/write functions.
|
||||
** pcibus_tag():
|
||||
** Creates a handle for pci configuration space access.
|
||||
** This handle is given to the read/write functions.
|
||||
**
|
||||
** pb_read():
|
||||
** pcibus_ftag():
|
||||
** Creates a modified handle.
|
||||
**
|
||||
** pcibus_read():
|
||||
** Read a long word from the pci configuration space.
|
||||
** Requires a tag (from pcitag) and the register
|
||||
** number (should be a long word aligned one).
|
||||
** number (should be a long word alligned one).
|
||||
**
|
||||
** pb_write():
|
||||
** pcibus_write():
|
||||
** Writes a long word to the pci configuration space.
|
||||
** Requires a tag (from pcitag), the register number
|
||||
** (should be a long word aligned one), and a value.
|
||||
** (should be a long word alligned one), and a value.
|
||||
**
|
||||
** pb_regint():
|
||||
** pcibus_regirq():
|
||||
** Register an interupt handler for a pci device.
|
||||
** Requires a tag (from pcitag), the handler function
|
||||
** and it's argument, and an interupt mask.
|
||||
** Requires a tag (from pcitag), the register number
|
||||
** (should be a long word alligned one), and a value.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
struct pcibus {
|
||||
char *pb_name;
|
||||
int (*pb_mode ) (void);
|
||||
pcici_t (*pb_tag ) (u_char bus, u_char device, u_char func);
|
||||
u_long (*pb_read ) (pcici_t tag, u_long reg);
|
||||
void (*pb_write ) (pcici_t tag, u_long reg, u_long data);
|
||||
int (*pb_regint) (pcici_t tag, int(*func)(), void*arg, unsigned*mp);
|
||||
void (*pb_setup ) (void);
|
||||
pcici_t (*pb_tag ) (u_char bus, u_char device, u_char func);
|
||||
pcici_t (*pb_ftag ) (pcici_t tag, u_char func);
|
||||
u_long (*pb_read ) (pcici_t tag, u_long reg);
|
||||
void (*pb_write ) (pcici_t tag, u_long reg, u_long data);
|
||||
unsigned pb_maxirq;
|
||||
int (*pb_iattach) (int irq, void(*func)(), int arg, unsigned*maskp);
|
||||
int (*pb_idetach) (int irq, void(*func)());
|
||||
int (*pb_imaskinc)(int irq, unsigned *maskptr);
|
||||
int (*pb_imaskexc)(int irq, unsigned *maskptr);
|
||||
};
|
||||
|
||||
#define PCI_MAX_IRQ (16)
|
||||
|
||||
/*
|
||||
** The following structure should be generated by the driver
|
||||
*/
|
||||
|
@ -1,6 +1,6 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcireg.h,v 1.3 1995/02/02 13:12:18 davidg Exp $
|
||||
** $Id: pcireg.h,v 1.4 1995/02/02 22:01:40 se Exp $
|
||||
**
|
||||
** Names for PCI configuration space registers.
|
||||
**
|
||||
@ -33,8 +33,7 @@
|
||||
*/
|
||||
|
||||
#ifndef __PCI_REG_H__
|
||||
#define __PCI_REG_H__
|
||||
|
||||
#define __PCI_REG_H__ "pl2 95/03/21"
|
||||
|
||||
/*
|
||||
** Device identification register; contains a vendor ID and a device ID.
|
||||
@ -146,6 +145,32 @@
|
||||
#define PCI_MAP_MEMORY_ADDRESS_MASK 0xfffffff0
|
||||
|
||||
#define PCI_MAP_IO_ADDRESS_MASK 0xfffffffc
|
||||
/*
|
||||
** PCI-PCI bridge mapping registers
|
||||
*/
|
||||
#define PCI_PCI_BRIDGE_BUS_REG 0x18
|
||||
#define PCI_PCI_BRIDGE_IO_REG 0x1c
|
||||
#define PCI_PCI_BRIDGE_MEM_REG 0x20
|
||||
#define PCI_PCI_BRIDGE_PMEM_REG 0x24
|
||||
|
||||
|
||||
#define PCI_SUBORDINATE_BUS_MASK 0x00ff0000
|
||||
#define PCI_SECONDARY_BUS_MASK 0x0000ff00
|
||||
#define PCI_PRIMARY_BUS_MASK 0x000000ff
|
||||
|
||||
#define PCI_SUBORDINATE_BUS_EXTRACT(x) (((x) > 16) & 0xff)
|
||||
#define PCI_SECONDARY_BUS_EXTRACT(x) (((x) > 8) & 0xff)
|
||||
#define PCI_PRIMARY_BUS_EXTRACT(x) (((x) ) & 0xff)
|
||||
|
||||
#define PCI_PRIMARY_BUS_INSERT(x, y) (((x) & ~PCI_PRIMARY_BUS_MASK) | ((y) << 0))
|
||||
#define PCI_SECONDARY_BUS_INSERT(x, y) (((x) & ~PCI_SECONDARY_BUS_MASK) | ((y) << 8))
|
||||
#define PCI_SUBORDINATE_BUS_INSERT(x, y) (((x) & ~PCI_SUBORDINATE_BUS_MASK) | ((y) << 16))
|
||||
|
||||
#define PCI_PPB_IOBASE_EXTRACT(x) (((x) << 8) & 0xFF00)
|
||||
#define PCI_PPB_IOLIMIT_EXTRACT(x) (((x) << 0) & 0xFF00)
|
||||
|
||||
#define PCI_PPB_MEMBASE_EXTRACT(x) (((x) << 16) & 0xFFFF0000)
|
||||
#define PCI_PPB_MEMLIMIT_EXTRACT(x) (((x) << 0) & 0xFFFF0000)
|
||||
|
||||
/*
|
||||
** Interrupt configuration register
|
||||
|
@ -1,20 +1,20 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcisupport.c,v 1.11 1995/03/02 23:29:44 se Exp $
|
||||
** $Id: pcisupport.c,v 1.12 1995/03/17 04:27:20 davidg Exp $
|
||||
**
|
||||
** Device driver for INTEL PCI chipsets.
|
||||
** Device driver for DEC/INTEL PCI chipsets.
|
||||
**
|
||||
** 386bsd / FreeBSD
|
||||
** FreeBSD
|
||||
**
|
||||
**-------------------------------------------------------------------------
|
||||
**
|
||||
** Written for 386bsd and FreeBSD by
|
||||
** wolf@dentaro.gun.de Wolfgang Stanglmeier
|
||||
** Written for FreeBSD by
|
||||
** wolf@cologne.de Wolfgang Stanglmeier
|
||||
** se@mi.Uni-Koeln.de Stefan Esser
|
||||
**
|
||||
**-------------------------------------------------------------------------
|
||||
**
|
||||
** Copyright (c) 1994 Stefan Esser. All rights reserved.
|
||||
** Copyright (c) 1994,1995 Stefan Esser. All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
** modification, are permitted provided that the following conditions
|
||||
@ -41,28 +41,19 @@
|
||||
***************************************************************************
|
||||
*/
|
||||
|
||||
#define __PCISUPPORT_C_PATCHLEVEL__ "pl2 95/02/27"
|
||||
|
||||
/*==========================================================
|
||||
**
|
||||
** Include files
|
||||
**
|
||||
**==========================================================
|
||||
*/
|
||||
#define __PCISUPPORT_C__ "pl4 95/03/21"
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/devconf.h>
|
||||
|
||||
#include <machine/cpu.h>
|
||||
|
||||
#include <pci/pcivar.h>
|
||||
#include <pci/pcireg.h>
|
||||
|
||||
extern void printf();
|
||||
|
||||
extern int bootverbose;
|
||||
|
||||
|
||||
/*---------------------------------------------------------
|
||||
**
|
||||
** Intel chipsets for 486 / Pentium processor
|
||||
@ -74,7 +65,7 @@ static char* chipset_probe (pcici_t tag, pcidi_t type);
|
||||
static void chipset_attach(pcici_t tag, int unit);
|
||||
static u_long chipset_count;
|
||||
|
||||
struct pci_device chipset_device = {
|
||||
struct pci_device chipset_device = {
|
||||
"chip",
|
||||
chipset_probe,
|
||||
chipset_attach,
|
||||
@ -84,8 +75,6 @@ struct pci_device chipset_device = {
|
||||
|
||||
DATA_SET (pcidevice_set, chipset_device);
|
||||
|
||||
static char confread(pcici_t config_id, int port);
|
||||
|
||||
struct condmsg {
|
||||
unsigned char port;
|
||||
unsigned char mask;
|
||||
@ -94,12 +83,11 @@ struct condmsg {
|
||||
char *text;
|
||||
};
|
||||
|
||||
#define M_EQ 0 /* mask and return true if equal */
|
||||
#define M_NE 1 /* mask and return true if not equal */
|
||||
#define TRUE 2 /* don't read config, always true */
|
||||
|
||||
static char* chipset_probe (pcici_t tag, pcidi_t type)
|
||||
static char*
|
||||
chipset_probe (pcici_t tag, pcidi_t type)
|
||||
{
|
||||
u_long data;
|
||||
|
||||
switch (type) {
|
||||
case 0x04848086:
|
||||
return ("Intel 82378IB PCI-ISA bridge");
|
||||
@ -109,11 +97,28 @@ static char* chipset_probe (pcici_t tag, pcidi_t type)
|
||||
return ("Intel 82375EB PCI-EISA bridge");
|
||||
case 0x04a38086:
|
||||
return ("Intel 82434LX PCI cache memory controller");
|
||||
case 0x00011011:
|
||||
return ("DEC 21050 PCI-PCI bridge");
|
||||
};
|
||||
|
||||
/*
|
||||
** check classes
|
||||
*/
|
||||
|
||||
data = pci_conf_read(tag, PCI_CLASS_REG);
|
||||
switch (data & (PCI_CLASS_MASK|PCI_SUBCLASS_MASK)) {
|
||||
|
||||
case PCI_CLASS_BRIDGE|PCI_SUBCLASS_BRIDGE_PCI:
|
||||
return ("PCI-PCI bridge");
|
||||
};
|
||||
return ((char*)0);
|
||||
}
|
||||
|
||||
struct condmsg conf82424zx[] =
|
||||
#define M_EQ 0 /* mask and return true if equal */
|
||||
#define M_NE 1 /* mask and return true if not equal */
|
||||
#define TRUE 2 /* don't read config, always true */
|
||||
|
||||
static const struct condmsg conf82424zx[] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, TRUE, "\tCPU: " },
|
||||
{ 0x50, 0xe0, 0x00, M_EQ, "486DX" },
|
||||
@ -177,7 +182,7 @@ struct condmsg conf82424zx[] =
|
||||
{ 0 }
|
||||
};
|
||||
|
||||
struct condmsg conf82434lx[] =
|
||||
static const struct condmsg conf82434lx[] =
|
||||
{
|
||||
{ 0x00, 0x00, 0x00, TRUE, "\tCPU: " },
|
||||
{ 0x50, 0xe3, 0x82, M_EQ, "Pentium, 60MHz" },
|
||||
@ -246,7 +251,8 @@ static char confread (pcici_t config_id, int port)
|
||||
return (l >> ports);
|
||||
}
|
||||
|
||||
static void writeconfig(pcici_t config_id, struct condmsg *tbl)
|
||||
static void
|
||||
writeconfig (pcici_t config_id, const struct condmsg *tbl)
|
||||
{
|
||||
while (tbl->text) {
|
||||
int cond = 0;
|
||||
@ -268,10 +274,13 @@ static void writeconfig(pcici_t config_id, struct condmsg *tbl)
|
||||
}
|
||||
}
|
||||
|
||||
void chipset_attach(pcici_t config_id, int unit)
|
||||
static void
|
||||
chipset_attach (pcici_t config_id, int unit)
|
||||
{
|
||||
if (bootverbose) {
|
||||
switch (pci_conf_read (config_id, 0)) {
|
||||
if (!bootverbose)
|
||||
return;
|
||||
|
||||
switch (pci_conf_read (config_id, PCI_ID_REG)) {
|
||||
|
||||
case 0x04838086:
|
||||
writeconfig (config_id, conf82424zx);
|
||||
@ -287,64 +296,23 @@ void chipset_attach(pcici_t config_id, int unit)
|
||||
pci_conf_read (config_id, 0x54));
|
||||
break;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------
|
||||
**
|
||||
** Catchall driver for pci-pci bridges.
|
||||
**
|
||||
**---------------------------------------------------------
|
||||
*/
|
||||
|
||||
static char* ppb_probe (pcici_t tag, pcidi_t type);
|
||||
static void ppb_attach(pcici_t tag, int unit);
|
||||
static u_long ppb_count;
|
||||
|
||||
struct pci_device ppb_device = {
|
||||
"ppb",
|
||||
ppb_probe,
|
||||
ppb_attach,
|
||||
&ppb_count,
|
||||
NULL
|
||||
};
|
||||
|
||||
DATA_SET (pcidevice_set, ppb_device);
|
||||
|
||||
static char* ppb_probe (pcici_t tag, pcidi_t type)
|
||||
{
|
||||
int data = pci_conf_read(tag, PCI_CLASS_REG);
|
||||
|
||||
if ((data & (PCI_CLASS_MASK|PCI_SUBCLASS_MASK)) ==
|
||||
(PCI_CLASS_BRIDGE|PCI_SUBCLASS_BRIDGE_PCI))
|
||||
return ("PCI-PCI bridge");
|
||||
return ((char*)0);
|
||||
}
|
||||
|
||||
static void ppb_attach(pcici_t tag, int unit)
|
||||
{
|
||||
/*
|
||||
** XXX should read bus number from device
|
||||
*/
|
||||
(void) pci_map_bus (tag, 1);
|
||||
}
|
||||
|
||||
/*---------------------------------------------------------
|
||||
**
|
||||
** Catchall driver for VGA devices
|
||||
**
|
||||
**
|
||||
** By Garrett Wollman
|
||||
** <wollman@halloran-eldar.lcs.mit.edu>
|
||||
**
|
||||
**---------------------------------------------------------
|
||||
*/
|
||||
|
||||
static char* vga_probe (pcici_t tag, pcidi_t type);
|
||||
static void vga_attach(pcici_t tag, int unit);
|
||||
static char* vga_probe (pcici_t tag, pcidi_t type);
|
||||
static void vga_attach (pcici_t tag, int unit);
|
||||
static u_long vga_count;
|
||||
|
||||
struct pci_device vga_device = {
|
||||
struct pci_device vga_device = {
|
||||
"vga",
|
||||
vga_probe,
|
||||
vga_attach,
|
||||
@ -354,7 +322,7 @@ struct pci_device vga_device = {
|
||||
|
||||
DATA_SET (pcidevice_set, vga_device);
|
||||
|
||||
static char* vga_probe (pcici_t tag, pcidi_t type)
|
||||
static char* vga_probe (pcici_t tag, pcidi_t type)
|
||||
{
|
||||
int data = pci_conf_read(tag, PCI_CLASS_REG);
|
||||
|
||||
@ -375,11 +343,11 @@ static char* vga_probe (pcici_t tag, pcidi_t type)
|
||||
return ((char*)0);
|
||||
}
|
||||
|
||||
static void vga_attach(pcici_t tag, int unit)
|
||||
static void vga_attach (pcici_t tag, int unit)
|
||||
{
|
||||
/*
|
||||
** The assigned adresses may not be remapped,
|
||||
** because certain values are assumed by the console driver.
|
||||
** If the assigned addresses are remapped,
|
||||
** the console driver has to be informed about the new address.
|
||||
*/
|
||||
#if 0
|
||||
vm_offset_t va;
|
||||
@ -389,7 +357,7 @@ static void vga_attach(pcici_t tag, int unit)
|
||||
(void) pci_map_mem (tag, reg, &va, &pa);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
/*---------------------------------------------------------
|
||||
**
|
||||
** Hook for loadable pci drivers
|
||||
@ -397,11 +365,11 @@ static void vga_attach(pcici_t tag, int unit)
|
||||
**---------------------------------------------------------
|
||||
*/
|
||||
|
||||
static char* lkm_probe (pcici_t tag, pcidi_t type);
|
||||
static void lkm_attach(pcici_t tag, int unit);
|
||||
static char* lkm_probe (pcici_t tag, pcidi_t type);
|
||||
static void lkm_attach (pcici_t tag, int unit);
|
||||
static u_long lkm_count;
|
||||
|
||||
struct pci_device lkm_device = {
|
||||
struct pci_device lkm_device = {
|
||||
"lkm",
|
||||
lkm_probe,
|
||||
lkm_attach,
|
||||
@ -411,19 +379,20 @@ struct pci_device lkm_device = {
|
||||
|
||||
DATA_SET (pcidevice_set, lkm_device);
|
||||
|
||||
static char* lkm_probe (pcici_t tag, pcidi_t type)
|
||||
static char*
|
||||
lkm_probe (pcici_t tag, pcidi_t type)
|
||||
{
|
||||
/*
|
||||
** Should try to load a matching driver.
|
||||
** XXX Not yet!
|
||||
** Not yet!
|
||||
** (Should try to load a matching driver)
|
||||
*/
|
||||
return ((char*)0);
|
||||
}
|
||||
|
||||
static void lkm_attach(pcici_t tag, int unit)
|
||||
{
|
||||
}
|
||||
|
||||
static void
|
||||
lkm_attach (pcici_t tag, int unit)
|
||||
{}
|
||||
|
||||
/*---------------------------------------------------------
|
||||
**
|
||||
** Devices to ignore
|
||||
@ -431,11 +400,11 @@ static void lkm_attach(pcici_t tag, int unit)
|
||||
**---------------------------------------------------------
|
||||
*/
|
||||
|
||||
static char* ign_probe (pcici_t tag, pcidi_t type);
|
||||
static void ign_attach(pcici_t tag, int unit);
|
||||
static char* ign_probe (pcici_t tag, pcidi_t type);
|
||||
static void ign_attach (pcici_t tag, int unit);
|
||||
static u_long ign_count;
|
||||
|
||||
struct pci_device ign_device = {
|
||||
struct pci_device ign_device = {
|
||||
NULL,
|
||||
ign_probe,
|
||||
ign_attach,
|
||||
@ -445,17 +414,17 @@ struct pci_device ign_device = {
|
||||
|
||||
DATA_SET (pcidevice_set, ign_device);
|
||||
|
||||
static char* ign_probe (pcici_t tag, pcidi_t type)
|
||||
static char*
|
||||
ign_probe (pcici_t tag, pcidi_t type)
|
||||
{
|
||||
switch (type) {
|
||||
|
||||
case 0x10001042ul: /* wd */
|
||||
return ("");
|
||||
|
||||
};
|
||||
return ((char*)0);
|
||||
}
|
||||
|
||||
static void ign_attach(pcici_t tag, int unit)
|
||||
{
|
||||
}
|
||||
static void
|
||||
ign_attach (pcici_t tag, int unit)
|
||||
{}
|
||||
|
114
sys/pci/pcivar.h
114
sys/pci/pcivar.h
@ -1,10 +1,10 @@
|
||||
/**************************************************************************
|
||||
**
|
||||
** $Id: pcivar.h,v 1.2 1995/02/27 17:17:14 se Exp $
|
||||
** $Id: pcivar.h,v 1.3 1995/03/17 04:27:21 davidg Exp $
|
||||
**
|
||||
** Declarations for pci device drivers.
|
||||
**
|
||||
** 386bsd / FreeBSD
|
||||
** FreeBSD
|
||||
**
|
||||
**-------------------------------------------------------------------------
|
||||
**
|
||||
@ -36,10 +36,8 @@
|
||||
*/
|
||||
|
||||
#ifndef __PCI_VAR_H__
|
||||
#define __PCI_VAR_H__
|
||||
#define __PCI_VAR_H__ "pl2 95/03/21"
|
||||
|
||||
#define PCIVAR_H_PATCHLEVEL "pl1 95/02/27"
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** main pci initialization function.
|
||||
@ -60,13 +58,16 @@ void pci_configure (void);
|
||||
|
||||
typedef union {
|
||||
u_long cfg1;
|
||||
struct {
|
||||
struct {
|
||||
u_char enable;
|
||||
u_char forward;
|
||||
u_short port;
|
||||
} cfg2;
|
||||
unsigned tag;
|
||||
} pcici_t;
|
||||
|
||||
#define sametag(x,y) ((x).tag == (y).tag)
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** Each pci device has an unique device id.
|
||||
@ -98,7 +99,7 @@ typedef u_long pcidi_t;
|
||||
u_long pci_conf_read (pcici_t tag, u_long reg );
|
||||
|
||||
void pci_conf_write (pcici_t tag, u_long reg, u_long data);
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** The pci driver structure.
|
||||
@ -141,7 +142,11 @@ struct pci_device {
|
||||
*/
|
||||
|
||||
extern struct linker_set pcidevice_set;
|
||||
|
||||
|
||||
extern unsigned pci_max_burst_len; /* log2 of safe burst transfer length */
|
||||
extern unsigned pci_mechanism;
|
||||
extern unsigned pci_maxdevice;
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** The pci-devconf interface.
|
||||
@ -150,8 +155,8 @@ extern struct linker_set pcidevice_set;
|
||||
*/
|
||||
|
||||
struct pci_info {
|
||||
u_short pi_bus;
|
||||
u_short pi_device;
|
||||
u_short pi_bus;
|
||||
u_short pi_device;
|
||||
};
|
||||
|
||||
#define PCI_EXT_CONF_LEN (16)
|
||||
@ -162,31 +167,18 @@ struct pci_externalize_buffer {
|
||||
u_long peb_config[PCI_EXT_CONF_LEN];
|
||||
};
|
||||
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** Register an additional pci bus for probing.
|
||||
** Called by pci-pci bridge handlers.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int pci_map_bus (pcici_t tag, u_long bus);
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** Map a pci device to physical and virtual memory.
|
||||
**
|
||||
** The va and pa addresses are "in/out" parameters.
|
||||
** If they are 0 on entry, the function assigns an address.
|
||||
**
|
||||
** Entry selects the register in the pci configuration
|
||||
** Entry selects the register in the pci configuration
|
||||
** space, which supplies the size of the region, and
|
||||
** receives the physical address.
|
||||
**
|
||||
** If there is any error, a message is written, and
|
||||
** the function returns with zero.
|
||||
** Else it returns with a value different to zero.
|
||||
** In case of success the function sets the addresses
|
||||
** in *va and *pa, and returns 1.
|
||||
** In case of errors a message is written,
|
||||
** and the function returns 0.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
@ -197,59 +189,65 @@ int pci_map_mem (pcici_t tag, u_long entry, u_long * va, u_long * pa);
|
||||
**
|
||||
** Map a pci device to an io port area.
|
||||
**
|
||||
** *pa is an "in/out" parameter.
|
||||
** If it's 0 on entry, the function assigns an port number..
|
||||
**
|
||||
** Entry selects the register in the pci configuration
|
||||
** space, which supplies the size of the region, and
|
||||
** receives the port number.
|
||||
**
|
||||
** If there is any error, a message is written, and
|
||||
** the function returns with zero.
|
||||
** Else it returns with a value different to zero.
|
||||
** In case of success the function sets the port number in pa,
|
||||
** and returns 1.
|
||||
** In case of errors a message is written,
|
||||
** and the function returns 0.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
int pci_map_port(pcici_t tag, u_long entry, u_short * pa);
|
||||
|
||||
int pci_map_port (pcici_t tag, u_long entry, u_short * pa);
|
||||
|
||||
/*-----------------------------------------------------------------
|
||||
**
|
||||
** Map a pci interrupt to an isa irq line,
|
||||
** and enable the interrupt.
|
||||
** Map a pci interrupt to an isa irq line, and enable the interrupt.
|
||||
**
|
||||
** func is the interrupt handler, arg is the argument
|
||||
** to this function.
|
||||
** -----------------
|
||||
**
|
||||
** The maskptr argument should be &bio_imask,
|
||||
** &net_imask etc. or NULL.
|
||||
** func is the interrupt handler, arg is the argument
|
||||
** to the handler (usually a pointer to a softc).
|
||||
**
|
||||
** If there is any error, a message is written, and
|
||||
** the function returns with zero.
|
||||
** Else it returns with a value different to zero.
|
||||
** The maskptr argument should be &bio_imask,
|
||||
** &net_imask etc. or NULL.
|
||||
**
|
||||
** A word of caution for FreeBSD 2.0:
|
||||
** If there is any error, a message is written, and
|
||||
** the function returns with zero.
|
||||
** Else it returns with a value different to zero.
|
||||
**
|
||||
** We use the register_intr() function.
|
||||
** -----------------
|
||||
**
|
||||
** The interrupt line of the selected device is included
|
||||
** into the supplied mask: after the corresponding splXXX
|
||||
** this drivers interrupts are blocked.
|
||||
** The irq number is read from the configuration space.
|
||||
** (Should have been set by the bios).
|
||||
**
|
||||
** But in the interrupt handlers startup code ONLY
|
||||
** the interrupt of the driver is blocked, and NOT
|
||||
** all interrupts of the spl group.
|
||||
** Supports multiple handlers per irq (shared interrupts).
|
||||
**
|
||||
** It may be required to additional block the group
|
||||
** interrupts by splXXX() inside the interrupt handler.
|
||||
** -----------------
|
||||
**
|
||||
** In pre 2.0 kernels we emulate the register_intr
|
||||
** function. The emulating function blocks all interrupts
|
||||
** of the group in the interrupt handler prefix code.
|
||||
** There is code to support shared edge triggered ints.
|
||||
** This relies on the cooperation of the interrupt handlers:
|
||||
** they have to return a value <>0 if and only if something
|
||||
** was done. Beware of the performance penalty.
|
||||
**
|
||||
**-----------------------------------------------------------------
|
||||
*/
|
||||
|
||||
struct pci_int_desc {
|
||||
struct pci_int_desc * pcid_next;
|
||||
pcici_t pcid_tag;
|
||||
int (*pcid_handler)();
|
||||
void* pcid_argument;
|
||||
unsigned * pcid_maskptr;
|
||||
unsigned pcid_tally;
|
||||
unsigned pcid_mask;
|
||||
};
|
||||
|
||||
int pci_map_int (pcici_t tag, int (*func)(), void* arg, unsigned * maskptr);
|
||||
|
||||
int pci_unmap_int (pcici_t tag);
|
||||
|
||||
#endif
|
||||
|
Loading…
x
Reference in New Issue
Block a user