NT4/private/ntos/fw/mips/eisaini.c
2020-09-30 17:12:29 +02:00

3196 lines
77 KiB
C
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// ----------------------------------------------------------------------------
// Copyright (c) 1992 Olivetti
//
// File: eisaini.c
//
// Description: EISA initialization routines.
// ----------------------------------------------------------------------------
//
#include "fwp.h"
#include "oli2msft.h"
#include "arceisa.h"
#include "inc.h"
#include "string.h"
#include "debug.h"
#include "eisastr.h"
//extern BL_DEVICE_ENTRY_TABLE OmfEntryTable[];
// NOTE: Not used in JAZZ.
//extern ULONG ErrorWord; // POD error flags
//extern ULONG FlagWord; // system flags
extern ULONG MemorySize; // size of memory in Mb
extern PCHAR MnemonicTable[];
extern ULONG EisaPoolSize; // # bytes really used
extern ULONG EisaDynMemSize; // dynamic memory size (bytes)
extern ULONG EisaFreeTop; // top of free mem
extern ULONG EisaFreeBytes; // free bytes left
// remove the following function prototypes when using common code
PFW_MD
GetFwMd
(
VOID
);
PFW_MD
LinkPhysFwMd
(
PFW_MD * pFwMdBase,
PFW_MD pFwMd
);
// ----------------------------------------------------------------------------
// Declare Function Prototypes
// ----------------------------------------------------------------------------
VOID
EisaIni
(
VOID
);
VOID
EisaGeneralIni
(
VOID
);
BOOLEAN
EisaBusStructIni
(
IN ULONG BusNumber
);
BOOLEAN
EisaCheckAdapterComponent
(
IN ULONG BusNumber,
OUT PCONFIGURATION_COMPONENT *pEisaComp
);
BOOLEAN
EisaBusPod
(
IN ULONG BusNumber
);
BOOLEAN
EisaPortIni
(
IN PUCHAR EisaIoStart
);
BOOLEAN
EisaIntIni
(
IN PUCHAR EisaIoStart,
IN PEISA_INT_INFO pIntInfo
);
BOOLEAN
EisaDmaIni
(
IN PUCHAR EisaIoStart,
IN PEISA_DMA_INFO pDmaInfo
);
BOOLEAN
EisaBusCfg
(
IN PCONFIGURATION_COMPONENT EisaComponent
);
BOOLEAN
EisaPhysSlotCfg
(
IN ULONG BusNumber,
IN PCONFIGURATION_COMPONENT Controller,
IN ULONG AdapId
);
BOOLEAN
EisaVirSlotCfg
(
IN ULONG BusNumber,
IN PCONFIGURATION_COMPONENT Controller
);
BOOLEAN
EisaSlotCfg
(
IN ULONG BusNumber,
IN PCONFIGURATION_COMPONENT Controller,
IN UCHAR FunctionsNumber
);
BOOLEAN
EisaSlotCfgMem
(
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PUCHAR EisaFuncInfo
);
BOOLEAN
EisaSlotCfgIrq
(
IN PUCHAR EisaIoStart,
IN PEISA_INT_INFO pIntInfo,
IN PUCHAR EisaFuncInfo
);
BOOLEAN
EisaSlotCfgDma
(
IN PUCHAR EisaIoStart,
IN PEISA_DMA_INFO pDmaInfo,
IN PUCHAR EisaFuncInfo
);
BOOLEAN
EisaSlotCfgIni
(
IN PUCHAR EisaIoStart,
IN PUCHAR EisaFuncInfo,
OUT PBOOLEAN EnabAdapter
);
VOID
EisaSlotErrorLog
(
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN EISA_CFG_ERROR ErrorCode
);
VOID
EisaPathErrorLog
(
IN PCONFIGURATION_COMPONENT Controller,
IN EISA_CFG_ERROR ErrorCode
);
VOID
EisaStrErrorLog
(
IN PCHAR Str,
IN EISA_CFG_ERROR ErrorCode
);
VOID
EisaCheckpointFirstFase
(
IN EISA_CHECKPOINT Chk
);
BOOLEAN
EisaCheckpointFinalFase
(
IN EISA_CHECKPOINT Chk,
IN BOOLEAN Passed
);
BOOLEAN
EisaReadReadyId
(
IN PUCHAR EisaIoStart,
IN ULONG SlotNumber,
OUT PULONG AdapId
);
VOID
EisaReadId
(
IN PUCHAR EisaIoStart,
IN ULONG SlotNumber,
OUT PULONG AdapId
);
BOOLEAN
EisaMemIni
(
VOID
);
VOID
EisaDynMemIni
(
VOID
);
PCONFIGURATION_COMPONENT
FwGetChild
(
IN PCONFIGURATION_COMPONENT Component OPTIONAL
);
PCONFIGURATION_COMPONENT
FwGetPeer
(
IN PCONFIGURATION_COMPONENT Component
);
PCONFIGURATION_COMPONENT
FwAddChild
(
IN PCONFIGURATION_COMPONENT Component,
IN PCONFIGURATION_COMPONENT NewComponent,
IN PVOID ConfigurationData OPTIONAL
);
PCONFIGURATION_COMPONENT
FwGetComponent
(
IN PCHAR Pathname
);
PCONFIGURATION_COMPONENT
FwGetParent
(
IN PCONFIGURATION_COMPONENT Component
);
VOID
FwStallExecution
(
IN ULONG Seconds
);
ARC_STATUS
AllocateMemoryResources
(
IN OUT PFW_MD pBuffFwMd
);
// ----------------------------------------------------------------------------
// Declare General Function Prototypes
// ----------------------------------------------------------------------------
PCHAR
FwToUpperStr
(
IN OUT PCHAR s
);
PCHAR
FwToLowerStr
(
IN OUT PCHAR s
);
PCHAR
FwGetPath
(
IN PCONFIGURATION_COMPONENT Component,
OUT PCHAR String
);
VOID
FwDelCfgTreeNode
(
IN PCONFIGURATION_COMPONENT pComp,
IN BOOLEAN Peer
);
PCHAR
FwGetMnemonic
(
IN PCONFIGURATION_COMPONENT Component
);
BOOLEAN
FwValidMnem
(
IN PCHAR Str
);
ULONG
Fw2UcharToUlongLSB
(
IN PUCHAR String
);
ULONG
Fw3UcharToUlongLSB
(
IN PUCHAR String
);
ULONG
Fw4UcharToUlongLSB
(
IN PUCHAR String
);
ULONG
Fw4UcharToUlongMSB
(
IN PUCHAR String
);
PCHAR
FwStoreStr
(
IN PCHAR Str
);
// ----------------------------------------------------------------------------
// GLOBAL: EISA configuration variables
// ----------------------------------------------------------------------------
// EISA buses info
EISA_BUS_INFO EisaBusInfo[ EISA_BUSES ]; // eisa bus info pointers
// descriptor pointers
PFW_MD LogFwMdBase = NULL; // starting logical descriptors pointer
PFW_MD VirFwMdBase = NULL; // starting virtual descriptors pointer
PFW_MD pFwMdPool; // descriptors pool
// ----------------------------------------------------------------------------
// PROCEDURE: EisaIni:
//
// DESCRIPTION: This function does the eisa controller configuration.
//
// ARGUMENTS: none
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS: ErrorWord
//
// NOTES:
// ----------------------------------------------------------------------------
//
VOID
EisaIni
(
VOID
)
{
// define local variables
PCONFIGURATION_COMPONENT pEisaComp; // eisa bus component
CHAR EisaMnemonic[MAX_MNEMONIC_LEN +1]; // to hold the eisa path
ULONG EisaBus; // eisa bus number
BOOLEAN IniOk; // EISA configuration bus status
PRINTDBG("EisaIni\n\r"); // DEBUG SUPPORT
//
// perform any general initialization
//
EisaGeneralIni();
// NOTE: EisaMemIni not used on JAZZ.
// if ( !EisaMemIni() )
// {
// EisaStrErrorLog("EISA Initialization", MemAllocError);
// return;
// }
//
// initialize and configure the eisa buses (one per loop)
//
for ( EisaBus = 0; EisaBus < EISA_BUSES; EisaBus++ )
{
//
// display message
//
FwPrint(EISA_INIT_MSG, EisaBus);
//
// eisa bus structures initialization
//
if ( !EisaBusStructIni( EisaBus ))
{
EisaStrErrorLog( EISA_BUS_MSG, MemAllocError);
return;
}
//
// eisa bus hardware test and initialization
//
if ( EisaBusInfo[ EisaBus ].Flags.Error = !EisaBusPod( EisaBus ))
{
// ErrorWord |= E_HARDWARE_ERROR;
}
//
// check the EISA adapter component
//
IniOk = TRUE;
EisaCheckpointFirstFase( EisaCfg );
if ( !EisaCheckAdapterComponent( EisaBus, &pEisaComp ))
{
IniOk = FALSE;
}
//
// Return if no EISA information available.
//
if (pEisaComp == NULL) {
return;
}
//
// configure the bus if no hardware errors and configuration jumper not
// present.
//
// NOTE: FlagWord is not used in JAZZ.
// if (!EisaBusInfo[EisaBus].Flags.Error && !(FlagWord & F_CONFIG_JUMPER))
if (!EisaBusInfo[EisaBus].Flags.Error)
{
if ( !EisaBusCfg( pEisaComp ))
{
IniOk = FALSE;
}
}
EisaCheckpointFinalFase( EisaCfg, IniOk );
if ( IniOk != TRUE )
{
// NOTE: Not used in JAZZ.
// ErrorWord |= E_CONFIG_ERROR;
}
//
// store the POD initialization status
//
EisaBusInfo[ EisaBus ].Flags.IniDone = 1;
pEisaComp->Flags.Failed = EisaBusInfo[ EisaBus ].Flags.Error;
if (IniOk == TRUE) {
FwPrint(EISA_OK_MSG);
FwStallExecution(500000);
}
FwPrint(EISA_CRLF_MSG);
}
//
// Big Endian initialization
//
// NOTE: BigEndian is not used on JAZZ.
// BiEndianIni();
//
// EISA dynamic memory initializzation
//
// NOTE: EisaDynMemIni not used on JAZZ.
// EisaDynMemIni();
//
// OMF initialization: final phase
//
// NOTE: EisaOmfIni not used on JAZZ.
// EisaOmfIni();
//
// Write out the hardware id, JAZZ only. The first page of the EISA
// I/O control space is actually translated into a page of memory, where
// the hardware ID is stored.
//
*(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c80) = (('J' - 'A' + 1) << 2) +
(('A' - 'A' + 1) >> 3);
*(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c81) = (('A' - 'A' + 1) << 5) +
('Z' - 'A' + 1);
*(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c82) = 0;
*(PUCHAR)(EISA_EXTERNAL_IO_VIRTUAL_BASE + 0x0c83) = 0;
//
// all done
//
return;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaGeneralIni:
//
// DESCRIPTION: This function performs general initialization
// for the EISA buses.
//
// ARGUMENTS: none
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
VOID
EisaGeneralIni
(
VOID
)
{
PRINTDBG("EisaGeneralIni\n\r"); // DEBUG SUPPORT
//
// update system parameter block
//
SYSTEM_BLOCK->AdapterCount = 1;
SYSTEM_BLOCK->Adapter0Type = EisaAdapter;
SYSTEM_BLOCK->Adapter0Length = (ULONG)MaximumEisaRoutine * sizeof(ULONG);
SYSTEM_BLOCK->Adapter0Vector = (PVOID)(SYSTEM_BLOCK->VendorVector +
SYSTEM_BLOCK->VendorVectorLength);
//
// initialize EISA call back vectors
//
(PEISA_PROCESS_EOI_RTN)SYSTEM_BLOCK->Adapter0Vector
[ProcessEOIRoutine] = EisaProcessEndOfInterrupt;
// [ProcessEOIRoutine] = FwpReservedRoutine;
(PEISA_TEST_INT_RTN)SYSTEM_BLOCK->Adapter0Vector
[TestIntRoutine] = EisaTestEisaInterrupt;
// [TestIntRoutine] = FwpReservedRoutine;
(PEISA_REQ_DMA_XFER_RTN)SYSTEM_BLOCK->Adapter0Vector
// [RequestDMARoutine] = EisaRequestEisaDmaTransfer;
[RequestDMARoutine] = FwpReservedRoutine;
(PEISA_ABORT_DMA_RTN)SYSTEM_BLOCK->Adapter0Vector
// [AbortDMARoutine] = EisaAbortEisaDmaTransfer;
[AbortDMARoutine] = FwpReservedRoutine;
(PEISA_DMA_XFER_STATUS_RTN)SYSTEM_BLOCK->Adapter0Vector
// [GetDMAStatusRoutine] = EisaGetEisaDmaTransferStatus;
[GetDMAStatusRoutine] = FwpReservedRoutine;
(PEISA_LOCK_RTN)SYSTEM_BLOCK->Adapter0Vector
// [DoLockRoutine] = EisaDoLockedOperation;
[DoLockRoutine] = FwpReservedRoutine;
(PEISA_REQUEST_BUS_MASTER_RTN)SYSTEM_BLOCK->Adapter0Vector
// [RequestBusMasterRoutine] = EisaRequestEisaBusMasterTransfer;
[RequestBusMasterRoutine] = FwpReservedRoutine;
(PEISA_RELEASE_BUS_MASTER_RTN)SYSTEM_BLOCK->Adapter0Vector
// [ReleaseBusMasterRoutine] = EisaReleaseEisaBusMasterTransfer;
[ReleaseBusMasterRoutine] = FwpReservedRoutine;
(PEISA_REQUEST_CPU_TO_BUS_ACCESS_RTN)SYSTEM_BLOCK->Adapter0Vector
// [RequestCpuAccessToBusRoutine] = EisaRequestCpuAccessToEisaBus;
[RequestCpuAccessToBusRoutine] = FwpReservedRoutine;
(PEISA_RELEASE_CPU_TO_BUS_ACCESS_RTN)SYSTEM_BLOCK->Adapter0Vector
// [ReleaseCpuAccessToBusRoutine] = EisaReleaseCpuAccessToEisaBus;
[ReleaseCpuAccessToBusRoutine] = FwpReservedRoutine;
(PEISA_FLUSH_CACHE_RTN)SYSTEM_BLOCK->Adapter0Vector
// [FlushCacheRoutine] = EisaFlushCache;
[FlushCacheRoutine] = FwpReservedRoutine;
(PEISA_INVALIDATE_CACHE_RTN)SYSTEM_BLOCK->Adapter0Vector
// [InvalidateCacheRoutine] = EisaInvalidateCache;
[InvalidateCacheRoutine] = FwpReservedRoutine;
(PEISA_BEGIN_CRITICAL_SECTION_RTN)SYSTEM_BLOCK->Adapter0Vector
[BeginCriticalSectionRoutine] = EisaBeginCriticalSection;
// [BeginCriticalSectionRoutine] = FwpReservedRoutine;
(PEISA_RESERVED_RTN)SYSTEM_BLOCK->Adapter0Vector
[ReservedRoutine] = NULL;
(PEISA_END_CRITICAL_SECTION_RTN)SYSTEM_BLOCK->Adapter0Vector
[EndCriticalSectionRoutine] = EisaEndCriticalSection;
// [EndCriticalSectionRoutine] = FwpReservedRoutine;
(PEISA_GENERATE_TONE_RTN)SYSTEM_BLOCK->Adapter0Vector
[GenerateToneRoutine] = EisaGenerateTone;
(PEISA_FLUSH_WRITE_BUFFER_RTN)SYSTEM_BLOCK->Adapter0Vector
// [FlushWriteBuffersRoutine] = EisaFlushWriteBuffers;
[FlushWriteBuffersRoutine] = FwpReservedRoutine;
(PEISA_YIELD_RTN)SYSTEM_BLOCK->Adapter0Vector
// [YieldRoutine] = EisaYield;
[YieldRoutine] = FwpReservedRoutine;
(PEISA_STALL_PROCESSOR_RTN)SYSTEM_BLOCK->Adapter0Vector
[StallProcessorRoutine] = FwStallExecution;
//
// all done
//
return;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaBusStructIni:
//
// DESCRIPTION: This function builds all the required structures
// for the specified EISA bus.
//
// ARGUMENTS: BusNumber EISA bus number
//
// RETURN: TRUE All done
// FALSE Error
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES: This routine is hardware design dependent.
//
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaBusStructIni
(
IN ULONG BusNumber
)
{
//
// define local variables
//
PVOID pInfo; // General pointer
PEISA_BUS_INFO pBusInfo; // EISA bus info pointer
PFW_MD pIoBusInfo; // I/O info pointer
PFW_MD pMemBusInfo; // Memory info pointer
PEISA_SLOTS_INFO pSlotsInfo; // Slots info pointer
PEISA_DMA_INFO pDmaInfo; // DMA info pointer
PEISA_INT_INFO pIntInfo; // INT info pointer
PEISA_PORT_INFO pPortInfo; // port info pointer
ULONG Index; // general index
PRINTDBG("EisaBusStructIni\n\r"); // DEBUG SUPPORT
//
// initialize variables
//
pBusInfo = &EisaBusInfo[ BusNumber ];
pBusInfo->Flags.IniDone = 0;
//
// first EISA bus
//
if ( BusNumber == 0 )
{
//
// perform any info structure initialization
//
if ((pInfo = (PVOID)FwAllocatePool( sizeof( FW_MD ) +
sizeof( FW_MD ) +
sizeof( EISA_SLOTS_INFO ) +
sizeof( EISA_DMA_INFO ) +
sizeof( EISA_INT_INFO ))) == NULL )
{
return FALSE;
}
//
// I/O bus info initialization
//
pBusInfo->IoBusInfo = pIoBusInfo = (PFW_MD)pInfo;
// set link and flags
pIoBusInfo->Link = NULL;
pIoBusInfo->Flags.Busy = 1;
pIoBusInfo->Counter = 1;
// set window size in 4k units
pIoBusInfo->PhysAddr = EISA_IO_PHYSICAL_BASE/PAGE_SIZE;
pIoBusInfo->PagOffs = 0;
pIoBusInfo->VirAddr = (PVOID)EISA_EXTERNAL_IO_VIRTUAL_BASE;
pIoBusInfo->Size = 64 * 1024;
pIoBusInfo->PagNumb = 64/4;
((PFW_MD)pInfo)++;
//
// memory bus info initialization
//
pBusInfo->MemBusInfo = pMemBusInfo = (PFW_MD)pInfo;
// set link and flags
pMemBusInfo->Link = NULL;
pMemBusInfo->Flags.Busy = 0; // window busy flag
pMemBusInfo->Counter = 0;
#ifdef KPW4010
// set size of window in 4k units
pMemBusInfo->PhysAddr = EISA_MEM_PHYSBASE_KPW4010; // #4kpages
pMemBusInfo->PagOffs = 0;
pMemBusInfo->VirAddr = (PVOID)EISA_VIR_MEM;
pMemBusInfo->Size = 0; // 4 Gbytes
pMemBusInfo->PagNumb = PAGES_IN_4G;
//
// Because the EISA memory space in some designs can reach
// 4Gbytes of length, it is not possible to map the entire area.
// The allocation of the TLB entries for this space is done at
// run time using the general calls to the TLB services.
//
pMemBusInfo->u.em.WinRelAddr = 0;
pMemBusInfo->u.em.WinRelAddrCtrl = NULL;
pMemBusInfo->u.em.WinShift = PAGE_4G_SHIFT;
#else // KPW 4000
// set size of window in 4k units
pMemBusInfo->PhysAddr = EISA_MEMORY_PHYSICAL_BASE/PAGE_SIZE;
pMemBusInfo->PagOffs = 0;
pMemBusInfo->VirAddr = (PVOID)EISA_MEMORY_VIRTUAL_BASE;
pMemBusInfo->Size = PAGE_16M_SIZE;
pMemBusInfo->PagNumb = PAGE_16M_SIZE/PAGE_SIZE;
//
// Because the EISA memory space in some designs can reach
// 4Gbytes of length, it is not possible to map the entire area.
// The allocation of the TLB entries for this space is done at
// run time using the general calls to the TLB services.
//
pMemBusInfo->u.em.WinRelAddr = 0;
pMemBusInfo->u.em.WinRelAddrCtrl = (PVOID)EISA_LATCH_VIRTUAL_BASE;
pMemBusInfo->u.em.WinShift = PAGE_16M_SHIFT;
#endif
((PFW_MD)pInfo)++;
//
// slot info initialization
//
pBusInfo->SlotsInfo = pSlotsInfo = (PEISA_SLOTS_INFO)pInfo;
pSlotsInfo->PhysSlots = PHYS_0_SLOTS;
pSlotsInfo->VirSlots = VIR_0_SLOTS;
((PEISA_SLOTS_INFO)pInfo)++;
//
// DMA info initialization
//
pBusInfo->DmaInfo = pDmaInfo = (PEISA_DMA_INFO)pInfo;
pDmaInfo->Flags.IniDone = 0;
((PEISA_DMA_INFO)pInfo)++;
//
// PIC info initialization
//
pBusInfo->IntInfo = pIntInfo = (PEISA_INT_INFO)pInfo;
pIntInfo->Flags.IniDone = 0;
((PEISA_INT_INFO)pInfo)++;
//
// port info initialization
//
pBusInfo->PortInfo = pPortInfo = (PEISA_PORT_INFO)pInfo;
pPortInfo->Flags.IniDone = 0;
}
else
{
//
// invalid bus number
//
return FALSE;
}
//
// all done
//
return TRUE;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaCheckAdapterComponent:
//
// DESCRIPTION: This function makes sure that there is an EISA adapter
// component with the correct configuration data for the
// specified EISA bus number. The routine uses the
// following logic :
//
// if !(ARC component present)
// {
// add ARC component;
// }
// if (EISA bus component present)
// {
// if !(configuration data correct)
// {
// display error message;
// delete EISA bus node;
// add EISA bus component;
// return FALSE;
// }
// }
// else
// {
// add EISA bus component;
// }
// return TRUE;
//
// ARGUMENTS: BusNumber EISA bus number
// pEisaComp address where to store the EISA
// configuration pointer
//
// RETURN: FALSE The configuration tree was incorrect.
// TRUE The configuration tree is correct.
//
// ASSUMPTIONS: The ARC component is present.
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaCheckAdapterComponent
(
IN ULONG BusNumber,
OUT PCONFIGURATION_COMPONENT *pEisaComp
)
{
//
// define local variables
//
PCONFIGURATION_COMPONENT pComp;
CONFIGURATION_COMPONENT Comp;
EISA_ADAPTER_DETAILS ConfigData;
BOOLEAN CfgOk = TRUE;
CHAR EisaMnemonic[MAX_MNEMONIC_LEN +1];
PVOID IoStart;
ULONG IoSize;
ULONG Slots;
PRINTDBG("EisaCheckAdapterComponent\n\r"); // DEBUG SUPPORT
//
// initialize varables
//
sprintf( EisaMnemonic, "eisa(%lu)", BusNumber );
*pEisaComp = NULL;
IoStart = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
IoSize = EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots * 0x1000;
Slots = EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots ?
EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots + 16 :
EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots;
//
// if EISA adapter component is present, check its configuration data
//
if ((*pEisaComp = FwGetComponent(EisaMnemonic)) != NULL)
{
if ((*pEisaComp)->ConfigurationDataLength !=
sizeof(EISA_ADAPTER_DETAILS) ||
FwGetConfigurationData( (PVOID)&ConfigData, *pEisaComp ) ||
ConfigData.NumberOfSlots != Slots ||
ConfigData.IoStart != IoStart ||
ConfigData.IoSize != IoSize )
{
EisaPathErrorLog( *pEisaComp, CfgIncorrect );
FwDelCfgTreeNode( *pEisaComp, FALSE );
*pEisaComp = NULL;
CfgOk = FALSE;
}
}
//
// add EISA adapter component if not present
//
if ( *pEisaComp == NULL )
{
// get the root component pointer
if ((pComp = FwGetChild(NULL)) == NULL) {
return(FALSE);
}
// component structure
RtlZeroMemory( &Comp, sizeof(CONFIGURATION_COMPONENT));
Comp.Class = AdapterClass;
Comp.Type = EisaAdapter;
Comp.Version = ARC_VERSION;
Comp.Revision = ARC_REVISION;
Comp.Key = BusNumber;
Comp.ConfigurationDataLength = sizeof(EISA_ADAPTER_DETAILS);
Comp.IdentifierLength = sizeof("EISA");
Comp.Identifier = "EISA";
// configuration data structure
RtlZeroMemory( &ConfigData, sizeof(EISA_ADAPTER_DETAILS));
// NOTE: ConfigDataHeader is not used in JAZZ.
// ConfigData.ConfigDataHeader.Version = ARC_VERSION;
// ConfigData.ConfigDataHeader.Revision = ARC_REVISION;
// ConfigData.ConfigDataHeader.Type = NULL;
// ConfigData.ConfigDataHeader.Vendor = NULL;
// ConfigData.ConfigDataHeader.ProductName = NULL;
// ConfigData.ConfigDataHeader.SerialNumber = NULL;
ConfigData.NumberOfSlots = Slots;
ConfigData.IoStart = IoStart;
ConfigData.IoSize = IoSize;
*pEisaComp = FwAddChild( pComp, &Comp, (PVOID)&ConfigData );
}
//
// return status
//
return CfgOk;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaBusCfg:
//
// DESCRIPTION: This function configures the slots of the specified
// eisa bus.
//
// if we detect a "not-ready" board, we have to retry
// reading the ID again and report a time-out error if
// the ID is still not available after 100 msecs.
// (according to the EISA specs, the board should be
// ready within 100 msecs after reporting the "not-ready"
// status). However, due to the slow init process of
// the ESC-1, we need to go with the following algorithm:
// - cfg the physical slots, marking the ones not ready.
// - cfg the virtual slots
// - go back to cfg the not-ready physical slots.
// A time of 2 sec will be given to all these not-ready
// slots : 200 loops of 10 msec. This period does not
// include configuration time for any slot which now
// comes up with a valid ID.
//
// ARGUMENTS: EisaComponent EISA component pointer
//
// RETURN: TRUE Configuration completed successfully
// FALSE At least one configuration error
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaBusCfg
(
IN PCONFIGURATION_COMPONENT EisaComponent
)
{
//
// define local variables
//
BOOLEAN CfgOk = TRUE; // starting value: all fine
ULONG IdTimeoutFlags = 0; // eisa controllers in time-out
USHORT WaitTimeout=TIMEOUT_UNITS; // time to wait before aborting
PCONFIGURATION_COMPONENT FirstController; // first eisa controller
PCONFIGURATION_COMPONENT Controller; // eisa controller to configure
ULONG BusNumber; // eisa bus number
ULONG PhysSlots; // eisa physical slots
ULONG MaxSlots; // eisa last slot
ULONG SlotNumber; // slot number configured
PULONG pSlotCfgMap; // slot cfg map pointer
PUCHAR EisaIoStart; // i/o eisa starting space
ULONG AdapId; // eisa controller id
PRINTDBG("EisaBusCfg\n\r"); // DEBUG SUPPORT
//
// initialize same variables using the eisa component structure
//
BusNumber = EisaComponent->Key;
EisaIoStart = EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
PhysSlots = EisaBusInfo[ BusNumber ].SlotsInfo->PhysSlots;
MaxSlots = EisaBusInfo[ BusNumber ].SlotsInfo->VirSlots + 16;
pSlotCfgMap = &EisaBusInfo[ BusNumber ].SlotsInfo->SlotCfgMap;
*pSlotCfgMap = 0;
FirstController = FwGetChild(EisaComponent);
//
// physical slot initialization : one loop per physical slot
//
for (SlotNumber=0; SlotNumber<PhysSlots; SlotNumber++)
{
// read eisa controller id
if (!EisaReadReadyId(EisaIoStart, SlotNumber, &AdapId))
{
IdTimeoutFlags |= 1<<SlotNumber;
continue;
}
// find the eisa controller for the specified slot
for (Controller = FirstController;
Controller!=NULL && Controller->Key!=SlotNumber;
Controller = FwGetPeer(Controller));
// skip cfg if empty slot; report an error if ARC cfg is missing
if (Controller==NULL)
{
if (AdapId!=NO_ADAP_ID)
{
EisaSlotErrorLog( BusNumber, SlotNumber, CfgMissing );
CfgOk = FALSE;
}
continue;
}
// one physical slot configuration
if (!EisaPhysSlotCfg(BusNumber, Controller, AdapId))
{
CfgOk = FALSE;
continue;
}
// set the "slot" bit to indicate configuration ok
*pSlotCfgMap |= 1<<SlotNumber;
// I/O function structures initialization
// NOTE: EisaOmf is not supported in JAZZ.
// EisaOmfCheck( BusNumber, Controller, AdapId );
}
//
// virtual slot initialization : one loop per virtual slot
//
for (SlotNumber=16; SlotNumber<MaxSlots; SlotNumber++)
{
// find the eisa controller for the specified slot
for (Controller = FirstController;
Controller!=NULL && Controller->Key!=SlotNumber;
Controller = FwGetPeer(Controller));
// if component not present, skip to next virtual slot
if (Controller==NULL)
{
continue;
}
// one virtual slot configuration
if(!EisaVirSlotCfg(BusNumber, Controller))
{
CfgOk = FALSE;
continue;
}
// set the "slot" bit to indicate configuration ok
*pSlotCfgMap |= 1<<SlotNumber;
}
//
// time-out slot initialization
//
while(IdTimeoutFlags && WaitTimeout--)
{
for ( SlotNumber = 0;
IdTimeoutFlags && SlotNumber < PHYS_0_SLOTS;
SlotNumber++ )
{
// check if the slot wasn't ready.
if ( !(IdTimeoutFlags & 1<<SlotNumber))
{
continue;
}
// read eisa controller id
if (!EisaReadReadyId(EisaIoStart, SlotNumber, &AdapId))
{
continue;
}
IdTimeoutFlags &= ~(1<<SlotNumber);
// find the eisa controller for the specified slot
for (Controller = FirstController;
Controller!=NULL && Controller->Key!=SlotNumber;
Controller = FwGetPeer(Controller));
// skip cfg if empty slot; report an error if ARC cfg is missing
if (Controller==NULL)
{
if (AdapId!=NO_ADAP_ID)
{
EisaSlotErrorLog(BusNumber, SlotNumber, CfgMissing);
CfgOk = FALSE;
}
continue;
}
// one physical slot configuration
if (!EisaPhysSlotCfg(BusNumber, Controller, AdapId))
{
CfgOk = FALSE;
continue;
}
// set the "slot" bit to indicate configuration ok
*pSlotCfgMap |= 1<<SlotNumber;
// I/O function structures initialization
// NOTE: EisaOmf is not supported in JAZZ.
// EisaOmfCheck( BusNumber, Controller, AdapId );
}
// if there are still some slots in time-out stall execution
// for 10 msec (10,000 usec).
if (IdTimeoutFlags)
{
FwStallExecution (10000l);
}
}
//
// if controllers in time-out, display error messages and set the
// failed bit within the associated "components".
//
if (IdTimeoutFlags)
{
for ( SlotNumber = 0; SlotNumber < PHYS_0_SLOTS; SlotNumber++ )
{
if ( IdTimeoutFlags & 1<<SlotNumber )
{
// display error message
EisaSlotErrorLog( BusNumber, SlotNumber, IdTimeout );
// find the eisa controller for the specified slot
for (Controller = FirstController;
Controller!=NULL && Controller->Key!=SlotNumber;
Controller = FwGetPeer(Controller));
// if component present, set failed bit
if (Controller != NULL)
{
Controller->Flags.Failed = 1;
}
}
}
CfgOk = FALSE;
}
// //
// // add a wild omf path name for the physical slots non configurated.
// //
//
// for ( SlotNumber = 0; SlotNumber < PHYS_0_SLOTS; SlotNumber++ )
// {
// if ( !(*pSlotCfgMap & 1<<SlotNumber) )
// {
// EisaOtherOmfIni( EisaComponent, SlotNumber );
// }
// }
//
// return configuration status
//
return CfgOk;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaPhysSlotCfg:
//
// DESCRIPTION: This function configures the specified physical slot.
//
// ARGUMENTS: BusNumber EISA bus number
// Controller eisa controller component pointer.
// AdapId Eisa Id read from hardware.
//
//
// RETURN: FALSE Error
// TRUE All done
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaPhysSlotCfg
(
IN ULONG BusNumber,
IN PCONFIGURATION_COMPONENT Controller,
IN ULONG AdapId
)
{
//
// define local variables
//
EISA_SLOT_INFO EisaSlotInfo; // pointer to first eisa info
EISA_CFG_ERROR ErrMessage = CfgNoErrCode; // eisa cfg error code
PRINTDBG("EisaPhysSlotCfg\n\r"); // DEBUG SUPPORT
//
// validate physical slot configuration
//
if (Controller->Flags.Failed)
{
ErrMessage = CfgDeviceFailed; // device failure
}
else if ( !(Controller->ConfigurationDataLength) )
{
ErrMessage = CfgMissing; // eisa configuration missing
}
else if (Controller->ConfigurationDataLength < EISA_SLOT_MIN_INFO)
{
ErrMessage = CfgIncorrect; // configuration length incorrect
}
else if (FwGetConfigurationDataIndex( (PVOID)&EisaSlotInfo,
Controller,
CONFIGDATAHEADER_SIZE,
EISA_SLOT_INFO_SIZE ))
{
ErrMessage = CfgIncorrect; // invalid component
}
else if (EisaSlotInfo.FunctionsNumber * EISA_FUNC_INFO_SIZE +
EISA_SLOT_MIN_INFO != Controller->ConfigurationDataLength)
{
ErrMessage = CfgIncorrect; // configuration length incorrect
}
else if (!(EisaSlotInfo.IdInfo & CFG_UNREADABLE_ID)^(AdapId != NO_ADAP_ID))
{
ErrMessage = CfgIdError; // wrong configuration
}
else if (AdapId != NO_ADAP_ID &&
AdapId != Fw4UcharToUlongMSB(&EisaSlotInfo.Id1stChar))
{
ErrMessage = CfgIdError; // wrong configuration
}
else if ((EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_EXP &&
(EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_EMB )
{
ErrMessage = CfgIncorrect; // wrong configuration
}
//
// if any error, dispaly error message and set the failed bit
//
if (ErrMessage != CfgNoErrCode)
{
EisaSlotErrorLog( BusNumber, Controller->Key, ErrMessage );
Controller->Flags.Failed = 1;
return FALSE;
}
//
// eisa adapter configuration
//
return( EisaSlotCfg( BusNumber,
Controller,
EisaSlotInfo.FunctionsNumber ));
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaVirSlotCfg:
//
// DESCRIPTION: This function configures the specified virtual slot.
//
// ARGUMENTS: BusNumber EISA bus number
// Controller eisa controller component pointer.
//
//
// RETURN: FALSE Error
// TRUE All done
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaVirSlotCfg
(
IN ULONG BusNumber,
IN PCONFIGURATION_COMPONENT Controller
)
{
//
// define local variables
//
EISA_SLOT_INFO EisaSlotInfo; // pointer to first eisa info
EISA_CFG_ERROR ErrMessage = CfgNoErrCode; // eisa cfg error code
PRINTDBG("EisaVirSlotCfg\n\r"); // DEBUG SUPPORT
//
// validate virtual slot configuration
//
if (Controller->Flags.Failed)
{
ErrMessage = CfgDeviceFailed; // device failure
}
else if ( !(Controller->ConfigurationDataLength) )
{
ErrMessage = CfgMissing; // configuration missing
}
if (Controller->ConfigurationDataLength < EISA_SLOT_MIN_INFO)
{
ErrMessage = CfgIncorrect; // configuration length incorrect
}
else if (FwGetConfigurationDataIndex( (PVOID)&EisaSlotInfo,
Controller,
CONFIGDATAHEADER_SIZE,
EISA_SLOT_INFO_SIZE ))
{
ErrMessage = CfgIncorrect; // invalid component
}
else if (EisaSlotInfo.FunctionsNumber * EISA_FUNC_INFO_SIZE +
EISA_SLOT_MIN_INFO != Controller->ConfigurationDataLength)
{
ErrMessage = CfgIncorrect; // configuration length incorrect
}
else if ( !(EisaSlotInfo.IdInfo & CFG_UNREADABLE_ID) )
{
ErrMessage = CfgIdError; // wrong configuration
}
else if ( (EisaSlotInfo.IdInfo & CFG_SLOT_MASK) != CFG_SLOT_VIR)
{
ErrMessage = CfgIncorrect; // wrong configuration
}
//
// if any error, display error message and set the failed bit
//
if (ErrMessage != CfgNoErrCode)
{
EisaSlotErrorLog( BusNumber, Controller->Key, ErrMessage );
Controller->Flags.Failed = 1;
return FALSE;
}
//
// eisa adapter configuration
//
return( EisaSlotCfg( BusNumber,
Controller,
EisaSlotInfo.FunctionsNumber ));
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaSlotCfg:
//
// DESCRIPTION: This function configures the specified slot.
//
// ARGUMENTS: BusNumber EISA bus number
// Controller Controller component pointer
// FunctionsNumber Number of function to configure
//
// RETURN: TRUE Configuration done
// FALSE Error
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaSlotCfg
(
IN ULONG BusNumber,
IN PCONFIGURATION_COMPONENT Controller,
IN UCHAR FunctionsNumber
)
{
//
// define local variables
//
UCHAR FuncFlags; // function info flags
UCHAR Function; // current function number
BOOLEAN CfgOk = TRUE; // local configuration status
BOOLEAN EnabAdapter = TRUE; // adapter enable flag
PUCHAR EnabPort; // used to enable the adapter
PUCHAR EisaIoStart; // Eisa I/O virtual space
PEISA_DMA_INFO pDmaInfo; // DMA info pointer
PEISA_INT_INFO pIntInfo; // interrupts info pointer
BOOLEAN CfgMemOk = TRUE; // prevent multiple messages
BOOLEAN CfgIrqOk = TRUE; // " " "
BOOLEAN CfgDmaOk = TRUE; // " " "
BOOLEAN CfgIniOk = TRUE; // " " "
UCHAR EisaFuncInfo[ EISA_FUNC_INFO_SIZE ];
ULONG EisaFuncIndex;
PRINTDBG("EisaSlotCfg\n\r"); // DEBUG SUPPORT
//
// initialize variables
//
EisaIoStart = (PUCHAR)EisaBusInfo[ BusNumber ].IoBusInfo->VirAddr;
pDmaInfo = EisaBusInfo[ BusNumber ].DmaInfo;
pIntInfo = EisaBusInfo[ BusNumber ].IntInfo;
EisaFuncIndex = EISA_SLOT_MIN_INFO;
//
// one function per loop
//
for ( Function = 0;
Function < FunctionsNumber;
Function++, EisaFuncIndex += EISA_FUNC_INFO_SIZE )
{
//
// read function info
//
FwGetConfigurationDataIndex( (PVOID)EisaFuncInfo,
Controller,
EisaFuncIndex,
EISA_FUNC_INFO_SIZE );
//
// check if configuration complete, exit if not.
//
if ( EisaFuncInfo[ CFG_SLOT_INFO_OFS ] & CFG_INCOMPLETE )
{
EisaSlotErrorLog( BusNumber, Controller->Key, CfgIncomplete );
CfgOk = FALSE;
break;
}
// update eisa function flags
FuncFlags = EisaFuncInfo[ CFG_FN_INFO_OFS ];
// skip if free form function
if ( FuncFlags & CFG_FREE_FORM )
{
continue;
}
//
// check if there is any memory entry
//
// NOTE: Eisa memory not supported on JAZZ.
// if ( FuncFlags & CFG_MEM_ENTRY )
// {
// if ( !EisaSlotCfgMem( BusNumber, Controller->Key, EisaFuncInfo ) &&
// CfgMemOk )
// {
// EisaSlotErrorLog( BusNumber, Controller->Key, CfgMemError );
// CfgOk = CfgMemOk = FALSE;
// }
// }
//
// check if there is any interrupt entry
//
if ( FuncFlags & CFG_IRQ_ENTRY )
{
if (!EisaSlotCfgIrq( EisaIoStart, pIntInfo, EisaFuncInfo ) &&
CfgIrqOk )
{
EisaSlotErrorLog( BusNumber, Controller->Key, CfgIrqError );
CfgOk = CfgIrqOk = FALSE;
}
}
//
// check if there is any DMA entry
//
if ( FuncFlags & CFG_DMA_ENTRY )
{
if ( !EisaSlotCfgDma( EisaIoStart, pDmaInfo, EisaFuncInfo ) &&
CfgDmaOk )
{
EisaSlotErrorLog( BusNumber, Controller->Key, CfgDmaError );
CfgOk = CfgDmaOk = FALSE;
}
}
//
// check if there is any port init entry
//
if ( FuncFlags & CFG_INI_ENTRY )
{
if ( !EisaSlotCfgIni( EisaIoStart, EisaFuncInfo, &EnabAdapter ) &&
CfgIniOk )
{
EisaSlotErrorLog( BusNumber, Controller->Key, CfgIniError );
CfgOk = CfgIniOk = FALSE;
}
}
}
//
// if all fine, enable the adapter
//
if (CfgOk && EnabAdapter)
{
EnabPort=EisaIoStart+ Controller->Key*0x1000 +EXPANSION_BOARD_CTRL_BITS;
EisaOutUchar(EnabPort, EisaInUchar(EnabPort) | 0x01);
}
//
// return status of configuration process
//
return CfgOk;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaSlotCfgMem:
//
// DESCRIPTION: This function configures the eisa memory registers
// based on info from NVRAM.
//
// ARGUMENTS: BusNumber EISA bus number.
// SlotNumber EISA slot number.
// EisaFuncInfo Function info pointer.
//
// RETURN: TRUE All done
// FALSE Error
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
// NOTE: Eisa memory not supported on JAZZ.
#if 0
BOOLEAN
EisaSlotCfgMem
(
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN PUCHAR EisaFuncInfo
)
{
//
// define local variables
//
BOOLEAN CfgOk = TRUE; // local configuration status
PUCHAR MemBlock; // start of DMA data buffer
USHORT Index = 0; // index within the memory block
PFW_MD pFwMd; // memory decriptor pointer
ULONG Addr; // address in 256 units
ULONG Size; // size in 1k units
ULONG WinSize, WinOffs; // EISA windows characteristic
PFW_MD pMemInfo; // EISA memory address space info
PRINTDBG("EisaSlotCfgMem\n\r"); // DEBUG SUPPORT
//
// initialize variables
//
pMemInfo = EisaBusInfo[ BusNumber ].MemBusInfo;
MemBlock = &EisaFuncInfo[ CFG_MEM_BLK_OFS ];
//
// one loop per each memory entry
//
do
{
//
// get a memory descriptor
//
if ( (pFwMd = GetFwMd()) == NULL )
{
EisaSlotErrorLog( BusNumber, SlotNumber, MemAllocError);
return FALSE;
}
//
// memory block start and length
//
Addr = Fw3UcharToUlongLSB( &MemBlock[Index + 2] );
Size = Fw2UcharToUlongLSB( &MemBlock[Index + 5] );
pFwMd->VirAddr = NULL;
pFwMd->PhysAddr = Addr >> 4;
pFwMd->PagOffs = (Addr << 8) & (PAGE_SIZE - 1);
pFwMd->Size = Size ? Size << 10 : 64*1024*1024 ;
pFwMd->PagNumb = (pFwMd->PagOffs + Size + PAGE_SIZE - 1) >> PAGE_SHIFT;
pFwMd->Cache = FALSE;
pFwMd->u.m.BusNumber = BusNumber;
pFwMd->u.m.SlotNumber = SlotNumber;
pFwMd->u.m.Type = MemBlock[ Index ] & CFG_MEM_TYPE;
//
// check if the memory size fits within the EISA window
//
if ( pMemInfo->u.em.WinShift != PAGE_4G_SHIFT )
{
// window size < 4 Gbytes
WinSize = 1 << pMemInfo->u.em.WinShift;
WinOffs = (Addr << 8) & (WinSize - 1);
if ( WinSize - WinOffs < pFwMd->Size )
{
ReleaseFwMd( &pMemInfo->Link, pFwMd );
CfgOk = FALSE;
continue;
}
}
//
// link the memory descriptor
//
if ( LinkPhysFwMd( &pMemInfo->Link, pFwMd ) == NULL )
{
ReleaseFwMd( &pMemInfo->Link, pFwMd );
CfgOk = FALSE;
continue;
}
}
while ((MemBlock[Index]&CFG_MORE_ENTRY) && ((Index+=7)<CFG_MEM_BLK_LEN));
//
// check final index
//
if ( !(Index < CFG_MEM_BLK_LEN) )
{
CfgOk=FALSE;
}
//
// return configuration status
//
return CfgOk;
}
#endif // 0
// ----------------------------------------------------------------------------
// PROCEDURE: EisaSlotCfgIrq:
//
// DESCRIPTION: This function configures the interrupt registers
// based on info from NVRAM.
//
// ARGUMENTS: EisaIoStart EISA I/O virtual address
// pIntInfo interrupt info pointer
// EisaFuncInfo function info pointer.
//
// RETURN: TRUE All done
// FALSE Error
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaSlotCfgIrq
(
IN PUCHAR EisaIoStart,
IN PEISA_INT_INFO pIntInfo,
IN PUCHAR EisaFuncInfo
)
{
//
// define local variables
//
BOOLEAN CfgOk = TRUE; // local configuration status
PUCHAR IrqBlock; // start of IRQ data buffer
USHORT Index = 0; // index within the IRQ block
USHORT IrqBit; // 0x1=IRQ0... 0x8000=IRQ15
UCHAR Register; // used to update the registers
PRINTDBG("EisaSlotCfgIrq\n\r"); // DEBUG SUPPORT
//
// initialize variables
//
IrqBlock = &EisaFuncInfo[ CFG_IRQ_BLK_OFS ];
//
// one loop per each IRQ entries
//
do
{
IrqBit = 1 << ( IrqBlock[ Index ] & CFG_IRQ_MASK ); // compute IRQ bit
//
// check shareable and edge/level trigger mode
//
if ( pIntInfo->IrqPresent & IrqBit )
{
//
// IRQ already used: check if it is shareabe
//
if ( !(pIntInfo->IrqShareable & IrqBit) )
{
CfgOk = FALSE;
continue;
}
else if ( !(IrqBlock[Index] & CFG_IRQ_SHARE) )
{
CfgOk = FALSE;
continue;
}
//
// IRQ is shareable: check if the levels are compatible
//
else if ( (pIntInfo->IrqLevel & IrqBit) &&
!(IrqBlock[Index] & CFG_IRQ_LEVEL) )
{
CfgOk=FALSE;
continue;
}
else if ( !(pIntInfo->IrqLevel & IrqBit) &&
(IrqBlock[Index] & CFG_IRQ_LEVEL) )
{
CfgOk=FALSE;
continue;
}
}
else
{
//
// new IRQ: check if the IRQ 0, 1, 2, 8 and 13 are configurated
// for edge triggered.
//
switch(IrqBit)
{
case (0x0001): // IRQ 0 only edge triggered
case (0x0002): // IRQ 1 " " "
case (0x0004): // IRQ 2 " " "
case (0x0100): // IRQ 8 " " "
case (0x2000): // IRQ 13 " " "
if (IrqBlock[Index] & CFG_IRQ_LEVEL)
{
CfgOk=FALSE;
continue;
}
break;
default:
break;
}
}
//
// set the present bit and update sharable and edge/level
// triggered variables
//
pIntInfo->IrqPresent |= IrqBit;
if (IrqBlock[Index] & CFG_IRQ_SHARE)
{
pIntInfo->IrqShareable |= IrqBit;
}
if (IrqBlock[Index] & CFG_IRQ_LEVEL)
{
pIntInfo->IrqLevel |= IrqBit;
}
}
while ((IrqBlock[Index]&CFG_MORE_ENTRY) && ((Index+=2)<CFG_IRQ_BLK_LEN));
//
// check final index
//
if ( !( Index < CFG_IRQ_BLK_LEN ) )
{
CfgOk=FALSE;
}
//
// initialize ELCR registers with new values.
//
Register = EisaInUchar(EisaIoStart + PIC1_ELCR);
Register &= ~(pIntInfo->IrqPresent);
Register |= pIntInfo->IrqLevel;
EisaOutUchar(EisaIoStart + PIC1_ELCR, Register);
Register = EisaInUchar(EisaIoStart + PIC2_ELCR);
Register &= ~(pIntInfo->IrqPresent >> BITSXBYTE);
Register |= pIntInfo->IrqLevel >> BITSXBYTE;
EisaOutUchar(EisaIoStart + PIC2_ELCR, Register);
//
// return configuration status
//
return CfgOk;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaSlotCfgDma:
//
// DESCRIPTION: This function configures the DMA registers
// based on info from NVRAM.
//
// ARGUMENTS: EisaIoStart EISA I/O virtual address
// pDmaInfo DMA info pointer
// EisaFuncInfo function info pointer.
//
// RETURN: TRUE All done
// FALSE Error
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaSlotCfgDma
(
IN PUCHAR EisaIoStart,
IN PEISA_DMA_INFO pDmaInfo,
IN PUCHAR EisaFuncInfo
)
{
//
// define local variables
//
BOOLEAN CfgOk=TRUE; // local configuration status
PUCHAR DmaBlock; // start of DMA data buffer
USHORT Index=0; // index within the DMA block
UCHAR DmaNumber; // DMA under configuration
UCHAR Register; // used to update the registers
PRINTDBG("EisaSlotCfgDma\n\r"); // DEBUG SUPPORT
//
// initialize variables
//
DmaBlock = &EisaFuncInfo[ CFG_DMA_BLK_OFS ];
//
// one loop per each DMA entry
//
do
{
//
// skip if shareable. device drivers should init DMA, not ROM
//
// NOTE: the following code has been removed because all the
// EISA cards that share the same DMA channel have the
// same value in this register. This is guaranteed by
// the configuration utility.
//if ( DmaBlock[Index] & CFG_DMA_SHARED )
//{
// continue;
//}
//
// Program the specified DMA channel using the new info.
//
DmaNumber = DmaBlock[Index] & CFG_DMA_MASK;
// keep the "stop register" and "T-C" bits
Register = pDmaInfo->DmaExtReg[ DmaNumber ] & ~CFG_DMA_CFG_MASK;
// use the new timing and bit I/O selection
Register |= DmaBlock[Index+1] & CFG_DMA_CFG_MASK;
// update the register
if (DmaNumber < 4)
{
EisaOutUchar(EisaIoStart + DMA_EXTMODE03, Register);
}
else
{
EisaOutUchar(EisaIoStart + DMA_EXTMODE47, Register);
}
// This register value is used to validate the DMA requestes
// (see the "EisaRequestEisaDmaTransfer" function).
// The DMA channels used by more than one card have always the
// same value ( check with the configuration guys ).
pDmaInfo->DmaExtReg[ DmaNumber ] = Register;
}
while ((DmaBlock[Index]&CFG_MORE_ENTRY) && ((Index+=2)<CFG_DMA_BLK_LEN));
//
// check final index
//
if ( !(Index < CFG_DMA_BLK_LEN) )
{
CfgOk=FALSE;
}
//
// return configuration status
//
return CfgOk;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaSlotCfgIni:
//
// DESCRIPTION: This function configures the I/O port registers
// based on info from NVRAM.
//
// ARGUMENTS: EisaIoStart Starting eisa I/O area.
// EisaFuncInfo Function info pointer.
// EnabAdapter Enable adapter flag pointer.
//
// RETURN: TRUE All done
// FALSE Error
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaSlotCfgIni
(
IN PUCHAR EisaIoStart,
IN PUCHAR EisaFuncInfo,
OUT PBOOLEAN EnabAdapter
)
{
//
// define local variables
//
BOOLEAN CfgOk = TRUE; // local configuration status
PUCHAR IniBlock; // start of init data buffer
USHORT Index = 0; // index within the init block
USHORT Next = 0; // index within the entry
USHORT IoPort; // I/O address port
UCHAR ByteValue; // used to init the registers
UCHAR ByteMask; //
USHORT ShortValue; // used to init the registers
USHORT ShortMask; //
ULONG WordValue; // used to init the registers
ULONG WordMask; //
PRINTDBG("EisaSlotCfgIni\n\r"); // DEBUG SUPPORT
// initialize variables
IniBlock = &EisaFuncInfo[CFG_INI_BLK_OFS];
//
// one loop per each init entries
//
do
{
// load the i/o address port
Next = 1;
IoPort = IniBlock[Index + Next++];
IoPort |= IniBlock[Index + Next++] << BITSXBYTE;
switch(IniBlock[Index] & CFG_INI_MASK)
{
//
// 8-bit I/O access
//
case(CFG_INI_BYTE):
ByteValue = IniBlock[Index + Next++];
if (IniBlock[Index] & CFG_INI_PMASK) // use the mask
{
ByteMask = IniBlock[Index + Next++];
ByteValue |= READ_REGISTER_UCHAR(EisaIoStart+IoPort) & ByteMask;
EISA_IO_DELAY;
}
if ((IoPort & 0x0FFF) == EXPANSION_BOARD_CTRL_BITS)
{
*EnabAdapter=FALSE;
}
WRITE_REGISTER_UCHAR(EisaIoStart+IoPort, ByteValue);
EISA_IO_DELAY;
break;
//
// 16-bit I/O access
//
case(CFG_INI_HWORD):
ShortValue = IniBlock[Index + Next++];
ShortValue |= IniBlock[Index + Next++] << BITSXBYTE;
if (IniBlock[Index] & CFG_INI_PMASK) // use the mask
{
ShortMask = IniBlock[Index + Next++];
ShortMask |= IniBlock[Index + Next++] << BITSXBYTE;
ShortValue |= READ_REGISTER_USHORT(EisaIoStart + IoPort) &
ShortMask;
EISA_IO_DELAY;
}
WRITE_REGISTER_USHORT(EisaIoStart + IoPort, ShortValue);
EISA_IO_DELAY;
break;
//
// 32-bit I/O access
//
case(CFG_INI_WORD):
WordValue = Fw4UcharToUlongLSB( &IniBlock[Index + Next] );
Next += 4;
if (IniBlock[Index]&CFG_INI_PMASK) // use the mask
{
WordMask = Fw4UcharToUlongLSB( &IniBlock[Index + Next] );
Next += 4;
WordValue |= READ_REGISTER_ULONG(EisaIoStart + IoPort) &
WordMask;
EISA_IO_DELAY;
}
WRITE_REGISTER_ULONG(EisaIoStart + IoPort, WordValue);
EISA_IO_DELAY;
break;
//
// error
//
default:
CfgOk=FALSE;
break;
}
}
while ((IniBlock[Index]&CFG_MORE_ENTRY) && ((Index+=Next)<CFG_INI_BLK_LEN));
//
// check final index
//
if ( !(Index < CFG_INI_BLK_LEN) )
{
CfgOk=FALSE;
}
//
// return configuration status
//
return CfgOk;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaSlotErrorLog:
//
// DESCRIPTION: This function displays the corresponding eisa
// error message.
//
// ARGUMENTS: BusNumber BusNumber (not used)
// SlotNumber Slot in error
// ErrorCode Error number.
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
VOID
EisaSlotErrorLog
(
IN ULONG BusNumber,
IN ULONG SlotNumber,
IN EISA_CFG_ERROR ErrorCode
)
{
PRINTDBG("EisaSlotErrorLog\n\r"); // DEBUG SUPPORT
// display the error message
FwPrint( EISA_ERROR_SLOT_MSG, SlotNumber, EisaCfgMessages[ErrorCode] );
FwMoveCursorToColumn( 37 );
FwPrint( EISA_ERROR1_MSG );
FwStallExecution(1500000);
// all done
return;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaPathErrorLog:
//
// DESCRIPTION: This function displays the corresponding eisa
// error message.
//
// ARGUMENTS: Component Component in error.
// ErrorCode Error number.
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
VOID
EisaPathErrorLog
(
IN PCONFIGURATION_COMPONENT Controller,
IN EISA_CFG_ERROR ErrorCode
)
{
CHAR Path[ MAX_DEVICE_PATH_LEN +1 ];
PRINTDBG("EisaPathErrorLog\n\r"); // DEBUG SUPPORT
EisaStrErrorLog( FwGetPath( Controller, Path ), ErrorCode );
return;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaStrErrorLog:
//
// DESCRIPTION: This function displays the corresponding eisa
// error message.
//
// ARGUMENTS: Str String Message
// ErrorCode Error number.
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
VOID
EisaStrErrorLog
(
IN PCHAR Str,
IN EISA_CFG_ERROR ErrorCode
)
{
PRINTDBG("EisaStrErrorLog\n\r"); // DEBUG SUPPORT
FwPrint( "\r\n %s %s ", Str, EisaCfgMessages[ErrorCode] );
if ( strlen(Str) + strlen(EisaCfgMessages[ErrorCode]) + 2 < 36 )
{
FwMoveCursorToColumn( 37 );
}
FwPrint( EISA_ERROR1_MSG );
FwStallExecution(1500000);
return;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaCheckpointFirstFase:
//
// DESCRIPTION: This function displays the specified checkpoint
// number on the internal LED and sends it to the
// parallel port.
//
// ARGUMENTS: Chk checkpoint number
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
//
// ----------------------------------------------------------------------------
//
VOID
EisaCheckpointFirstFase
(
IN EISA_CHECKPOINT Chk
)
{
ULONG TestFlags;
PRINTDBG("EisaCheckpointFirstFase\n\r"); // DEBUG SUPPORT
TestFlags = ( (ULONG)EisaCheckpointInfo[ Chk ].SubLed << 28 ) +
( (ULONG)EisaCheckpointInfo[ Chk ].Led << 24 ) +
( (ULONG)EisaCheckpointInfo[ Chk ].SubPar << 8 ) +
( (ULONG)EisaCheckpointInfo[ Chk ].Par );
// NOTE: The parallel port test flag support is not used on JAZZ.
// DisplayOnParallelPort( TestFlags );
return;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaCheckpointFinalFase:
//
// DESCRIPTION: This function returns the value of the specified
// real-time clock internal address.
//
// ARGUMENTS: Chk checkpoint number
// Passed pass or fail
//
// RETURN: Repeat = TRUE repeat checkpoint
// = FALSE continue
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
//
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaCheckpointFinalFase
(
IN EISA_CHECKPOINT Chk,
IN BOOLEAN Passed
)
{
ULONG TestFlags;
PRINTDBG("EisaCheckpointFinalFase\n\r"); // DEBUG SUPPORT
if ( Passed )
{
EisaCheckpointInfo[ Chk ].Flags &= ~0x01; // all fine
EisaCheckpointInfo[ Chk ].Flags &= ~0x08; // no message
}
else
{
EisaCheckpointInfo[ Chk ].Flags |= 0x01; // error
if ( EisaCheckpointInfo[ Chk ].Flags & 0x08 ) // display message
{
FwPrint( "%s", EisaCheckpointInfo[ Chk ].Msg );
FwStallExecution(1500000);
}
}
TestFlags = (( (ULONG)EisaCheckpointInfo[ Chk ].SubLed << 28 ) +
( (ULONG)EisaCheckpointInfo[ Chk ].Led << 24 ) +
( (ULONG)EisaCheckpointInfo[ Chk ].Flags << 16 ) +
( (ULONG)EisaCheckpointInfo[ Chk ].SubPar << 8 ) +
( (ULONG)EisaCheckpointInfo[ Chk ].Par ));
// TEMPTEMP: Changed until we get the EvaluateTestResult routine from Olivetti.
// return EvaluateTestResult( TestFlags ) == ESUCCESS ? FALSE : TRUE;
return(FALSE); // Never repeat.
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaReadReadyId:
//
// DESCRIPTION: This function reads the eisa id of the specified
// slot.
//
// ARGUMENTS: EisaIoStart Starting eisa I/O address.
// SlotNumber Eisa slot number.
// AdapId Eisa ID returned.
//
// RETURN: FALSE Time-out error
// TRUE Valid adapter Id
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
EisaReadReadyId
(
IN PUCHAR EisaIoStart,
IN ULONG SlotNumber,
OUT PULONG AdapId
)
{
// define local variables
BOOLEAN Ready=TRUE;
PRINTDBG("EisaReadReadyId\n\r"); // DEBUG SUPPORT
//
// read adapter id
//
EisaReadId(EisaIoStart, SlotNumber, AdapId);
//
// check if adapter id is ready
//
if ( *AdapId & NO_ADAP_ID )
{
*AdapId = NO_ADAP_ID; // empty slot
}
else if ((*AdapId & WAIT_ADAP_ID) == WAIT_ADAP_ID)
{
Ready = FALSE; // adapter not ready
}
return Ready;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaReadId:
//
// DESCRIPTION: This function reads the eisa id of the specified
// slot.
//
// ARGUMENTS: EisaIoStart Starting eisa I/O address.
// SlotNumber Eisa slot number.
// AdapId Eisa ID returned.
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
VOID
EisaReadId
(
IN PUCHAR EisaIoStart,
IN ULONG SlotNumber,
OUT PULONG AdapId
)
{
// define local variables
PUCHAR AdapIdPort; // eisa I/O ID port
PUCHAR RefreshPort; // eisa refresh port
UCHAR RefreshStatus; // eisa refresh status (port 61h)
ULONG Retry; // # retry
PRINTDBG("EisaReadId\n\r"); // DEBUG SUPPORT
// initialize variables
AdapIdPort = EisaIoStart + SlotNumber * 0x1000 + EISA_PRODUCT_ID;
RefreshPort = EisaIoStart + EISA_SYS_CTRL_PORTB;
// wait for the end of a refresh cycle (bit 4 of port 61h toggles)
for ( Retry = EISA_RFR_RETRY,
RefreshStatus = READ_REGISTER_UCHAR(RefreshPort) & EISA_REFRESH;
Retry &&
RefreshStatus == (READ_REGISTER_UCHAR(RefreshPort) & EISA_REFRESH);
Retry-- );
// write 0xFF to the adapter ID port
EisaOutUchar(AdapIdPort, 0xFF);
// read adapter id
*AdapId = EisaInUchar(AdapIdPort++);
*AdapId = *AdapId << BITSXBYTE | EisaInUchar(AdapIdPort++);
*AdapId = *AdapId << BITSXBYTE | EisaInUchar(AdapIdPort++);
*AdapId = *AdapId << BITSXBYTE | EisaInUchar(AdapIdPort++);
// all done, return.
return;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaMemIni:
//
// DESCRIPTION: This function allocates memory for the descriptor
// pool and computes the top address and the length
// of a physical contiguous memory block to be used as
// OMF device drivers and dynamic memory pool.
// Note that only the memory really used will be
// allocated.
//
// ARGUMENTS: none
//
// RETURN: TRUE all done
// FALSE memory initialization error
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS: pFwMdPool // descriptor pool
// MemorySize // memory size in Mbytes
// EisaPoolSize // # bytes really used
// EisaFreeTop // top of free mem
// EisaDynMemSize // dynamic memory size (bytes)
// EisaFreeBytes // free bytes left
//
// NOTES:
// ----------------------------------------------------------------------------
//
// NOTE: Not used for JAZZ.
#if 0
BOOLEAN
EisaMemIni
(
VOID
)
{
FW_MD BuffFwMd;
PVOID Dummy;
PRINTDBG("EisaMemIni\n\r"); // DEBUG SUPPORT
//
// allocate descriptor pool
//
if ( (pFwMdPool = (PFW_MD)FwAllocatePool( sizeof(FW_MD)*FW_MD_POOL ))
== NULL )
{
return FALSE;
}
//
// set all the necessary TLB entries to map the whole system memory
//
RtlZeroMemory( &BuffFwMd, sizeof(FW_MD));
BuffFwMd.Size = 256 << 20;
BuffFwMd.PagNumb = 256 << (20 - PAGE_SHIFT);
BuffFwMd.Cache = TRUE;
if ( AllocateMemoryResources( &BuffFwMd ) != ESUCCESS )
{
return FALSE;
}
//
// compute OMF device drivers and dynamic memory pool area
//
EisaPoolSize = EisaDynMemSize = EISA_DYN_MEM_SIZE;
if ( MemorySize >= 16 )
{
//
// we don't use the memory above 16Mbytes because in this way we
// can use this logic in a machine without translation registers
// (logical I/O to physical) for the ISA boards which have a
// transfer range of 24 bits (16Mbytes).
//
EisaFreeTop = EISA_FREE_TOP_16;
EisaFreeBytes = EISA_FREE_BYTES_16;
}
else if ( MemorySize >= 12 )
{
EisaFreeTop = EISA_FREE_TOP_12;
EisaFreeBytes = EISA_FREE_BYTES_12;
}
else if ( MemorySize >= 8 )
{
EisaFreeTop = EISA_FREE_TOP_8;
EisaFreeBytes = EISA_FREE_BYTES_8;
}
else
{
return FALSE;
}
EisaFreeBytes -= EisaDynMemSize;
return TRUE;
}
#endif // 0
// ----------------------------------------------------------------------------
// PROCEDURE: EisaDynMemIni:
//
// DESCRIPTION: This function allocates the requested space for the
// the dynamic memory allocation.
//
// ARGUMENTS: none
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS: EisaFreeTop top of free mem
// EisaDynMemSize dynamic memory size (bytes)
// EisaPoolSize EISA pool size (bytes)
//
// NOTES:
// ----------------------------------------------------------------------------
//
// NOTE: Not used for JAZZ.
#if 0
VOID
EisaDynMemIni
(
VOID
)
{
//
// define local variables
//
ULONG BytesToPage; // bytes left to make a page
PHEADER pHdr; // memory descriptor header ptr
PVOID Buffer; // data area
PRINTDBG("EisaDynMemIni\n\r"); // DEBUG SUPPORT
//
// align the dynamic memory buffer on a page boundary
//
BytesToPage = PAGE_SIZE - (EisaDynMemSize & ((1 << PAGE_SHIFT) - 1));
EisaDynMemSize += BytesToPage;
EisaPoolSize += BytesToPage;
EisaFreeTop -= EisaDynMemSize;
//
// initialize first memory descriptor
//
pHdr = (PHEADER)EisaFreeTop;
Buffer = (PVOID)(pHdr + 1);
pHdr->m.id = Buffer;
pHdr->m.size = EisaDynMemSize/sizeof(HEADER);
EisaFreeMemory( Buffer );
return;
}
#endif // 0
// ----------------------------------------------------------------------------
// PROCEDURE: FwGetPath:
//
// DESCRIPTION: This function builds the path name for the specified
// component.
//
// ARGUMENTS: Component Component pointer.
// Str Path name pointer.
//
// RETURN: Str Path name pointer.
//
// ASSUMPTIONS: The string must be large enoungh to hold the
// requested path name.
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
PCHAR
FwGetPath
(
IN PCONFIGURATION_COMPONENT Component,
OUT PCHAR Str
)
{
PCONFIGURATION_COMPONENT pComp;
PRINTDBG("FwGetPath\n\r"); // DEBUG SUPPORT
if ( (pComp = FwGetParent( Component )) != NULL )
{
FwGetPath( pComp, Str);
strcat( Str, FwGetMnemonic( Component ) );
sprintf( Str + strlen( Str ), "(%lu)", Component->Key);
}
else
{
*Str = '\0';
}
return Str;
}
// ----------------------------------------------------------------------------
// PROCEDURE: FwDelCfgTreeNode:
//
// DESCRIPTION: This function removes from the configuration tree
// the specified component and all its children.
//
// ARGUMENTS: pComp component pointer.
// Peer = TRUE delete all its peers.
// = FALSE delete just this branch.
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
VOID
FwDelCfgTreeNode
(
IN PCONFIGURATION_COMPONENT pComp,
IN BOOLEAN Peer
)
{
//
// define local variables
//
PCONFIGURATION_COMPONENT NextComp;
PRINTDBG("FwDelCfgTreeNode\n\r"); // DEBUG SUPPORT
//
// check for a child
//
if ( (NextComp = FwGetChild( pComp )) != NULL )
{
FwDelCfgTreeNode( NextComp, TRUE );
}
//
// check for a peer.
//
if ( Peer && (NextComp = FwGetPeer( pComp )) != NULL )
{
FwDelCfgTreeNode( NextComp, TRUE );
}
//
// this is a leaf, delete it
//
FwDeleteComponent( pComp );
//
// all done
//
return;
}
// ----------------------------------------------------------------------------
// PROCEDURE: FwGetMnemonic:
//
// DESCRIPTION: This function stores the mnemonic name for the
// requested component type.
//
// ARGUMENTS: Component Component pointer.
//
// RETURN: Str Mnemonic pointer
//
// ASSUMPTIONS: none
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
PCHAR
FwGetMnemonic
(
IN PCONFIGURATION_COMPONENT Component
)
{
PRINTDBG("FwGetMnemonic\n\r"); // DEBUG SUPPORT
return MnemonicTable[Component->Type];
}
// ----------------------------------------------------------------------------
// PROCEDURE: FwValidMnem:
//
// DESCRIPTION: This function validates the specified mnemonic.
// If the mnemonic is valid, a TURE value is returned,
// otherwise a FALSE is returned.
//
// ARGUMENTS: Str Mnemonic pointer
//
// RETURN: FALSE Mnemonic incorrect
// TRUE Mnemonic correct
//
// ASSUMPTIONS: none
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
BOOLEAN
FwValidMnem
(
IN PCHAR Str
)
{
// define local variables
CONFIGURATION_TYPE CfgType;
PRINTDBG("FwValidMnem\n\r"); // DEBUG SUPPORT
// check the mnemonic table
for ( CfgType = ArcSystem;
CfgType < MaximumType && strcmp( MnemonicTable[ CfgType ], Str );
CfgType++ );
return CfgType < MaximumType ? TRUE : FALSE;
}
// ----------------------------------------------------------------------------
// GLOBAL: I/O functions variables
// ----------------------------------------------------------------------------
PCHAR AsciiBlock; // pointer the ASCII block
ULONG AsciiBlockLength = 0; // length of the ASCII block
// ----------------------------------------------------------------------------
// PROCEDURE: FwStoreStr:
//
// DESCRIPTION: This function stores the specified string within
// the ASCII block. The NULL pointer is returned if
// there isn't space available for the string.
//
// ARGUMENTS: Str String pointer
//
// RETURN: Str String pointer
//
// ASSUMPTIONS:
//
// CALLS:
//
// GLOBALS:
//
// NOTES:
// ----------------------------------------------------------------------------
//
PCHAR
FwStoreStr
(
IN PCHAR Str
)
{
PRINTDBG("FwStoreStr\n\r"); // DEBUG SUPPORT
// if not enough space, allocate new ASCII block
if ( AsciiBlockLength < strlen( Str ) + 1 )
{
if((AsciiBlock = (PUCHAR)FwAllocatePool(ASCII_BLOCK_SIZE)) == NULL)
{
return NULL;
}
}
// store the string and update the pointers.
Str = strcpy( AsciiBlock, Str );
AsciiBlock += strlen( Str ) + 1;
AsciiBlockLength = ASCII_BLOCK_SIZE - (strlen( Str ) + 1);
// all done, return the new string pointer
return Str;
}