pci_enum.c

来自「WinCE 3.0 BSP, 包含Inter SA1110, Intel_815」· C语言 代码 · 共 796 行 · 第 1/3 页

C
796
字号
/***************************************************************************** 
 * File:        	pci.c
 * Author:      	Naresh Gupta (nkgupta@hotmail.com)
 * Organization:	Hitachi Microsystems Inc.
 * Date:        	July 10, 1998
 * Purpose:     	This file contains the code for the pci enumerator.
 ******************************************************************************/


/***************************************************************************** 
 * If you want to run the code on CMON, uncomment the following line. 
******************************************************************************/
// #define CMON  					// Wanna run the code on CMON ?

/****************************************************************************** 
 * If you are using GCC to compile the code, instead of WINCE EDK, uncomment 
 * the following line. Also if you define GCC, you are also Required to define 
 * CMON.
******************************************************************************/
// #define GCC						// If GCC is the compiler.
#ifdef GCC
#	define CMON
#endif


/* The following were introduced to remove linker errors */
#ifndef SDBTESTS
int glbl_wait = 1000;
void Command_Scan(void) {}
void DbgPrintf(void) {}
void ProcessCommands(void) {}
#endif SDBTESTS


/******************************************************************************
 * This enables some macros useful while testing. Disable it in the release
 * version.
 *****************************************************************************/
#define TEST_PCI

#ifndef M1						// Presently this code is only for M1.
#	define 	M1 					// Tells whether i'm running on x86 or SH3.
#endif

#ifdef SDBTESTS
#include "StandAlone.h"
#else
#if (defined CMON)
#	define DWORD 			unsigned long
#	define WORD  			unsigned short
#	define PBYTE 			unsigned char *
#	define UCHAR 			unsigned char
#	define ULONG 			unsigned long
#	define USHORT			unsigned short
#	define PUCHAR 			unsigned char *
#	define PULONG 			unsigned long *
#	define PUSHORT			unsigned short *
#	define VOID				void
#	define INT32 			long
#	define NULL  			0
#	define FALSE			0
#	define TRUE				1
#	undef TEXT
#	define TEXT(x) 			x
#	define WCHAR				char
#	define WCR2 			0xffffff66
#	define DEBUGMSG(x,y) 	OutputFormatString y
	extern void 			OutputFormatString();
#	define BOOL  			unsigned char
#else
#	include <windows.h>
#endif
#endif

#include < platform.H>

#include <my_pci.h>
#ifndef SDBTESTS
#include <nkintr.h>
#endif SDBTESTS
#include <oalintr.h>

// Levels of Debugging. 
#define LEVEL1	1
#define LEVEL5	1

// The value 64 Mb.
#define MB_64		(64*1024*1024)
#define MB_16		(16*1024*1024)
#define MB_4		(4*1024*1024)
/* 
 * Note:- For PCI Io accesses. All long accesses must be done at 0xb8800000, 
 * short at 0xb8400000, and byte at 0xb8000000.
 * The PCI driver does not do any PCI IO accesses. It reads and writes only
 * the configuration address space. So the following macros have been modified
 * to do all accesses at b8000000.
 */
#define ASLONG(ADDR)		ADDR	// ((ULONG)ADDR | 0x00800000)
#define ASSHORT(ADDR)		ADDR	// ((ULONG)ADDR | 0x00400000)
#define ASCHAR(ADDR)		ADDR	// ((ULONG)ADDR | 0x00000000)

#define NO_PCI_SLOTS		21			// No of PCI slots.

// Align must be a power of two, which it is for PCI Base Addresses.
#define ALIGN(val, align)	(((val) + ((align) - 1)) & ~((align) - 1))

// Define PCI_DRIVER_ALLOCATES_PCI_MEM if you want the PCI driver to map the physical
// PCI memory address space to virtual addresses and return them to the
// calling driver.
// This would not be defined in the final version because it leads to
// wastage of virtual address space.
// #define PCI_DRIVER_ALLOCATES_PCI_MEM

/****************************************************************************
 * The S3 card requests for 64 Mb memory space and the IGS card requests for
 * 16 Mb memory space. The PCI driver must make sure that it allocates all
 * the memory to the display driver starting from location zero. To all other
 * drivers, it can allocate memory above 64 Mb. This is because of the following
 * reason :-

 * The PCI memory addresses have been allocated 16 MB of SH3 address space 
 * starting at PCI_PHYSICAL_MEM. The PCI_CONTROL_REG is used to map 16 Mb chunks
 * of PCI memory space into the sh3 address space.
 * For eg. If the control register is 0, then if you access 0xb9000004, the
 * address 0x4 is generated on the pci bus.
 *  If the contorol register is 4, then if you access 0xb9000004, the address
 *  0x04000004 is generated on the PCI bus.

  * So using this multiplexing technique you can access 256*16 Mb (4GB) of 
  * PCI memory address space. Please refer to the M1 Hardware reference section 
  * for details.

 * The display driver, while initializing, gives the address of the linear frame
 * buffer to the GWE. After that it has no control over the reads and writes in the
 * PCI memory space. So it is not possible to do a write to the PCI contorl register
 * before any read/write. Thus the Display driver should not pass more than first 
 * 16 MB of memory as linear frame buffer to the GWE.

 * Other drivers, like the 1394 driver which require PCI memory space can be allocated
 * space starting at let's say 64 Mb. These drivers can find out the base address
 * allocated to them by looking at the BaseAddressRegister field of the pcidev 
 * structure. So if the base address field of the pcidev structure has 0x04000000
 * then the 1394 driver would have to do the following :-

 *   1. Split up the address 0x04000000 into two parts, the upper byte and the lower
 *      3 bytes. The upper byte would be written to the control register and the
 *      lower 3 bytes would then be used to generate an address in the pci space.

 *   2. Virtual copy memory starting at PHYSICAL_PCI_MEM.
 *   3. Before performing any access in the pci memory address space, write a 4
 *      (upper byte of the Base Register) to the control register
 *   4. Perform the read/write
 *   5. Write a 0 to the PCI control register.
 ******************************************************************************/


// Reserve the lowest DISPLAY_MEM_SIZE in PCI Memory Address space for the
// display driver. If  your platform does not have a display card, then
// you can comment out the line below. If this line is commented, then other
// cards, which request for PCI Memory space, would be allocated memory starting
// from address 0.
#define RESERVE_DISPLAY_MEM

#ifdef RESERVE_DISPLAY_MEM
//   Reserve first 64 Mb in memory space for the display device.
//   This will take care of both S3Trio64 and IGS cards and any other display 
//   cards which access upto 64 Mb. If you plan to use a display card that
//   requests more than 64  Mb, change this.
#	define DISPLAY_MEM_SIZE		MB_64			// 64 Mb.
#	define DISPLAY_MEM_BASE		0x0				// Starting from 0.
#else
//    Do not reserve space for the display driver.
#	define DISPLAY_MEM_SIZE		0			// 64 Mb.
#	define DISPLAY_MEM_BASE		0x0			// Starting from 0.
#endif

// Start allocating PCI resources from the following.
// IOBASE is an arbitrary number in the PCI IO address space. This value
// was chosen so that none of the addresses allocated clash with the 
// display card which always uses addresses 3d? and 3c?.
#define IOBASE				0x400
#define MEMBASE				(DISPLAY_MEM_SIZE + DISPLAY_MEM_BASE)
#define INTBASE				0x9				// Starting Interrupt number

#define MAX_IO_ADDRESS		0x10000			// Max IO Address a PCI device can access. 64k

// Max memory that the device can request. It may not get all of it.
// This is just to put an upper limit on the amount of memory requested by the device.
// If some device requests for more than the, the driver would fail and you need to
// increase these limits. Currently the max space a device can request and be allocated
// is 64 Mb.
#define MAX_MEM_REQUEST		MB_64			// 64 Mb
// PCI specifications restrict a device to request at max 256 bytes of IO space per
// BaseAddressRegister. We assign 0x100 bytes to any BaseAddressRegister that asks
// for Io Address space.
#define MAX_IO_REQUEST		0x100			// 256 bytes.
#define MAX_IO_ALLOCATE		MAX_IO_REQUEST

// Values to be written to command register.
#define COMMAND_MEM			0x2
#define COMMAND_IO			0x1

#define PCI_MEM_SIZE		MB_4			// Map only 4 Mb.

#define DEFAULT_LATENCY		32				// Value to program in LATENCY_TIMER
#define DEFAULT_STATUS		0xffff

// PCI Configuration Space registers.
#define COMMAND_REGISTER	0x04
#define STATUS_REGISTER		0x06
#define BASE_CLASS_CODE		0x0b
#define LATENCY_TIMER		0x0d
#define HEADER_TYPE			0x0e
#define INTERRUPT_LINE		0x3c
#define INTERRUPT_PIN		0x3d


/*****************************************************************************
 *********** SHARED DATA SECTION VALUES **************************************
 *
 * Need for Shared Data Section :-
 * ----------------------------
 *   Enumeration should be done only once for all the pci devices present
 *   in the system. After that only Mapping of Virtual Address space,
 *   if need be, should be done.
 ****************************************************************************/

#pragma data_seg(".shared")

// What are the values you need to write to enable each of the slots.
// Actually the best way is to start from bit 2 and assert each of the
// bits to see whether a PCI card responds in that slot. But M1 has only
// 3 slots so that technique is not needed.
// Another reason for not implementing all possible Slot Enables is that
// in the current FPGA EPROMs if the card is not inserted it does not return 
// 0xFFFF.
unsigned SlotEnable[NO_PCI_SLOTS] = {	
										0x80000008,
										0x80000020,
										0x80000080
								    };

// Getting problem in initializing This data structure between Bootloader
// and Wince.
// At present i just define WCHAR to be char to remove this problem
#ifdef SDBTESTS
#undef WCHAR
#define WCHAR char
#endif SDBTESTS
// Class code (Byte 0x0b) gives the Base Class Code.
extern WCHAR *DeviceClass[15] = {	TEXT("Unknown Type"),
							TEXT("Mass Storage Controller"),
							TEXT("Network Controller"),
							TEXT("Display Controller"),
							TEXT("Multimedia Device"),
							TEXT("Memory Controller"),
							TEXT("Bridge Device"),
							TEXT("Simple Communications Controller"),
							TEXT("Base System Peripherals"),
							TEXT("Input Devices"),
							TEXT("Docking Stations"),
							TEXT("Processors"),
							TEXT("Serial Bus Controllers"),
							TEXT("Reserved"),				// 0x0d - 0xfe
							TEXT("Device does not fit in any defined classes") // 0xff
					    };

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?