📄 sysserialpci.c
字号:
/* sysSerialPci.c - Intel Architecture BSP network susbsystem support *//* Copyright 2001 Wind River Systems, Inc. *//*modification history--------------------01,09dec03,ann written. *//*DESCRIPTIONThis library contains BSP-specific routines for serial subsystems,including serial interface card device driver configuration andsupport routines. Generic serial interface drivers are not providedin source code form. As a result, this module does not #include theactual device drivers via the C-preprocessor.Note that the routines implemented in this file will not necessarilybe included in future versions of Wind River Systems' Intel ArchitectureBSPs.SEE ALSO:.pG "Configuration"*//* includes */#include <vxWorks.h>#include <sioLib.h>#include <iv.h>#include <intLib.h>#include "configInum.h"#include <drv\pci\pciConfigLib.h>#include <ttyLib.h>#include <tyLib.h>#include <assert.h>#include "p3544Sio.h"// extern UINT8 sysInumTbl[];#define NUM_PCI_TTY 4#define INCLUDE_PCI_SERIAL/*marco define */#define ADL_VENDOR_ID 0x144A#define ADL_DEVICE_ID 0x3544#define TYPE_UNKNOWN 7#define TYPE_PCI3538 0#define TYPE_PCI3544 1#define TYPE_P518 2#define TYPE_P514 3#define TYPE_P124 4#define TYPE_P220 5#define TYPE_P984 6/* forward declare */LOCAL UINT32 sysSerialDevToType(UINT32 vendorId,UINT32 deviceId,UINT8 revisionId );LOCAL STATUS syscPci3544SerialInit ( UINT32 pciBus, /* store a PCI bus number */ UINT32 pciDevice, /* store a PCI device number */ UINT32 pciFunc, /* store a PCI function number */ UINT32 vendorId, /* store a PCI vendor ID */ UINT32 deviceId, /* store a PCI device ID */ UINT8 revisionId /* store a PCI revision ID */ ); /* typedefs */typedef STATUS (* INIT_FUNCPTR) (UINT32, UINT32, UINT32, UINT32, UINT32, UINT8);typedef struct vendIdsDesc /* VEND_ID_DESC */ { UINT32 vendorId; /* PCI Vendor ID */ UINT32 deviceId; /* PCI Device ID */ INIT_FUNCPTR pPciInitRtn; /* associated pciInit() routine */ } VEND_ID_SDESC;/* locals *//* This table defines board PCI resources */LOCAL PCI_BOARD_RESOURCE s3544PciResources [NUM_PCI_TTY] = { {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, {NONE, NONE, NONE, NONE, NONE, NONE},NULL }, {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, {NONE, NONE, NONE, NONE, NONE, NONE},NULL }, {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, {NONE, NONE, NONE, NONE, NONE, NONE},NULL }, {NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, NONE, {NONE, NONE, NONE, NONE, NONE, NONE},NULL } };static p3544_CHAN P3544Chan[NUM_PCI_TTY];LOCAL UINT32 cPci3544Units = 0; /* number of FEIs we found *//* This table maps Serial PCI driver initialization routines to * the PCI Vendor IDs for supported (tested) device types. */LOCAL VEND_ID_SDESC vendorIdSerial [] = { #ifdef INCLUDE_PCI_SERIAL {ADL_VENDOR_ID, ADL_DEVICE_ID, syscPci3544SerialInit}, #endif /* INCLUDE_PCI3544_SERIAL */ {0xffffffff, 0xffffffff,NULL} /* last entry */ };#define PCI_UART_REG(reg,chan) (P3544Chan[chan].ioBase + reg) /********************************************************************************* sysSerialPciInit - initialize PCI Serial devices** This routine invokes the driver or BSP-specific PCI initialization routine* for a Serial Class, device specified by the <pciBus>,* <pciDevice>, and <pciFunc> parameters.** The interface is constructed such that this function can be invoked* via pciConfigForeachFunc(). Internally, this routine tests the 24-bit* PCI class code value (class/subclass/prog_if) to ensure that the* specified function is an ethernet controller.** INTERNAL* This callback will terminate pciConfigForeachFunc() if it returns ERROR.* So, this routine returns OK always such that a failure to config one* ethernet device will not prevent attempts to initialize other ethernet* devices.** RETURNS: OK always.** NOMANUAL*/STATUS sysSerialPciInit ( UINT32 pciBus, /* store a PCI bus number */ UINT32 pciDevice, /* store a PCI device number */ UINT32 pciFunc, /* store a PCI function number */ void * pArg /* reserved argument */ ) { UINT32 classCodeReg; /* store a 24-bit PCI class code */ UINT32 vendorId; /* store a PCI vendor ID */ UINT32 deviceId; /* store a PCI device ID */ UINT8 revisionId; /* store a PCI revision ID */ int i; /* index Vendor ID --> pciInit() table */ UINT32 pciClass; printf("sysSerialPciInit is entry!\n"); revisionId=0x02; /* get the PCI Vendor and Device IDs */ //pciConfigInLong (1, pciDevice, pciFunc, // PCI_CFG_VENDOR_ID, &vendorId); //printf("pciBus=%ld, pciDevice=%ld, PCI_CFG_VENDOR_ID=%ld",pciBus, pciDevice, PCI_CFG_VENDOR_ID); /* get the PCI Revision ID */ // pciConfigInByte (pciBus, pciDevice, pciFunc, // PCI_CFG_REVISION, &revisionId); /* test for driver support of the specified Ethernet function */ // deviceId = ((vendorId >> 16) & 0x0000ffff); // vendorId = (vendorId & 0x0000ffff); //printf("\n\ndeviceId=%x vendorId=%x \t\n\n",deviceId,vendorId); /* find & exec. a PCI initialization routine for the device */ for (i = 0; (vendorIdSerial[i].pPciInitRtn) != NULL; ++i) { if ((vendorId == vendorIdSerial[i].vendorId) && (deviceId == vendorIdSerial[i].deviceId) && (*(vendorIdSerial[i].pPciInitRtn)) (pciBus, pciDevice, pciFunc, vendorId, deviceId, revisionId) == OK) { /* initialized the device - move on */ printf("hao!\n"); return OK; } } return (OK);}/********************************************************************************* syscPci3544SerialInit - initialize a 3544 PCI serial device** This routine performs basic PCI initialization for Compact 3544 PCI serial * devices supported by the cPci3544 serial driver. If supported, the device* memory and I/O addresses are mapped into the local CPU address space* and an internal board-specific resource table is updated with information* on the board type, memory and I/O addresses.** CAVEATS* This routine must be called before the driver attempts to initialize itself* and the physical device via sys3544Init(). Also, this routine must be done* prior to MMU initialization, usrMmuInit().** The number of supported devices that can be configured for a particular* system is finite and is specified by the NUM_PCI_TTY configuration* constant.** RETURNS:* OK, else ERROR when the specified device is not supported, or if* the device could not be mapped into the local CPU memory space.*/STATUS syscPci3544SerialInit ( UINT32 pciBus, /* store a PCI bus number */ UINT32 pciDevice, /* store a PCI device number */ UINT32 pciFunc, /* store a PCI function number */ UINT32 vendorId, /* store a PCI vendor ID */ UINT32 deviceId, /* store a PCI device ID */ UINT8 revisionId /* store a PCI revision ID */ ) { UINT32 boardType; /* store a BSP-specific board type constant */ UINT32 subVendorId; /* store a sub PCI vendor ID */ UINT32 subSystemId; /* store a sub PCI system ID */ UINT32 ioBase; /* IO base address (BAR 2) */ UINT32 stusBase; /* status base (BAR 3) */ UINT8 irq; /* interrupt line number (IRQ) for device */ UINT ix,unit; /* number of physical units exceeded the number supported ? */ if (cPci3544Units * 4 >= NUM_PCI_TTY) { return (ERROR); } printf("pciBus=%d, pciDevice=%d, pciFunc=%s,PCI_CFG_BASE_ADDRESS_2=%x, &ioBase%x",pciBus, pciDevice, pciFunc,PCI_CFG_BASE_ADDRESS_2, &ioBase); pciConfigInLong(pciBus, pciDevice, pciFunc,PCI_CFG_BASE_ADDRESS_2, &ioBase); printf("****pciBus=%d, pciDevice=%d, pciFunc=%s,PCI_CFG_BASE_ADDRESS_2=%x, ioBase%x",pciBus, pciDevice, pciFunc,PCI_CFG_BASE_ADDRESS_2, ioBase); // if(ioBase == 0) //pciConfigInLong(pciBus, pciDevice, pciFunc,PCI_CFG_BASE_ADDRESS_0, &ioBase); //pciConfigInLong(pciBus, pciDevice, pciFunc,PCI_CFG_BASE_ADDRESS_3, &stusBase); //printf("PCI_CFG_BASE_ADDRESS_0,PCI_CFG_BASE_ADDRESS_3=%x",PCI_CFG_BASE_ADDRESS_0,PCI_CFG_BASE_ADDRESS_3); boardType = TYPE_PCI3544; ioBase &= PCI_IOBASE_MASK; stusBase &= PCI_IOBASE_MASK; /* read the IRQ number and vector and save to the resource table */ pciConfigInByte (pciBus, pciDevice, pciFunc, PCI_CFG_DEV_INT_LINE, &irq); /* update the board-specific resource table */ printf("cPci3544Units=%d\n",cPci3544Units); s3544PciResources[cPci3544Units].bar[0] = ioBase; s3544PciResources[cPci3544Units].bar[1] = stusBase; s3544PciResources[cPci3544Units].irq = irq; s3544PciResources[cPci3544Units].irqvec = 0x30/*INT_NUM_GET (irq)*/; s3544PciResources[cPci3544Units].vendorID = vendorId; s3544PciResources[cPci3544Units].deviceID = deviceId; s3544PciResources[cPci3544Units].revisionID = revisionId; s3544PciResources[cPci3544Units].boardType = boardType; /* the following support legacy interfaces and data structures */ s3544PciResources[cPci3544Units].pciBus = pciBus; s3544PciResources[cPci3544Units].pciDevice = pciDevice; s3544PciResources[cPci3544Units].pciFunc = pciFunc; printf("ioBase=%d\t stusBase=%d\t irq=%d \nvendorId=%d\t revisionId=%d\n",ioBase,stusBase,irq,vendorId,revisionId); /* enable mapped memory and IO decoders */ pciConfigOutWord (pciBus, pciDevice, pciFunc, PCI_CFG_COMMAND, PCI_CMD_MEM_ENABLE | PCI_CMD_IO_ENABLE | PCI_CMD_MASTER_ENABLE); /* disable sleep mode */ pciConfigOutByte (pciBus, pciDevice, pciFunc, PCI_CFG_MODE, SLEEP_MODE_DIS); unit = cPci3544Units; printf("unit=%d\n",unit); for (ix = 0; ix < 4; ix ++) { P3544Chan[unit*4 + ix].ioBase = ioBase + ix*8; P3544Chan[unit*4 + ix].channelMode = 0; P3544Chan[unit*4 + ix].lcr = PCI_UART_REG(p3544_UART_LCR, unit*4 + ix); P3544Chan[unit*4 + ix].lsr = PCI_UART_REG(p3544_UART_LSR, unit*4 + ix); P3544Chan[unit*4 + ix].mcr = PCI_UART_REG(p3544_UART_MCR, unit*4 + ix); P3544Chan[unit*4 + ix].msr = PCI_UART_REG(p3544_UART_MSR, unit*4 + ix); P3544Chan[unit*4 + ix].ier = PCI_UART_REG(p3544_UART_IER, unit*4 + ix); P3544Chan[unit*4 + ix].iir = PCI_UART_REG(p3544_UART_IIR, unit*4 + ix); P3544Chan[unit*4 + ix].scr = PCI_UART_REG(p3544_UART_SCR, unit*4 + ix); P3544Chan[unit*4 + ix].fcr = PCI_UART_REG(p3544_UART_FCR, unit*4 + ix); P3544Chan[unit*4 + ix].efr = PCI_UART_REG(p3544_UART_EFR, unit*4 + ix); P3544Chan[unit*4 + ix].dll = PCI_UART_REG(p3544_UART_DLL, unit*4 + ix); P3544Chan[unit*4 + ix].dlm = PCI_UART_REG(p3544_UART_DLM, unit*4 + ix); P3544Chan[unit*4 + ix].data = PCI_UART_REG(p3544_UART_DATA, unit*4 + ix); p3544HrdInit(&P3544Chan[unit*4 +ix]); } ++cPci3544Units; /* increment number of units initialized */ return (OK); }/******************************************************************************** sysSerialHwInit2 - connect BSP serial device interrupts** This routine connects the BSP serial device interrupts. It is called from* sysHwInit2(). * * Serial device interrupts cannot be connected in sysSerialHwInit() because* the kernel memory allocator is not initialized at that point, and* intConnect() calls malloc().** RETURNS: N/A** SEE ALSO: sysHwInit2()*/void sysPciSerialHwInit2 (void) { int i,rs; /* connect serial interrupts */ for (i = 0; i < cPci3544Units; i++) if (s3544PciResources[i].irqvec ) { //sucongna rs =pciIntConnect(INUM_TO_IVEC (s3544PciResources[i].irqvec) , rs =intConnect(INUM_TO_IVEC (0x30), p3544Int, (int)&P3544Chan[i*4] ); if (rs == ERROR) printf ("pciIntConnect ERR %d \n",i); rs = sysIntEnablePIC (s3544PciResources[i].irq ); if (rs == ERROR) printf ("sysIntEnablePIC ERR %d \n",i); } }/******************************************************************************** sysSerialChanGet - get the SIO_CHAN device associated with a serial channel** This routine gets the SIO_CHAN device associated with a specified serial* channel.** RETURNS: A pointer to the SIO_CHAN structure for the channel, or ERROR* if the channel is invalid.*/SIO_CHAN * sysPciSerialChanGet ( int channel /* serial channel */ ) { if ((channel >= 0) && (channel < NUM_PCI_TTY)) { return ((SIO_CHAN * ) &P3544Chan[channel]); } return ((SIO_CHAN *) ERROR); } /****************************************************** *CreateP3544 - create CPCI3544 serial port driver in system * * */int CreateP3544(){ int ix; char tyName [20]; printf("createp3544 is entry!\n"); pciConfigForeachFunc (1, TRUE, (PCI_FOREACH_FUNC) sysSerialPciInit,1,0xd,0x0); sysPciSerialHwInit2(); ttyDrv(); /* install console driver */ for (ix = 0; ix < NUM_PCI_TTY; ix++) /* create serial devices */ { sprintf (tyName, "%s%d", "/tyCo/", ix+3); (void) ttyDevCreate (tyName, sysPciSerialChanGet(ix), 512, 512); } return 0;}/* end */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -