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

681 lines
18 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: eisafunc.c
//
// Description: Eisa code support functions.
// ----------------------------------------------------------------------------
//
#include "fwp.h"
#include "oli2msft.h"
#include "arceisa.h"
#include "inc.h"
#include "string.h"
#include "debug.h"
extern EISA_BUS_INFO EisaBusInfo[];
extern BL_FILE_TABLE BlFileTable [BL_FILE_TABLE_SIZE];
// Function prototypes.
VOID
EisaFlushCache
(
IN PVOID Address,
IN ULONG Length
);
VOID
EisaInvalidateCache
(
IN PVOID Address,
IN ULONG Length
);
ARC_STATUS
EisaDoLockedOperation
(
IN ULONG BusNumber,
IN EISA_LOCK_OPERATION Operation,
IN PVOID Semaphore,
IN SEMAPHORE_SIZE SemaphoreSize,
IN PVOID OperationArgument,
OUT PVOID OperationResult
);
ARC_STATUS
EisaCheckLockPassingParameters
(
IN ULONG BusNumber,
IN EISA_LOCK_OPERATION Operation,
IN PVOID Semaphore,
IN SEMAPHORE_SIZE SemaphoreSize,
IN PVOID OperationArgument,
OUT PVOID OperationResult
);
VOID
EisaFlushWriteBuffers
(
VOID
);
ARC_STATUS
EisaGenerateTone
(
IN ULONG Frequency,
IN ULONG Duration
);
BOOLEAN_ULONG
EisaYield
(
VOID
);
// ----------------------------------------------------------------------------
// PROCEDURE: EisaFlushCache:
//
// DESCRIPTION: This function flushes the instruction and data caches
// starting at the address specified in "Address" for
// number of bytes specified in "Length".
//
// ARGUMENTS: Address - Starting virtual address of a range of virtual
// addresses that are to be flushed from the instruction
// and data caches. If Address is 0 the entire instruction
// and data caches are flushed.
//
// Length - The length of range of virtual addresses that
// are to be flushed from the instruction and data caches.
//
// RETURN: none
//
// ASSUMPTIONS:
//
// CALLS: GetICacheSize, GetDCacheSize, FlushInvalidateDCacheIndex
//
// GLOBALS: none.
//
// NOTES:
// ----------------------------------------------------------------------------
//
// NOTE: Not used on JAZZ.
#if 0
VOID
EisaFlushCache
(
IN PVOID Address,
IN ULONG Length
)
{
ULONG CacheSize;
ULONG CacheLineSize;
if ( !Length ) // flush entire cache ?
{ // yes, get cache sizes and flush
GetDCacheSize( (ULONG)&CacheSize, (ULONG)&CacheLineSize );
FlushInvalidateDCacheIndex( (PVOID)KSEG0_BASE, CacheSize );
return; // return to caller
}
//
// User specified a specific address to flush. So take the users starting
// virtual address and size and flush data cache.
//
Address = (PVOID)((ULONG)Address & 0x1FFFFFFF | KSEG0_BASE);
FlushInvalidateDCacheIndex( Address, Length );
return; // return
}
#endif // 0
// ----------------------------------------------------------------------------
// PROCEDURE: EisaInvalidateCache:
//
// DESCRIPTION: This functions sets the invalid bit in the cache line for
// the specified range of addresses.
//
// ARGUMENTS: Address - Starting virtual address of a range of virtual
// addresses that are to be invalidated in the instruction
// and data caches. If Address is 0 the entire instruction
// and data caches are invalidated.
//
// Length - The length of range of virtual addresses that
// are to be invalidated in the instruction and data caches.
//
// RETURN: none
//
// ASSUMPTIONS: none
//
// CALLS: GetICacheSize, GetDCacheSize, InvalidateICacheIndex,
// FlushInvalidateDCacheIndex
//
// GLOBALS: none
//
// NOTES:
// ----------------------------------------------------------------------------
//
// NOTE: Not used on JAZZ.
#if 0
VOID
EisaInvalidateCache
(
IN PVOID Address,
IN ULONG Length
)
{
ULONG CacheSize;
ULONG CacheLineSize;
if ( !Length ) // invalidate entire cache ?
{ // yes, get cache sizes and invalidate
GetDCacheSize( (ULONG)&CacheSize, (ULONG)&CacheLineSize );
FlushInvalidateDCacheIndex( (PVOID)KSEG0_BASE, CacheSize );
GetICacheSize( (ULONG)&CacheSize, (ULONG)&CacheLineSize );
InvalidateICacheIndex( (PVOID)KSEG0_BASE, CacheSize );
return; // return to caller
}
//
// User specified a specific address to invalidate. So take the users
// starting virtual address and size and invalidate both instruction and
// data caches.
//
Address = (PVOID)((ULONG)Address & 0x1FFFFFFF | KSEG0_BASE);
FlushInvalidateDCacheIndex( Address, Length );
InvalidateICacheIndex( Address, Length );
return; // return to caller
}
#endif // 0
// ----------------------------------------------------------------------------
// PROCEDURE: EisaDoEISALockedOperation:
//
// DESCRIPTION: A CPU or a bus master can assert LOCK* to guarantee
// exclusive memory access during the time LOCK* is
// asserted. Assertion of LOCK* allows bit test and set
// operations (as used for semaphores) to be executed
// as a unit (atomically), with the bus lock preventing
// multiple devices from simultaneously modifying the
// semaphore bit. The MIPS family of microprocessors
// does not assert LOCK* during the execution of any
// function. As such, the system firmware provides an
// abstracted programmatic interface through which option
// module firmware (OMF) can assert and negate LOCK*.
//
// EISA option module firmware's LOCK* requests are
// performed by the EISA LOCK function. If there are
// multiple EISA buses in the system, the buses may share
// the LOCK hardware among the different EISA buses.
//
// ARGUMENTS: BusNumber The bus that contains the device that
// is sharing semaphore. This number is
// the Key of the buses' component
// structure.
//
// Opeation The type of locked operation to be
// performed.
//
// Semaphore A pointer to the varialbe in EISA or
// system memory.
//
// SemaphoreSize The size of the semaphore.
//
// OperationArgument The value to change the Semaphore to.
//
// OperationResult A pointer to a memory location that
// will receive the value of Semaphore
// before Operation.
//
// RETURN: ESUCCESS all done
// EINVAL passing parameters error
//
// ASSUMPTIONS: none
//
// CALLS: EisaCheckLockPassingParameters
//
// GLOBALS: none
//
// NOTES:
// ----------------------------------------------------------------------------
//
// NOTE: Not used on JAZZ.
#if 0
ARC_STATUS
EisaDoLockedOperation
(
IN ULONG BusNumber,
IN EISA_LOCK_OPERATION Operation,
IN PVOID Semaphore,
IN SEMAPHORE_SIZE SemaphoreSize,
IN PVOID OperationArgument,
OUT PVOID OperationResult
)
{
ARC_STATUS Status;
//
// validate the passing parameters to avoind exceptions.
//
if ( Status = EisaCheckLockPassingParameters( BusNumber, Operation,
Semaphore, SemaphoreSize, OperationArgument, OperationResult ))
{
return Status;
}
//
// assert lock on the BUS.
//
WRITE_REGISTER_UCHAR( EISA_LOCK_VIRTUAL_BASE,
READ_REGISTER_UCHAR( EISA_LOCK_VIRTUAL_BASE ) | 0x01 );
//
// Now check to see what type of operation the caller is asking us
// to perform.
//
if (Operation == Exchange)
{
//
// User wants to exchange the current semaphore value with the
// one passed. So, lets get the semaphore size and do the
// exchange.
//
switch(SemaphoreSize)
{
case ByteSemaphore:
*(PUCHAR)OperationResult = *(PUCHAR)Semaphore;
*(PUCHAR)Semaphore = *(PUCHAR)OperationArgument;
break;
case HalfWordSemaphore:
*(PUSHORT)OperationResult = *(PUSHORT)Semaphore;
*(PUSHORT)Semaphore = *(PUSHORT)OperationArgument;
break;
case WordSemaphore:
*(PULONG)OperationResult = *(PULONG)Semaphore;
*(PULONG)Semaphore = *(PULONG)OperationArgument;
break;
default:
break;
}
}
//
// The operation on the semaphore is now complete. Now we need to
// negate the LOCK* signal.
//
WRITE_REGISTER_UCHAR( EISA_LOCK_VIRTUAL_BASE,
READ_REGISTER_UCHAR( EISA_LOCK_VIRTUAL_BASE ) & 0xFE );
return ESUCCESS;
}
#endif // 0
// ----------------------------------------------------------------------------
// PROCEDURE: EisaCheckLockPassingParameters:
//
// DESCRIPTION: The functions checks the lock function passing
// parameters. This is neccessary to avoin exceptions.
//
// ARGUMENTS: BusNumber The bus that contains the device that
// is sharing semaphore. This number is
// the Key of the buses' component
// structure.
//
// Opeation The type of locked operation to be
// performed.
//
// Semaphore A pointer to the varialbe in EISA or
// system memory.
//
// SemaphoreSize The size of the semaphore.
//
// OperationArgument The value to change the Semaphore to.
//
// OperationResult A pointer to a memory location that
// will receive the value of Semaphore
// before Operation.
//
// RETURN: ESUCCESS parameters are correct.
// EINVAL at least one parameter was not correct.
//
// ASSUMPTIONS: none
//
// CALLS: EisaCheckBusNumber
//
// GLOBALS: none
//
// NOTES: none
// ----------------------------------------------------------------------------
//
// NOTE: Not used on JAZZ.
#if 0
ARC_STATUS
EisaCheckLockPassingParameters
(
IN ULONG BusNumber,
IN EISA_LOCK_OPERATION Operation,
IN PVOID Semaphore,
IN SEMAPHORE_SIZE SemaphoreSize,
IN PVOID OperationArgument,
OUT PVOID OperationResult
)
{
ARC_STATUS Status = EINVAL;
ULONG Size = 1 << SemaphoreSize; // semaphore size (# bytes)
//
// check the bus number
//
if ( EisaCheckBusNumber( BusNumber ) != ESUCCESS );
//
// check lock operation
//
else if ( Operation >= LockMaxOperation );
//
// check semaphore size
//
else if ( SemaphoreSize >= MaxSemaphore );
//
// make sure that there is physical memory at the specified locations
//
else if ( EisaCheckVirtualAddress( BusNumber, Semaphore, Size ));
else if ( EisaCheckVirtualAddress( BusNumber, OperationArgument, Size ));
else if ( EisaCheckVirtualAddress( BusNumber, OperationResult, Size ));
//
// check pointers boundaries
//
else if ( ((ULONG)Semaphore | (ULONG)OperationArgument |
(ULONG)OperationResult) & ((1 << SemaphoreSize)-1) );
//
// if we got here, the parameters are correct
//
else
{
Status = ESUCCESS;
}
return Status;
}
#endif // 0
// ----------------------------------------------------------------------------
// PROCEDURE: EisaFlushWriteBuffers:
//
// DESCRIPTION: This function flushes any external write buffers.
//
// ARGUMENTS: none.
//
// RETURN: none
//
// ASSUMPTIONS: none
//
// CALLS: FlushWriteBuffers
//
// GLOBALS: none
//
// NOTES:
// ----------------------------------------------------------------------------
//
// NOTE: Not used on JAZZ.
#if 0
VOID
EisaFlushWriteBuffers
(
VOID
)
{
FlushWriteBuffers(); // flush external write buffers.
return; // return to caller.
}
#endif // 0
// ----------------------------------------------------------------------------
// PROCEDURE: EisaGenerateTone:
//
// DESCRIPTION: This function generate tones of a specified
// frequency and duration an the system speaker.
//
// ARGUMENTS: Frequency the frequency of the tone in hertz
// Duration The duration of the tone in msec
//
// RETURN: ESUCCESS Operation completed successfully
// ENODEV System can not generate tones
//
// ASSUMPTIONS: none
//
// CALLS: none
//
// GLOBALS: none
//
// NOTES: The routine uses the timer1-counter2 and the system
// control port B of the 1st EISA bus to generate the
// specified tone.
// ----------------------------------------------------------------------------
//
ARC_STATUS
EisaGenerateTone
(
IN ULONG Frequency,
IN ULONG Duration
)
{
//
// define local variables
//
PUCHAR EisaIoStart, Ctrl, Data, Port61; // general I/O address
//
// exit if duration is null
//
if ( !Duration )
{
return ESUCCESS;
}
//
// initialize local variables
//
EisaIoStart = EisaBusInfo[ 0 ].IoBusInfo->VirAddr;
Ctrl = EisaIoStart + EISA_TIMER1_CTRL;
Data = EisaIoStart + EISA_TIMER1_COUNTER2;
Port61 = EisaIoStart + EISA_SYS_CTRL_PORTB;
//
// make sure that the speaker is disabled
//
EisaOutUchar( Port61, ( EisaInUchar( Port61 ) &
~( EISA_SPEAKER_GATE | EISA_SPEAKER_TIMER )) & 0x0F );
//
// if frequency value is valid, program timer1-counter2 and enable speaker
//
if (Frequency>=EISA_SPEAKER_MIN_FREQ && Frequency<=EISA_SPEAKER_MAX_FREQ)
{
//
// initialize timer1 counter2 in 16-bit , mode 3
//
// NOTE: CriticalSection not supported in JAZZ.
// EisaBeginCriticalSection();
EisaOutUchar( Ctrl, 0xB6 );
EisaOutUchar( Data, (UCHAR)(EISA_SPEAKER_CLOCK/Frequency));
EisaOutUchar( Data, (UCHAR)(EISA_SPEAKER_CLOCK/Frequency >> 8));
// NOTE: CriticalSection not supported in JAZZ.
// EisaEndCriticalSection();
//
// enable speaker gate and speaker output
//
EisaOutUchar( Port61, ( EisaInUchar( Port61 ) |
EISA_SPEAKER_GATE | EISA_SPEAKER_TIMER ) & 0x0F );
}
//
// ... wait
//
while ( Duration-- )
{
ArcEisaStallProcessor( 1000 ); // 1 msec
}
//
// disable speaker before returning
//
EisaOutUchar( Port61, ( EisaInUchar( Port61 ) &
~( EISA_SPEAKER_GATE | EISA_SPEAKER_TIMER )) & 0x0F );
//
// all done
//
return ESUCCESS;
}
// ----------------------------------------------------------------------------
// PROCEDURE: EisaYield:
//
// DESCRIPTION: System utilities and option module firmware
// must surrender the processor so that the system
// module firmware can check for pending input.
// To surrender the prcessor, call this function.
//
// ARGUMENTS: none
//
// RETURN: TRUE Indicates that the BREAK key was
// pressed. Yield continues to return
// TREUE until the BREAK key is read
// from the console input device.
// FALSE Inidicates that the BREAK key has
// not been pressed.
// ASSUMPTIONS: none
//
// CALLS: none
//
// GLOBALS: none
//
// NOTES: none
// ----------------------------------------------------------------------------
//
// NOTE: Not used on JAZZ.
#if 0
BOOLEAN_ULONG
EisaYield
(
VOID
)
{
//
// call all device strategy routines with FC_POLL command
//
EisaOmfPoll();
//
// read any char available from the console in into the console in buffer
//
if ( !BlFileTable[ 0 ].Flags.Open )
{
//
// the console in device is not available, return no Ctrl-C.
//
return FALSE;
}
//
// read any available data from the console in device
//
ConsoleInFill();
//
// and scan buffer checking contrl-C
//
return ConsoleInCtrlC();
}
#endif // 0