Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3195 lines
77 KiB

4 years ago
  1. // ----------------------------------------------------------------------------
  2. // Copyright (c) 1992 Olivetti
  3. //
  4. // File: eisaini.c
  5. //
  6. // Description: EISA initialization routines.
  7. // ----------------------------------------------------------------------------
  8. //
  9. #include "fwp.h"
  10. #include "oli2msft.h"
  11. #include "arceisa.h"
  12. #include "inc.h"
  13. #include "string.h"
  14. #include "debug.h"
  15. #include "eisastr.h"
  16. //extern BL_DEVICE_ENTRY_TABLE OmfEntryTable[];
  17. // NOTE: Not used in JAZZ.
  18. //extern ULONG ErrorWord; // POD error flags
  19. //extern ULONG FlagWord; // system flags
  20. extern ULONG MemorySize; // size of memory in Mb
  21. extern PCHAR MnemonicTable[];
  22. extern ULONG EisaPoolSize; // # bytes really used
  23. extern ULONG EisaDynMemSize; // dynamic memory size (bytes)
  24. extern ULONG EisaFreeTop; // top of free mem
  25. extern ULONG EisaFreeBytes; // free bytes left
  26. // remove the following function prototypes when using common code
  27. PFW_MD
  28. GetFwMd
  29. (
  30. VOID
  31. );
  32. PFW_MD
  33. LinkPhysFwMd
  34. (
  35. PFW_MD * pFwMdBase,
  36. PFW_MD pFwMd
  37. );
  38. // ----------------------------------------------------------------------------
  39. // Declare Function Prototypes
  40. // ----------------------------------------------------------------------------
  41. VOID
  42. EisaIni
  43. (
  44. VOID
  45. );
  46. VOID
  47. EisaGeneralIni
  48. (
  49. VOID
  50. );
  51. BOOLEAN
  52. EisaBusStructIni
  53. (
  54. IN ULONG BusNumber
  55. );
  56. BOOLEAN
  57. EisaCheckAdapterComponent
  58. (
  59. IN ULONG BusNumber,
  60. OUT PCONFIGURATION_COMPONENT *pEisaComp
  61. );
  62. BOOLEAN
  63. EisaBusPod
  64. (
  65. IN ULONG BusNumber
  66. );
  67. BOOLEAN
  68. EisaPortIni
  69. (
  70. IN PUCHAR EisaIoStart
  71. );
  72. BOOLEAN
  73. EisaIntIni
  74. (
  75. IN PUCHAR EisaIoStart,
  76. IN PEISA_INT_INFO pIntInfo
  77. );
  78. BOOLEAN
  79. EisaDmaIni
  80. (
  81. IN PUCHAR EisaIoStart,
  82. IN PEISA_DMA_INFO pDmaInfo
  83. );
  84. BOOLEAN
  85. EisaBusCfg
  86. (
  87. IN PCONFIGURATION_COMPONENT EisaComponent
  88. );
  89. BOOLEAN
  90. EisaPhysSlotCfg
  91. (
  92. IN ULONG BusNumber,
  93. IN PCONFIGURATION_COMPONENT Controller,
  94. IN ULONG AdapId
  95. );
  96. BOOLEAN
  97. EisaVirSlotCfg
  98. (
  99. IN ULONG BusNumber,
  100. IN PCONFIGURATION_COMPONENT Controller
  101. );
  102. BOOLEAN
  103. EisaSlotCfg
  104. (
  105. IN ULONG BusNumber,
  106. IN PCONFIGURATION_COMPONENT Controller,
  107. IN UCHAR FunctionsNumber
  108. );
  109. BOOLEAN
  110. EisaSlotCfgMem
  111. (
  112. IN ULONG BusNumber,
  113. IN ULONG SlotNumber,
  114. IN PUCHAR EisaFuncInfo
  115. );
  116. BOOLEAN
  117. EisaSlotCfgIrq
  118. (
  119. IN PUCHAR EisaIoStart,
  120. IN PEISA_INT_INFO pIntInfo,
  121. IN PUCHAR EisaFuncInfo
  122. );
  123. BOOLEAN
  124. EisaSlotCfgDma
  125. (
  126. IN PUCHAR EisaIoStart,
  127. IN PEISA_DMA_INFO pDmaInfo,
  128. IN PUCHAR EisaFuncInfo
  129. );
  130. BOOLEAN
  131. EisaSlotCfgIni
  132. (
  133. IN PUCHAR EisaIoStart,
  134. IN PUCHAR EisaFuncInfo,
  135. OUT PBOOLEAN EnabAdapter
  136. );
  137. VOID
  138. EisaSlotErrorLog
  139. (
  140. IN ULONG BusNumber,
  141. IN ULONG SlotNumber,
  142. IN EISA_CFG_ERROR ErrorCode
  143. );
  144. VOID
  145. EisaPathErrorLog
  146. (
  147. IN PCONFIGURATION_COMPONENT Controller,
  148. IN EISA_CFG_ERROR ErrorCode
  149. );
  150. VOID
  151. EisaStrErrorLog
  152. (
  153. IN PCHAR Str,
  154. IN EISA_CFG_ERROR ErrorCode
  155. );
  156. VOID
  157. EisaCheckpointFirstFase
  158. (
  159. IN EISA_CHECKPOINT Chk
  160. );
  161. BOOLEAN
  162. EisaCheckpointFinalFase
  163. (
  164. IN EISA_CHECKPOINT Chk,
  165. IN BOOLEAN Passed
  166. );
  167. BOOLEAN
  168. EisaReadReadyId
  169. (
  170. IN PUCHAR EisaIoStart,
  171. IN ULONG SlotNumber,
  172. OUT PULONG AdapId
  173. );
  174. VOID
  175. EisaReadId
  176. (
  177. IN PUCHAR EisaIoStart,
  178. IN ULONG SlotNumber,
  179. OUT PULONG AdapId
  180. );
  181. BOOLEAN
  182. EisaMemIni
  183. (
  184. VOID
  185. );
  186. VOID
  187. EisaDynMemIni
  188. (
  189. VOID
  190. );
  191. PCONFIGURATION_COMPONENT
  192. FwGetChild
  193. (
  194. IN PCONFIGURATION_COMPONENT Component OPTIONAL
  195. );
  196. PCONFIGURATION_COMPONENT
  197. FwGetPeer
  198. (
  199. IN PCONFIGURATION_COMPONENT Component
  200. );
  201. PCONFIGURATION_COMPONENT
  202. FwAddChild
  203. (
  204. IN PCONFIGURATION_COMPONENT Component,
  205. IN PCONFIGURATION_COMPONENT NewComponent,
  206. IN PVOID ConfigurationData OPTIONAL
  207. );
  208. PCONFIGURATION_COMPONENT
  209. FwGetComponent
  210. (
  211. IN PCHAR Pathname
  212. );
  213. PCONFIGURATION_COMPONENT
  214. FwGetParent
  215. (
  216. IN PCONFIGURATION_COMPONENT Component
  217. );
  218. VOID
  219. FwStallExecution
  220. (
  221. IN ULONG Seconds
  222. );
  223. ARC_STATUS
  224. AllocateMemoryResources
  225. (
  226. IN OUT PFW_MD pBuffFwMd
  227. );
  228. // ----------------------------------------------------------------------------
  229. // Declare General Function Prototypes
  230. // ----------------------------------------------------------------------------
  231. PCHAR
  232. FwToUpperStr
  233. (
  234. IN OUT PCHAR s
  235. );
  236. PCHAR
  237. FwToLowerStr
  238. (
  239. IN OUT PCHAR s
  240. );
  241. PCHAR
  242. FwGetPath
  243. (
  244. IN PCONFIGURATION_COMPONENT Component,
  245. OUT PCHAR String
  246. );
  247. VOID
  248. FwDelCfgTreeNode
  249. (
  250. IN PCONFIGURATION_COMPONENT pComp,
  251. IN BOOLEAN Peer
  252. );
  253. PCHAR
  254. FwGetMnemonic
  255. (
  256. IN PCONFIGURATION_COMPONENT Component
  257. );
  258. BOOLEAN
  259. FwValidMnem
  260. (
  261. IN PCHAR Str
  262. );
  263. ULONG
  264. Fw2UcharToUlongLSB
  265. (
  266. IN PUCHAR String
  267. );
  268. ULONG
  269. Fw3UcharToUlongLSB
  270. (
  271. IN PUCHAR String
  272. );
  273. ULONG
  274. Fw4UcharToUlongLSB
  275. (
  276. IN PUCHAR String
  277. );
  278. ULONG
  279. Fw4UcharToUlongMSB
  280. (
  281. IN PUCHAR String
  282. );
  283. PCHAR
  284. FwStoreStr
  285. (
  286. IN PCHAR Str
  287. );
  288. // ----------------------------------------------------------------------------
  289. // GLOBAL: EISA configuration variables
  290. // ----------------------------------------------------------------------------
  291. // EISA buses info
  292. EISA_BUS_INFO EisaBusInfo[ EISA_BUSES ]; // eisa bus info pointers
  293. // descriptor pointers
  294. PFW_MD LogFwMdBase = NULL; // starting logical descriptors pointer
  295. PFW_MD VirFwMdBase = NULL; // starting virtual descriptors pointer
  296. PFW_MD pFwMdPool; // descriptors pool
  297. // ----------------------------------------------------------------------------
  298. // PROCEDURE: EisaIni:
  299. //
  300. // DESCRIPTION: This function does the eisa controller configuration.
  301. //
  302. // ARGUMENTS: none
  303. //
  304. // RETURN: none
  305. //
  306. // ASSUMPTIONS:
  307. //
  308. // CALLS:
  309. //
  310. // GLOBALS: ErrorWord
  311. //
  312. // NOTES:
  313. // ----------------------------------------------------------------------------
  314. //
  315. VOID
  316. EisaIni
  317. (
  318. VOID
  319. )
  320. {
  321. // define local variables
  322. PCONFIGURATION_COMPONENT pEisaComp; // eisa bus component
  323. CHAR EisaMnemonic[MAX_MNEMONIC_LEN +1]; // to hold the eisa path
  324. ULONG EisaBus; // eisa bus number
  325. BOOLEAN IniOk; // EISA configuration bus status
  326. PRINTDBG("EisaIni\n\r"); // DEBUG SUPPORT
  327. //
  328. // perform any general initialization
  329. //
  330. EisaGeneralIni();
  331. // NOTE: EisaMemIni not used on JAZZ.
  332. // if ( !EisaMemIni() )
  333. // {
  334. // EisaStrErrorLog("EISA Initialization", MemAllocError);
  335. // return;
  336. // }
  337. //
  338. // initialize and configure the eisa buses (one per loop)
  339. //
  340. for ( EisaBus = 0; EisaBus < EISA_BUSES; EisaBus++ )
  341. {
  342. //
  343. // display message
  344. //
  345. FwPrint(EISA_INIT_MSG, EisaBus);
  346. //
  347. // eisa bus structures initialization
  348. //
  349. if ( !EisaBusStructIni( EisaBus ))
  350. {
  351. EisaStrErrorLog( EISA_BUS_MSG, MemAllocError);
  352. return;
  353. }
  354. //
  355. // eisa bus hardware test and initialization
  356. //
  357. if ( EisaBusInfo[ EisaBus ].Flags.Error = !EisaBusPod( EisaBus ))
  358. {
  359. // ErrorWord |= E_HARDWARE_ERROR;
  360. }
  361. //
  362. // check the EISA adapter component
  363. //
  364. IniOk = TRUE;
  365. EisaCheckpointFirstFase( EisaCfg );
  366. if ( !EisaCheckAdapterComponent( EisaBus, &pEisaComp ))
  367. {
  368. IniOk = FALSE;
  369. }
  370. //
  371. // Return if no EISA information available.
  372. //
  373. if (pEisaComp == NULL) {
  374. return;
  375. }
  376. //
  377. // configure the bus if no hardware errors and configuration jumper not
  378. // present.
  379. //
  380. // NOTE: FlagWord is not used in JAZZ.
  381. // if (!EisaBusInfo[EisaBus].Flags.Error && !(FlagWord & F_CONFIG_JUMPER))
  382. if (!EisaBusInfo[EisaBus].Flags.Error)
  383. {
  384. if ( !EisaBusCfg( pEisaComp ))
  385. {
  386. IniOk = FALSE;
  387. }
  388. }
  389. EisaCheckpointFinalFase( EisaCfg, IniOk );
  390. if ( IniOk != TRUE )
  391. {
  392. // NOTE: Not used in JAZZ.
  393. // ErrorWord |= E_CONFIG_ERROR;
  394. }
  395. //
  396. // store the POD initialization status
  397. //
  398. EisaBusInfo[ EisaBus ].Flags.IniDone = 1;
  399. pEisaComp->Flags.Failed = EisaBusInfo[ EisaBus ].Flags.Error;
  400. if (IniOk == TRUE) {
  401. FwPrint(EISA_OK_MSG);
  402. FwStallExecution(500000);
  403. }
  404. FwPrint(EISA_CRLF_MSG);
  405. }
  406. //
  407. // Big Endian initialization
  408. //
  409. // NOTE: BigEndian is not used on JAZZ.
  410. // BiEndianIni();
  411. //
  412. // EISA dynamic memory initializzation
  413. //
  414. // NOTE: EisaDynMemIni not used on JAZZ.
  415. // EisaDynMemIni();
  416. //
  417. // OMF initialization: final phase
  418. //
  419. // NOTE: EisaOmfIni not used on JAZZ.
  420. // EisaOmfIni();
  421. //
  422. // Write out the hardware id, JAZZ only. The first page of the EISA
  423. // I/O control space is actually translated into a page of memory, where
  424. // the hardware ID is stored.
  425. //
  426. *(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c80) = (('J' - 'A' + 1) << 2) +
  427. (('A' - 'A' + 1) >> 3);
  428. *(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c81) = (('A' - 'A' + 1) << 5) +
  429. ('Z' - 'A' + 1);
  430. *(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c82) = 0;
  431. *(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c83) = 0;
  432. //
  433. // all done
  434. //
  435. return;
  436. }
  437. // ----------------------------------------------------------------------------
  438. // PROCEDURE: EisaGeneralIni:
  439. //
  440. // DESCRIPTION: This function performs general initialization
  441. // for the EISA buses.
  442. //
  443. // ARGUMENTS: none
  444. //
  445. // RETURN: none
  446. //
  447. // ASSUMPTIONS:
  448. //
  449. // CALLS:
  450. //
  451. // GLOBALS:
  452. //
  453. // NOTES:
  454. // ----------------------------------------------------------------------------
  455. //
  456. VOID
  457. EisaGeneralIni
  458. (
  459. VOID
  460. )
  461. {
  462. PRINTDBG("EisaGeneralIni\n\r"); // DEBUG SUPPORT
  463. //
  464. // update system parameter block
  465. //
  466. SYSTEM_BLOCK->AdapterCount = 1;
  467. SYSTEM_BLOCK->Adapter0Type = EisaAdapter;
  468. SYSTEM_BLOCK->Adapter0Length = (ULONG)MaximumEisaRoutine * sizeof(ULONG);
  469. SYSTEM_BLOCK->Adapter0Vector = (PVOID)(SYSTEM_BLOCK->VendorVector +
  470. SYSTEM_BLOCK->VendorVectorLength);
  471. //
  472. // initialize EISA call back vectors
  473. //
  474. (PEISA_PROCESS_EOI_RTN)SYSTEM_BLOCK->Adapter0Vector
  475. [ProcessEOIRoutine] = EisaProcessEndOfInterrupt;
  476. // [ProcessEOIRoutine] = FwpReservedRoutine;
  477. (PEISA_TEST_INT_RTN)SYSTEM_BLOCK->Adapter0Vector
  478. [TestIntRoutine] = EisaTestEisaInterrupt;
  479. // [TestIntRoutine] = FwpReservedRoutine;
  480. (PEISA_REQ_DMA_XFER_RTN)SYSTEM_BLOCK->Adapter0Vector
  481. // [RequestDMARoutine] = EisaRequestEisaDmaTransfer;
  482. [RequestDMARoutine] = FwpReservedRoutine;
  483. (PEISA_ABORT_DMA_RTN)SYSTEM_BLOCK->Adapter0Vector
  484. // [AbortDMARoutine] = EisaAbortEisaDmaTransfer;
  485. [AbortDMARoutine] = FwpReservedRoutine;
  486. (PEISA_DMA_XFER_STATUS_RTN)SYSTEM_BLOCK->Adapter0Vector
  487. // [GetDMAStatusRoutine] = EisaGetEisaDmaTransferStatus;
  488. [GetDMAStatusRoutine] = FwpReservedRoutine;
  489. (PEISA_LOCK_RTN)SYSTEM_BLOCK->Adapter0Vector
  490. // [DoLockRoutine] = EisaDoLockedOperation;
  491. [DoLockRoutine] = FwpReservedRoutine;
  492. (PEISA_REQUEST_BUS_MASTER_RTN)SYSTEM_BLOCK->Adapter0Vector
  493. // [RequestBusMasterRoutine] = EisaRequestEisaBusMasterTransfer;
  494. [RequestBusMasterRoutine] = FwpReservedRoutine;
  495. (PEISA_RELEASE_BUS_MASTER_RTN)SYSTEM_BLOCK->Adapter0Vector
  496. // [ReleaseBusMasterRoutine] = EisaReleaseEisaBusMasterTransfer;
  497. [ReleaseBusMasterRoutine] = FwpReservedRoutine;
  498. (PEISA_REQUEST_CPU_TO_BUS_ACCESS_RTN)SYSTEM_BLOCK->Adapter0Vector
  499. // [RequestCpuAccessToBusRoutine] = EisaRequestCpuAccessToEisaBus;
  500. [RequestCpuAccessToBusRoutine] = FwpReservedRoutine;
  501. (PEISA_RELEASE_CPU_TO_BUS_ACCESS_RTN)SYSTEM_BLOCK->Adapter0Vector
  502. // [ReleaseCpuAccessToBusRoutine] = EisaReleaseCpuAccessToEisaBus;
  503. [ReleaseCpuAccessToBusRoutine] = FwpReservedRoutine;
  504. (PEISA_FLUSH_CACHE_RTN)SYSTEM_BLOCK->Adapter0Vector
  505. // [FlushCacheRoutine] = EisaFlushCache;
  506. [FlushCacheRoutine] = FwpReservedRoutine;
  507. (PEISA_INVALIDATE_CACHE_RTN)SYSTEM_BLOCK->Adapter0Vector
  508. // [InvalidateCacheRoutine] = EisaInvalidateCache;
  509. [InvalidateCacheRoutine] = FwpReservedRoutine;
  510. (PEISA_BEGIN_CRITICAL_SECTION_RTN)SYSTEM_BLOCK->Adapter0Vector
  511. [BeginCriticalSectionRoutine] = EisaBeginCriticalSection;
  512. // [BeginCriticalSectionRoutine] = FwpReservedRoutine;
  513. (PEISA_RESERVED_RTN)SYSTEM_BLOCK->Adapter0Vector
  514. [ReservedRoutine] = NULL;
  515. (PEISA_END_CRITICAL_SECTION_RTN)SYSTEM_BLOCK->Adapter0Vector
  516. [EndCriticalSectionRoutine] = EisaEndCriticalSection;
  517. // [EndCriticalSectionRoutine] = FwpReservedRoutine;
  518. (PEISA_GENERATE_TONE_RTN)SYSTEM_BLOCK->Adapter0Vector
  519. [GenerateToneRoutine] = EisaGenerateTone;
  520. (PEISA_FLUSH_WRITE_BUFFER_RTN)SYSTEM_BLOCK->Adapter0Vector
  521. // [FlushWriteBuffersRoutine] = EisaFlushWriteBuffers;
  522. [FlushWriteBuffersRoutine] = FwpReservedRoutine;
  523. (PEISA_YIELD_RTN)SYSTEM_BLOCK->Adapter0Vector
  524. // [YieldRoutine] = EisaYield;
  525. [YieldRoutine] = FwpReservedRoutine;
  526. (PEISA_STALL_PROCESSOR_RTN)SYSTEM_BLOCK->Adapter0Vector
  527. [StallProcessorRoutine] = FwStallExecution;
  528. //
  529. // all done
  530. //
  531. return;
  532. }
  533. // ----------------------------------------------------------------------------
  534. // PROCEDURE: EisaBusStructIni:
  535. //
  536. // DESCRIPTION: This function builds all the required structures
  537. // for the specified EISA bus.
  538. //
  539. // ARGUMENTS: BusNumber EISA bus number
  540. //
  541. // RETURN: TRUE All done
  542. // FALSE Error
  543. //
  544. // ASSUMPTIONS:
  545. //
  546. // CALLS:
  547. //
  548. // GLOBALS:
  549. //
  550. // NOTES: This routine is hardware design dependent.
  551. //
  552. // ----------------------------------------------------------------------------
  553. //
  554. BOOLEAN
  555. EisaBusStructIni
  556. (
  557. IN ULONG BusNumber
  558. )
  559. {
  560. //
  561. // define local variables
  562. //
  563. PVOID pInfo; // General pointer
  564. PEISA_BUS_INFO pBusInfo; // EISA bus info pointer
  565. PFW_MD pIoBusInfo; // I/O info pointer
  566. PFW_MD pMemBusInfo; // Memory info pointer
  567. PEISA_SLOTS_INFO pSlotsInfo; // Slots info pointer
  568. PEISA_DMA_INFO pDmaInfo; // DMA info pointer
  569. PEISA_INT_INFO pIntInfo; // INT info pointer
  570. PEISA_PORT_INFO pPortInfo; // port info pointer
  571. ULONG Index; // general index
  572. PRINTDBG("EisaBusStructIni\n\r"); // DEBUG SUPPORT
  573. //
  574. // initialize variables
  575. //
  576. pBusInfo = &EisaBusInfo[ BusNumber ];
  577. pBusInfo->Flags.IniDone = 0;
  578. //
  579. // first EISA bus
  580. //
  581. if ( BusNumber == 0 )
  582. {
  583. //
  584. // perform any info structure initialization
  585. //
  586. if ((pInfo = (PVOID)FwAllocatePool( sizeof( FW_MD ) +
  587. sizeof( FW_MD ) +
  588. sizeof( EISA_SLOTS_INFO ) +
  589. sizeof( EISA_DMA_INFO ) +
  590. sizeof( EISA_INT_INFO ))) == NULL )
  591. {
  592. return FALSE;
  593. }
  594. //
  595. // I/O bus info initialization
  596. //
  597. pBusInfo->IoBusInfo = pIoBusInfo = (PFW_MD)pInfo;
  598. // set link and flags
  599. pIoBusInfo->Link = NULL;
  600. pIoBusInfo->Flags.Busy = 1;
  601. pIoBusInfo->Counter = 1;
  602. // set window size in 4k units
  603. pIoBusInfo->PhysAddr = EISA_IO_PHYSICAL_BASE/PAGE_SIZE;
  604. pIoBusInfo->PagOffs = 0;
  605. pIoBusInfo->VirAddr = (PVOID)EISA_EXTERNAL_IO_VIRTUAL_BASE;
  606. pIoBusInfo->Size = 64 * 1024;
  607. pIoBusInfo->PagNumb = 64/4;
  608. ((PFW_MD)pInfo)++;
  609. //
  610. // memory bus info initialization
  611. //
  612. pBusInfo->MemBusInfo = pMemBusInfo = (PFW_MD)pInfo;
  613. // set link and flags
  614. pMemBusInfo->Link = NULL;
  615. pMemBusInfo->Flags.Busy = 0; // window busy flag
  616. pMemBusInfo->Counter = 0;
  617. #ifdef KPW4010
  618. // set size of window in 4k units
  619. pMemBusInfo->PhysAddr = EISA_MEM_PHYSBASE_KPW4010; // #4kpages
  620. pMemBusInfo->PagOffs = 0;
  621. pMemBusInfo->VirAddr = (PVOID)EISA_VIR_MEM;
  622. pMemBusInfo->Size = 0; // 4 Gbytes
  623. pMemBusInfo->PagNumb = PAGES_IN_4G;
  624. //
  625. // Because the EISA memory space in some designs can reach
  626. // 4Gbytes of length, it is not possible to map the entire area.
  627. // The allocation of the TLB entries for this space is done at
  628. // run time using the general calls to the TLB services.
  629. //
  630. pMemBusInfo->u.em.WinRelAddr = 0;
  631. pMemBusInfo->u.em.WinRelAddrCtrl = NULL;
  632. pMemBusInfo->u.em.WinShift = PAGE_4G_SHIFT;
  633. #else // KPW 4000
  634. // set size of window in 4k units
  635. pMemBusInfo->PhysAddr = EISA_MEMORY_PHYSICAL_BASE/PAGE_SIZE;
  636. pMemBusInfo->PagOffs = 0;
  637. pMemBusInfo->VirAddr = (PVOID)EISA_MEMORY_VIRTUAL_BASE;
  638. pMemBusInfo->Size = PAGE_16M_SIZE;
  639. pMemBusInfo->PagNumb = PAGE_16M_SIZE/PAGE_SIZE;
  640. //
  641. // Because the EISA memory space in some designs can reach
  642. // 4Gbytes of length, it is not possible to map the entire area.
  643. // The allocation of the TLB entries for this space is done at
  644. // run time using the general calls to the TLB services.
  645. //
  646. pMemBusInfo->u.em.WinRelAddr = 0;
  647. pMemBusInfo->u.em.WinRelAddrCtrl = (PVOID)EISA_LATCH_VIRTUAL_BASE;
  648. pMemBusInfo->u.em.WinShift = PAGE_16M_SHIFT;
  649. #endif
  650. ((PFW_MD)pInfo)++;
  651. //
  652. // slot info initialization
  653. //
  654. pBusInfo->SlotsInfo = pSlotsInfo = (PEISA_SLOTS_INFO)pInfo;
  655. pSlotsInfo->PhysSlots = PHYS_0_SLOTS;
  656. pSlotsInfo->VirSlots = VIR_0_SLOTS;
  657. ((PEISA_SLOTS_INFO)pInfo)++;
  658. //
  659. // DMA info initialization
  660. //
  661. pBusInfo->DmaInfo = pDmaInfo = (PEISA_DMA_INFO)pInfo;
  662. pDmaInfo->Flags.IniDone = 0;
  663. ((PEISA_DMA_INFO)pInfo)++;
  664. //
  665. // PIC info initialization
  666. //
  667. pBusInfo->IntInfo = pIntInfo = (PEISA_INT_INFO)pInfo;
  668. pIntInfo->Flags.IniDone = 0;
  669. ((PEISA_INT_INFO)pInfo)++;
  670. //
  671. // port info initialization
  672. //
  673. pBusInfo->PortInfo = pPortInfo = (PEISA_PORT_INFO)pInfo;
  674. pPortInfo->Flags.IniDone = 0;
  675. }
  676. else
  677. {
  678. //
  679. // invalid bus number
  680. //
  681. return FALSE;
  682. }
  683. //
  684. // all done
  685. //
  686. return TRUE;
  687. }
  688. // ----------------------------------------------------------------------------
  689. // PROCEDURE: EisaCheckAdapterComponent:
  690. //
  691. // DESCRIPTION: This function makes sure that there is an EISA adapter
  692. // component with the correct configuration data for the
  693. // specified EISA bus number. The routine uses the
  694. // following logic :
  695. //
  696. // if !(ARC component present)
  697. // {
  698. // add ARC component;
  699. // }
  700. // if (EISA bus component present)
  701. // {
  702. // if !(configuration data correct)
  703. // {
  704. // display error message;
  705. // delete EISA bus node;
  706. // add EISA bus component;
  707. // return FALSE;
  708. // }
  709. // }
  710. // else
  711. // {
  712. // add EISA bus component;
  713. // }
  714. // return TRUE;
  715. //
  716. // ARGUMENTS: BusNumber EISA bus number
  717. // pEisaComp address where to store the EISA
  718. // configuration pointer
  719. //
  720. // RETURN: FALSE The configuration tree was incorrect.
  721. // TRUE The configuration tree is correct.
  722. //
  723. // ASSUMPTIONS: The ARC component is present.
  724. //
  725. // CALLS:
  726. //
  727. // GLOBALS:
  728. //
  729. // NOTES:
  730. // ----------------------------------------------------------------------------
  731. //
  732. BOOLEAN
  733. EisaCheckAdapterComponent
  734. (
  735. IN ULONG BusNumber,
  736. OUT PCONFIGURATION_COMPONENT *pEisaComp
  737. )
  738. {
  739. //
  740. // define local variables
  741. //
  742. PCONFIGURATION_COMPONENT pComp;
  743. CONFIGURATION_COMPONENT Comp;
  744. EISA_ADAPTER_DETAILS ConfigData;
  745. BOOLEAN CfgOk = TRUE;
  746. CHAR EisaMnemonic[MAX_MNEMONIC_LEN +1];
  747. PVOID IoStart;
  748. ULONG IoSize;
  749. ULONG Slots;
  750. PRINTDBG("EisaCheckAdapterComponent\n\r"); // DEBUG SUPPORT
  751. //
  752. // initialize varables
  753. //
  754. sprintf( EisaMnemonic, "eisa(%lu)", BusNumber );
  755. *pEisaComp = NULL;
  756. IoStart = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
  757. IoSize = EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots * 0x1000;
  758. Slots = EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots ?
  759. EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots + 16 :
  760. EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots;
  761. //
  762. // if EISA adapter component is present, check its configuration data
  763. //
  764. if ((*pEisaComp = FwGetComponent(EisaMnemonic)) != NULL)
  765. {
  766. if ((*pEisaComp)->ConfigurationDataLength !=
  767. sizeof(EISA_ADAPTER_DETAILS) ||
  768. FwGetConfigurationData( (PVOID)&ConfigData, *pEisaComp ) ||
  769. ConfigData.NumberOfSlots != Slots ||
  770. ConfigData.IoStart != IoStart ||
  771. ConfigData.IoSize != IoSize )
  772. {
  773. EisaPathErrorLog( *pEisaComp, CfgIncorrect );
  774. FwDelCfgTreeNode( *pEisaComp, FALSE );
  775. *pEisaComp = NULL;
  776. CfgOk = FALSE;
  777. }
  778. }
  779. //
  780. // add EISA adapter component if not present
  781. //
  782. if ( *pEisaComp == NULL )
  783. {
  784. // get the root component pointer
  785. if ((pComp = FwGetChild(NULL)) == NULL) {
  786. return(FALSE);
  787. }
  788. // component structure
  789. RtlZeroMemory( &Comp, sizeof(CONFIGURATION_COMPONENT));
  790. Comp.Class = AdapterClass;
  791. Comp.Type = EisaAdapter;
  792. Comp.Version = ARC_VERSION;
  793. Comp.Revision = ARC_REVISION;
  794. Comp.Key = BusNumber;
  795. Comp.ConfigurationDataLength = sizeof(EISA_ADAPTER_DETAILS);
  796. Comp.IdentifierLength = sizeof("EISA");
  797. Comp.Identifier = "EISA";
  798. // configuration data structure
  799. RtlZeroMemory( &ConfigData, sizeof(EISA_ADAPTER_DETAILS));
  800. // NOTE: ConfigDataHeader is not used in JAZZ.
  801. // ConfigData.ConfigDataHeader.Version = ARC_VERSION;
  802. // ConfigData.ConfigDataHeader.Revision = ARC_REVISION;
  803. // ConfigData.ConfigDataHeader.Type = NULL;
  804. // ConfigData.ConfigDataHeader.Vendor = NULL;
  805. // ConfigData.ConfigDataHeader.ProductName = NULL;
  806. // ConfigData.ConfigDataHeader.SerialNumber = NULL;
  807. ConfigData.NumberOfSlots = Slots;
  808. ConfigData.IoStart = IoStart;
  809. ConfigData.IoSize = IoSize;
  810. *pEisaComp = FwAddChild( pComp, &Comp, (PVOID)&ConfigData );
  811. }
  812. //
  813. // return status
  814. //
  815. return CfgOk;
  816. }
  817. // ----------------------------------------------------------------------------
  818. // PROCEDURE: EisaBusCfg:
  819. //
  820. // DESCRIPTION: This function configures the slots of the specified
  821. // eisa bus.
  822. //
  823. // if we detect a "not-ready" board, we have to retry
  824. // reading the ID again and report a time-out error if
  825. // the ID is still not available after 100 msecs.
  826. // (according to the EISA specs, the board should be
  827. // ready within 100 msecs after reporting the "not-ready"
  828. // status). However, due to the slow init process of
  829. // the ESC-1, we need to go with the following algorithm:
  830. // - cfg the physical slots, marking the ones not ready.
  831. // - cfg the virtual slots
  832. // - go back to cfg the not-ready physical slots.
  833. // A time of 2 sec will be given to all these not-ready
  834. // slots : 200 loops of 10 msec. This period does not
  835. // include configuration time for any slot which now
  836. // comes up with a valid ID.
  837. //
  838. // ARGUMENTS: EisaComponent EISA component pointer
  839. //
  840. // RETURN: TRUE Configuration completed successfully
  841. // FALSE At least one configuration error
  842. //
  843. // ASSUMPTIONS:
  844. //
  845. // CALLS:
  846. //
  847. // GLOBALS:
  848. //
  849. // NOTES:
  850. // ----------------------------------------------------------------------------
  851. //
  852. BOOLEAN
  853. EisaBusCfg
  854. (
  855. IN PCONFIGURATION_COMPONENT EisaComponent
  856. )
  857. {
  858. //
  859. // define local variables
  860. //
  861. BOOLEAN CfgOk = TRUE; // starting value: all fine
  862. ULONG IdTimeoutFlags = 0; // eisa controllers in time-out
  863. USHORT WaitTimeout=TIMEOUT_UNITS; // time to wait before aborting
  864. PCONFIGURATION_COMPONENT FirstController; // first eisa controller
  865. PCONFIGURATION_COMPONENT Controller; // eisa controller to configure
  866. ULONG BusNumber; // eisa bus number
  867. ULONG PhysSlots; // eisa physical slots
  868. ULONG MaxSlots; // eisa last slot
  869. ULONG SlotNumber; // slot number configured
  870. PULONG pSlotCfgMap; // slot cfg map pointer
  871. PUCHAR EisaIoStart; // i/o eisa starting space
  872. ULONG AdapId; // eisa controller id
  873. PRINTDBG("EisaBusCfg\n\r"); // DEBUG SUPPORT
  874. //
  875. // initialize same variables using the eisa component structure
  876. //
  877. BusNumber = EisaComponent->Key;
  878. EisaIoStart = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
  879. PhysSlots = EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots;
  880. MaxSlots = EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots + 16;
  881. pSlotCfgMap = &EisaBusInfo[ BusNumber ].SlotsInfo->SlotCfgMap;
  882. *pSlotCfgMap = 0;
  883. FirstController = FwGetChild(EisaComponent);
  884. //
  885. // physical slot initialization : one loop per physical slot
  886. //
  887. for (SlotNumber=0; SlotNumber<PhysSlots; SlotNumber++)
  888. {
  889. // read eisa controller id
  890. if (!EisaReadReadyId(EisaIoStart, SlotNumber, &AdapId))
  891. {
  892. IdTimeoutFlags |= 1<<SlotNumber;
  893. continue;
  894. }
  895. // find the eisa controller for the specified slot
  896. for (Controller = FirstController;
  897. Controller!=NULL && Controller->Key!=SlotNumber;
  898. Controller = FwGetPeer(Controller));
  899. // skip cfg if empty slot; report an error if ARC cfg is missing
  900. if (Controller==NULL)
  901. {
  902. if (AdapId!=NO_ADAP_ID)
  903. {
  904. EisaSlotErrorLog( BusNumber, SlotNumber, CfgMissing );
  905. CfgOk = FALSE;
  906. }
  907. continue;
  908. }
  909. // one physical slot configuration
  910. if (!EisaPhysSlotCfg(BusNumber, Controller, AdapId))
  911. {
  912. CfgOk = FALSE;
  913. continue;
  914. }
  915. // set the "slot" bit to indicate configuration ok
  916. *pSlotCfgMap |= 1<<SlotNumber;
  917. // I/O function structures initialization
  918. // NOTE: EisaOmf is not supported in JAZZ.
  919. // EisaOmfCheck( BusNumber, Controller, AdapId );
  920. }
  921. //
  922. // virtual slot initialization : one loop per virtual slot
  923. //
  924. for (SlotNumber=16; SlotNumber<MaxSlots; SlotNumber++)
  925. {
  926. // find the eisa controller for the specified slot
  927. for (Controller = FirstController;
  928. Controller!=NULL && Controller->Key!=SlotNumber;
  929. Controller = FwGetPeer(Controller));
  930. // if component not present, skip to next virtual slot
  931. if (Controller==NULL)
  932. {
  933. continue;
  934. }
  935. // one virtual slot configuration
  936. if(!EisaVirSlotCfg(BusNumber, Controller))
  937. {
  938. CfgOk = FALSE;
  939. continue;
  940. }
  941. // set the "slot" bit to indicate configuration ok
  942. *pSlotCfgMap |= 1<<SlotNumber;
  943. }
  944. //
  945. // time-out slot initialization
  946. //
  947. while(IdTimeoutFlags && WaitTimeout--)
  948. {
  949. for ( SlotNumber = 0;
  950. IdTimeoutFlags && SlotNumber < PHYS_0_SLOTS;
  951. SlotNumber++ )
  952. {
  953. // check if the slot wasn't ready.
  954. if ( !(IdTimeoutFlags & 1<<SlotNumber))
  955. {
  956. continue;
  957. }
  958. // read eisa controller id
  959. if (!EisaReadReadyId(EisaIoStart, SlotNumber, &AdapId))
  960. {
  961. continue;
  962. }
  963. IdTimeoutFlags &= ~(1<<SlotNumber);
  964. // find the eisa controller for the specified slot
  965. for (Controller = FirstController;
  966. Controller!=NULL && Controller->Key!=SlotNumber;
  967. Controller = FwGetPeer(Controller));
  968. // skip cfg if empty slot; report an error if ARC cfg is missing
  969. if (Controller==NULL)
  970. {
  971. if (AdapId!=NO_ADAP_ID)
  972. {
  973. EisaSlotErrorLog(BusNumber, SlotNumber, CfgMissing);
  974. CfgOk = FALSE;
  975. }
  976. continue;
  977. }
  978. // one physical slot configuration
  979. if (!EisaPhysSlotCfg(BusNumber, Controller, AdapId))
  980. {
  981. CfgOk = FALSE;
  982. continue;
  983. }
  984. // set the "slot" bit to indicate configuration ok
  985. *pSlotCfgMap |= 1<<SlotNumber;
  986. // I/O function structures initialization
  987. // NOTE: EisaOmf is not supported in JAZZ.
  988. // EisaOmfCheck( BusNumber, Controller, AdapId );
  989. }
  990. // if there are still some slots in time-out stall execution
  991. // for 10 msec (10,000 usec).
  992. if (IdTimeoutFlags)
  993. {
  994. FwStallExecution (10000l);
  995. }
  996. }
  997. //
  998. // if controllers in time-out, display error messages and set the
  999. // failed bit within the associated "components".
  1000. //
  1001. if (IdTimeoutFlags)
  1002. {
  1003. for ( SlotNumber = 0; SlotNumber < PHYS_0_SLOTS; SlotNumber++ )
  1004. {
  1005. if ( IdTimeoutFlags & 1<<SlotNumber )
  1006. {
  1007. // display error message
  1008. EisaSlotErrorLog( BusNumber, SlotNumber, IdTimeout );
  1009. // find the eisa controller for the specified slot
  1010. for (Controller = FirstController;
  1011. Controller!=NULL && Controller->Key!=SlotNumber;
  1012. Controller = FwGetPeer(Controller));
  1013. // if component present, set failed bit
  1014. if (Controller != NULL)
  1015. {
  1016. Controller->Flags.Failed = 1;
  1017. }
  1018. }
  1019. }
  1020. CfgOk = FALSE;
  1021. }
  1022. // //
  1023. // // add a wild omf path name for the physical slots non configurated.
  1024. // //
  1025. //
  1026. // for ( SlotNumber = 0; SlotNumber < PHYS_0_SLOTS; SlotNumber++ )
  1027. // {
  1028. // if ( !(*pSlotCfgMap & 1<<SlotNumber) )
  1029. // {
  1030. // EisaOtherOmfIni( EisaComponent, SlotNumber );
  1031. // }
  1032. // }
  1033. //
  1034. // return configuration status
  1035. //
  1036. return CfgOk;
  1037. }
  1038. // ----------------------------------------------------------------------------
  1039. // PROCEDURE: EisaPhysSlotCfg:
  1040. //
  1041. // DESCRIPTION: This function configures the specified physical slot.
  1042. //
  1043. // ARGUMENTS: BusNumber EISA bus number
  1044. // Controller eisa controller component pointer.
  1045. // AdapId Eisa Id read from hardware.
  1046. //
  1047. //
  1048. // RETURN: FALSE Error
  1049. // TRUE All done
  1050. //
  1051. // ASSUMPTIONS:
  1052. //
  1053. // CALLS:
  1054. //
  1055. // GLOBALS:
  1056. //
  1057. // NOTES:
  1058. // ----------------------------------------------------------------------------
  1059. //
  1060. BOOLEAN
  1061. EisaPhysSlotCfg
  1062. (
  1063. IN ULONG BusNumber,
  1064. IN PCONFIGURATION_COMPONENT Controller,
  1065. IN ULONG AdapId
  1066. )
  1067. {
  1068. //
  1069. // define local variables
  1070. //
  1071. EISA_SLOT_INFO EisaSlotInfo; // pointer to first eisa info
  1072. EISA_CFG_ERROR ErrMessage = CfgNoErrCode; // eisa cfg error code
  1073. PRINTDBG("EisaPhysSlotCfg\n\r"); // DEBUG SUPPORT
  1074. //
  1075. // validate physical slot configuration
  1076. //
  1077. if (Controller->Flags.Failed)
  1078. {
  1079. ErrMessage = CfgDeviceFailed; // device failure
  1080. }
  1081. else if ( !(Controller->ConfigurationDataLength) )
  1082. {
  1083. ErrMessage = CfgMissing; // eisa configuration missing
  1084. }
  1085. else if (Controller->ConfigurationDataLength < EISA_SLOT_MIN_INFO)
  1086. {
  1087. ErrMessage = CfgIncorrect; // configuration length incorrect
  1088. }
  1089. else if (FwGetConfigurationDataIndex( (PVOID)&EisaSlotInfo,
  1090. Controller,
  1091. CONFIGDATAHEADER_SIZE,
  1092. EISA_SLOT_INFO_SIZE ))
  1093. {
  1094. ErrMessage = CfgIncorrect; // invalid component
  1095. }
  1096. else if (EisaSlotInfo.FunctionsNumber * EISA_FUNC_INFO_SIZE +
  1097. EISA_SLOT_MIN_INFO != Controller->ConfigurationDataLength)
  1098. {
  1099. ErrMessage = CfgIncorrect; // configuration length incorrect
  1100. }
  1101. else if (!(EisaSlotInfo.IdInfo & CFG_UNREADABLE_ID)^(AdapId != NO_ADAP_ID))
  1102. {
  1103. ErrMessage = CfgIdError; // wrong configuration
  1104. }
  1105. else if (AdapId != NO_ADAP_ID &&
  1106. AdapId != Fw4UcharToUlongMSB(&EisaSlotInfo.Id1stChar))
  1107. {
  1108. ErrMessage = CfgIdError; // wrong configuration
  1109. }
  1110. else if ((EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_EXP &&
  1111. (EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_EMB )
  1112. {
  1113. ErrMessage = CfgIncorrect; // wrong configuration
  1114. }
  1115. //
  1116. // if any error, dispaly error message and set the failed bit
  1117. //
  1118. if (ErrMessage != CfgNoErrCode)
  1119. {
  1120. EisaSlotErrorLog( BusNumber, Controller->Key, ErrMessage );
  1121. Controller->Flags.Failed = 1;
  1122. return FALSE;
  1123. }
  1124. //
  1125. // eisa adapter configuration
  1126. //
  1127. return( EisaSlotCfg( BusNumber,
  1128. Controller,
  1129. EisaSlotInfo.FunctionsNumber ));
  1130. }
  1131. // ----------------------------------------------------------------------------
  1132. // PROCEDURE: EisaVirSlotCfg:
  1133. //
  1134. // DESCRIPTION: This function configures the specified virtual slot.
  1135. //
  1136. // ARGUMENTS: BusNumber EISA bus number
  1137. // Controller eisa controller component pointer.
  1138. //
  1139. //
  1140. // RETURN: FALSE Error
  1141. // TRUE All done
  1142. //
  1143. // ASSUMPTIONS:
  1144. //
  1145. // CALLS:
  1146. //
  1147. // GLOBALS:
  1148. //
  1149. // NOTES:
  1150. // ----------------------------------------------------------------------------
  1151. //
  1152. BOOLEAN
  1153. EisaVirSlotCfg
  1154. (
  1155. IN ULONG BusNumber,
  1156. IN PCONFIGURATION_COMPONENT Controller
  1157. )
  1158. {
  1159. //
  1160. // define local variables
  1161. //
  1162. EISA_SLOT_INFO EisaSlotInfo; // pointer to first eisa info
  1163. EISA_CFG_ERROR ErrMessage = CfgNoErrCode; // eisa cfg error code
  1164. PRINTDBG("EisaVirSlotCfg\n\r"); // DEBUG SUPPORT
  1165. //
  1166. // validate virtual slot configuration
  1167. //
  1168. if (Controller->Flags.Failed)
  1169. {
  1170. ErrMessage = CfgDeviceFailed; // device failure
  1171. }
  1172. else if ( !(Controller->ConfigurationDataLength) )
  1173. {
  1174. ErrMessage = CfgMissing; // configuration missing
  1175. }
  1176. if (Controller->ConfigurationDataLength < EISA_SLOT_MIN_INFO)
  1177. {
  1178. ErrMessage = CfgIncorrect; // configuration length incorrect
  1179. }
  1180. else if (FwGetConfigurationDataIndex( (PVOID)&EisaSlotInfo,
  1181. Controller,
  1182. CONFIGDATAHEADER_SIZE,
  1183. EISA_SLOT_INFO_SIZE ))
  1184. {
  1185. ErrMessage = CfgIncorrect; // invalid component
  1186. }
  1187. else if (EisaSlotInfo.FunctionsNumber * EISA_FUNC_INFO_SIZE +
  1188. EISA_SLOT_MIN_INFO != Controller->ConfigurationDataLength)
  1189. {
  1190. ErrMessage = CfgIncorrect; // configuration length incorrect
  1191. }
  1192. else if ( !(EisaSlotInfo.IdInfo & CFG_UNREADABLE_ID) )
  1193. {
  1194. ErrMessage = CfgIdError; // wrong configuration
  1195. }
  1196. else if ( (EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_VIR)
  1197. {
  1198. ErrMessage = CfgIncorrect; // wrong configuration
  1199. }
  1200. //
  1201. // if any error, display error message and set the failed bit
  1202. //
  1203. if (ErrMessage != CfgNoErrCode)
  1204. {
  1205. EisaSlotErrorLog( BusNumber, Controller->Key, ErrMessage );
  1206. Controller->Flags.Failed = 1;
  1207. return FALSE;
  1208. }
  1209. //
  1210. // eisa adapter configuration
  1211. //
  1212. return( EisaSlotCfg( BusNumber,
  1213. Controller,
  1214. EisaSlotInfo.FunctionsNumber ));
  1215. }
  1216. // ----------------------------------------------------------------------------
  1217. // PROCEDURE: EisaSlotCfg:
  1218. //
  1219. // DESCRIPTION: This function configures the specified slot.
  1220. //
  1221. // ARGUMENTS: BusNumber EISA bus number
  1222. // Controller Controller component pointer
  1223. // FunctionsNumber Number of function to configure
  1224. //
  1225. // RETURN: TRUE Configuration done
  1226. // FALSE Error
  1227. //
  1228. // ASSUMPTIONS:
  1229. //
  1230. // CALLS:
  1231. //
  1232. // GLOBALS:
  1233. //
  1234. // NOTES:
  1235. // ----------------------------------------------------------------------------
  1236. //
  1237. BOOLEAN
  1238. EisaSlotCfg
  1239. (
  1240. IN ULONG BusNumber,
  1241. IN PCONFIGURATION_COMPONENT Controller,
  1242. IN UCHAR FunctionsNumber
  1243. )
  1244. {
  1245. //
  1246. // define local variables
  1247. //
  1248. UCHAR FuncFlags; // function info flags
  1249. UCHAR Function; // current function number
  1250. BOOLEAN CfgOk = TRUE; // local configuration status
  1251. BOOLEAN EnabAdapter = TRUE; // adapter enable flag
  1252. PUCHAR EnabPort; // used to enable the adapter
  1253. PUCHAR EisaIoStart; // Eisa I/O virtual space
  1254. PEISA_DMA_INFO pDmaInfo; // DMA info pointer
  1255. PEISA_INT_INFO pIntInfo; // interrupts info pointer
  1256. BOOLEAN CfgMemOk = TRUE; // prevent multiple messages
  1257. BOOLEAN CfgIrqOk = TRUE; // " " "
  1258. BOOLEAN CfgDmaOk = TRUE; // " " "
  1259. BOOLEAN CfgIniOk = TRUE; // " " "
  1260. UCHAR EisaFuncInfo[ EISA_FUNC_INFO_SIZE ];
  1261. ULONG EisaFuncIndex;
  1262. PRINTDBG("EisaSlotCfg\n\r"); // DEBUG SUPPORT
  1263. //
  1264. // initialize variables
  1265. //
  1266. EisaIoStart = (PUCHAR)EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
  1267. pDmaInfo = EisaBusInfo[ BusNumber ].DmaInfo;
  1268. pIntInfo = EisaBusInfo[ BusNumber ].IntInfo;
  1269. EisaFuncIndex = EISA_SLOT_MIN_INFO;
  1270. //
  1271. // one function per loop
  1272. //
  1273. for ( Function = 0;
  1274. Function < FunctionsNumber;
  1275. Function++, EisaFuncIndex += EISA_FUNC_INFO_SIZE )
  1276. {
  1277. //
  1278. // read function info
  1279. //
  1280. FwGetConfigurationDataIndex( (PVOID)EisaFuncInfo,
  1281. Controller,
  1282. EisaFuncIndex,
  1283. EISA_FUNC_INFO_SIZE );
  1284. //
  1285. // check if configuration complete, exit if not.
  1286. //
  1287. if ( EisaFuncInfo[ CFG_SLOT_INFO_OFS ] & CFG_INCOMPLETE )
  1288. {
  1289. EisaSlotErrorLog( BusNumber, Controller->Key, CfgIncomplete );
  1290. CfgOk = FALSE;
  1291. break;
  1292. }
  1293. // update eisa function flags
  1294. FuncFlags = EisaFuncInfo[ CFG_FN_INFO_OFS ];
  1295. // skip if free form function
  1296. if ( FuncFlags & CFG_FREE_FORM )
  1297. {
  1298. continue;
  1299. }
  1300. //
  1301. // check if there is any memory entry
  1302. //
  1303. // NOTE: Eisa memory not supported on JAZZ.
  1304. // if ( FuncFlags & CFG_MEM_ENTRY )
  1305. // {
  1306. // if ( !EisaSlotCfgMem( BusNumber, Controller->Key, EisaFuncInfo ) &&
  1307. // CfgMemOk )
  1308. // {
  1309. // EisaSlotErrorLog( BusNumber, Controller->Key, CfgMemError );
  1310. // CfgOk = CfgMemOk = FALSE;
  1311. // }
  1312. // }
  1313. //
  1314. // check if there is any interrupt entry
  1315. //
  1316. if ( FuncFlags & CFG_IRQ_ENTRY )
  1317. {
  1318. if (!EisaSlotCfgIrq( EisaIoStart, pIntInfo, EisaFuncInfo ) &&
  1319. CfgIrqOk )
  1320. {
  1321. EisaSlotErrorLog( BusNumber, Controller->Key, CfgIrqError );
  1322. CfgOk = CfgIrqOk = FALSE;
  1323. }
  1324. }
  1325. //
  1326. // check if there is any DMA entry
  1327. //
  1328. if ( FuncFlags & CFG_DMA_ENTRY )
  1329. {
  1330. if ( !EisaSlotCfgDma( EisaIoStart, pDmaInfo, EisaFuncInfo ) &&
  1331. CfgDmaOk )
  1332. {
  1333. EisaSlotErrorLog( BusNumber, Controller->Key, CfgDmaError );
  1334. CfgOk = CfgDmaOk = FALSE;
  1335. }
  1336. }
  1337. //
  1338. // check if there is any port init entry
  1339. //
  1340. if ( FuncFlags & CFG_INI_ENTRY )
  1341. {
  1342. if ( !EisaSlotCfgIni( EisaIoStart, EisaFuncInfo, &EnabAdapter ) &&
  1343. CfgIniOk )
  1344. {
  1345. EisaSlotErrorLog( BusNumber, Controller->Key, CfgIniError );
  1346. CfgOk = CfgIniOk = FALSE;
  1347. }
  1348. }
  1349. }
  1350. //
  1351. // if all fine, enable the adapter
  1352. //
  1353. if (CfgOk && EnabAdapter)
  1354. {
  1355. EnabPort=EisaIoStart+ Controller->Key*0x1000 +EXPANSION_BOARD_CTRL_BITS;
  1356. EisaOutUchar(EnabPort, EisaInUchar(EnabPort) | 0x01);
  1357. }
  1358. //
  1359. // return status of configuration process
  1360. //
  1361. return CfgOk;
  1362. }
  1363. // ----------------------------------------------------------------------------
  1364. // PROCEDURE: EisaSlotCfgMem:
  1365. //
  1366. // DESCRIPTION: This function configures the eisa memory registers
  1367. // based on info from NVRAM.
  1368. //
  1369. // ARGUMENTS: BusNumber EISA bus number.
  1370. // SlotNumber EISA slot number.
  1371. // EisaFuncInfo Function info pointer.
  1372. //
  1373. // RETURN: TRUE All done
  1374. // FALSE Error
  1375. //
  1376. // ASSUMPTIONS:
  1377. //
  1378. // CALLS:
  1379. //
  1380. // GLOBALS:
  1381. //
  1382. // NOTES:
  1383. // ----------------------------------------------------------------------------
  1384. //
  1385. // NOTE: Eisa memory not supported on JAZZ.
  1386. #if 0
  1387. BOOLEAN
  1388. EisaSlotCfgMem
  1389. (
  1390. IN ULONG BusNumber,
  1391. IN ULONG SlotNumber,
  1392. IN PUCHAR EisaFuncInfo
  1393. )
  1394. {
  1395. //
  1396. // define local variables
  1397. //
  1398. BOOLEAN CfgOk = TRUE; // local configuration status
  1399. PUCHAR MemBlock; // start of DMA data buffer
  1400. USHORT Index = 0; // index within the memory block
  1401. PFW_MD pFwMd; // memory decriptor pointer
  1402. ULONG Addr; // address in 256 units
  1403. ULONG Size; // size in 1k units
  1404. ULONG WinSize, WinOffs; // EISA windows characteristic
  1405. PFW_MD pMemInfo; // EISA memory address space info
  1406. PRINTDBG("EisaSlotCfgMem\n\r"); // DEBUG SUPPORT
  1407. //
  1408. // initialize variables
  1409. //
  1410. pMemInfo = EisaBusInfo[ BusNumber ].MemBusInfo;
  1411. MemBlock = &EisaFuncInfo[ CFG_MEM_BLK_OFS ];
  1412. //
  1413. // one loop per each memory entry
  1414. //
  1415. do
  1416. {
  1417. //
  1418. // get a memory descriptor
  1419. //
  1420. if ( (pFwMd = GetFwMd()) == NULL )
  1421. {
  1422. EisaSlotErrorLog( BusNumber, SlotNumber, MemAllocError);
  1423. return FALSE;
  1424. }
  1425. //
  1426. // memory block start and length
  1427. //
  1428. Addr = Fw3UcharToUlongLSB( &MemBlock[Index + 2] );
  1429. Size = Fw2UcharToUlongLSB( &MemBlock[Index + 5] );
  1430. pFwMd->VirAddr = NULL;
  1431. pFwMd->PhysAddr = Addr >> 4;
  1432. pFwMd->PagOffs = (Addr << 8) & (PAGE_SIZE - 1);
  1433. pFwMd->Size = Size ? Size << 10 : 64*1024*1024 ;
  1434. pFwMd->PagNumb = (pFwMd->PagOffs + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
  1435. pFwMd->Cache = FALSE;
  1436. pFwMd->u.m.BusNumber = BusNumber;
  1437. pFwMd->u.m.SlotNumber = SlotNumber;
  1438. pFwMd->u.m.Type = MemBlock[ Index ] & CFG_MEM_TYPE;
  1439. //
  1440. // check if the memory size fits within the EISA window
  1441. //
  1442. if ( pMemInfo->u.em.WinShift != PAGE_4G_SHIFT )
  1443. {
  1444. // window size < 4 Gbytes
  1445. WinSize = 1 << pMemInfo->u.em.WinShift;
  1446. WinOffs = (Addr << 8) & (WinSize - 1);
  1447. if ( WinSize - WinOffs < pFwMd->Size )
  1448. {
  1449. ReleaseFwMd( &pMemInfo->Link, pFwMd );
  1450. CfgOk = FALSE;
  1451. continue;
  1452. }
  1453. }
  1454. //
  1455. // link the memory descriptor
  1456. //
  1457. if ( LinkPhysFwMd( &pMemInfo->Link, pFwMd ) == NULL )
  1458. {
  1459. ReleaseFwMd( &pMemInfo->Link, pFwMd );
  1460. CfgOk = FALSE;
  1461. continue;
  1462. }
  1463. }
  1464. while ((MemBlock[Index]&CFG_MORE_ENTRY) && ((Index+=7)<CFG_MEM_BLK_LEN));
  1465. //
  1466. // check final index
  1467. //
  1468. if ( !(Index < CFG_MEM_BLK_LEN) )
  1469. {
  1470. CfgOk=FALSE;
  1471. }
  1472. //
  1473. // return configuration status
  1474. //
  1475. return CfgOk;
  1476. }
  1477. #endif // 0
  1478. // ----------------------------------------------------------------------------
  1479. // PROCEDURE: EisaSlotCfgIrq:
  1480. //
  1481. // DESCRIPTION: This function configures the interrupt registers
  1482. // based on info from NVRAM.
  1483. //
  1484. // ARGUMENTS: EisaIoStart EISA I/O virtual address
  1485. // pIntInfo interrupt info pointer
  1486. // EisaFuncInfo function info pointer.
  1487. //
  1488. // RETURN: TRUE All done
  1489. // FALSE Error
  1490. //
  1491. // ASSUMPTIONS:
  1492. //
  1493. // CALLS:
  1494. //
  1495. // GLOBALS:
  1496. //
  1497. // NOTES:
  1498. // ----------------------------------------------------------------------------
  1499. //
  1500. BOOLEAN
  1501. EisaSlotCfgIrq
  1502. (
  1503. IN PUCHAR EisaIoStart,
  1504. IN PEISA_INT_INFO pIntInfo,
  1505. IN PUCHAR EisaFuncInfo
  1506. )
  1507. {
  1508. //
  1509. // define local variables
  1510. //
  1511. BOOLEAN CfgOk = TRUE; // local configuration status
  1512. PUCHAR IrqBlock; // start of IRQ data buffer
  1513. USHORT Index = 0; // index within the IRQ block
  1514. USHORT IrqBit; // 0x1=IRQ0... 0x8000=IRQ15
  1515. UCHAR Register; // used to update the registers
  1516. PRINTDBG("EisaSlotCfgIrq\n\r"); // DEBUG SUPPORT
  1517. //
  1518. // initialize variables
  1519. //
  1520. IrqBlock = &EisaFuncInfo[ CFG_IRQ_BLK_OFS ];
  1521. //
  1522. // one loop per each IRQ entries
  1523. //
  1524. do
  1525. {
  1526. IrqBit = 1 << ( IrqBlock[ Index ] & CFG_IRQ_MASK ); // compute IRQ bit
  1527. //
  1528. // check shareable and edge/level trigger mode
  1529. //
  1530. if ( pIntInfo->IrqPresent & IrqBit )
  1531. {
  1532. //
  1533. // IRQ already used: check if it is shareabe
  1534. //
  1535. if ( !(pIntInfo->IrqShareable & IrqBit) )
  1536. {
  1537. CfgOk = FALSE;
  1538. continue;
  1539. }
  1540. else if ( !(IrqBlock[Index] & CFG_IRQ_SHARE) )
  1541. {
  1542. CfgOk = FALSE;
  1543. continue;
  1544. }
  1545. //
  1546. // IRQ is shareable: check if the levels are compatible
  1547. //
  1548. else if ( (pIntInfo->IrqLevel & IrqBit) &&
  1549. !(IrqBlock[Index] & CFG_IRQ_LEVEL) )
  1550. {
  1551. CfgOk=FALSE;
  1552. continue;
  1553. }
  1554. else if ( !(pIntInfo->IrqLevel & IrqBit) &&
  1555. (IrqBlock[Index] & CFG_IRQ_LEVEL) )
  1556. {
  1557. CfgOk=FALSE;
  1558. continue;
  1559. }
  1560. }
  1561. else
  1562. {
  1563. //
  1564. // new IRQ: check if the IRQ 0, 1, 2, 8 and 13 are configurated
  1565. // for edge triggered.
  1566. //
  1567. switch(IrqBit)
  1568. {
  1569. case (0x0001): // IRQ 0 only edge triggered
  1570. case (0x0002): // IRQ 1 " " "
  1571. case (0x0004): // IRQ 2 " " "
  1572. case (0x0100): // IRQ 8 " " "
  1573. case (0x2000): // IRQ 13 " " "
  1574. if (IrqBlock[Index] & CFG_IRQ_LEVEL)
  1575. {
  1576. CfgOk=FALSE;
  1577. continue;
  1578. }
  1579. break;
  1580. default:
  1581. break;
  1582. }
  1583. }
  1584. //
  1585. // set the present bit and update sharable and edge/level
  1586. // triggered variables
  1587. //
  1588. pIntInfo->IrqPresent |= IrqBit;
  1589. if (IrqBlock[Index] & CFG_IRQ_SHARE)
  1590. {
  1591. pIntInfo->IrqShareable |= IrqBit;
  1592. }
  1593. if (IrqBlock[Index] & CFG_IRQ_LEVEL)
  1594. {
  1595. pIntInfo->IrqLevel |= IrqBit;
  1596. }
  1597. }
  1598. while ((IrqBlock[Index]&CFG_MORE_ENTRY) && ((Index+=2)<CFG_IRQ_BLK_LEN));
  1599. //
  1600. // check final index
  1601. //
  1602. if ( !( Index < CFG_IRQ_BLK_LEN ) )
  1603. {
  1604. CfgOk=FALSE;
  1605. }
  1606. //
  1607. // initialize ELCR registers with new values.
  1608. //
  1609. Register = EisaInUchar(EisaIoStart + PIC1_ELCR);
  1610. Register &= ~(pIntInfo->IrqPresent);
  1611. Register |= pIntInfo->IrqLevel;
  1612. EisaOutUchar(EisaIoStart + PIC1_ELCR, Register);
  1613. Register = EisaInUchar(EisaIoStart + PIC2_ELCR);
  1614. Register &= ~(pIntInfo->IrqPresent >> BITSXBYTE);
  1615. Register |= pIntInfo->IrqLevel >> BITSXBYTE;
  1616. EisaOutUchar(EisaIoStart + PIC2_ELCR, Register);
  1617. //
  1618. // return configuration status
  1619. //
  1620. return CfgOk;
  1621. }
  1622. // ----------------------------------------------------------------------------
  1623. // PROCEDURE: EisaSlotCfgDma:
  1624. //
  1625. // DESCRIPTION: This function configures the DMA registers
  1626. // based on info from NVRAM.
  1627. //
  1628. // ARGUMENTS: EisaIoStart EISA I/O virtual address
  1629. // pDmaInfo DMA info pointer
  1630. // EisaFuncInfo function info pointer.
  1631. //
  1632. // RETURN: TRUE All done
  1633. // FALSE Error
  1634. //
  1635. // ASSUMPTIONS:
  1636. //
  1637. // CALLS:
  1638. //
  1639. // GLOBALS:
  1640. //
  1641. // NOTES:
  1642. // ----------------------------------------------------------------------------
  1643. //
  1644. BOOLEAN
  1645. EisaSlotCfgDma
  1646. (
  1647. IN PUCHAR EisaIoStart,
  1648. IN PEISA_DMA_INFO pDmaInfo,
  1649. IN PUCHAR EisaFuncInfo
  1650. )
  1651. {
  1652. //
  1653. // define local variables
  1654. //
  1655. BOOLEAN CfgOk=TRUE; // local configuration status
  1656. PUCHAR DmaBlock; // start of DMA data buffer
  1657. USHORT Index=0; // index within the DMA block
  1658. UCHAR DmaNumber; // DMA under configuration
  1659. UCHAR Register; // used to update the registers
  1660. PRINTDBG("EisaSlotCfgDma\n\r"); // DEBUG SUPPORT
  1661. //
  1662. // initialize variables
  1663. //
  1664. DmaBlock = &EisaFuncInfo[ CFG_DMA_BLK_OFS ];
  1665. //
  1666. // one loop per each DMA entry
  1667. //
  1668. do
  1669. {
  1670. //
  1671. // skip if shareable. device drivers should init DMA, not ROM
  1672. //
  1673. // NOTE: the following code has been removed because all the
  1674. // EISA cards that share the same DMA channel have the
  1675. // same value in this register. This is guaranteed by
  1676. // the configuration utility.
  1677. //if ( DmaBlock[Index] & CFG_DMA_SHARED )
  1678. //{
  1679. // continue;
  1680. //}
  1681. //
  1682. // Program the specified DMA channel using the new info.
  1683. //
  1684. DmaNumber = DmaBlock[Index] & CFG_DMA_MASK;
  1685. // keep the "stop register" and "T-C" bits
  1686. Register = pDmaInfo->DmaExtReg[ DmaNumber ] & ~CFG_DMA_CFG_MASK;
  1687. // use the new timing and bit I/O selection
  1688. Register |= DmaBlock[Index+1] & CFG_DMA_CFG_MASK;
  1689. // update the register
  1690. if (DmaNumber < 4)
  1691. {
  1692. EisaOutUchar(EisaIoStart + DMA_EXTMODE03, Register);
  1693. }
  1694. else
  1695. {
  1696. EisaOutUchar(EisaIoStart + DMA_EXTMODE47, Register);
  1697. }
  1698. // This register value is used to validate the DMA requestes
  1699. // (see the "EisaRequestEisaDmaTransfer" function).
  1700. // The DMA channels used by more than one card have always the
  1701. // same value ( check with the configuration guys ).
  1702. pDmaInfo->DmaExtReg[ DmaNumber ] = Register;
  1703. }
  1704. while ((DmaBlock[Index]&CFG_MORE_ENTRY) && ((Index+=2)<CFG_DMA_BLK_LEN));
  1705. //
  1706. // check final index
  1707. //
  1708. if ( !(Index < CFG_DMA_BLK_LEN) )
  1709. {
  1710. CfgOk=FALSE;
  1711. }
  1712. //
  1713. // return configuration status
  1714. //
  1715. return CfgOk;
  1716. }
  1717. // ----------------------------------------------------------------------------
  1718. // PROCEDURE: EisaSlotCfgIni:
  1719. //
  1720. // DESCRIPTION: This function configures the I/O port registers
  1721. // based on info from NVRAM.
  1722. //
  1723. // ARGUMENTS: EisaIoStart Starting eisa I/O area.
  1724. // EisaFuncInfo Function info pointer.
  1725. // EnabAdapter Enable adapter flag pointer.
  1726. //
  1727. // RETURN: TRUE All done
  1728. // FALSE Error
  1729. //
  1730. // ASSUMPTIONS:
  1731. //
  1732. // CALLS:
  1733. //
  1734. // GLOBALS:
  1735. //
  1736. // NOTES:
  1737. // ----------------------------------------------------------------------------
  1738. //
  1739. BOOLEAN
  1740. EisaSlotCfgIni
  1741. (
  1742. IN PUCHAR EisaIoStart,
  1743. IN PUCHAR EisaFuncInfo,
  1744. OUT PBOOLEAN EnabAdapter
  1745. )
  1746. {
  1747. //
  1748. // define local variables
  1749. //
  1750. BOOLEAN CfgOk = TRUE; // local configuration status
  1751. PUCHAR IniBlock; // start of init data buffer
  1752. USHORT Index = 0; // index within the init block
  1753. USHORT Next = 0; // index within the entry
  1754. USHORT IoPort; // I/O address port
  1755. UCHAR ByteValue; // used to init the registers
  1756. UCHAR ByteMask; //
  1757. USHORT ShortValue; // used to init the registers
  1758. USHORT ShortMask; //
  1759. ULONG WordValue; // used to init the registers
  1760. ULONG WordMask; //
  1761. PRINTDBG("EisaSlotCfgIni\n\r"); // DEBUG SUPPORT
  1762. // initialize variables
  1763. IniBlock = &EisaFuncInfo[CFG_INI_BLK_OFS];
  1764. //
  1765. // one loop per each init entries
  1766. //
  1767. do
  1768. {
  1769. // load the i/o address port
  1770. Next = 1;
  1771. IoPort = IniBlock[Index + Next++];
  1772. IoPort |= IniBlock[Index + Next++] << BITSXBYTE;
  1773. switch(IniBlock[Index] & CFG_INI_MASK)
  1774. {
  1775. //
  1776. // 8-bit I/O access
  1777. //
  1778. case(CFG_INI_BYTE):
  1779. ByteValue = IniBlock[Index + Next++];
  1780. if (IniBlock[Index] & CFG_INI_PMASK) // use the mask
  1781. {
  1782. ByteMask = IniBlock[Index + Next++];
  1783. ByteValue |= READ_REGISTER_UCHAR(EisaIoStart+IoPort) & ByteMask;
  1784. EISA_IO_DELAY;
  1785. }
  1786. if ((IoPort & 0x0FFF) == EXPANSION_BOARD_CTRL_BITS)
  1787. {
  1788. *EnabAdapter=FALSE;
  1789. }
  1790. WRITE_REGISTER_UCHAR(EisaIoStart+IoPort, ByteValue);
  1791. EISA_IO_DELAY;
  1792. break;
  1793. //
  1794. // 16-bit I/O access
  1795. //
  1796. case(CFG_INI_HWORD):
  1797. ShortValue = IniBlock[Index + Next++];
  1798. ShortValue |= IniBlock[Index + Next++] << BITSXBYTE;
  1799. if (IniBlock[Index] & CFG_INI_PMASK) // use the mask
  1800. {
  1801. ShortMask = IniBlock[Index + Next++];
  1802. ShortMask |= IniBlock[Index + Next++] << BITSXBYTE;
  1803. ShortValue |= READ_REGISTER_USHORT(EisaIoStart + IoPort) &
  1804. ShortMask;
  1805. EISA_IO_DELAY;
  1806. }
  1807. WRITE_REGISTER_USHORT(EisaIoStart + IoPort, ShortValue);
  1808. EISA_IO_DELAY;
  1809. break;
  1810. //
  1811. // 32-bit I/O access
  1812. //
  1813. case(CFG_INI_WORD):
  1814. WordValue = Fw4UcharToUlongLSB( &IniBlock[Index + Next] );
  1815. Next += 4;
  1816. if (IniBlock[Index]&CFG_INI_PMASK) // use the mask
  1817. {
  1818. WordMask = Fw4UcharToUlongLSB( &IniBlock[Index + Next] );
  1819. Next += 4;
  1820. WordValue |= READ_REGISTER_ULONG(EisaIoStart + IoPort) &
  1821. WordMask;
  1822. EISA_IO_DELAY;
  1823. }
  1824. WRITE_REGISTER_ULONG(EisaIoStart + IoPort, WordValue);
  1825. EISA_IO_DELAY;
  1826. break;
  1827. //
  1828. // error
  1829. //
  1830. default:
  1831. CfgOk=FALSE;
  1832. break;
  1833. }
  1834. }
  1835. while ((IniBlock[Index]&CFG_MORE_ENTRY) && ((Index+=Next)<CFG_INI_BLK_LEN));
  1836. //
  1837. // check final index
  1838. //
  1839. if ( !(Index < CFG_INI_BLK_LEN) )
  1840. {
  1841. CfgOk=FALSE;
  1842. }
  1843. //
  1844. // return configuration status
  1845. //
  1846. return CfgOk;
  1847. }
  1848. // ----------------------------------------------------------------------------
  1849. // PROCEDURE: EisaSlotErrorLog:
  1850. //
  1851. // DESCRIPTION: This function displays the corresponding eisa
  1852. // error message.
  1853. //
  1854. // ARGUMENTS: BusNumber BusNumber (not used)
  1855. // SlotNumber Slot in error
  1856. // ErrorCode Error number.
  1857. //
  1858. // RETURN: none
  1859. //
  1860. // ASSUMPTIONS:
  1861. //
  1862. // CALLS:
  1863. //
  1864. // GLOBALS:
  1865. //
  1866. // NOTES:
  1867. // ----------------------------------------------------------------------------
  1868. //
  1869. VOID
  1870. EisaSlotErrorLog
  1871. (
  1872. IN ULONG BusNumber,
  1873. IN ULONG SlotNumber,
  1874. IN EISA_CFG_ERROR ErrorCode
  1875. )
  1876. {
  1877. PRINTDBG("EisaSlotErrorLog\n\r"); // DEBUG SUPPORT
  1878. // display the error message
  1879. FwPrint( EISA_ERROR_SLOT_MSG, SlotNumber, EisaCfgMessages[ErrorCode] );
  1880. FwMoveCursorToColumn( 37 );
  1881. FwPrint( EISA_ERROR1_MSG );
  1882. FwStallExecution(1500000);
  1883. // all done
  1884. return;
  1885. }
  1886. // ----------------------------------------------------------------------------
  1887. // PROCEDURE: EisaPathErrorLog:
  1888. //
  1889. // DESCRIPTION: This function displays the corresponding eisa
  1890. // error message.
  1891. //
  1892. // ARGUMENTS: Component Component in error.
  1893. // ErrorCode Error number.
  1894. //
  1895. // RETURN: none
  1896. //
  1897. // ASSUMPTIONS:
  1898. //
  1899. // CALLS:
  1900. //
  1901. // GLOBALS:
  1902. //
  1903. // NOTES:
  1904. // ----------------------------------------------------------------------------
  1905. //
  1906. VOID
  1907. EisaPathErrorLog
  1908. (
  1909. IN PCONFIGURATION_COMPONENT Controller,
  1910. IN EISA_CFG_ERROR ErrorCode
  1911. )
  1912. {
  1913. CHAR Path[ MAX_DEVICE_PATH_LEN +1 ];
  1914. PRINTDBG("EisaPathErrorLog\n\r"); // DEBUG SUPPORT
  1915. EisaStrErrorLog( FwGetPath( Controller, Path ), ErrorCode );
  1916. return;
  1917. }
  1918. // ----------------------------------------------------------------------------
  1919. // PROCEDURE: EisaStrErrorLog:
  1920. //
  1921. // DESCRIPTION: This function displays the corresponding eisa
  1922. // error message.
  1923. //
  1924. // ARGUMENTS: Str String Message
  1925. // ErrorCode Error number.
  1926. //
  1927. // RETURN: none
  1928. //
  1929. // ASSUMPTIONS:
  1930. //
  1931. // CALLS:
  1932. //
  1933. // GLOBALS:
  1934. //
  1935. // NOTES:
  1936. // ----------------------------------------------------------------------------
  1937. //
  1938. VOID
  1939. EisaStrErrorLog
  1940. (
  1941. IN PCHAR Str,
  1942. IN EISA_CFG_ERROR ErrorCode
  1943. )
  1944. {
  1945. PRINTDBG("EisaStrErrorLog\n\r"); // DEBUG SUPPORT
  1946. FwPrint( "\r\n %s %s ", Str, EisaCfgMessages[ErrorCode] );
  1947. if ( strlen(Str) + strlen(EisaCfgMessages[ErrorCode]) + 2 < 36 )
  1948. {
  1949. FwMoveCursorToColumn( 37 );
  1950. }
  1951. FwPrint( EISA_ERROR1_MSG );
  1952. FwStallExecution(1500000);
  1953. return;
  1954. }
  1955. // ----------------------------------------------------------------------------
  1956. // PROCEDURE: EisaCheckpointFirstFase:
  1957. //
  1958. // DESCRIPTION: This function displays the specified checkpoint
  1959. // number on the internal LED and sends it to the
  1960. // parallel port.
  1961. //
  1962. // ARGUMENTS: Chk checkpoint number
  1963. //
  1964. // RETURN: none
  1965. //
  1966. // ASSUMPTIONS:
  1967. //
  1968. // CALLS:
  1969. //
  1970. // GLOBALS:
  1971. //
  1972. // NOTES:
  1973. //
  1974. // ----------------------------------------------------------------------------
  1975. //
  1976. VOID
  1977. EisaCheckpointFirstFase
  1978. (
  1979. IN EISA_CHECKPOINT Chk
  1980. )
  1981. {
  1982. ULONG TestFlags;
  1983. PRINTDBG("EisaCheckpointFirstFase\n\r"); // DEBUG SUPPORT
  1984. TestFlags = ( (ULONG)EisaCheckpointInfo[ Chk ].SubLed << 28 ) +
  1985. ( (ULONG)EisaCheckpointInfo[ Chk ].Led << 24 ) +
  1986. ( (ULONG)EisaCheckpointInfo[ Chk ].SubPar << 8 ) +
  1987. ( (ULONG)EisaCheckpointInfo[ Chk ].Par );
  1988. // NOTE: The parallel port test flag support is not used on JAZZ.
  1989. // DisplayOnParallelPort( TestFlags );
  1990. return;
  1991. }
  1992. // ----------------------------------------------------------------------------
  1993. // PROCEDURE: EisaCheckpointFinalFase:
  1994. //
  1995. // DESCRIPTION: This function returns the value of the specified
  1996. // real-time clock internal address.
  1997. //
  1998. // ARGUMENTS: Chk checkpoint number
  1999. // Passed pass or fail
  2000. //
  2001. // RETURN: Repeat = TRUE repeat checkpoint
  2002. // = FALSE continue
  2003. //
  2004. // ASSUMPTIONS:
  2005. //
  2006. // CALLS:
  2007. //
  2008. // GLOBALS:
  2009. //
  2010. // NOTES:
  2011. //
  2012. // ----------------------------------------------------------------------------
  2013. //
  2014. BOOLEAN
  2015. EisaCheckpointFinalFase
  2016. (
  2017. IN EISA_CHECKPOINT Chk,
  2018. IN BOOLEAN Passed
  2019. )
  2020. {
  2021. ULONG TestFlags;
  2022. PRINTDBG("EisaCheckpointFinalFase\n\r"); // DEBUG SUPPORT
  2023. if ( Passed )
  2024. {
  2025. EisaCheckpointInfo[ Chk ].Flags &= ~0x01; // all fine
  2026. EisaCheckpointInfo[ Chk ].Flags &= ~0x08; // no message
  2027. }
  2028. else
  2029. {
  2030. EisaCheckpointInfo[ Chk ].Flags |= 0x01; // error
  2031. if ( EisaCheckpointInfo[ Chk ].Flags & 0x08 ) // display message
  2032. {
  2033. FwPrint( "%s", EisaCheckpointInfo[ Chk ].Msg );
  2034. FwStallExecution(1500000);
  2035. }
  2036. }
  2037. TestFlags = (( (ULONG)EisaCheckpointInfo[ Chk ].SubLed << 28 ) +
  2038. ( (ULONG)EisaCheckpointInfo[ Chk ].Led << 24 ) +
  2039. ( (ULONG)EisaCheckpointInfo[ Chk ].Flags << 16 ) +
  2040. ( (ULONG)EisaCheckpointInfo[ Chk ].SubPar << 8 ) +
  2041. ( (ULONG)EisaCheckpointInfo[ Chk ].Par ));
  2042. // TEMPTEMP: Changed until we get the EvaluateTestResult routine from Olivetti.
  2043. // return EvaluateTestResult( TestFlags ) == ESUCCESS ? FALSE : TRUE;
  2044. return(FALSE); // Never repeat.
  2045. }
  2046. // ----------------------------------------------------------------------------
  2047. // PROCEDURE: EisaReadReadyId:
  2048. //
  2049. // DESCRIPTION: This function reads the eisa id of the specified
  2050. // slot.
  2051. //
  2052. // ARGUMENTS: EisaIoStart Starting eisa I/O address.
  2053. // SlotNumber Eisa slot number.
  2054. // AdapId Eisa ID returned.
  2055. //
  2056. // RETURN: FALSE Time-out error
  2057. // TRUE Valid adapter Id
  2058. //
  2059. // ASSUMPTIONS:
  2060. //
  2061. // CALLS:
  2062. //
  2063. // GLOBALS:
  2064. //
  2065. // NOTES:
  2066. // ----------------------------------------------------------------------------
  2067. //
  2068. BOOLEAN
  2069. EisaReadReadyId
  2070. (
  2071. IN PUCHAR EisaIoStart,
  2072. IN ULONG SlotNumber,
  2073. OUT PULONG AdapId
  2074. )
  2075. {
  2076. // define local variables
  2077. BOOLEAN Ready=TRUE;
  2078. PRINTDBG("EisaReadReadyId\n\r"); // DEBUG SUPPORT
  2079. //
  2080. // read adapter id
  2081. //
  2082. EisaReadId(EisaIoStart, SlotNumber, AdapId);
  2083. //
  2084. // check if adapter id is ready
  2085. //
  2086. if ( *AdapId & NO_ADAP_ID )
  2087. {
  2088. *AdapId = NO_ADAP_ID; // empty slot
  2089. }
  2090. else if ((*AdapId & WAIT_ADAP_ID) == WAIT_ADAP_ID)
  2091. {
  2092. Ready = FALSE; // adapter not ready
  2093. }
  2094. return Ready;
  2095. }
  2096. // ----------------------------------------------------------------------------
  2097. // PROCEDURE: EisaReadId:
  2098. //
  2099. // DESCRIPTION: This function reads the eisa id of the specified
  2100. // slot.
  2101. //
  2102. // ARGUMENTS: EisaIoStart Starting eisa I/O address.
  2103. // SlotNumber Eisa slot number.
  2104. // AdapId Eisa ID returned.
  2105. //
  2106. // RETURN: none
  2107. //
  2108. // ASSUMPTIONS:
  2109. //
  2110. // CALLS:
  2111. //
  2112. // GLOBALS:
  2113. //
  2114. // NOTES:
  2115. // ----------------------------------------------------------------------------
  2116. //
  2117. VOID
  2118. EisaReadId
  2119. (
  2120. IN PUCHAR EisaIoStart,
  2121. IN ULONG SlotNumber,
  2122. OUT PULONG AdapId
  2123. )
  2124. {
  2125. // define local variables
  2126. PUCHAR AdapIdPort; // eisa I/O ID port
  2127. PUCHAR RefreshPort; // eisa refresh port
  2128. UCHAR RefreshStatus; // eisa refresh status (port 61h)
  2129. ULONG Retry; // # retry
  2130. PRINTDBG("EisaReadId\n\r"); // DEBUG SUPPORT
  2131. // initialize variables
  2132. AdapIdPort = EisaIoStart + SlotNumber * 0x1000 + EISA_PRODUCT_ID;
  2133. RefreshPort = EisaIoStart + EISA_SYS_CTRL_PORTB;
  2134. // wait for the end of a refresh cycle (bit 4 of port 61h toggles)
  2135. for ( Retry = EISA_RFR_RETRY,
  2136. RefreshStatus = READ_REGISTER_UCHAR(RefreshPort) & EISA_REFRESH;
  2137. Retry &&
  2138. RefreshStatus == (READ_REGISTER_UCHAR(RefreshPort) & EISA_REFRESH);
  2139. Retry-- );
  2140. // write 0xFF to the adapter ID port
  2141. EisaOutUchar(AdapIdPort, 0xFF);
  2142. // read adapter id
  2143. *AdapId = EisaInUchar(AdapIdPort++);
  2144. *AdapId = *AdapId << BITSXBYTE | EisaInUchar(AdapIdPort++);
  2145. *AdapId = *AdapId << BITSXBYTE | EisaInUchar(AdapIdPort++);
  2146. *AdapId = *AdapId << BITSXBYTE | EisaInUchar(AdapIdPort++);
  2147. // all done, return.
  2148. return;
  2149. }
  2150. // ----------------------------------------------------------------------------
  2151. // PROCEDURE: EisaMemIni:
  2152. //
  2153. // DESCRIPTION: This function allocates memory for the descriptor
  2154. // pool and computes the top address and the length
  2155. // of a physical contiguous memory block to be used as
  2156. // OMF device drivers and dynamic memory pool.
  2157. // Note that only the memory really used will be
  2158. // allocated.
  2159. //
  2160. // ARGUMENTS: none
  2161. //
  2162. // RETURN: TRUE all done
  2163. // FALSE memory initialization error
  2164. //
  2165. // ASSUMPTIONS:
  2166. //
  2167. // CALLS:
  2168. //
  2169. // GLOBALS: pFwMdPool // descriptor pool
  2170. // MemorySize // memory size in Mbytes
  2171. // EisaPoolSize // # bytes really used
  2172. // EisaFreeTop // top of free mem
  2173. // EisaDynMemSize // dynamic memory size (bytes)
  2174. // EisaFreeBytes // free bytes left
  2175. //
  2176. // NOTES:
  2177. // ----------------------------------------------------------------------------
  2178. //
  2179. // NOTE: Not used for JAZZ.
  2180. #if 0
  2181. BOOLEAN
  2182. EisaMemIni
  2183. (
  2184. VOID
  2185. )
  2186. {
  2187. FW_MD BuffFwMd;
  2188. PVOID Dummy;
  2189. PRINTDBG("EisaMemIni\n\r"); // DEBUG SUPPORT
  2190. //
  2191. // allocate descriptor pool
  2192. //
  2193. if ( (pFwMdPool = (PFW_MD)FwAllocatePool( sizeof(FW_MD)*FW_MD_POOL ))
  2194. == NULL )
  2195. {
  2196. return FALSE;
  2197. }
  2198. //
  2199. // set all the necessary TLB entries to map the whole system memory
  2200. //
  2201. RtlZeroMemory( &BuffFwMd, sizeof(FW_MD));
  2202. BuffFwMd.Size = 256 << 20;
  2203. BuffFwMd.PagNumb = 256 << (20 - PAGE_SHIFT);
  2204. BuffFwMd.Cache = TRUE;
  2205. if ( AllocateMemoryResources( &BuffFwMd ) != ESUCCESS )
  2206. {
  2207. return FALSE;
  2208. }
  2209. //
  2210. // compute OMF device drivers and dynamic memory pool area
  2211. //
  2212. EisaPoolSize = EisaDynMemSize = EISA_DYN_MEM_SIZE;
  2213. if ( MemorySize >= 16 )
  2214. {
  2215. //
  2216. // we don't use the memory above 16Mbytes because in this way we
  2217. // can use this logic in a machine without translation registers
  2218. // (logical I/O to physical) for the ISA boards which have a
  2219. // transfer range of 24 bits (16Mbytes).
  2220. //
  2221. EisaFreeTop = EISA_FREE_TOP_16;
  2222. EisaFreeBytes = EISA_FREE_BYTES_16;
  2223. }
  2224. else if ( MemorySize >= 12 )
  2225. {
  2226. EisaFreeTop = EISA_FREE_TOP_12;
  2227. EisaFreeBytes = EISA_FREE_BYTES_12;
  2228. }
  2229. else if ( MemorySize >= 8 )
  2230. {
  2231. EisaFreeTop = EISA_FREE_TOP_8;
  2232. EisaFreeBytes = EISA_FREE_BYTES_8;
  2233. }
  2234. else
  2235. {
  2236. return FALSE;
  2237. }
  2238. EisaFreeBytes -= EisaDynMemSize;
  2239. return TRUE;
  2240. }
  2241. #endif // 0
  2242. // ----------------------------------------------------------------------------
  2243. // PROCEDURE: EisaDynMemIni:
  2244. //
  2245. // DESCRIPTION: This function allocates the requested space for the
  2246. // the dynamic memory allocation.
  2247. //
  2248. // ARGUMENTS: none
  2249. //
  2250. // RETURN: none
  2251. //
  2252. // ASSUMPTIONS:
  2253. //
  2254. // CALLS:
  2255. //
  2256. // GLOBALS: EisaFreeTop top of free mem
  2257. // EisaDynMemSize dynamic memory size (bytes)
  2258. // EisaPoolSize EISA pool size (bytes)
  2259. //
  2260. // NOTES:
  2261. // ----------------------------------------------------------------------------
  2262. //
  2263. // NOTE: Not used for JAZZ.
  2264. #if 0
  2265. VOID
  2266. EisaDynMemIni
  2267. (
  2268. VOID
  2269. )
  2270. {
  2271. //
  2272. // define local variables
  2273. //
  2274. ULONG BytesToPage; // bytes left to make a page
  2275. PHEADER pHdr; // memory descriptor header ptr
  2276. PVOID Buffer; // data area
  2277. PRINTDBG("EisaDynMemIni\n\r"); // DEBUG SUPPORT
  2278. //
  2279. // align the dynamic memory buffer on a page boundary
  2280. //
  2281. BytesToPage = PAGE_SIZE - (EisaDynMemSize & ((1 << PAGE_SHIFT) - 1));
  2282. EisaDynMemSize += BytesToPage;
  2283. EisaPoolSize += BytesToPage;
  2284. EisaFreeTop -= EisaDynMemSize;
  2285. //
  2286. // initialize first memory descriptor
  2287. //
  2288. pHdr = (PHEADER)EisaFreeTop;
  2289. Buffer = (PVOID)(pHdr + 1);
  2290. pHdr->m.id = Buffer;
  2291. pHdr->m.size = EisaDynMemSize/sizeof(HEADER);
  2292. EisaFreeMemory( Buffer );
  2293. return;
  2294. }
  2295. #endif // 0
  2296. // ----------------------------------------------------------------------------
  2297. // PROCEDURE: FwGetPath:
  2298. //
  2299. // DESCRIPTION: This function builds the path name for the specified
  2300. // component.
  2301. //
  2302. // ARGUMENTS: Component Component pointer.
  2303. // Str Path name pointer.
  2304. //
  2305. // RETURN: Str Path name pointer.
  2306. //
  2307. // ASSUMPTIONS: The string must be large enoungh to hold the
  2308. // requested path name.
  2309. //
  2310. // CALLS:
  2311. //
  2312. // GLOBALS:
  2313. //
  2314. // NOTES:
  2315. // ----------------------------------------------------------------------------
  2316. //
  2317. PCHAR
  2318. FwGetPath
  2319. (
  2320. IN PCONFIGURATION_COMPONENT Component,
  2321. OUT PCHAR Str
  2322. )
  2323. {
  2324. PCONFIGURATION_COMPONENT pComp;
  2325. PRINTDBG("FwGetPath\n\r"); // DEBUG SUPPORT
  2326. if ( (pComp = FwGetParent( Component )) != NULL )
  2327. {
  2328. FwGetPath( pComp, Str);
  2329. strcat( Str, FwGetMnemonic( Component ) );
  2330. sprintf( Str + strlen( Str ), "(%lu)", Component->Key);
  2331. }
  2332. else
  2333. {
  2334. *Str = '\0';
  2335. }
  2336. return Str;
  2337. }
  2338. // ----------------------------------------------------------------------------
  2339. // PROCEDURE: FwDelCfgTreeNode:
  2340. //
  2341. // DESCRIPTION: This function removes from the configuration tree
  2342. // the specified component and all its children.
  2343. //
  2344. // ARGUMENTS: pComp component pointer.
  2345. // Peer = TRUE delete all its peers.
  2346. // = FALSE delete just this branch.
  2347. //
  2348. // RETURN: none
  2349. //
  2350. // ASSUMPTIONS:
  2351. //
  2352. // CALLS:
  2353. //
  2354. // GLOBALS:
  2355. //
  2356. // NOTES:
  2357. // ----------------------------------------------------------------------------
  2358. //
  2359. VOID
  2360. FwDelCfgTreeNode
  2361. (
  2362. IN PCONFIGURATION_COMPONENT pComp,
  2363. IN BOOLEAN Peer
  2364. )
  2365. {
  2366. //
  2367. // define local variables
  2368. //
  2369. PCONFIGURATION_COMPONENT NextComp;
  2370. PRINTDBG("FwDelCfgTreeNode\n\r"); // DEBUG SUPPORT
  2371. //
  2372. // check for a child
  2373. //
  2374. if ( (NextComp = FwGetChild( pComp )) != NULL )
  2375. {
  2376. FwDelCfgTreeNode( NextComp, TRUE );
  2377. }
  2378. //
  2379. // check for a peer.
  2380. //
  2381. if ( Peer && (NextComp = FwGetPeer( pComp )) != NULL )
  2382. {
  2383. FwDelCfgTreeNode( NextComp, TRUE );
  2384. }
  2385. //
  2386. // this is a leaf, delete it
  2387. //
  2388. FwDeleteComponent( pComp );
  2389. //
  2390. // all done
  2391. //
  2392. return;
  2393. }
  2394. // ----------------------------------------------------------------------------
  2395. // PROCEDURE: FwGetMnemonic:
  2396. //
  2397. // DESCRIPTION: This function stores the mnemonic name for the
  2398. // requested component type.
  2399. //
  2400. // ARGUMENTS: Component Component pointer.
  2401. //
  2402. // RETURN: Str Mnemonic pointer
  2403. //
  2404. // ASSUMPTIONS: none
  2405. //
  2406. // CALLS:
  2407. //
  2408. // GLOBALS:
  2409. //
  2410. // NOTES:
  2411. // ----------------------------------------------------------------------------
  2412. //
  2413. PCHAR
  2414. FwGetMnemonic
  2415. (
  2416. IN PCONFIGURATION_COMPONENT Component
  2417. )
  2418. {
  2419. PRINTDBG("FwGetMnemonic\n\r"); // DEBUG SUPPORT
  2420. return MnemonicTable[Component->Type];
  2421. }
  2422. // ----------------------------------------------------------------------------
  2423. // PROCEDURE: FwValidMnem:
  2424. //
  2425. // DESCRIPTION: This function validates the specified mnemonic.
  2426. // If the mnemonic is valid, a TURE value is returned,
  2427. // otherwise a FALSE is returned.
  2428. //
  2429. // ARGUMENTS: Str Mnemonic pointer
  2430. //
  2431. // RETURN: FALSE Mnemonic incorrect
  2432. // TRUE Mnemonic correct
  2433. //
  2434. // ASSUMPTIONS: none
  2435. //
  2436. // CALLS:
  2437. //
  2438. // GLOBALS:
  2439. //
  2440. // NOTES:
  2441. // ----------------------------------------------------------------------------
  2442. //
  2443. BOOLEAN
  2444. FwValidMnem
  2445. (
  2446. IN PCHAR Str
  2447. )
  2448. {
  2449. // define local variables
  2450. CONFIGURATION_TYPE CfgType;
  2451. PRINTDBG("FwValidMnem\n\r"); // DEBUG SUPPORT
  2452. // check the mnemonic table
  2453. for ( CfgType = ArcSystem;
  2454. CfgType < MaximumType && strcmp( MnemonicTable[ CfgType ], Str );
  2455. CfgType++ );
  2456. return CfgType < MaximumType ? TRUE : FALSE;
  2457. }
  2458. // ----------------------------------------------------------------------------
  2459. // GLOBAL: I/O functions variables
  2460. // ----------------------------------------------------------------------------
  2461. PCHAR AsciiBlock; // pointer the ASCII block
  2462. ULONG AsciiBlockLength = 0; // length of the ASCII block
  2463. // ----------------------------------------------------------------------------
  2464. // PROCEDURE: FwStoreStr:
  2465. //
  2466. // DESCRIPTION: This function stores the specified string within
  2467. // the ASCII block. The NULL pointer is returned if
  2468. // there isn't space available for the string.
  2469. //
  2470. // ARGUMENTS: Str String pointer
  2471. //
  2472. // RETURN: Str String pointer
  2473. //
  2474. // ASSUMPTIONS:
  2475. //
  2476. // CALLS:
  2477. //
  2478. // GLOBALS:
  2479. //
  2480. // NOTES:
  2481. // ----------------------------------------------------------------------------
  2482. //
  2483. PCHAR
  2484. FwStoreStr
  2485. (
  2486. IN PCHAR Str
  2487. )
  2488. {
  2489. PRINTDBG("FwStoreStr\n\r"); // DEBUG SUPPORT
  2490. // if not enough space, allocate new ASCII block
  2491. if ( AsciiBlockLength < strlen( Str ) + 1 )
  2492. {
  2493. if((AsciiBlock = (PUCHAR)FwAllocatePool(ASCII_BLOCK_SIZE)) == NULL)
  2494. {
  2495. return NULL;
  2496. }
  2497. }
  2498. // store the string and update the pointers.
  2499. Str = strcpy( AsciiBlock, Str );
  2500. AsciiBlock += strlen( Str ) + 1;
  2501. AsciiBlockLength = ASCII_BLOCK_SIZE - (strlen( Str ) + 1);
  2502. // all done, return the new string pointer
  2503. return Str;
  2504. }