diff options
author | Joel Sherrill <joel.sherrill@OARcorp.com> | 1999-02-18 16:48:14 +0000 |
---|---|---|
committer | Joel Sherrill <joel.sherrill@OARcorp.com> | 1999-02-18 16:48:14 +0000 |
commit | 0c04c377bc8ac177d28bd0e0096d7c6940d33cd4 (patch) | |
tree | ba3062eb819e89de2eee14397ffe61b202ad10de /c/src/lib/libbsp/powerpc/ppcn_60x/pci | |
parent | ./clock/Makefile.in,v (diff) | |
download | rtems-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.in | 56 | ||||
-rw-r--r-- | c/src/lib/libbsp/powerpc/ppcn_60x/pci/pci.c | 342 |
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); +} |