www.pudn.com > Tornado2.2 for RTL8139Çý¶¯³ÌÐò.zip > sysLib.c
/* sysLib.c - PC [34]86/Pentium/Pentium[234] system-dependent library */ /* Copyright 1984-2002 Wind River Systems, Inc. */ #include "copyright_wrs.h" /* modification history -------------------- 05c,21jun02,pai Linker-definedsymbol is now cast to an unsigned integer instead of a signed integer where needed. Updated commentary and page-sized stride in sysPhysMemTop() memory auto-size algorithm (SPR 79525). 05b,12jul02,dmh include sysNvRam.c based value of NV_RAM_SIZE instead of IACSF 05a,11jul02,dmh remove SFL_START_ADDR for iacsfl-based BSPs. 04z,04jul02,hdn added the checksum to the FAST_REBOOT mechanism. 04y,18jun02,hdn cleaned up sysPhysMemDesc[] and new reboot mechanism. 04x,03jun02,pai Updated sysMmuMapAdd() documentation. Modified file I/O status messages in sysToMonitor(). 04w,05jun02,hdn added 2MB page size support for 36Bit MMU 04v,25may02,hdn updated sysMmuMapAdd to align VM_PAGE_SIZE (spr 77530) added intLock/Unlock in sysIntLock/Unlock (spr 75694) 04u,24may02,hdn replaced PAGE_SIZE with VM_PAGE_SIZE for 4MB page 04t,23may02,pai Add WindML device initialization to sysHwInit(). 04s,20may02,rhe added USB support for ohci cards. SPR# 76308 04r,09may02,hdn added Pentium4 Asymmetric Multi Processor configuration 04q,29apr02,pai Complete the fix for (SPR 8385). Modified sysPhysMemTop() will now auto-size a larger address space. 04p,28apr02,hdn added optional new i8259 PIC specific features (spr 76411) 04o,22apr02,pai Removed configuration related to obsolete SMC Ultra Netif driver. 04n,09apr02,pai Reworked ATA configuration and documentation (SPR# 73848). Added sysHwInit0() for the (SPR 74951) fix implementation. 04m,01apr02,jkf Added _WRS_BSP_DEBUG_NULL_ACCESS to generate exception when code accesses to lower page of memory, null ptr, occur. 04l,25mar02,pai Conditionally include MTRR table based upon PENTIUM2/3/4 CPU types - a modification to the version 04k implementation. 04k,22mar02,pai Do not include table for P5/PENTIUM builds (SPR# 73939). 04j,21mar02,pai Make pciConfigShow configurable based upon the INCLUDE_PCI_CFGSHOW component (SPR 74274). 04i,12mar02,hdn replaced redTable[] with sysInumTbl[] for HTT (spr 73738) 04h,07mar02,hdn excluded MTRR code from P5 (spr 73939) 04g,03dec01,jkf sysToMonitor: checks if device exists before creation, and using new macros for device and file name strings. 04f,27nov01,dmh move include of iacsfl.h from sysLib.c to config.h 04e,16nov01,ahm added power management mode initialization (SPR#32599) 04d,06nov01,hdn added PIRQ[n] and IOAPIC support for Pentium4 04c,02nov01,dmh add nvram for iacsfl boards. SPR# 70433 04b,01nov01,hdn added MSRs init, reset PM, enabled MCA w pentiumMcaEnable() 04a,01nov01,jln added support for gei82543End driver 03z,22oct01,dmh replace iPiix4 support with pciAutoConfig. SPR# 65192. 03y,17oct01,hdn removed duplicate sysMmuMapAdd() prototype. moved enabling MC exception into excArchLib. added LOCAL_MEM_AUTOSIZE in sysPhysMemTop(). made LOWER_MEM_TOP configurable to preserve the MP table. 03x,11oct01,pai Updating details related to BSP NIC driver support. Removed INCLUDE_EEX32 and INCLUDE_FEI definition conditional on DOC macro. Updated description of BSP driver config routines. Added PCI library customization and BSP-specific PCI support. Implemented new PCI Ethernet controller initialization (SPR# 35716) and (SPR# 69775). 03w,01oct01,hdn replaced INT_NUM_GET(LPT0_INT_LVL) with INT_NUM_LPT0 03v,26sep01,pai Added support for dec21x40End driver. Added sysLn97xEnd driver configuration file. Added WindML BSP routines. sysToMonitor() now opens bootrom.sys as RDONLY (SPR 23057). 03u,24sep01,pai Updated LPT resource table and macros (SPR 30067). 03t,11sep01,hdn renamed XXX_INT_VEC to INT_NUM_XXX as vector no of XXX updated sysIntEoiGet() as APIC's INT_LVL got cleaned up updated CPUID structure for PENTIUM4 removed sysCodeSelector. 03s,16aug01,hdn added PENTIUM2/3/4 support 03r,15aug01,hdn included iacsfl.h if INCLUDE_IACSFL is defined. 03q,15jun00,jkf release floppy disk on reboot(), SPR#30280 03p,15jun00,jkf sysPhysMemTop() loop changed to report all found memory. 03o,03may00,mks modified sysHwInit and sysToMonitor to support SFL based boot process. 03n,07sep99,stv macros for including END driver components are conditioned according to SPR# 26296. 03m,21apr99,hdn added conditional tffsDrv.h inclusion (SPR# 26922) 03l,12mar99,cn added support for el3c90xEnd driver (SPR# 25327). 03k,09mar99,sbs added support for ne2000End driver added support for ultraEnd driver added support for elt3c509End driver 03j,01feb99,jkf added END support for AMD 7997x PCI card. 03i,26jan99,jkf changed sysHwInit2 to use INCLUDE_ADD_BOOTMEM and removed ATA_MEM_DOSFS from sysToMonitor. SPR#21338 03h,31mar98,cn Added Enhanced Network Driver support. 03g,04jun98,hdn made sysIntLevel() faster. added sysIntCount[] for debug. 03f,28may98,hdn added support for APIC. 03e,12may98,hdn merged with pcPentium/sysLib.c. obsolete INCLUDE_IDE. 03d,23apr98,yp merged TrueFFS support. 03c,16apr98,hdn added sysCpuid[] for sysCpuProbe(). 03b,17mar98,sbs using macro for dummy mmu entry. added forward declaration for sysMmuMapAdd(). changed sysIntIdtType and sysWarmType to use macros. documentation update. 03a,12mar98,sbs moved PCI initialization from sysPhysMemTop() to sysHwInit(). changed the PCI library calls to the new updated library API. moved sys557PciInit() from sysPhysMemTop() to sysHwInit(). added sysAic7880PciInit(). 02z,02mar98,sbs removed device specific mmu entries and added dynamic entries in sysPhysMemDesc table. added sysMmuMapAdd(). added initialization of sysPhysMemDescNumEnt in sysHwInit(). 02y,06jan98,hdn included tffsDrv.h. 02x,15dec97,hdn added support for warm start from TFFS device. 02w,10jul97,dds added SCSI-2 support. 02v,24mar97,mas added sysPhysMemTop(); removed NOMANUAL from sysHwInit2(); parameterized the sysWarm* reboot variables (SPR 7806, 7850). 02u,03dec96,hdn added sys557PciInit(). moved PCI initialization from sysHwInit2() to sysMemTop(). 02t,22nov96,dat added sysNetif.c, for all network support rtns. (if_eex32.c and if_i82557 were combined into sysNetif.c) 02s,20nov96,db conditionally defined INCLUDE_EEX32 for man page(SPR #6190). 02r,20nov96,hdn added support for PRO100B. 02q,01nov96,hdn added support for PCMCIA. 02p,21oct96,hdn removed lptTimeout, added lptResources[]. 02o,14oct96,dat removed ref to i8253TimerTS.c, merged from windview102. 02n,24sep96,hdn fixed by removing IMPORT ATA_RESOURCE ataResources[]. 02m,03sep96,hdn added the compression support. changed constants to ROM_WARM_HIGH and ROM_WARM_LOW. 02l,09aug96,hdn renamed INT_VEC_IRQ0 to INT_NUM_IRQ0. 02k,26jul96,hdn shut off warning message: "implicit declaration of function" 02j,18jul96,hdn added support for INCLUDE_ATA. 02i,19jul96,wlf doc: cleanup. 02h,25jun96,hdn added support for TIMESTAMP timer. 02g,17jun96,hdn initialized sysProcessor to NONE 02f,14jun96,hdn added support for PCI bus. 02e,28may96,hdn renamed PIT_INT_xxx to PIT0_INT_xxx. 02d,28sep95,dat new BSP revision id 02c,27sep95,hdn fixed a typo by changing IO_ADRS_ULTRA to IO_ADRS_ELC. 02b,14jun95,hdn added a global variable sysCodeSelector. added a local function sysIntVecSetEnt(), sysIntVecSetExit(). renamed pSysEndOfInt to intEOI. moved global function declarations to sysLib.h. 02a,14jun95,myz moved serial configuration to sysSerial.c 01z,07jan95,hdn added an accurate memory size checking. 01y,31oct94,hdn changed sysMemTop() to find out a memory size. deleted sysGDT and used sysGdt in sysALib.s. added the Intel EtherExpress32 driver. deleted a conditional macro for INCLUDE_LPT. swapped 1st and 2nd parameter of fdDevCreate(). imported globals to timeout IDE and LPT. 01x,12oct94,hdn deleted sysBootType. added a conditional macro for INCLUDE_LPT. 01w,29may94,hdn moved sysCpuProbe() to cacheArchLib.c. added open and read bootrom.dat in sysToMonitor(). 01v,22apr94,hdn moved sysVectorIRQ0 from i8259Pic.c. made new globals sysFdBuf and sysFdBufSize. supported the warm start from the EPROM. 01u,06apr94,hdn added sysCpuProbe(). 01t,17feb94,hdn deleted memAddToPool() in sysHwInit2(). added a conditional statement in sysMemTop(). changed sysWarmType 0 to 1. 01s,03feb94,hdn added MMU conditional macro for the limit in the GDT. 01r,29nov93,hdn added sysBspRev () routine. 01q,22nov93,hdn added xxdetach () routine for warm start. 01p,16nov93,hdn added sysWarmType which controls warm start device. 01o,09nov93,hdn added warm start (control X). 01n,08nov93,vin added support pc console drivers. 01m,27oct93,hdn added memAddToPool stuff to sysHwInit2(). 01l,12oct93,hdn changed PIT_INT_VEC_NUM to PIT_INT_VEC. 01k,05sep93,hdn moved PIC related functions to intrCtl/i8259Pic.c. added sysDelay (). 01j,12aug93,hdn changed a global descriptor table sysGDT. deleted sysGDTSet. 01i,11aug93,hdn added a global sysVectorIRQ0. 01h,03aug93,hdn changed a mapping IRQ to Vector Table. 01g,26jul93,hdn added a memory descriptor table sysPhysMemDesc[]. 01f,25jun93,hdn changed sysToMonitor() to call sysReboot. 01e,24jun93,hdn changed the initialization of PIC. 01d,17jun93,hdn updated to 5.1. 01c,08apr93,jdi doc cleanup. 01d,07apr93,hdn renamed Compaq to PC. 01c,26mar93,hdn added the global descriptor table, memAddToPool. moved enabling A20 to romInit.s. added cacheClear for 486. 01b,18nov92,hdn supported nested interrupt. 01a,15may92,hdn written based on frc386 version. */ /* DESCRIPTION This library provides board-specific routines. The device configuration modules and device drivers included are: i8253Timer.c - Intel 8253 timer driver i8259Intr.c - Intel 8259 Programmable Interrupt Controller (PIC) library ioApicIntr.c - Intel IO APIC/xAPIC driver ioApicIntrShow.c - Intel IO APIC/xAPIC driver show routines iPiix4Pci.c - low level initalization code for PCI ISA/IDE Xcelerator loApicIntr.c - Intel Pentium[234] Local APIC/xAPIC driver loApicIntrShow.c - Intel Local APIC/xAPIC driver show routines loApicTimer.c - Intel Pentium2/3/4 Local APIC timer library nullNvRam.c - null NVRAM library nullVme.c - null VMEbus library pccardLib.c - PC CARD enabler library pccardShow.c - PC CARD show library pciCfgStub.c - customizes pciConfigLib for the BSP pciCfgIntStub.c - customizes pciIntLib for the BSP pciConfigLib.c - PCI configuration space access support for PCI drivers pciIntLib.c - PCI shared interrupt support pciConfigShow.c - Show routines for PCI configuration library sysDec21x40End.c - system configuration module for dec21x40End driver sysEl3c509End.c - system configuratin module for elt3c509End driver sysEl3c90xEnd.c - system configuration module for el3c90xEnd driver sysFei82557End.c - system configuration module for fei82557End driver sysGei82543End.c - system configuration module for gei82543End driver sysLn97xEnd.c - system configuration module for ln97xEnd driver sysNe2000End.c - system configuration module for ne2000End driver sysUltraEnd.c - system configuration module for SMC Elite ultraEnd driver sysWindML.c - WindML BSP support routines INCLUDE FILES: sysLib.h SEE ALSO: .pG "Configuration" */ /* includes (header file) */ #include "vxWorks.h" #include "vme.h" #include "memLib.h" #include "sysLib.h" #include "string.h" #include "intLib.h" #include "config.h" #include "logLib.h" #include "taskLib.h" #include "vxLib.h" #include "errnoLib.h" #include "dosFsLib.h" #include "stdio.h" #include "cacheLib.h" #include "private/vmLibP.h" #include "arch/i86/pentiumLib.h" #ifdef INCLUDE_TFFS # include "tffs/tffsDrv.h" #endif /* INCLUDE_TFFS */ #ifdef INCLUDE_SMCFDC37B78X # include "drv/multi/smcFdc37b78x.h" # ifndef PRJ_BUILD # include "multi/smcFdc37b78x.c" # endif /* PRJ_BUILD */ #endif /* INCLUDE_SMCFDC37B78X */ #if defined(INCLUDE_PC_CONSOLE) && defined(INCLUDE_CTB69000VGA) # ifndef PRJ_BUILD # include "video/ctB69000Vga.c" # endif /* PRJ_BUILD */ #endif /* INCLUDE_PC_CONSOLE && INCLUDE_CTB69000VGA */ /* defines */ #define ROM_SIGNATURE_SIZE 16 #if (VM_PAGE_SIZE == PAGE_SIZE_4KB) # if (LOCAL_MEM_LOCAL_ADRS >= 0x00100000) # define LOCAL_MEM_SIZE_OS 0x00180000 /* n * VM_PAGE_SIZE */ # else # define LOCAL_MEM_SIZE_OS 0x00080000 /* n * VM_PAGE_SIZE */ # endif /* (LOCAL_MEM_LOCAL_ADRS >= 0x00100000) */ #else /* VM_PAGE_SIZE is 2/4MB */ # define LOCAL_MEM_SIZE_OS VM_PAGE_SIZE /* n * VM_PAGE_SIZE */ #endif /* (VM_PAGE_SIZE == PAGE_SIZE_4KB) */ #if defined (TGT_CPU) && defined (BOOTCODE_IN_RAM) # ifndef FAST_REBOOT # define FAST_REBOOT /* fast reboot */ # endif #endif /* defined (TGT_CPU) && defined (BOOTCODE_IN_RAM) */ /* * IA-32 protected mode physical address space 4GB (2^32) and protected * mode physical address space extension 64GB (2^36) size constants. */ #define SIZE_ADDR_SPACE_32 (0x100000000ull) #define SIZE_ADDR_SPACE_36 (0x1000000000ull) /* maximum address space probed when using memory auto-sizing */ #define PHYS_MEM_MAX (SIZE_ADDR_SPACE_32) #define HALF(x) (((x) + 1) >> 1) /* sysPhysMemTop() memory test patterns */ #define TEST_PATTERN_A (0x57696E64) #define TEST_PATTERN_B (0x52697665) #define TEST_PATTERN_C (0x72537973) #define TEST_PATTERN_D (0x74656D73) /* imports */ IMPORT char end; /* linker defined end-of-image */ IMPORT GDT sysGdt[]; /* the global descriptor table */ IMPORT void elcdetach (int unit); IMPORT VOIDFUNCPTR intEoiGet; /* BOI/EOI function pointer */ IMPORT void intEnt (void); IMPORT int sysCpuProbe (void); /* set a type of CPU family */ IMPORT VOID sysUsbOhciPciInit (void); /* USB OHCI Init */ /* include rtl81x9End driver support routines */ #ifdef INCLUDE_RTL_81X9_END IMPORT STATUS sysRtl81x9PciInit (void); #endif /* INCLUDE_RTL_81X9_END */ /* include dm9102 End driver support routines */ #ifdef INCLUDE_DM_9102_END IMPORT STATUS sysDm9102PciInit (void); #endif /* INCLUDE_DM_9102_END */ /* globals */ PHYS_MEM_DESC sysPhysMemDesc [] = { /* adrs and length parameters must be page-aligned (multiples of 4KB/4MB) */ #if (VM_PAGE_SIZE == PAGE_SIZE_4KB) /* * Defining _WRS_BSP_DEBUG_NULL_ACCESS for debugging configuration. * Doing so explicitly marks some lower memory invalid. * Any code access to the invalid address range will generate * a MMU exception and the offending task will be suspended. * Then use l(), lkAddr, ti(), and tt() to find the NULL access. * Defining _WRS_BSP_DEBUG_NULL_ACCESS adds an entry to the front * of the sysPhysMemDesc[] array. Any code which alters this table * will need adjustment (for example: sysPhysMemTop() is altered * to account for another entry into the sysPhysMemDesc[] array * when _WRS_BSP_DEBUG_NULL_ACCESS is defined. */ /* lower memory for invalid access */ { (void *) 0x0, (void *) 0x0, _WRS_BSP_VM_PAGE_OFFSET, # ifdef _WRS_BSP_DEBUG_NULL_ACCESS VM_STATE_MASK_VALID | VM_STATE_MASK_WRITABLE | VM_STATE_MASK_CACHEABLE, VM_STATE_VALID_NOT | VM_STATE_WRITABLE_NOT | VM_STATE_CACHEABLE_NOT # else VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_OS # endif /* _WRS_BSP_DEBUG_NULL_ACCESS */ }, /* lower memory for valid access */ { (void *) _WRS_BSP_VM_PAGE_OFFSET, (void *) _WRS_BSP_VM_PAGE_OFFSET, 0xa0000 - _WRS_BSP_VM_PAGE_OFFSET, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_OS }, /* video ram, etc */ { (void *) 0x000a0000, (void *) 0x000a0000, 0x00060000, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_IO }, # if (LOCAL_MEM_LOCAL_ADRS >= 0x00100000) /* upper memory for OS */ { (void *) LOCAL_MEM_LOCAL_ADRS, (void *) LOCAL_MEM_LOCAL_ADRS, LOCAL_MEM_SIZE_OS, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_OS }, /* upper memory for Application */ { (void *) LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE_OS, (void *) LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE_OS, LOCAL_MEM_SIZE - LOCAL_MEM_SIZE_OS, /* it is changed in sysMemTop() */ VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_APPLICATION }, # else /* LOCAL_MEM_LOCAL_ADRS is 0x0 */ /* upper memory for OS */ { (void *) 0x00100000, (void *) 0x00100000, LOCAL_MEM_SIZE_OS, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_OS }, /* upper memory for Application */ { (void *) 0x00100000 + LOCAL_MEM_SIZE_OS, (void *) 0x00100000 + LOCAL_MEM_SIZE_OS, LOCAL_MEM_SIZE - (0x00100000 + LOCAL_MEM_SIZE_OS), /* sysMemTop() fix */ VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_APPLICATION }, # endif /* (LOCAL_MEM_LOCAL_ADRS >= 0x00100000) */ # if defined(INCLUDE_SM_NET) && (SM_MEM_ADRS != 0x0) /* upper memory for sm net/obj pool */ { (void *) SM_MEM_ADRS, (void *) SM_MEM_ADRS, SM_MEM_SIZE + SM_OBJ_MEM_SIZE, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_APPLICATION }, # endif /* defined(INCLUDE_SM_NET) && (SM_MEM_ADRS != 0x0) */ # ifdef INCLUDE_IACSFL { (void *) 0xFFF80000, (void *) 0xFFF80000, 0x00080000, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_APPLICATION }, # endif /* INCLUDE_IACSFL */ #else /* VM_PAGE_SIZE is 2/4MB */ /* 1st 2/4MB: lower mem + video ram etc + sm pool + upper mem */ { (void *) 0x0, (void *) 0x0, VM_PAGE_SIZE, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_OS }, # if (LOCAL_MEM_LOCAL_ADRS >= VM_PAGE_SIZE) /* 2nd 2/4MB: upper memory for OS */ { (void *) LOCAL_MEM_LOCAL_ADRS, (void *) LOCAL_MEM_LOCAL_ADRS, LOCAL_MEM_SIZE_OS, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_OS }, /* remaining 2/4MB pages: upper memory for Application */ { (void *) LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE_OS, (void *) LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE_OS, LOCAL_MEM_SIZE - LOCAL_MEM_SIZE_OS, /* it is changed in sysMemTop() */ VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_APPLICATION }, # else /* LOCAL_MEM_LOCAL_ADRS is 0x0 */ /* 2nd 2/4MB: upper memory for OS */ { (void *) VM_PAGE_SIZE, (void *) VM_PAGE_SIZE, LOCAL_MEM_SIZE_OS, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_OS }, /* remaining 2/4MB pages: upper memory for Application */ { (void *) VM_PAGE_SIZE + LOCAL_MEM_SIZE_OS, (void *) VM_PAGE_SIZE + LOCAL_MEM_SIZE_OS, LOCAL_MEM_SIZE - (VM_PAGE_SIZE + LOCAL_MEM_SIZE_OS), /* sysMemTop() fix */ VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_MEM_APPLICATION }, # endif /* (LOCAL_MEM_LOCAL_ADRS >= VM_PAGE_SIZE) */ #endif /* (VM_PAGE_SIZE == PAGE_SIZE_4KB) */ /* entries for dynamic mappings - create sufficient entries */ DUMMY_MMU_ENTRY, DUMMY_MMU_ENTRY, DUMMY_MMU_ENTRY, DUMMY_MMU_ENTRY, DUMMY_MMU_ENTRY, DUMMY_MMU_ENTRY, DUMMY_MMU_ENTRY, DUMMY_MMU_ENTRY, }; int sysPhysMemDescNumEnt; /* number Mmu entries to be mapped */ #ifdef INCLUDE_PC_CONSOLE PC_CON_DEV pcConDv [N_VIRTUAL_CONSOLES] = { {{{{NULL}}}, FALSE, NULL, NULL}, {{{{NULL}}}, FALSE, NULL, NULL} }; #endif /* INCLUDE_PC_CONSOLE */ #ifdef INCLUDE_FD IMPORT STATUS usrFdConfig (int type, int drive, char *fileName); FD_TYPE fdTypes[] = { {2880,18,2,80,2,0x1b,0x54,0x00,0x0c,0x0f,0x02,1,1,"1.44M"}, {2400,15,2,80,2,0x24,0x50,0x00,0x0d,0x0f,0x02,1,1,"1.2M"}, }; UINT sysFdBuf = FD_DMA_BUF_ADDR; /* floppy disk DMA buffer address */ UINT sysFdBufSize = FD_DMA_BUF_SIZE; /* floppy disk DMA buffer size */ #endif /* INCLUDE_FD */ #ifdef INCLUDE_ATA IMPORT STATUS usrAtaConfig (int ctrl, int drive, char *fileName); ATA_TYPE ataTypes[ATA_MAX_CTRLS][ATA_MAX_DRIVES] = { /* controller zero */ { /* ctrl 0 drive 0 */ { ATA_CTRL0_DRV0_CYL, /* Number of cylinders on device */ ATA_CTRL0_DRV0_HDS, /* Number of heads on device */ ATA_CTRL0_DRV0_SPT, /* Number of sectors per track on device */ ATA_CTRL0_DRV0_BPS, /* Number of bytes per sector on device */ ATA_CTRL0_DRV0_WPC /* write precompensation 0xff = dont use */ }, /* ctrl 0 drive 1 */ { ATA_CTRL0_DRV1_CYL, /* Number of cylinders on device */ ATA_CTRL0_DRV1_HDS, /* Number of heads on device */ ATA_CTRL0_DRV1_SPT, /* Number of sectors per track on device */ ATA_CTRL0_DRV1_BPS, /* Number of bytes per sector on device */ ATA_CTRL0_DRV1_WPC /* write precompensation 0xff = dont use */ }, }, /* controller one */ { /* ctrl 1 drive 0 */ { ATA_CTRL1_DRV0_CYL, /* Number of cylinders on device */ ATA_CTRL1_DRV0_HDS, /* Number of heads on device */ ATA_CTRL1_DRV0_SPT, /* Number of sectors per track on device */ ATA_CTRL1_DRV0_BPS, /* Number of bytes per sector on device */ ATA_CTRL1_DRV0_WPC /* write precompensation 0xff = dont use */ }, /* ctrl 1 drive 1 */ { ATA_CTRL1_DRV1_CYL, /* Number of cylinders on device */ ATA_CTRL1_DRV1_HDS, /* Number of heads on device */ ATA_CTRL1_DRV1_SPT, /* Number of sectors per track on device */ ATA_CTRL1_DRV1_BPS, /* Number of bytes per sector on device */ ATA_CTRL1_DRV1_WPC /* write precompensation 0xff = dont use */ } } }; ATA_RESOURCE ataResources[ATA_MAX_CTRLS] = { /* ATA controller zero resources */ { /* PCCARD_RESOURCE */ { ATA0_VCC, /* 3-5 volts Vcc */ ATA0_VPP, /* 5-12 volts Vpp */ { ATA0_IO_START0, /* start I/O address 0 */ ATA0_IO_START1 /* start I/O address 1 */ }, { ATA0_IO_STOP0, /* end I/0 address 0 */ ATA0_IO_STOP1 /* end I/0 address 1 */ }, ATA0_EXTRA_WAITS, /* extra wait states 0-2 */ ATA0_MEM_START, /* start host mem address */ ATA0_MEM_STOP, /* stop host mem address */ ATA0_MEM_WAITS, /* mem extra wait states 0-2 */ ATA0_MEM_OFFSET, /* mem offset of card address */ ATA0_MEM_LENGTH /* length of memory */ }, ATA0_CTRL_TYPE, /* IDE_LOCAL or ATA_PCMCIA */ ATA0_NUM_DRIVES, /* number of drives on controller */ INT_NUM_ATA0, /* interrupt number of controller */ ATA0_INT_LVL, /* interrupt level of controller */ ATA0_CONFIG, /* device configuration settings */ ATA0_SEM_TIMEOUT, /* semaphore timeout for controller */ ATA0_WDG_TIMEOUT, /* watchdog timeout for controller */ ATA0_SOCKET_TWIN, /* socket number for twin card */ ATA0_POWER_DOWN /* power down mode for this controller */ }, /* ctrl 0 end */ /* ATA controller one resources */ { /* PCCARD_RESOURCE */ { ATA1_VCC, /* 3-5 volts Vcc */ ATA1_VPP, /* 5-12 volts Vpp */ { ATA1_IO_START0, /* start I/O address 0 */ ATA1_IO_START1 /* start I/O address 1 */ }, { ATA1_IO_STOP0, /* end I/0 address 0 */ ATA1_IO_STOP1 /* end I/0 address 1 */ }, ATA1_EXTRA_WAITS, /* extra wait states 0-2 */ ATA1_MEM_START, /* start host mem address */ ATA1_MEM_STOP, /* stop host mem address */ ATA1_MEM_WAITS, /* mem extra wait states 0-2 */ ATA1_MEM_OFFSET, /* mem offset of card address */ ATA1_MEM_LENGTH /* length of memory */ }, ATA1_CTRL_TYPE, /* IDE_LOCAL or ATA_PCMCIA */ ATA1_NUM_DRIVES, /* number of drives on controller */ INT_NUM_ATA1, /* interrupt number of controller */ ATA1_INT_LVL, /* interrupt level of controller */ ATA1_CONFIG, /* device configuration settings */ ATA1_SEM_TIMEOUT, /* semaphore timeout for controller */ ATA1_WDG_TIMEOUT, /* watchdog timeout for controller */ ATA1_SOCKET_TWIN, /* socket number for twin card */ ATA1_POWER_DOWN /* power down mode for this controller */ } /* ctrl 1 end */ }; #endif /* INCLUDE_ATA */ #ifdef INCLUDE_LPT LPT_RESOURCE lptResources [N_LPT_CHANNELS] = { {LPT0_BASE_ADRS, INT_NUM_LPT0, LPT0_INT_LVL, TRUE, 10000, 10000, 1, 1, 0 }, {LPT1_BASE_ADRS, INT_NUM_LPT1, LPT1_INT_LVL, TRUE, 10000, 10000, 1, 1, 0 }, {LPT2_BASE_ADRS, INT_NUM_LPT2, LPT2_INT_LVL, TRUE, 10000, 10000, 1, 1, 0 } }; #endif /* INCLUDE_LPT */ int sysBus = BUS; /* system bus type (VME_BUS, etc) */ int sysCpu = CPU; /* system cpu type (MC680x0) */ char *sysBootLine = BOOT_LINE_ADRS; /* address of boot line */ char *sysExcMsg = EXC_MSG_ADRS; /* catastrophic message area */ int sysProcNum; /* processor number of this cpu */ int sysFlags; /* boot flags */ char sysBootHost [BOOT_FIELD_LEN]; /* name of host from which we booted */ char sysBootFile [BOOT_FIELD_LEN]; /* name of file from which we booted */ UINT sysIntIdtType = SYS_INT_TRAPGATE; /* IDT entry type */ UINT sysProcessor = NONE; /* 0=386, 1=486, 2=P5, 4=P6, 5=P7 */ UINT sysCoprocessor = 0; /* 0=none, 1=387, 2=487 */ int sysWarmType = SYS_WARM_TYPE; /* system warm boot type */ int sysWarmFdDrive = SYS_WARM_FD_DRIVE; /* 0 = drive a:, 1 = b: */ int sysWarmFdType = SYS_WARM_FD_TYPE; /* 0 = 3.5" 2HD, 1 = 5.25" 2HD */ int sysWarmAtaCtrl = SYS_WARM_ATA_CTRL; /* controller 0 or 1 */ int sysWarmAtaDrive = SYS_WARM_ATA_DRIVE; /* Hd drive 0 (c:), 1 (d:) */ int sysWarmTffsDrive= SYS_WARM_TFFS_DRIVE; /* TFFS drive 0 (DOC) */ UINT sysStrayIntCount = 0; /* Stray interrupt count */ char *memTopPhys = NULL; /* top of memory */ char *memRom = NULL; /* saved bootrom image */ GDT *pSysGdt = (GDT *)(LOCAL_MEM_LOCAL_ADRS + GDT_BASE_OFFSET); CPUID sysCpuId = {0,{0},0,0,0,0,0,0,0,0,{0},{0}}; /* CPUID struct. */ BOOL sysBp = TRUE; /* TRUE for BP, FALSE for AP */ #ifdef SYS_INT_DEBUG /* element should be > sysInumTblNumEnt */ UINT32 sysIntCount[64]; /* incremented in the EOI routine */ #endif /* SYS_INT_DEBUG */ #if defined(VIRTUAL_WIRE_MODE) UINT8 sysInumTbl[] = /* IRQ vs IntNum table */ { INT_NUM_IRQ0, /* IRQ 0 Vector No */ INT_NUM_IRQ0 + 1, /* IRQ 1 Vector No */ INT_NUM_IRQ0 + 2, /* IRQ 2 Vector No */ INT_NUM_IRQ0 + 3, /* IRQ 3 Vector No */ INT_NUM_IRQ0 + 4, /* IRQ 4 Vector No */ INT_NUM_IRQ0 + 5, /* IRQ 5 Vector No */ INT_NUM_IRQ0 + 6, /* IRQ 6 Vector No */ INT_NUM_IRQ0 + 7, /* IRQ 7 Vector No */ INT_NUM_IRQ0 + 8, /* IRQ 8 Vector No */ INT_NUM_IRQ0 + 9, /* IRQ 9 Vector No */ INT_NUM_IRQ0 + 10, /* IRQ 10 Vector No */ INT_NUM_IRQ0 + 11, /* IRQ 11 Vector No */ INT_NUM_IRQ0 + 12, /* IRQ 12 Vector No */ INT_NUM_IRQ0 + 13, /* IRQ 13 Vector No */ INT_NUM_IRQ0 + 14, /* IRQ 14 Vector No */ INT_NUM_IRQ0 + 15, /* IRQ 15 Vector No */ INT_NUM_LOAPIC_TIMER, /* Local APIC Timer Vector No */ INT_NUM_LOAPIC_ERROR, /* Local APIC Error Vector No */ INT_NUM_LOAPIC_LINT0, /* Local APIC LINT0 Vector No */ INT_NUM_LOAPIC_LINT1, /* Local APIC LINT1 Vector No */ INT_NUM_LOAPIC_PMC, /* Local APIC PMC Vector No */ INT_NUM_LOAPIC_THERMAL, /* Local APIC Thermal Vector No */ INT_NUM_LOAPIC_SPURIOUS, /* Local APIC Spurious Vector No */ INT_NUM_LOAPIC_SM, /* Local APIC SM Vector No */ INT_NUM_LOAPIC_SM + 1, /* Local APIC SM Vector No */ INT_NUM_LOAPIC_SM + 2, /* Local APIC SM Vector No */ INT_NUM_LOAPIC_SM + 3, /* Local APIC SM Vector No */ INT_NUM_LOAPIC_IPI, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 1, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 2, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 3, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 4, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 5, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 6, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 7 /* Local APIC IPI Vector No */ }; #elif defined(SYMMETRIC_IO_MODE) UINT8 sysInumTbl[] = /* IRQ vs IntNum table */ { INT_NUM_IOAPIC_IRQ0, /* IO APIC IRQ 0 Vector No */ INT_NUM_IOAPIC_IRQ1, /* IO APIC IRQ 1 Vector No */ INT_NUM_IOAPIC_IRQ2, /* IO APIC IRQ 2 Vector No */ INT_NUM_IOAPIC_IRQ3, /* IO APIC IRQ 3 Vector No */ INT_NUM_IOAPIC_IRQ4, /* IO APIC IRQ 4 Vector No */ INT_NUM_IOAPIC_IRQ5, /* IO APIC IRQ 5 Vector No */ INT_NUM_IOAPIC_IRQ6, /* IO APIC IRQ 6 Vector No */ INT_NUM_IOAPIC_IRQ7, /* IO APIC IRQ 7 Vector No */ INT_NUM_IOAPIC_IRQ8, /* IO APIC IRQ 8 Vector No */ INT_NUM_IOAPIC_IRQ9, /* IO APIC IRQ 9 Vector No */ INT_NUM_IOAPIC_IRQA, /* IO APIC IRQ 10 Vector No */ INT_NUM_IOAPIC_IRQB, /* IO APIC IRQ 11 Vector No */ INT_NUM_IOAPIC_IRQC, /* IO APIC IRQ 12 Vector No */ INT_NUM_IOAPIC_IRQD, /* IO APIC IRQ 13 Vector No */ INT_NUM_IOAPIC_IRQE, /* IO APIC IRQ 14 Vector No */ INT_NUM_IOAPIC_IRQF, /* IO APIC IRQ 15 Vector No */ INT_NUM_IOAPIC_PIRQA, /* IO APIC PIRQ A Vector No */ INT_NUM_IOAPIC_PIRQB, /* IO APIC PIRQ B Vector No */ INT_NUM_IOAPIC_PIRQC, /* IO APIC PIRQ C Vector No */ INT_NUM_IOAPIC_PIRQD, /* IO APIC PIRQ D Vector No */ INT_NUM_IOAPIC_PIRQE, /* IO APIC PIRQ E Vector No */ INT_NUM_IOAPIC_PIRQF, /* IO APIC PIRQ F Vector No */ INT_NUM_IOAPIC_PIRQG, /* IO APIC PIRQ G Vector No */ INT_NUM_IOAPIC_PIRQH, /* IO APIC PIRQ H Vector No */ INT_NUM_LOAPIC_TIMER, /* Local APIC Timer Vector No */ INT_NUM_LOAPIC_ERROR, /* Local APIC Error Vector No */ INT_NUM_LOAPIC_LINT0, /* Local APIC LINT0 Vector No */ INT_NUM_LOAPIC_LINT1, /* Local APIC LINT1 Vector No */ INT_NUM_LOAPIC_PMC, /* Local APIC PMC Vector No */ INT_NUM_LOAPIC_THERMAL, /* Local APIC Thermal Vector No */ INT_NUM_LOAPIC_SPURIOUS, /* Local APIC Spurious Vector No */ INT_NUM_LOAPIC_SM, /* Local APIC SM Vector No */ INT_NUM_LOAPIC_SM + 1, /* Local APIC SM Vector No */ INT_NUM_LOAPIC_SM + 2, /* Local APIC SM Vector No */ INT_NUM_LOAPIC_SM + 3, /* Local APIC SM Vector No */ INT_NUM_LOAPIC_IPI, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 1, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 2, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 3, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 4, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 5, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 6, /* Local APIC IPI Vector No */ INT_NUM_LOAPIC_IPI + 7 /* Local APIC IPI Vector No */ }; #else UINT8 sysInumTbl[] = /* IRQ vs IntNum table */ { INT_NUM_IRQ0, /* IRQ 0 Vector No */ INT_NUM_IRQ0 + 1, /* IRQ 1 Vector No */ INT_NUM_IRQ0 + 2, /* IRQ 2 Vector No */ INT_NUM_IRQ0 + 3, /* IRQ 3 Vector No */ INT_NUM_IRQ0 + 4, /* IRQ 4 Vector No */ INT_NUM_IRQ0 + 5, /* IRQ 5 Vector No */ INT_NUM_IRQ0 + 6, /* IRQ 6 Vector No */ INT_NUM_IRQ0 + 7, /* IRQ 7 Vector No */ INT_NUM_IRQ0 + 8, /* IRQ 8 Vector No */ INT_NUM_IRQ0 + 9, /* IRQ 9 Vector No */ INT_NUM_IRQ0 + 10, /* IRQ 10 Vector No */ INT_NUM_IRQ0 + 11, /* IRQ 11 Vector No */ INT_NUM_IRQ0 + 12, /* IRQ 12 Vector No */ INT_NUM_IRQ0 + 13, /* IRQ 13 Vector No */ INT_NUM_IRQ0 + 14, /* IRQ 14 Vector No */ INT_NUM_IRQ0 + 15, /* IRQ 15 Vector No */ }; #endif /* defined(VIRTUAL_WIRE_MODE) */ UINT32 sysInumTblNumEnt = NELEMENTS (sysInumTbl); /* locals */ #ifdef INCLUDE_ROMCARD LOCAL short *sysRomBase[] = { (short *)0xce000, (short *)0xce800, (short *)0xcf000, (short *)0xcf800 }; LOCAL char sysRomSignature[ROM_SIGNATURE_SIZE] = { 0x55,0xaa,0x01,0x90,0x90,0x90,0x90,0x90, 0x90,0x90,0x90,0x90,0x90,0x90,0x90,0x90 }; #endif /* INCLUDE_ROMCARD */ #if (CPU == PENTIUM2) || (CPU == PENTIUM3) || (CPU == PENTIUM4) /* * The cache control flags and MTRRs operate hierarchically for restricting * caching. That is, if the CD flag is set, caching is prevented globally. * If the CD flag is clear, either the PCD flags and/or the MTRRs can be * used to restrict caching. If there is an overlap of page-level caching * control and MTRR caching control, the mechanism that prevents caching * has precedence. For example, if an MTRR makes a region of system memory * uncachable, a PCD flag cannot be used to enable caching for a page in * that region. The converse is also true; that is, if the PCD flag is * set, an MTRR cannot be used to make a region of system memory cacheable. * If there is an overlap in the assignment of the write-back and write- * through caching policies to a page and a region of memory, the write- * through policy takes precedence. The write-combining policy takes * precedence over either write-through or write-back. */ LOCAL MTRR sysMtrr = { /* MTRR table */ {0,0}, /* MTRR_CAP register */ {0,0}, /* MTRR_DEFTYPE register */ /* Fixed Range MTRRs */ {{{MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB}}, {{MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB, MTRR_WB}}, {{MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_WC, MTRR_WC, MTRR_WC, MTRR_WC}}, {{MTRR_WP, MTRR_WP, MTRR_WP, MTRR_WP, MTRR_WP, MTRR_WP, MTRR_WP, MTRR_WP}}, {{MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC}}, {{MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC}}, {{MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC}}, {{MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC}}, {{MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC}}, {{MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC}}, {{MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC, MTRR_UC}}}, {{0LL, 0LL}, /* Variable Range MTRRs */ {0LL, 0LL}, {0LL, 0LL}, {0LL, 0LL}, {0LL, 0LL}, {0LL, 0LL}, {0LL, 0LL}, {0LL, 0LL}} }; #endif /* (CPU == PENTIUM[2/3/4]) */ /* forward declarations */ LOCAL void sysStrayInt (void); char * sysPhysMemTop (void); STATUS sysMmuMapAdd (void * address, UINT len, UINT initialStateMask, UINT initialState); LOCAL void sysIntInitPIC (void); LOCAL void sysIntEoiGet (VOIDFUNCPTR * vector, VOIDFUNCPTR * routineBoi, int * parameterBoi, VOIDFUNCPTR * routineEoi, int * parameterEoi); /* includes (source file) */ #if (NV_RAM_SIZE != NONE) # include "sysNvRam.c" #else /* default to nullNvRam */ # include "mem/nullNvRam.c" #endif /* (NV_RAM_SIZE != NONE) */ #include "sysSerial.c" #if defined (TGT_CPU) && defined (SYMMETRIC_IO_MODE) # include "sysAmp.c" #else # include "vme/nullVme.c" #endif /* defined (TGT_CPU) && defined (SYMMETRIC_IO_MODE) */ #if defined(VIRTUAL_WIRE_MODE) # include "intrCtl/loApicIntr.c" # include "intrCtl/i8259Intr.c" # ifdef INCLUDE_APIC_TIMER # include "timer/loApicTimer.c" /* includes timestamp driver */ # else # include "timer/i8253Timer.c" /* includes timestamp driver */ # endif /* INCLUDE_APIC_TIMER */ # ifdef INCLUDE_SHOW_ROUTINES # include "intrCtl/loApicIntrShow.c" # endif /* INCLUDE_SHOW_ROUTINES */ #elif defined(SYMMETRIC_IO_MODE) # include "intrCtl/loApicIntr.c" # include "intrCtl/i8259Intr.c" # include "intrCtl/ioApicIntr.c" # ifdef INCLUDE_APIC_TIMER # include "timer/loApicTimer.c" /* includes timestamp driver */ # else # include "timer/i8253Timer.c" /* includes timestamp driver */ # endif /* INCLUDE_APIC_TIMER */ # ifdef INCLUDE_SHOW_ROUTINES # include "intrCtl/loApicIntrShow.c" # include "intrCtl/ioApicIntrShow.c" # endif /* INCLUDE_SHOW_ROUTINES */ #else # include "intrCtl/i8259Intr.c" # include "timer/i8253Timer.c" /* includes timestamp driver */ #endif /* defined(VIRTUAL_WIRE_MODE) */ #ifdef INCLUDE_PCI /* BSP PCI bus & config support */ # include "pciCfgStub.c" /* customize pciConfigLib for BSP */ # include "pci/pciConfigLib.c" # include "pciCfgIntStub.c" /* customize pciIntLib for BSP */ # include "pci/pciIntLib.c" # if (defined(INCLUDE_PCI_CFGSHOW) && !defined(PRJ_BUILD)) # include "pci/pciConfigShow.c" # endif /* (defined(INCLUDE_PCI_CFGSHOW) && !defined(PRJ_BUILD)) */ #if (PCI_CFG_TYPE == PCI_CFG_AUTO) # include "pci/pciAutoConfigLib.c" # include "sysBusPci.c" #endif /* (PCI_CFG_TYPE == PCI_CFG_AUTO) */ #endif /* INCLUDE_PCI */ #ifdef INCLUDE_PCMCIA # include "pcmcia/pccardLib.c" # include "pcmcia/pccardShow.c" #endif /* INCLUDE_PCMCIA */ #ifdef INCLUDE_NETWORK # include "sysNet.c" /* network driver support */ #endif /* INCLUDE_NETWORK */ #ifdef INCLUDE_RTL_81X9_END #include "sysRtl81x9End.c" #endif /* INCLUDE_RTL_81X9_END */ /* include dm9102End driver support routines */ #ifdef INCLUDE_DM_9102_END #include "sysDm9102End.c" #endif /* INCLUDE_DM_9102_END */ #if defined(INCLUDE_SCSI) || defined(INCLUDE_SCSI2) # include "sysScsi.c" /* scsi support */ #endif /* INCLUDE_SCSI || INCLUDE_SCSI2 */ /* include BSP specific WindML configuration */ #if defined(INCLUDE_WINDML) # include "sysWindML.c" #endif /* INCLUDE_WINDML */ /******************************************************************************* * * sysModel - return the model name of the CPU board * * This routine returns the model name of the CPU board. * * RETURNS: A pointer to the string "PC 386, 486, PENTIUM or PENTIUM[234]". */ char *sysModel (void) { #if (CPU == I80386) return ("PC 386"); #elif (CPU == I80486) return ("PC 486"); #elif (CPU == PENTIUM) return ("PC PENTIUM"); #elif (CPU == PENTIUM2) return ("PC PENTIUM2"); #elif (CPU == PENTIUM3) return ("PC PENTIUM3"); #elif (CPU == PENTIUM4) return ("PC PENTIUM4"); #endif /* (CPU == I80386) */ } /******************************************************************************* * * sysBspRev - return the BSP version and revision number * * This routine returns a pointer to a BSP version and revision number, for * example, 1.1/0. BSP_REV is concatenated to BSP_VERSION and returned. * * RETURNS: A pointer to the BSP version/revision string. */ char * sysBspRev (void) { return (BSP_VERSION BSP_REV); } #ifdef INCLUDE_SYS_HW_INIT_0 /******************************************************************************* * * sysHwInit0 - BSP-specific hardware initialization * * This routine is called from usrInit() to perform BSP-specific initialization * that must be done before cacheLibInit() is called and/or the BSS is cleared. * * The BSP-specific sysCpuProbe() routine is called for the purpose of * identifying IA-32 target CPU variants, and the features or functions * supported by the target CPU. This information must be obtained relatively * early during system hardware initialization, as some support libraries * (mmuLib, cacheLib, &c.) will use the processor feature information to * enable or disable architecture-specific and/or BSP-specific functionality. * * RETURNS: N/A * * NOMANUAL */ void sysHwInit0 (void) { (void) sysCpuProbe (); } #endif /* INCLUDE_SYS_HW_INIT_0 */ /******************************************************************************* * * sysHwInit - initialize the system hardware * * This routine initializes various features of the i386/i486 board. * It is called from usrInit() in usrConfig.c. * * NOTE: This routine should not be called directly by the user application. * * RETURNS: N/A */ void sysHwInit (void) { PHYS_MEM_DESC *pMmu; int ix = 0; #if (CPU == PENTIUM) || (CPU == PENTIUM2) || (CPU == PENTIUM3) || \ (CPU == PENTIUM4) /* initialize the MSRs (Model Specific Registers) */ pentiumMsrInit (); # if (CPU != PENTIUM) /* enable the MTRR (Memory Type Range Registers) */ if ((sysCpuId.featuresEdx & CPUID_MTRR) == CPUID_MTRR) { pentiumMtrrDisable (); /* disable MTRR */ # ifdef INCLUDE_MTRR_GET (void) pentiumMtrrGet (&sysMtrr); /* get MTRR initialized by BIOS */ # else (void) pentiumMtrrSet (&sysMtrr); /* set your own MTRR */ # endif /* INCLUDE_MTRR_GET */ pentiumMtrrEnable (); /* enable MTRR */ } # endif /* (CPU != PENTIUM) */ # ifdef INCLUDE_PMC /* enable PMC (Performance Monitoring Counters) */ pentiumPmcStop (); /* stop PMC0 and PMC1 */ pentiumPmcReset (); /* reset PMC0 and PMC1 */ # endif /* INCLUDE_PMC */ /* enable the MCA (Machine Check Architecture) */ pentiumMcaEnable (TRUE); # ifdef INCLUDE_SHOW_ROUTINES /* * if excMcaInfoShow is not NULL, it is called in the default * exception handler when Machine Check Exception happened */ { IMPORT FUNCPTR excMcaInfoShow; excMcaInfoShow = (FUNCPTR) pentiumMcaShow; } vxShowInit (); # endif /* INCLUDE_SHOW_ROUTINES */ #endif /* (CPU == PENTIUM) || (CPU == PENTIUM[234]) */ /* initialize the number of active mappings (sysPhysMemDescNumEnt) */ pMmu = &sysPhysMemDesc[0]; for (ix = 0; ix < NELEMENTS (sysPhysMemDesc); ix++) if (pMmu->virtualAddr != (void *)DUMMY_VIRT_ADDR) pMmu++; else break; sysPhysMemDescNumEnt = ix; /* initialize PCI library */ #ifdef INCLUDE_PCI pciConfigLibInit (PCI_MECHANISM_1, PCI_CONFIG_ADDR, PCI_CONFIG_DATA, NONE); sysPciIntInit (); /* it does pciIntLibInit() */ #ifdef INCLUDE_RTL_81X9_END sysRtl81x9PciInit (); #endif /* INCLUDE_RTL_81X9_END */ #ifdef INCLUDE_DM_9102_END sysDm9102PciInit (); #endif /* INCLUDE_DM_9102_END */ #endif /* INCLUDE_PCI */ /* initialize the PIC (Programmable Interrupt Controller) */ sysIntInitPIC (); /* should be after the PCI init for IOAPIC */ intEoiGet = sysIntEoiGet; /* function pointer used in intConnect () */ /* initialize PCI devices */ #ifdef INCLUDE_PCI #if (PCI_CFG_TYPE == PCI_CFG_AUTO) /* Some boards don't have a typical BIOS * for example, Intel's System Firmware Library needs pciAutoConfig */ sysPciAutoConfig(); #endif /* (PCI_CFG_TYPE == PCI_CFG_AUTO) */ /* * PCI-to-PCI bridge initialization should be done here, if it is. * It is not necessary for Intel 430HX PCISET, which splits * the extended memory area as follows: * - Flash BIOS area from 4GByte to (4GB - 512KB) * - DRAM memory from 1MB to a maximum of 512MB * - PCI memory space from the top of DRAM to (4GB - 512KB) */ #ifdef INCLUDE_NETWORK /* initialize PCI network controllers starting from Bus 0 */ pciConfigForeachFunc (0, TRUE, (PCI_FOREACH_FUNC) sysNetPciInit, NULL); #endif /* INCLUDE_NETWORK */ #if (defined(INCLUDE_SCSI) && defined(INCLUDE_AIC_7880)) sysAic7880PciInit (); #endif /* INCLUDE_SCSI && INCLUDE_AIC_7880 */ #endif /* INCLUDE_PCI */ /* initialize devices on the board if following SFL boot process */ #ifdef INCLUDE_IACSFL { # ifdef INCLUDE_CTB69000VGA extern int ctB69000VgaInit(); # endif /* INCLUDE_CTB69000VGA */ /* superIO - basic intialization */ # ifdef INCLUDE_SMCFDC37B78X smcFdc37b78xDevCreate ((void *) NULL); /* intialize superIO library */ /* enable only given devices on SuperIO chip */ smcFdc37b78xInit ((SMCFDC37B78X_FDD_EN | SMCFDC37B78X_COM1_EN | SMCFDC37B78X_COM2_EN | SMCFDC37B78X_LPT1_EN | SMCFDC37B78X_KBD_EN)); # endif /* INCLUDE_SMCFDC37B78X */ /* PC console - initialization */ # if defined(INCLUDE_PC_CONSOLE) # ifdef INCLUDE_SMCFDC37B78X smcFdc37b78xKbdInit (); /* Initialize Kbd on SuperIO */ # endif /* INCLUDE_SMCFDC37B78X */ # ifdef INCLUDE_CTB69000VGA ctB69000VgaInit (); /* Initialize VGA card */ # endif /* INCLUDE_CTB69000VGA */ # endif /* INCLUDE_PC_CONSOLE */ } #endif /* INCLUDE_IACSFL */ #ifdef INCLUDE_USB /* * Since the Pentium BSPs do not rely on pciAutoCfg, sysUsbOhciInit * must be called to update the MMU mapping for the ohci device. * Please Note: INCLUDE_USB is not supported for boot_rom images. */ sysUsbOhciPciInit (); #endif /* INCLUDE_USB */ /* initializes the serial devices */ sysSerialHwInit (); /* initialize serial data structure */ #ifdef INCLUDE_WINDML sysWindMLHwInit (); #endif /* INCLUDE_WINDML */ #ifdef VX_POWER_MANAGEMENT /* * initializes Power Management Mode * VX_POWER_MODE_DEFAULT is defined in config.h */ vxPowerModeSet(VX_POWER_MODE_DEFAULT); #endif /* VX_POWER_MANAGEMENT */ } /******************************************************************************* * * sysHwInit2 - additional system configuration and initialization * * This routine connects system interrupts and does any additional * configuration necessary. * * RETURNS: N/A */ void sysHwInit2 (void) { #if defined (INCLUDE_ADD_BOOTMEM) /* * We memAddToPool some upper memory into any low memory * x86 "rom" images pool. The x86 low memory images reside * from 0x8000 to 0xa0000. By memAddToPool'ing some upper * memory here, we allow devices a larger pool to swim within. * (SPR#21338). This is no longer performed in bootConfig.c */ # if (ADDED_BOOTMEM_SIZE != 0x0) /* * if &end (compiler symbol) is in lower memory, then we assume * this is a low memory image, and add some upper memory to the pool. */ if ((UINT32)(&end) < 0x100000) { /* Only do this if there is enough memory. Default is 4MB min. */ if ((UINT32)(memTopPhys) >= (0x00200000 + ADDED_BOOTMEM_SIZE)) { memAddToPool ((char *)memTopPhys - ADDED_BOOTMEM_SIZE, ADDED_BOOTMEM_SIZE); } } # endif /* (ADDED_BOOTMEM_SIZE !=0) */ #endif /* INCLUDE_ADD_BOOTMEM defined */ /* connect sys clock interrupt and auxiliary clock interrupt*/ #ifdef INCLUDE_APIC_TIMER (void)intConnect (INUM_TO_IVEC (INT_NUM_LOAPIC_TIMER), sysClkInt, 0); # ifdef PIT0_FOR_AUX (void)intConnect (INUM_TO_IVEC (INT_NUM_GET (PIT0_INT_LVL)), sysAuxClkInt, 0); # else (void)intConnect (INUM_TO_IVEC (INT_NUM_GET (RTC_INT_LVL)), sysAuxClkInt, 0); # endif /* PIT0_FOR_AUX */ #else (void)intConnect (INUM_TO_IVEC (INT_NUM_GET (PIT0_INT_LVL)), sysClkInt, 0); (void)intConnect (INUM_TO_IVEC (INT_NUM_GET (RTC_INT_LVL)), sysAuxClkInt, 0); #endif /* INCLUDE_APIC_TIMER */ /* connect serial interrupt */ sysSerialHwInit2(); /* connect stray(spurious/phantom) interrupt */ #if defined(VIRTUAL_WIRE_MODE) (void)intConnect (INUM_TO_IVEC (INT_NUM_LOAPIC_SPURIOUS), sysStrayInt, 0); (void)intConnect (INUM_TO_IVEC (INT_NUM_GET (LPT_INT_LVL)), sysStrayInt, 0); #elif defined(SYMMETRIC_IO_MODE) (void)intConnect (INUM_TO_IVEC (INT_NUM_LOAPIC_SPURIOUS), sysStrayInt, 0); #else (void)intConnect (INUM_TO_IVEC (INT_NUM_GET (LPT_INT_LVL)), sysStrayInt, 0); (void)intConnect (INUM_TO_IVEC (INT_NUM_GET (PIC_SLAVE_STRAY_INT_LVL)), sysStrayInt, 0); #endif /* defined(VIRTUAL_WIRE_MODE) */ #ifdef INCLUDE_PC_CONSOLE /* connect keyboard Controller 8042 chip interrupt */ (void) intConnect (INUM_TO_IVEC (INT_NUM_GET (KBD_INT_LVL)), kbdIntr, 0); #endif /* INCLUDE_PC_CONSOLE */ #if defined (TGT_CPU) && defined (SYMMETRIC_IO_MODE) /* init IPI vectors, connect IPI handler up to IPI_MAX_HANDLERS (=8) */ ipiVecInit (INT_NUM_LOAPIC_IPI); ipiConnect ((INT_NUM_LOAPIC_IPI + 0), ipiHandlerShutdown); ipiConnect ((INT_NUM_LOAPIC_IPI + 1), ipiHandlerTscReset); ipiConnect ((INT_NUM_LOAPIC_IPI + 2), ipiHandlerTlbFlush); #endif /* defined (TGT_CPU) && defined (SYMMETRIC_IO_MODE) */ } #ifdef LOCAL_MEM_AUTOSIZE /******************************************************************************* * * WRITE_MEMORY_TEST_PATTERN * * This routine writes the memory test pattern used in the sysPhysMemTop() * memory auto-size algorithm. 12 bytes of data stored at are * written to before a 12-byte test pattern is written to * . * * RETURNS: N/a * * SEE ALSO: RESTORE_MEMORY_TEST_ADDRS() */ __inline__ static void WRITE_MEMORY_TEST_PATTERN ( int * pTestAddr, int * pSaveAddr ) { pSaveAddr[0] = pTestAddr[0]; pSaveAddr[1] = pTestAddr[1]; pSaveAddr[2] = pTestAddr[2]; pTestAddr[0] = TEST_PATTERN_A; pTestAddr[1] = TEST_PATTERN_B; pTestAddr[2] = TEST_PATTERN_C; cacheFlush (DATA_CACHE, pTestAddr, 16); } /******************************************************************************* * * RESTORE_MEMORY_TEST_ADDRS * * This routine restores memory test locations which are modified in the * sysPhysMemTop() memory auto-size algorithm. 12 bytes of data stored at * are written to . * * RETURNS: N/a * * SEE ALSO: WRITE_MEMORY_TEST_PATTERN() */ __inline__ static void RESTORE_MEMORY_TEST_ADDRS ( int * pTestAddr, const int * pSaveAddr ) { pTestAddr[0] = pSaveAddr[0]; pTestAddr[1] = pSaveAddr[1]; pTestAddr[2] = pSaveAddr[2]; } #endif /* LOCAL_MEM_AUTOSIZE */ /******************************************************************************* * * sysPhysMemTop - get the address of the top of physical memory * * This routine returns the address of the first missing byte of memory, * which indicates the top of physical memory. * * INTERNAL * The memory auto-size logic assumes that the manifest constant PHYS_MEM_MAX * specifies the total size in bytes of the processor's physical address space. * In the case of IA-32 processors, PHYS_MEM_MAX will be 4GB (2^32 bytes) or * 64GB (2^36 bytes) if the 36-bit Physical Address Extension (PAE) is enabled * on select processor models. However, because the tool-chain and sysMemTop() * API are 32-bit, this routine currently will not auto-size a 36-bit address * space. Moreover, this routine will not return the memory top of a platform * with a memory device using a full 2^32 bytes of address space, as the memory * top of such a device would be a 33-bit value. * * When paging is used, the processor divides the linear address space into * fixed-size pages (of 4KB, 2MB, or 4MB in length) that can be mapped into * physical memory and/or disk storage. The auto-size algorithm organizes * the physical address space using the same concept. That is, rather than * treating the address space as an array of bytes, the memory auto-size * code treats the address space as an array of equal-sized pages. * * The auto-size algorithm attempts to locate the base-address of the first * non-existant page address in the physical address space. This is done by * writing, and then reading, a test pattern to each page base-address in the * address space. If the test pattern is not read back from a page, it is * assumed that the address does not physically exist. * * As the installed physical memory could be potentially quite large, the * auto-size code attempts a few optimizations, chief among these being a * binary (as opposed to linear) search of the page array (ie. address space). * An additional optimization is obtained by avoiding a search on memory * that _must_ exist; namely, the memory storing the VxWorks boot image or * RTOS image from whence this routine will execute. * * In the case of VxWorks boot and RTOS images for IA-32, the last byte of the * image section loaded highest in memory is assumed to be indicated by the * address of a symbol, named , which is typically supplied by the linker * (more precisely, the linker script) used to build the image. The search * for remaining extant physical page addresses on the system will use the * address of the first page following the symbol, or a page-aligned * address no lower than physical memory location 0x100000 (1Mb), as a lower * bound on the search. All memory locations below physical address 0x100000 * are assumed to be reserved existing target memory. * * RETURNS: The address of the top of physical memory. */ char * sysPhysMemTop (void) { PHYS_MEM_DESC * pMmu; /* points to memory desc. table entries */ char gdtr[6]; /* stores a copy of the GDT */ BOOL found = FALSE; if (memTopPhys != NULL) { return (memTopPhys); } #ifdef LOCAL_MEM_AUTOSIZE { /* Do not use a page-sized stride larger than 4Kb, as the end of usable * memory could possibly be within a 2Mb or 4Mb page memory range. */ const UINT32 pageSize = PAGE_SIZE_4KB; /* The lower bound for the probe will be the page-aligned VxWorks * end-of-image address, or a page-aligned address no less than * the 1Mb physical address. */ UINT8 * pPage = (UINT8 *) ROUND_UP (((UINT32)(&end) > 0x100000) ? (UINT32)(&end) : (0x100000), pageSize); /* Subtract the number of used pages from the total number of pages * possible in the address space. The resulting value is the total * number of pages that could possibly populate the remaining address * space above . */ const UINT32 pageNoUsed = ((UINT32) pPage / pageSize); const UINT32 pageNoTotal = (PHYS_MEM_MAX / pageSize) - pageNoUsed; UINT32 delta = HALF (pageNoTotal); int temp[4]; /* find out the actual size of the memory (up to PHYS_MEM_MAX) */ for (pPage += (pageSize * delta); delta != 0; delta >>= 1) { WRITE_MEMORY_TEST_PATTERN ((int *) pPage, &temp[0]); if (*((int *) pPage) != TEST_PATTERN_A) { /* The test pattern was not written, so assume that is the * base address of a page beyond available memory. Test the * next lowest page. If the test pattern is writable there, assume * that is the address of the first byte beyond the last * addressable page. */ UINT8 * pPrevPage = (UINT8 *)((UINT32) pPage - pageSize); WRITE_MEMORY_TEST_PATTERN ((int *) pPrevPage, &temp[0]); if (*((int *) pPrevPage) == TEST_PATTERN_A) { RESTORE_MEMORY_TEST_ADDRS ((int *) pPrevPage, &temp[0]); memTopPhys = pPage; found = TRUE; break; } pPage -= (pageSize * HALF (delta)); } else { /* The test pattern was written, so assume that is the base * address of a page in available memory. Test the next highest * page. If the test pattern is not writable there, assume that * is the address of the first byte beyond that last * addressable page. */ UINT8 * pNextPage = (UINT8 *)((UINT32) pPage + pageSize); RESTORE_MEMORY_TEST_ADDRS ((int *) pPage, &temp[0]); WRITE_MEMORY_TEST_PATTERN ((int *) pNextPage, &temp[0]); if (*((int *) pNextPage) != TEST_PATTERN_A) { memTopPhys = pNextPage; found = TRUE; break; } RESTORE_MEMORY_TEST_ADDRS ((int *) pNextPage, &temp[0]); pPage += (pageSize * HALF (delta)); } } } #endif /* LOCAL_MEM_AUTOSIZE */ if (!found) { memTopPhys = (char *)(LOCAL_MEM_LOCAL_ADRS + LOCAL_MEM_SIZE); } /* copy the global descriptor table from RAM/ROM to RAM */ bcopy ((char *)sysGdt, (char *)pSysGdt, GDT_ENTRIES * sizeof(GDT)); *(short *)&gdtr[0] = GDT_ENTRIES * sizeof(GDT) - 1; *(int *)&gdtr[2] = (int)pSysGdt; /* * We assume that there are no memory mapped IO addresses * above the "memTopPhys" if INCLUDE_PCI is not defined. * Thus we set the "limit" to get the General Protection Fault * when the memory above the "memTopPhys" is accessed. */ #if !defined (INCLUDE_PCI) && \ !defined (INCLUDE_MMU_BASIC) && !defined (INCLUDE_MMU_FULL) { int ix; GDT * pGdt = pSysGdt; int limit = (((UINT32) memTopPhys) >> 12) - 1; for (ix = 1; ix < GDT_ENTRIES; ++ix) { ++pGdt; pGdt->limit00 = limit & 0x0ffff; pGdt->limit01 = ((limit & 0xf0000) >> 16) | (pGdt->limit01 & 0xf0); } } #endif /* INCLUDE_PCI */ /* load the global descriptor table. set the MMU table */ sysLoadGdt (gdtr); #ifdef FAST_REBOOT /* * save the brand new bootrom image that will be protected by MMU. * The last 2 bytes of ROM_SIZE are for the checksum. * - compression would minimize the DRAM usage. * - when restore, jumping to the saved image would be faster. */ memTopPhys -= ROM_SIZE; bcopy ((char *)ROM_BASE_ADRS, memTopPhys, ROM_SIZE); *(UINT16 *)(memTopPhys + ROM_SIZE - 2) = checksum ((UINT16 *)memTopPhys, ROM_SIZE - 2); memRom = memTopPhys; /* remember it */ #endif /* FAST_REBOOT */ /* set the MMU descriptor table */ (UINT32)memTopPhys &= ~(VM_PAGE_SIZE - 1); /* VM_PAGE_SIZE aligned */ #if (VM_PAGE_SIZE == PAGE_SIZE_4KB) pMmu = &sysPhysMemDesc[4]; /* 5th entry: above 1.5MB upper memory */ pMmu->len = (UINT32) memTopPhys - (UINT32) pMmu->physicalAddr; #else /* (VM_PAGE_SIZE == PAGE_SIZE_4KB) */ pMmu = &sysPhysMemDesc[2]; /* 3rd entry: above 8MB upper memory */ pMmu->len = (UINT32) memTopPhys - (UINT32) pMmu->physicalAddr; #endif /* (VM_PAGE_SIZE == PAGE_SIZE_4KB) */ return (memTopPhys); } /******************************************************************************* * * sysMemTop - get the address of the top of VxWorks memory * * This routine returns a pointer to the first byte of memory not * controlled or used by VxWorks. * * The user can reserve memory space by defining the macro USER_RESERVED_MEM * in config.h. This routine returns the address of the reserved memory * area. The value of USER_RESERVED_MEM is in bytes. * * RETURNS: The address of the top of VxWorks memory. */ char * sysMemTop (void) { static char * memTop = NULL; if (memTop == NULL) { memTop = sysPhysMemTop () - USER_RESERVED_MEM; if ((UINT32)(&end) < 0x100000) /* this is for bootrom */ memTop = (char *)EBDA_START; /* preserve the MP table */ else if ((UINT32)(&end) < RAM_LOW_ADRS) /* bootrom in upper mem */ memTop = (char *)(RAM_LOW_ADRS & 0xfff00000); } return (memTop); } /******************************************************************************* * * sysToMonitor - transfer control to the ROM monitor * * This routine transfers control to the ROM monitor. It is usually called * only by reboot() -- which services ^X -- and by bus errors at interrupt * level. However, in some circumstances, the user may wish to introduce a * new to enable special boot ROM facilities. * * RETURNS: Does not return. */ STATUS sysToMonitor ( int startType /* passed to ROM to tell it how to boot */ ) { FUNCPTR pEntry; INT16 * pDst; VM_ENABLE (FALSE); /* disbale MMU */ #if (CPU == PENTIUM) || (CPU == PENTIUM2) || (CPU == PENTIUM3) || \ (CPU == PENTIUM4) pentiumMsrInit (); /* initialize MSRs */ #endif /* (CPU == PENTIUM) || (CPU == PENTIUM[234]) */ /* decide a destination RAM address and the entry point */ if ((UINT32)(&end) > RAM_LOW_ADRS) { pDst = (short *)RAM_HIGH_ADRS; /* copy it in lower mem */ pEntry = (FUNCPTR)(RAM_HIGH_ADRS + ROM_WARM_HIGH); } else { pDst = (short *)RAM_LOW_ADRS; /* copy it in upper mem */ pEntry = (FUNCPTR)(RAM_LOW_ADRS + ROM_WARM_LOW); } #ifdef FAST_REBOOT /* restore the saved brand new bootrom image, then jump */ if ((memRom != NULL) && (*(UINT16 *)(memRom + ROM_SIZE - 2) == checksum ((UINT16 *)memRom, ROM_SIZE - 2))) { INT32 ix; INT32 * dst = (INT32 *) ROM_TEXT_ADRS; INT32 * src = (INT32 *) memRom; pEntry = (FUNCPTR)(ROM_TEXT_ADRS + ROM_WARM_HIGH); for (ix = 0; ix < (ROM_SIZE >> 2); ix++) *dst++ = *src++; goto sysToMonitorJump; } #endif /* FAST_REBOOT */ /* disable 16-bit memory access */ #ifdef INCLUDE_ELC sysOutByte (IO_ADRS_ELC + 5, sysInByte (IO_ADRS_ELC + 5) & ~0x80); #endif /* INCLUDE_ELC */ #ifdef INCLUDE_ROMCARD { INT32 ix; INT32 iy; INT32 iz; char buf[ROM_SIGNATURE_SIZE]; short *pSrc; /* copy EPROM to RAM and jump, if there is a VxWorks EPROM */ for (ix = 0; ix < NELEMENTS(sysRomBase); ix++) { bcopyBytes ((char *)sysRomBase[ix], buf, ROM_SIGNATURE_SIZE); if (strncmp (sysRomSignature, buf, ROM_SIGNATURE_SIZE) == 0) { for (iy = 0; iy < 1024; iy++) { *sysRomBase[ix] = iy; /* map the moveable window */ pSrc = (short *)((int)sysRomBase[ix] + 0x200); for (iz = 0; iz < 256; iz++) *pDst++ = *pSrc++; } goto sysToMonitorJump; /* jump to the entry point */ } } } #endif /* INCLUDE_ROMCARD */ #ifdef INCLUDE_IACSFL { unsigned int * romSize = (unsigned int *)0xffffffe0; unsigned int * dest = (unsigned int *) pDst; unsigned int * src = (unsigned int *) (0 - *romSize); int i = 0; for (i = 0; i < (*romSize >> 2); i++) *dest++ = *src++; goto sysToMonitorJump; } #endif /* INCLUDE_IACSFL */ #if (defined(INCLUDE_FD) || defined(INCLUDE_ATA) || defined(INCLUDE_TFFS)) if ((sysWarmType == SYS_WARM_FD) || (sysWarmType == SYS_WARM_ATA) || (sysWarmType == SYS_WARM_TFFS)) { u_char * pChar; /* check to see if device exists, if so don't create it */ if (NULL != dosFsVolDescGet(BOOTROM_DIR, &pChar)) { goto bootDevExists; /* avoid attempt to recreate device */ } } #endif /* defined(INCLUDE_FD) || defined(INCLUDE_ATA) || defined(INCLUDE_TFFS) */ #ifdef INCLUDE_FD if (sysWarmType == SYS_WARM_FD) { IMPORT int dosFsDrvNum; fdDrv (INT_NUM_GET (FD_INT_LVL), FD_INT_LVL); /* initialize floppy */ if (dosFsDrvNum == ERROR) dosFsInit (NUM_DOSFS_FILES); /* initialize DOS-FS */ if (usrFdConfig (sysWarmFdDrive, sysWarmFdType, BOOTROM_DIR) == ERROR) { printErr ("usrFdConfig failed.\n"); return (ERROR); } } #endif /* INCLUDE_FD */ #ifdef INCLUDE_ATA if (sysWarmType == SYS_WARM_ATA) { ATA_RESOURCE *pAtaResource = &ataResources[sysWarmAtaCtrl]; IMPORT int dosFsDrvNum; if (ataDrv (sysWarmAtaCtrl, pAtaResource->drives, pAtaResource->intVector, pAtaResource->intLevel, pAtaResource->configType, pAtaResource->semTimeout, pAtaResource->wdgTimeout) == ERROR) /* initialize ATA/IDE disk */ { printErr ("Could not initialize.\n"); return (ERROR); } if (dosFsDrvNum == ERROR) dosFsInit (NUM_DOSFS_FILES); /* initialize DOS-FS */ if (ERROR == usrAtaConfig (sysWarmAtaCtrl, sysWarmAtaDrive, BOOTROM_DIR)) { printErr ("usrAtaConfig failed.\n"); return (ERROR); } } #endif /* INCLUDE_ATA */ #ifdef INCLUDE_TFFS if (sysWarmType == SYS_WARM_TFFS) { IMPORT int dosFsDrvNum; tffsDrv (); /* initialize TFFS */ if (dosFsDrvNum == ERROR) dosFsInit (NUM_DOSFS_FILES); /* initialize DOS-FS */ if (usrTffsConfig (sysWarmTffsDrive, FALSE, BOOTROM_DIR) == ERROR) { printErr ("usrTffsConfig failed.\n"); return (ERROR); } } #endif /* INCLUDE_TFFS */ #if (defined(INCLUDE_FD) || defined(INCLUDE_ATA) || defined(INCLUDE_TFFS)) bootDevExists: /* reboot device exists */ if ((sysWarmType == SYS_WARM_FD) || (sysWarmType == SYS_WARM_ATA) || (sysWarmType == SYS_WARM_TFFS)) { int fd; BOOL hasAoutHdr = FALSE; if ((fd = open (BOOTROM_BIN, O_RDONLY, 0644)) == ERROR) { printErr ("Error opening file \"%s\", trying \"%s\" ... \n", BOOTROM_BIN, BOOTROM_AOUT); if ((fd = open (BOOTROM_AOUT, O_RDONLY, 0644)) == ERROR) { printErr ("Error opening file \"%s\"\n", BOOTROM_AOUT); return (ERROR); } if (read (fd, (char *) pDst, 0x20) == ERROR) /* a.out header */ { printErr ("Error reading file \"%s\"\n", BOOTROM_AOUT); return (ERROR); } hasAoutHdr = TRUE; } /* read text and data, write them to the memory */ if (read (fd, (char *) pDst, 0x98000) == ERROR) { printErr ("Error reading file \"%s\"\n", hasAoutHdr ? BOOTROM_AOUT : BOOTROM_BIN); return (ERROR); } #ifdef INCLUDE_FD /* explicitly release floppy disk, SPR#30280 */ if (SYS_WARM_FD == sysWarmType) { sysOutByte(FD_REG_OUTPUT,(FD_DOR_CLEAR_RESET | FD_DOR_DMA_ENABLE)); sysDelay (); } #endif /* INCLUDE_FD */ goto sysToMonitorJump; /* jump to the entry point */ } #endif /* (INCLUDE_FD) || (INCLUDE_ATA) || (INCLUDE_TFFS) */ /* perform the cold boot since the warm boot is not possible */ { intLock (); #ifdef INCLUDE_ELC elcdetach (0); #endif /* INCLUDE_ELC */ sysClkDisable (); sysWait (); sysOutByte (COMMAND_8042, 0xfe); /* assert SYSRESET */ sysWait (); sysOutByte (COMMAND_8042, 0xff); /* NULL command */ sysReboot (); /* crash the global descriptor table */ return (OK); /* in case we ever continue from ROM monitor */ } /* jump to the warm start entry point */ sysToMonitorJump: /* cleanup and jump to the entry point */ sysClkDisable (); /* disable the system clock interrupt */ sysIntLock (); /* lock the used/owned interrupts */ #if defined (SYMMETRIC_IO_MODE) || defined (VIRTUAL_WIRE_MODE) intLock (); /* LOCK INTERRUPTS */ loApicEnable (FALSE); /* disable the Local APIC */ # ifdef SYMMETRIC_IO_MODE if (sysBp) ioApicEnable (FALSE); /* disable the IO APIC */ # endif /* SYMMETRIC_IO_MODE */ #endif /* defined (SYMMETRIC_IO_MODE) || defined (VIRTUAL_WIRE_MODE) */ (*pEntry) (startType); return (OK); /* in case we ever continue from ROM monitor */ } /******************************************************************************* * * sysIntInitPIC - initialize the interrupt controller * * This routine initializes the interrupt controller. * * RETURNS: N/A * * ARGSUSED0 */ LOCAL void sysIntInitPIC (void) { #if defined(VIRTUAL_WIRE_MODE) { UINT32 addrLo; /* page aligned Local APIC Base Address */ UINT32 lengthLo; /* length of Local APIC registers */ loApicInit (); i8259Init (); /* add an entry to the sysMmuPhysDesc[] for Local APIC */ addrLo = ((UINT32)loApicBase / VM_PAGE_SIZE) * VM_PAGE_SIZE; lengthLo = (UINT32)loApicBase - addrLo + LOAPIC_LENGTH; if ((lengthLo % VM_PAGE_SIZE) != 0) lengthLo = (lengthLo / VM_PAGE_SIZE + 1) * VM_PAGE_SIZE; sysMmuMapAdd ((void *)addrLo, lengthLo, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_IO); } #elif defined(SYMMETRIC_IO_MODE) { UINT32 addrLo; /* page aligned Local APIC Base Address */ UINT32 addrIo; /* page aligned IO APIC Base Address */ UINT32 lengthLo; /* length of Local APIC registers */ UINT32 lengthIo; /* length of IO APIC registers */ loApicInit (); i8259Init (); ioApicInit (); /* add an entry to the sysMmuPhysDesc[] for Local APIC and IO APIC */ addrLo = ((UINT32)loApicBase / VM_PAGE_SIZE) * VM_PAGE_SIZE; lengthLo = (UINT32)loApicBase - addrLo + LOAPIC_LENGTH; if ((lengthLo % VM_PAGE_SIZE) != 0) lengthLo = (lengthLo / VM_PAGE_SIZE + 1) * VM_PAGE_SIZE; addrIo = ((UINT32)ioApicBase / VM_PAGE_SIZE) * VM_PAGE_SIZE; lengthIo = (UINT32)ioApicBase - addrIo + IOAPIC_LENGTH; if ((lengthIo % VM_PAGE_SIZE) != 0) lengthIo = (lengthIo / VM_PAGE_SIZE + 1) * VM_PAGE_SIZE; if ((addrLo == addrIo) || ((addrLo < addrIo) && ((addrLo + lengthLo) >= addrIo)) || ((addrIo < addrLo) && ((addrIo + lengthIo) >= addrLo))) { UINT32 addr = min (addrLo, addrIo); UINT32 length = max ((addrLo + lengthLo), (addrIo + lengthIo)) - addr; sysMmuMapAdd ((void *)addr, length, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_IO); } else { sysMmuMapAdd ((void *)addrLo, lengthLo, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_IO); sysMmuMapAdd ((void *)addrIo, lengthIo, VM_STATE_MASK_FOR_ALL, VM_STATE_FOR_IO); } } #else i8259Init (); #endif /* defined(VIRTUAL_WIRE_MODE) */ } /******************************************************************************* * * sysIntLock - lock out all interrupts * * This routine saves the mask and locks out all interrupts. * * SEE ALSO: sysIntUnlock() * * ARGSUSED0 */ VOID sysIntLock (void) { INT32 oldLevel = intLock (); /* LOCK INTERRUPTS */ #if defined(VIRTUAL_WIRE_MODE) loApicIntLock (); i8259IntLock (); #elif defined(SYMMETRIC_IO_MODE) loApicIntLock (); ioApicIntLock (); #else i8259IntLock (); #endif /* defined(VIRTUAL_WIRE_MODE) */ intUnlock (oldLevel); /* UNLOCK INTERRUPTS */ } /******************************************************************************* * * sysIntUnlock - unlock the PIC interrupts * * This routine restores the mask and unlocks the PIC interrupts * * SEE ALSO: sysIntLock() * * ARGSUSED0 */ VOID sysIntUnlock (void) { INT32 oldLevel = intLock (); /* LOCK INTERRUPTS */ #if defined(VIRTUAL_WIRE_MODE) loApicIntUnlock (); i8259IntUnlock (); #elif defined(SYMMETRIC_IO_MODE) loApicIntUnlock (); ioApicIntUnlock (); #else i8259IntUnlock (); #endif /* defined(VIRTUAL_WIRE_MODE) */ intUnlock (oldLevel); /* UNLOCK INTERRUPTS */ } /******************************************************************************* * * sysIntDisablePIC - disable a bus interrupt level * * This routine disables a specified bus interrupt level. * * RETURNS: OK, or ERROR if failed. * * ARGSUSED0 */ STATUS sysIntDisablePIC ( int irqNo /* IRQ(PIC) or INTIN(APIC) number to disable */ ) { #if defined(VIRTUAL_WIRE_MODE) return (i8259IntDisable (irqNo)); #elif defined(SYMMETRIC_IO_MODE) return (ioApicIntDisable (irqNo)); #else return (i8259IntDisable (irqNo)); #endif /* defined(VIRTUAL_WIRE_MODE) */ } /******************************************************************************* * * sysIntEnablePIC - enable a bus interrupt level * * This routine enables a specified bus interrupt level. * * RETURNS: OK, or ERROR if failed. * * ARGSUSED0 */ STATUS sysIntEnablePIC ( int irqNo /* IRQ(PIC) or INTIN(APIC) number to enable */ ) { #if defined(VIRTUAL_WIRE_MODE) return (i8259IntEnable (irqNo)); #elif defined(SYMMETRIC_IO_MODE) return (ioApicIntEnable (irqNo)); #else return (i8259IntEnable (irqNo)); #endif /* defined(VIRTUAL_WIRE_MODE) */ } /******************************************************************************* * * sysIntEoiGet - get EOI/BOI function and its parameter * * This routine gets EOI function and its parameter for the interrupt controller. * If returned EOI/BOI function is NULL, intHandlerCreateX86() replaces * "call _routineBoi/Eoi" in intConnectCode[] with NOP instruction. * * RETURNS: N/A * * ARGSUSED0 */ LOCAL void sysIntEoiGet ( VOIDFUNCPTR * vector, /* interrupt vector to attach to */ VOIDFUNCPTR * routineBoi, /* BOI function */ int * parameterBoi, /* a parameter of the BOI function */ VOIDFUNCPTR * routineEoi, /* EOI function */ int * parameterEoi /* a parameter of the EOI function */ ) { int intNum = IVEC_TO_INUM (vector); int irqNo; /* set default BOI routine & parameter */ *routineBoi = NULL; *parameterBoi = 0; /* find a match in sysInumTbl[] */ for (irqNo = 0; irqNo < sysInumTblNumEnt; irqNo++) { if (sysInumTbl[irqNo] == intNum) break; } *parameterEoi = irqNo; /* irq is sysInumTblNumEnt, if no match */ #ifdef SYMMETRIC_IO_MODE if (irqNo < ioApicRedEntries) /* IRQ belongs to the IO APIC */ *routineEoi = ioApicIntEoi; /* set IO APIC's EOI routine */ else /* IRQ belongs to the Local APIC */ { if (intNum == INT_NUM_LOAPIC_SPURIOUS) *routineEoi = NULL; /* no EOI is necessary */ else *routineEoi = loApicIntEoi; /* set Local APIC's EOI routine */ } #else # ifdef VIRTUAL_WIRE_MODE if (irqNo >= N_PIC_IRQS) /* IRQ belongs to the Local APIC */ { if (intNum == INT_NUM_LOAPIC_SPURIOUS) *routineEoi = NULL; /* no EOI is necessary */ else *routineEoi = loApicIntEoi; /* set Local APIC's EOI routine */ return; } # endif /* VIRTUAL_WIRE_MODE */ /* set the [BE]OI parameter for the master & slave PIC */ *parameterBoi = irqNo; *parameterEoi = irqNo; /* set the right BOI routine */ if (irqNo == 0) /* IRQ0 BOI routine */ { #if (PIC_IRQ0_MODE == PIC_AUTO_EOI) *routineBoi = NULL; #elif (PIC_IRQ0_MODE == PIC_EARLY_EOI_IRQ0) *routineBoi = i8259IntBoiEem; #elif (PIC_IRQ0_MODE == PIC_SPECIAL_MASK_MODE_IRQ0) *routineBoi = i8259IntBoiSmm; #else *routineBoi = NULL; #endif /* (PIC_IRQ0_MODE == PIC_AUTO_EOI) */ } else if ((irqNo == PIC_MASTER_STRAY_INT_LVL) || (irqNo == PIC_SLAVE_STRAY_INT_LVL)) { *routineBoi = i8259IntBoi; } /* set the right EOI routine */ if (irqNo == 0) /* IRQ0 EOI routine */ { #if (PIC_IRQ0_MODE == PIC_AUTO_EOI) || \ (PIC_IRQ0_MODE == PIC_EARLY_EOI_IRQ0) *routineEoi = NULL; #elif (PIC_IRQ0_MODE == PIC_SPECIAL_MASK_MODE_IRQ0) *routineEoi = i8259IntEoiSmm; #else *routineEoi = i8259IntEoiMaster; #endif /* (PIC_IRQ0_MODE == PIC_AUTO_EOI) || (PIC_EARLY_EOI_IRQ0) */ } else if (irqNo < 8) /* IRQ[1-7] EOI routine */ { #if (PIC_IRQ0_MODE == PIC_AUTO_EOI) *routineEoi = NULL; #else *routineEoi = i8259IntEoiMaster; #endif /* (PIC_IRQ0_MODE == PIC_AUTO_EOI) */ } else /* IRQ[8-15] EOI routine */ { #if defined (PIC_SPECIAL_FULLY_NESTED_MODE) *routineEoi = i8259IntEoiSlaveSfnm; #else *routineEoi = i8259IntEoiSlaveNfnm; #endif /* defined (PIC_SPECIAL_FULLY_NESTED_MODE) */ } #endif /* SYMMETRIC_IO_MODE */ } /******************************************************************************* * * sysIntLevel - get an IRQ(PIC) or INTIN(APIC) number in service * * This routine gets an IRQ(PIC) or INTIN(APIC) number in service. * We assume followings: * - this function is called in intEnt() * - IRQ number of the interrupt is at intConnectCode [29] * * RETURNS: 0 - (sysInumTblNumEnt - 1), or sysInumTblNumEnt if we failed to get it. * * ARGSUSED0 */ int sysIntLevel ( int arg /* parameter to get the stack pointer */ ) { UINT32 * pStack; UCHAR * pInst; INT32 ix; INT32 irqNo = sysInumTblNumEnt; /* return sysInumTblNumEnt if we failed */ pStack = &arg; /* get the stack pointer */ pStack += 3; /* skip pushed volitile registers */ /* * we are looking for a return address on the stack which point * to the next instruction of "call _intEnt" in the malloced stub. * Then get the irqNo at intConnectCode [29]. */ for (ix = 0; ix < 10; ix++, pStack++) { pInst = (UCHAR *)*pStack; /* return address */ if ((*pInst == 0x50) && /* intConnectCode [5] */ ((*(int *)(pInst - 4) + (int)pInst) == (int)intEnt)) { irqNo = *(int *)(pInst + 24); /* intConnectCode [29] */ break; } } return (irqNo); } /**************************************************************************** * * sysProcNumGet - get the processor number * * This routine returns the processor number for the CPU board, which is * set with sysProcNumSet(). * * RETURNS: The processor number for the CPU board. * * SEE ALSO: sysProcNumSet() */ int sysProcNumGet (void) { return (sysProcNum); } /**************************************************************************** * * sysProcNumSet - set the processor number * * Set the processor number for the CPU board. Processor numbers should be * unique on a single backplane. * * NOTE: By convention, only Processor 0 should dual-port its memory. * * RETURNS: N/A * * SEE ALSO: sysProcNumGet() */ void sysProcNumSet ( int procNum /* processor number */ ) { sysProcNum = procNum; } /******************************************************************************* * * sysDelay - allow recovery time for port accesses * * This routine provides a brief delay used between accesses to the same serial * port chip. * * RETURNS: N/A */ void sysDelay (void) { char ix; ix = sysInByte (UNUSED_ISA_IO_ADDRESS); /* it takes 720ns */ } /******************************************************************************* * * sysStrayInt - Do nothing for stray interrupts. * * Do nothing for stray interrupts. */ LOCAL void sysStrayInt (void) { sysStrayIntCount++; } /******************************************************************************* * * sysMmuMapAdd - insert a new MMU mapping * * This routine will create a new table entry for a memory * region of specified in bytes and with a specified base * . The and parameters specify * a PHYS_MEM_DESC type state mask and state for the memory region. * * CAVEATS * This routine must be used before the table is * referenced for the purpose of initializing the MMU or processor address * space (us. in usrMmuInit()). * * The in bytes will be rounded up to a multiple of VM_PAGE_SIZE * bytes if necessary. * * The current implementation assumes a one-to-one mapping of physical to * virtual addresses. * * RETURNS: OK or ERROR depending on availability of free mappings. * * SEE ALSO: vmLib */ STATUS sysMmuMapAdd ( void * address, /* memory region base address */ UINT length, /* memory region length in bytes*/ UINT initialStateMask, /* PHYS_MEM_DESC state mask */ UINT initialState /* PHYS_MEM_DESC state */ ) { STATUS result = OK; PHYS_MEM_DESC * const pMmu = &sysPhysMemDesc[sysPhysMemDescNumEnt]; if (pMmu->virtualAddr != (void *) DUMMY_VIRT_ADDR) { result = ERROR; } else { address = (void *)(((UINT32) address / VM_PAGE_SIZE) * VM_PAGE_SIZE); if ((length % VM_PAGE_SIZE) != 0) length = (length / VM_PAGE_SIZE + 1) * VM_PAGE_SIZE; pMmu->virtualAddr = address; pMmu->physicalAddr = address; pMmu->len = length; pMmu->initialStateMask = initialStateMask; pMmu->initialState = initialState; sysPhysMemDescNumEnt += 1; } return (result); }