// ---------------------------------------------------------------------------- // 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