summaryrefslogtreecommitdiffstats
path: root/c/src/lib/libbsp/powerpc/ppcn_60x/pci
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>1999-02-18 16:48:14 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>1999-02-18 16:48:14 +0000
commit0c04c377bc8ac177d28bd0e0096d7c6940d33cd4 (patch)
treeba3062eb819e89de2eee14397ffe61b202ad10de /c/src/lib/libbsp/powerpc/ppcn_60x/pci
parent./clock/Makefile.in,v (diff)
downloadrtems-0c04c377bc8ac177d28bd0e0096d7c6940d33cd4.tar.bz2
./clock/Makefile.in,v
./clock/clock.c,v ./console/Makefile.in,v ./console/config.c,v ./console/console.c,v ./console/console.h,v ./console/debugio.c,v ./console/i8042.c,v ./console/i8042_p.h,v ./console/i8042vga.c,v ./console/i8042vga.h,v ./console/ns16550.c,v ./console/ns16550.h,v ./console/ns16550_p.h,v ./console/ns16550cfg.c,v ./console/ns16550cfg.h,v ./console/vga.c,v ./console/vga_p.h,v ./console/z85c30.c,v ./console/z85c30.h,v ./console/z85c30_p.h,v ./console/z85c30cfg.c,v ./console/z85c30cfg.h,v ./include/Makefile.in,v ./include/bsp.h,v ./include/chain.h,v ./include/coverhd.h,v ./include/extisrdrv.h,v ./include/nvram.h,v ./include/pci.h,v ./include/tod.h,v ./network/Makefile.in,v ./network/amd79c970.c,v ./network/amd79c970.h,v ./nvram/Makefile.in,v ./nvram/ds1385.h,v ./nvram/mk48t18.h,v ./nvram/nvram.c,v ./nvram/prepnvr.h,v ./nvram/stk11c68.h,v ./pci/Makefile.in,v ./pci/pci.c,v ./start/Makefile.in,v ./start/start.s,v ./startup/Makefile.in,v ./startup/bspclean.c,v ./startup/bspstart.c,v ./startup/bsptrap.s,v ./startup/device-tree,v ./startup/genpvec.c,v ./startup/linkcmds,v ./startup/rtems-ctor.cc,v ./startup/sbrk.c,v ./startup/setvec.c,v ./startup/spurious.c,v ./startup/swap.c,v ./timer/Makefile.in,v ./timer/timer.c,v ./tod/Makefile.in,v ./tod/cmos.h,v ./tod/tod.c,v ./universe/Makefile.in,v ./universe/universe.c,v ./vectors/Makefile.in,v ./vectors/README,v ./vectors/align_h.s,v ./vectors/vectors.s,v ./wrapup/Makefile.in,v ./Makefile.in,v ./README,v ./STATUS,v ./bsp_specs,v
Diffstat (limited to 'c/src/lib/libbsp/powerpc/ppcn_60x/pci')
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in56
-rw-r--r--c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c342
2 files changed, 398 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in b/c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in
new file mode 100644
index 0000000000..941fc1ada7
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/pci/Makefile.in
@@ -0,0 +1,56 @@
+#
+# $Id$
+#
+
+@SET_MAKE@
+srcdir = @srcdir@
+VPATH = @srcdir@
+RTEMS_ROOT = @top_srcdir@
+PROJECT_ROOT = @PROJECT_ROOT@
+
+PGM=${ARCH}/pci.rel
+
+# C source names, if any, go here -- minus the .c
+C_PIECES=$(PCI_PIECES)
+C_FILES=$(C_PIECES:%=%.c)
+C_O_FILES=$(C_PIECES:%=${ARCH}/%.o)
+
+H_FILES=
+
+SRCS=$(C_FILES) $(H_FILES)
+OBJS=$(C_O_FILES)
+
+include $(RTEMS_ROOT)/make/custom/$(RTEMS_BSP).cfg
+include $(RTEMS_ROOT)/make/leaf.cfg
+
+PCI_PIECES=pci
+
+#
+# (OPTIONAL) Add local stuff here using +=
+#
+
+DEFINES +=
+CPPFLAGS +=
+CFLAGS +=
+
+LD_PATHS +=
+LD_LIBS +=
+LDFLAGS +=
+
+#
+# Add your list of files to delete here. The config files
+# already know how to delete some stuff, so you may want
+# to just run 'make clean' first to see what gets missed.
+# 'make clobber' already includes 'make clean'
+#
+
+CLEAN_ADDITIONS +=
+CLOBBER_ADDITIONS +=
+
+${PGM}: ${SRCS} ${OBJS}
+ $(make-rel)
+
+all: ${ARCH} $(SRCS) $(PGM)
+
+# the .rel file built here will be put into libbsp.a by ../wrapup/Makefile
+install: all
diff --git a/c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c b/c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c
new file mode 100644
index 0000000000..909a568d55
--- /dev/null
+++ b/c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c
@@ -0,0 +1,342 @@
+/*
+ * COPYRIGHT (c) 1998 by Radstone Technology
+ *
+ *
+ * THIS FILE IS PROVIDED TO YOU, THE USER, "AS IS", WITHOUT WARRANTY OF ANY
+ * KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTY OF FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK
+ * AS TO THE QUALITY AND PERFORMANCE OF ALL CODE IN THIS FILE IS WITH YOU.
+ *
+ * You are hereby granted permission to use, copy, modify, and distribute
+ * this file, provided that this notice, plus the above copyright notice
+ * and disclaimer, appears in all copies. Radstone Technology will provide
+ * no support for this code.
+ *
+ */
+#include <bsp.h>
+#include <pci.h>
+
+/* SCE 97/4/9
+ *
+ * Use PCI configuration space access mechanism 1
+ *
+ * This is the preferred access mechanism and must be used when accessing
+ * bridged PCI busses.
+ *
+ * The address to be written to the PCI_CONFIG_ADDRESS port is constructed
+ * thus (the representation below is little endian):
+ *
+ * 31 30 24 23 16 15 11 10 8 7 2 1 0
+ * ----------------------------------------------------------------------
+ * | 1 | Resvd | Bus Number | Dev Number | Fn Number | Reg Number | 0 | 0 |
+ * ----------------------------------------------------------------------
+ *
+ * On bus 0, the first 'real' device is at Device number 11, the Eagle being
+ * device 0. On all other busses, device numbering starts at 0.
+ */
+/*
+ * Normal PCI device numbering on busses other than 0 is such that
+ * that the first device (0) is attached to AD16, second (1) to AD17 etc.
+ */
+#define CONFIG_ADDRESS(Bus, Device, Function, Offset) \
+ (0x80000000 | (Bus<<16) | \
+ ((Device+(((Bus==0)&&(Device>0)) ? 10 : 0))<<11) | \
+ (Function<<8) | \
+ (Offset&~0x03))
+#define BYTE_LANE_OFFSET(Offset) ((Offset)&0x3)
+
+/*
+ * Private data
+ */
+static unsigned8 ucMaxPCIBus;
+
+/*
+ * Public routines
+ */
+rtems_status_code PCIConfigWrite8(
+ unsigned8 ucBusNumber,
+ unsigned8 ucSlotNumber,
+ unsigned8 ucFunctionNumber,
+ unsigned8 ucOffset,
+ unsigned8 ucValue
+)
+{
+ ISR_Level Irql;
+
+ /*
+ * Ensure that accesses to the addr/data ports are indivisible
+ */
+ _ISR_Disable(Irql);
+
+ /*
+ * Write to the configuration space address register
+ */
+ outport_32(PCI_CONFIG_ADDR,
+ CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
+ ucFunctionNumber, ucOffset));
+ /*
+ * Write to the configuration space data register with the appropriate
+ * offset
+ */
+ outport_byte(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), ucValue);
+
+ _ISR_Enable(Irql);
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+rtems_status_code PCIConfigWrite16(
+ unsigned8 ucBusNumber,
+ unsigned8 ucSlotNumber,
+ unsigned8 ucFunctionNumber,
+ unsigned8 ucOffset,
+ unsigned16 usValue
+)
+{
+ ISR_Level Irql;
+
+ /*
+ * Ensure that accesses to the addr/data ports are indivisible
+ */
+ _ISR_Disable(Irql);
+
+ /*
+ * Write to the configuration space address register
+ */
+ outport_32(PCI_CONFIG_ADDR,
+ CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
+ ucFunctionNumber, ucOffset));
+ /*
+ * Write to the configuration space data register with the appropriate
+ * offset
+ */
+ outport_16(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), usValue);
+
+ _ISR_Enable(Irql);
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+rtems_status_code PCIConfigWrite32(
+ unsigned8 ucBusNumber,
+ unsigned8 ucSlotNumber,
+ unsigned8 ucFunctionNumber,
+ unsigned8 ucOffset,
+ unsigned32 ulValue
+)
+{
+ ISR_Level Irql;
+
+ /*
+ * Ensure that accesses to the addr/data ports are indivisible
+ */
+ _ISR_Disable(Irql);
+
+ /*
+ * Write to the configuration space address register
+ */
+ outport_32(PCI_CONFIG_ADDR,
+ CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
+ ucFunctionNumber, ucOffset));
+ /*
+ * Write to the configuration space data register with the appropriate
+ * offset
+ */
+ outport_32(PCI_CONFIG_DATA, ulValue);
+
+ _ISR_Enable(Irql);
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+rtems_status_code PCIConfigRead8(
+ unsigned8 ucBusNumber,
+ unsigned8 ucSlotNumber,
+ unsigned8 ucFunctionNumber,
+ unsigned8 ucOffset,
+ unsigned8 *pucValue
+)
+{
+ ISR_Level Irql;
+
+ /*
+ * Ensure that accesses to the addr/data ports are indivisible
+ */
+ _ISR_Disable(Irql);
+
+ /*
+ * Write to the configuration space address register
+ */
+ outport_32(PCI_CONFIG_ADDR,
+ CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
+ ucFunctionNumber, ucOffset));
+ /*
+ * Read from the configuration space data register with the appropriate
+ * offset
+ */
+ inport_byte(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), *pucValue);
+
+ _ISR_Enable(Irql);
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+rtems_status_code PCIConfigRead16(
+ unsigned8 ucBusNumber,
+ unsigned8 ucSlotNumber,
+ unsigned8 ucFunctionNumber,
+ unsigned8 ucOffset,
+ unsigned16 *pusValue
+)
+{
+ ISR_Level Irql;
+
+ /*
+ * Ensure that accesses to the addr/data ports are indivisible
+ */
+ _ISR_Disable(Irql);
+
+ /*
+ * Write to the configuration space address register
+ */
+ outport_32(PCI_CONFIG_ADDR,
+ CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
+ ucFunctionNumber, ucOffset));
+ /*
+ * Read from the configuration space data register with the appropriate
+ * offset
+ */
+ inport_16(PCI_CONFIG_DATA+BYTE_LANE_OFFSET(ucOffset), *pusValue);
+
+ _ISR_Enable(Irql);
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+rtems_status_code PCIConfigRead32(
+ unsigned8 ucBusNumber,
+ unsigned8 ucSlotNumber,
+ unsigned8 ucFunctionNumber,
+ unsigned8 ucOffset,
+ unsigned32 *pulValue
+)
+{
+ ISR_Level Irql;
+
+ /*
+ * Ensure that accesses to the addr/data ports are indivisible
+ */
+ _ISR_Disable(Irql);
+
+ /*
+ * Write to the configuration space address register
+ */
+ outport_32(PCI_CONFIG_ADDR,
+ CONFIG_ADDRESS(ucBusNumber, ucSlotNumber,
+ ucFunctionNumber, ucOffset));
+ /*
+ * Read from the configuration space data register with the appropriate
+ * offset
+ */
+ inport_32(PCI_CONFIG_DATA, *pulValue);
+
+ _ISR_Enable(Irql);
+
+ return(RTEMS_SUCCESSFUL);
+}
+
+/*
+ * This routine determines the maximum bus number in the system
+ */
+void InitializePCI()
+{
+ unsigned8 ucSlotNumber, ucFnNumber, ucNumFuncs;
+ unsigned8 ucHeader;
+ unsigned8 ucBaseClass, ucSubClass, ucMaxSubordinate;
+ unsigned32 ulDeviceID;
+
+ /*
+ * Scan PCI bus 0 looking for PCI-PCI bridges
+ */
+ for(ucSlotNumber=0;ucSlotNumber<PCI_MAX_DEVICES;ucSlotNumber++)
+ {
+ (void)PCIConfigRead32(0,
+ ucSlotNumber,
+ 0,
+ PCI_CONFIG_VENDOR_LOW,
+ &ulDeviceID);
+ if(ulDeviceID==PCI_INVALID_VENDORDEVICEID)
+ {
+ /*
+ * This slot is empty
+ */
+ continue;
+ }
+ (void)PCIConfigRead8(0,
+ ucSlotNumber,
+ 0,
+ PCI_CONFIG_HEADER_TYPE,
+ &ucHeader);
+ if(ucHeader&PCI_MULTI_FUNCTION)
+ {
+ ucNumFuncs=PCI_MAX_FUNCTIONS;
+ }
+ else
+ {
+ ucNumFuncs=1;
+ }
+ for(ucFnNumber=0;ucFnNumber<ucNumFuncs;ucFnNumber++)
+ {
+ (void)PCIConfigRead32(0,
+ ucSlotNumber,
+ ucFnNumber,
+ PCI_CONFIG_VENDOR_LOW,
+ &ulDeviceID);
+ if(ulDeviceID==PCI_INVALID_VENDORDEVICEID)
+ {
+ /*
+ * This slot/function is empty
+ */
+ continue;
+ }
+
+ /*
+ * This slot/function has a device fitted.
+ */
+ (void)PCIConfigRead8(0,
+ ucSlotNumber,
+ ucFnNumber,
+ PCI_CONFIG_CLASS_CODE_U,
+ &ucBaseClass);
+ (void)PCIConfigRead8(0,
+ ucSlotNumber,
+ ucFnNumber,
+ PCI_CONFIG_CLASS_CODE_M,
+ &ucSubClass);
+ if((ucBaseClass==PCI_BASE_CLASS_BRIDGE) &&
+ (ucSubClass==PCI_SUB_CLASS_BRIDGE_PCI))
+ {
+ /*
+ * We have found a PCI-PCI bridge
+ */
+ (void)PCIConfigRead8(0,
+ ucSlotNumber,
+ ucFnNumber,
+ PCI_BRIDGE_SUBORDINATE_BUS,
+ &ucMaxSubordinate);
+ if(ucMaxSubordinate>ucMaxPCIBus)
+ {
+ ucMaxPCIBus=ucMaxSubordinate;
+ }
+ }
+ }
+ }
+}
+
+/*
+ * Return the number of PCI busses in the system
+ */
+unsigned8 BusCountPCI()
+{
+ return(ucMaxPCIBus+1);
+}