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.
******************************************************************************/
#include <windows.h>
// #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 <ASPEN.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 + -
显示快捷键?