Пример #1
0
VOID
XenGfxChangeXgfxMode(PXENGFX_DEVICE_EXTENSION pXenGfxExtension, BOOLEAN Enable)
{
    ULONG ControlReg;

    if ((Enable)&&(!pXenGfxExtension->XgfxMode)) {
        ControlReg = READ_REGISTER_ULONG((PULONG)(pXenGfxExtension->pGlobalRegs + XGFX_CONTROL));

        // Enable XGFX hires mode and endable interrupts.
        ControlReg |= XGFX_CONTROL_INT_EN|XGFX_CONTROL_HIRES_EN;

        WRITE_REGISTER_ULONG((PULONG)(pXenGfxExtension->pGlobalRegs + XGFX_CONTROL), ControlReg);

        pXenGfxExtension->XgfxMode = TRUE;
    }
    else if ((!Enable)&&(pXenGfxExtension->XgfxMode)) {
        ControlReg = READ_REGISTER_ULONG((PULONG)(pXenGfxExtension->pGlobalRegs + XGFX_CONTROL));

        // Disable XGFX mode
        ControlReg &= ~(XGFX_CONTROL_INT_EN|XGFX_CONTROL_HIRES_EN);

        WRITE_REGISTER_ULONG((PULONG)(pXenGfxExtension->pGlobalRegs + XGFX_CONTROL), ControlReg);

        pXenGfxExtension->XgfxMode = FALSE;
    }
}
Пример #2
0
USHORT	CHalWaveDevice::TransferAudio( PVOID pvLeft, PVOID pvRight, ULONG ulSamplesToTransfer, LONG lPCIndex )
// ASIO Version, Sample Format will always be 32-bit Stereo
/////////////////////////////////////////////////////////////////////////////
{
	PULONG	pHWBuffer = (PULONG)m_pAudioBuffer;
	LONG	lLSample = 0, lRSample = 0;
	
	// are we overriding the PCIndex
	if( lPCIndex != -1 )
		m_lPCIndex = lPCIndex;

	m_ulBytesTransferred += (ulSamplesToTransfer * sizeof( DWORD ) * 2);
	m_ulSamplesTransferred += ulSamplesToTransfer;
	
	if( m_bIsRecord )
	{
		register PLONG	pLDst = (PLONG)pvLeft;
		register PLONG	pRDst = (PLONG)pvRight;

		//DC('r');	DX16( (USHORT)ulSamplesToTransfer, COLOR_NORMAL );	DC(' ');
		
		while( ulSamplesToTransfer-- )
		{
			lLSample = READ_REGISTER_ULONG( &pHWBuffer[ m_lPCIndex++ ] );
			lRSample = READ_REGISTER_ULONG( &pHWBuffer[ m_lPCIndex++ ] );
			if( m_lPCIndex >= WAVE_CIRCULAR_BUFFER_SIZE )
				m_lPCIndex = 0;
			if( pLDst )	*pLDst++ = lLSample;
			if( pRDst )	*pRDst++ = lRSample;
		} // while
	}
	else
	{
		register PLONG	pLSrc = (PLONG)pvLeft;
		register PLONG	pRSrc = (PLONG)pvRight;

		//DC('p');	DX16( (USHORT)ulSamplesToTransfer, COLOR_NORMAL );	DC(' ');
		
		while( ulSamplesToTransfer-- )
		{
			if( pLSrc )	lLSample = *pLSrc++;
			if( pRSrc )	lRSample = *pRSrc++;
			WRITE_REGISTER_ULONG( &pHWBuffer[ m_lPCIndex++ ], lLSample );	// Left Channel
			WRITE_REGISTER_ULONG( &pHWBuffer[ m_lPCIndex++ ], lRSample );	// Right Channel
			if( m_lPCIndex >= WAVE_CIRCULAR_BUFFER_SIZE )
				m_lPCIndex = 0;
		} // while
	}

	if( m_lPCIndex >= WAVE_CIRCULAR_BUFFER_SIZE )
		m_lPCIndex -= WAVE_CIRCULAR_BUFFER_SIZE;

	// Write the PCIndex to the hardware
	//DC('{'); DX16( (USHORT)m_lPCIndex, COLOR_BOLD ); DC('}');
	m_RegStreamControl.Write( (REG_STREAMCTL_XFERDONE | m_lPCIndex), (REG_STREAMCTL_XFERDONE | REG_STREAMCTL_PCPTR_MASK) );
	//DPF(("h%ld p%ld ", m_RegStreamStatus.Read() & REG_STREAMSTAT_L2PTR_MASK, m_lPCIndex ));

	return( HSTATUS_OK );
}
Пример #3
0
BOOLEAN
NTAPI
LlbHwUartTxReady(VOID)
{
    /* TX output buffer is ready? */
    return ((READ_REGISTER_ULONG(UART_PL01x_FR) & UART_PL01x_FR_TXFF) == 0);
}
Пример #4
0
ULONG
ScsiPortReadRegisterUlong(
    IN PULONG Register
)

/*++

Routine Description:

    Read from the specified register address.

Arguments:

    Register - Supplies a pointer to the register address.

Return Value:

    Returns the value read from the specified register address.

--*/

{

    return(READ_REGISTER_ULONG(Register));

}
Пример #5
0
ULONG
NTAPI
ScsiPortReadRegisterUlong(
    IN PULONG Register)
{
    return READ_REGISTER_ULONG(Register);
}
Пример #6
0
ULONG
NTAPI
VideoPortReadRegisterUlong(
    PULONG Register)
{
    return READ_REGISTER_ULONG(Register);
}
Пример #7
0
UINT32 io_read(struct fscc_card *card, unsigned bar, PULONG Address)
{
    if (card->bar[bar].memory_mapped)
        return READ_REGISTER_ULONG(Address);
    else
        return READ_PORT_ULONG(Address);
}
Пример #8
0
HRESULT __SORA_HW_STATUS_FENCE_UNSAFE(__PSORA_REGISTERS pRegFile)
{
    HRESULT hRes = S_OK;
    __REG32_HWSTATUS    HWStatus;
    int timeout;    
    for (timeout = 1024; timeout > 0; timeout--) 
    {
        HWStatus.Value = READ_REGISTER_ULONG(
        (PULONG)(&(pRegFile->HWStatus)));

        if (HWStatus.Value != 0x03)
        {
            DbgPrint("[Error] HW not ready, value=%08x\n", HWStatus.Value);
            hRes = E_HW_DDR2_INIT_FAIL;
        }
        else
        {
            DbgPrint("HW ready, value=%08x\n", HWStatus.Value);
            hRes = S_OK; 
            break;
        }
        
    }
    return hRes;
}
Пример #9
0
VOID __SORA_HW_READ_RADIO_ID(OUT PSORA_RADIO pRadio)
{
    KIRQL OldIrql;
    KeAcquireSpinLock(&pRadio->__HWOpLock, &OldIrql);
    pRadio->RadioID = 
        READ_REGISTER_ULONG((PULONG)&pRadio->__ctrl_reg.pRadioRegs->RadioID);   
    KeReleaseSpinLock(&pRadio->__HWOpLock, OldIrql);
}
Пример #10
0
ULONG	CHalRegister::Read()
/////////////////////////////////////////////////////////////////////////////
{
	if( m_ulType != REG_WRITEONLY )
		m_ulValue = READ_REGISTER_ULONG( m_pAddress );
	
	return( m_ulValue );
}
Пример #11
0
void __SoraHwPrintDbgRegsUnsafe(PTRANSFER_OBJ pTransferObj)
{
    PUCHAR Regs = (PUCHAR)pTransferObj->SoraSysReg;
    ULONG Offset;

    for (Offset = 0x80; Offset  < 0xFF; Offset += 4)
    {
        ULONG value;
        value = READ_REGISTER_ULONG((PULONG)(Regs + Offset));
        DbgPrint("[Error] %02x: %08x\n", Offset, value);
    }
    for (Offset = 0xF00; Offset < 0xF28; Offset += 4)
    {
        ULONG value;
        value = READ_REGISTER_ULONG((PULONG)(Regs + Offset));
        DbgPrint("[Error] %02x: %08x\n", Offset, value);
    }
}
Пример #12
0
ULONG
HWREG<ULONG>::Read(
    VOID
    )
{
    volatile ULONG *addr = &m_Value;
    ULONG v = READ_REGISTER_ULONG((PULONG)addr);
    return v;
}
Пример #13
0
HRESULT 
__SORA_HW_TX_TRANSFER_UNSAFE(
    IN HANDLE TransferObj,
    IN PTX_DESC    pTxDesc)
#endif
{
    PTRANSFER_OBJ pTransferObj = (PTRANSFER_OBJ)TransferObj;
	
    HRESULT hr = S_OK;
    __REG32_TRANS_CTRL TransCtrl;
    __PSORA_RADIO_REGS pRegs = pTransferObj->TransferReg;

#ifdef DEBUG_CHECKSUM	
	ULONG TransferErrorCount;
	TransferErrorCount = READ_REGISTER_ULONG((PULONG)&((pRegs->TransferErrorCount)));
#endif

#ifdef DEBUG_CHECKSUM	
    __SoraHwTransferUnsafeNoWait(pTransferObj, pTxDesc, Checksum);
#else
	__SoraHwTransferUnsafeNoWait(pTransferObj, pTxDesc);
#endif

    hr = __SoraHwWaitTransferDone(pTxDesc);

    TransCtrl.Value = 0;
    WRITE_REGISTER_ULONG((PULONG)&pRegs->TransferControl, TransCtrl.Value); //clear init bit

#ifdef DEBUG_CHECKSUM
	if (SUCCEEDED(hr)) {
		if (TransferErrorCount != READ_REGISTER_ULONG((PULONG)&((pRegs->TransferErrorCount))))
			hr = E_TX_TRANSFER_CHECKSUM_FAIL;
	}
	else
        __SoraHwPrintDbgRegsUnsafe(pTransferObj);
#else
	if (FAILED(hr))
		__SoraHwPrintDbgRegsUnsafe(pTransferObj);
#endif

    return hr;
    
}
Пример #14
0
void __SoraHwPrintRadioRegsUnsafe(PSORA_RADIO pRadio)
{
    PUCHAR Regs = (PUCHAR)pRadio->__ctrl_reg.pRadioRegs;
    ULONG Offset;
    for (Offset = 0x00; Offset  < 0x20; Offset += 4)
    {
        ULONG value;
        value = READ_REGISTER_ULONG((PULONG)(Regs + Offset));
        DbgPrint("[Error] %02x: %08x\n", Offset, value);
    }

    for (Offset = 0x70; Offset  < 0x100; Offset += 4)
    {
        ULONG value;
        value = READ_REGISTER_ULONG((PULONG)(Regs + Offset));
        DbgPrint("[Error] %02x: %08x\n", Offset, value);
    }
    
}
Пример #15
0
VOID
PLxHardwareReset(
    IN PDEVICE_EXTENSION DevExt
    )
/*++
Routine Description:

    Called by D0Exit when the device is being disabled or when the system is shutdown to
    put the device in a known initial state.

Arguments:

    DevExt     Pointer to Device Extension

Return Value:

--*/
{
    LARGE_INTEGER delay;

    union {
        EEPROM_CSR  bits;
        ULONG       ulong;
    } eeCSR;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "--> PLxIssueFullReset");

    //
    // Drive the 9656 into soft reset.
    //
    eeCSR.ulong =
        READ_REGISTER_ULONG( (PULONG) &DevExt->Regs->EEPROM_Ctrl_Stat );

    eeCSR.bits.SoftwareReset = TRUE;

    WRITE_REGISTER_ULONG( (PULONG) &DevExt->Regs->EEPROM_Ctrl_Stat,
                          eeCSR.ulong );

    //
    // Wait 100 msec.
    //
    delay.QuadPart =  WDF_REL_TIMEOUT_IN_MS(100);

    KeDelayExecutionThread( KernelMode, TRUE, &delay );

    //
    // Finally pull the 9656 out of reset.
    //
    eeCSR.bits.SoftwareReset = FALSE;

    WRITE_REGISTER_ULONG( (PULONG) &DevExt->Regs->EEPROM_Ctrl_Stat,
                          eeCSR.ulong );

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_PNP, "<-- PLxIssueFullReset");
}
Пример #16
0
HRESULT
SORAAPI
_CheckTXError(
	PSORA_RADIO pRadio,
	s_uint16 Checksum) {

	extern HRESULT _SoraRadioReadRFReg(PSORA_RADIO pRadio, s_uint32 addr, OUT s_uint32 *pValue);
	s_uint32 addr_23_CountChecksum;
	s_uint32 addr_21_CountChecksum;
	HRESULT hr;
	hr = E_TX_TRANSFER_CHECKSUM_FAIL;

	DbgPrint("TX Checksum: [0x%x], TX Count: [%d](16-bits)\n",  
		get_checksum(READ_REGISTER_ULONG((PULONG)&((pRadio->__ctrl_reg.pRadioRegs->TXCountChecksum)))),
		get_count(READ_REGISTER_ULONG((PULONG)&((pRadio->__ctrl_reg.pRadioRegs->TXCountChecksum)))));

	if (SUCCEEDED(_SoraRadioReadRFReg(pRadio,
		0x0023,
		&addr_23_CountChecksum))) {
		DbgPrint("addr 23 Checksum: [0x%x], addr 23 Count: [%d](16-bits)\n", 
			get_checksum(addr_23_CountChecksum), 
			get_count(addr_23_CountChecksum));
		if (get_checksum(addr_23_CountChecksum) != Checksum)
			hr = E_TX_TRANSFER_ADDR23_CHECKSUM_FAIL;
	}
	else
		DbgPrint("Failed to get addr 23 CountChecksum\n");

	if (SUCCEEDED(_SoraRadioReadRFReg(pRadio,
		0x0021,
		&addr_21_CountChecksum))) {
		DbgPrint("addr 21 Checksum: [0x%x], addr 21 Count: [%d](16-bits)\n", 
			get_checksum(addr_21_CountChecksum), 
			get_count(addr_21_CountChecksum));
		if (get_checksum(addr_21_CountChecksum) != Checksum)
			hr = E_TX_TRANSFER_ADDR21_CHECKSUM_FAIL;
	}
	else
		DbgPrint("Failed to get addr 21 CountChecksum\n");
	
	return hr;
}
Пример #17
0
HRESULT __SoraHwTxUnsafe(
    PSORA_RADIO pRadio, 
    PTX_DESC    pTxDesc)
#endif
{
    
    HRESULT    hr = S_OK;
    __REG32_TX_CTRL TXControl;
	__PSORA_RADIO_REGS pRegs = pRadio->__ctrl_reg.pRadioRegs;

#ifdef DEBUG_CHECKSUM
	ULONG TXErrorCount;
	TXErrorCount = READ_REGISTER_ULONG((PULONG)&pRegs->TXErrorCount);
#endif

#ifdef DEBUG_CHECKSUM
    __SoraHwTxUnsafeNoWait(pRadio, pTxDesc, Checksum);
#else
	__SoraHwTxUnsafeNoWait(pRadio, pTxDesc);
#endif
    
    hr = __SoraHwWaitTxDone(pRadio);

    TXControl.Value = 0;
    TXControl.Bits.TXInit   = 0;
    WRITE_REGISTER_ULONG(
        (PULONG)&pRadio->__ctrl_reg.pRadioRegs->TXControl,
        TXControl.Value);

#ifdef DEBUG_CHECKSUM
	if (SUCCEEDED(hr))
		if (TXErrorCount != READ_REGISTER_ULONG((PULONG)&pRegs->TXErrorCount))
			hr = _CheckTXError(pRadio, pTxDesc->Checksum);
#endif
	
    return hr;
}
Пример #18
0
VOID
NTAPI
KdPortPutByteEx(IN PCPPORT PortInformation,
                IN UCHAR ByteToSend)
{
    //
    // Wait for ready
    //
    while ((READ_REGISTER_ULONG((PULONG)UART_PL01x_FR) & UART_PL01x_FR_TXFF) != 0);

    //
    // Send the character
    //
    WRITE_REGISTER_ULONG((PULONG)UART_PL01x_DR, ByteToSend);
}
Пример #19
0
/*
 * @implemented
 */
BOOLEAN
NTAPI
HalQueryRealTimeClock(IN PTIME_FIELDS Time)
{
    LARGE_INTEGER LargeTime;
    ULONG Seconds;
    
    /* Query the RTC value */
    Seconds = READ_REGISTER_ULONG(RTC_DATA);
    
    /* Convert to time */
    RtlSecondsSince1970ToTime(Seconds, &LargeTime);
    
    /* Convert to time-fields */
    RtlTimeToTimeFields(&LargeTime, Time);
    return TRUE;
}
Пример #20
0
/*
 * get data processed by the module ,and clear the interrupt register
 */
static int aes_get_data(unsigned char * cipher_out_tmp, unsigned char * feedback_ivin_tmp)
{
	unsigned int * cipher_out  = (unsigned int *) cipher_out_tmp;
	unsigned int * feedback_ivin = (unsigned int*) feedback_ivin_tmp;

	if(NULL == cipher_out)
	{
		printf("the outtrans pointer is null !\n\n");
		return -1;
	}    

	if(-1== ioctl(fd_dev, SLAVE_GET_DATA, 0))
	{
		printf("in slave mod ,the signal for getting data does not come!\n");
		return -1;
	}

    	//deal with the cipher_out. 
       READ_REGISTER_ULONG(CIPHER_DOUT1_OFFSET, *cipher_out++);    
    
       READ_REGISTER_ULONG(CIPHER_DOUT2_OFFSET, *cipher_out++);
       
       READ_REGISTER_ULONG(CIPHER_DOUT3_OFFSET, *cipher_out++);
 
       READ_REGISTER_ULONG(CIPHER_DOUT4_OFFSET, *cipher_out);
	if( ((ctrl_word & AES_MODE_MASK) == CBC_MODE) || ((ctrl_word & AES_MODE_MASK) == CFB_MODE)
					|| ((ctrl_word & AES_MODE_MASK) == OFB_MODE))
	{
		READ_REGISTER_ULONG(CIPHER_IVOUT1_OFFSET, *feedback_ivin++);
		READ_REGISTER_ULONG(CIPHER_IVOUT2_OFFSET, *feedback_ivin++);
		READ_REGISTER_ULONG(CIPHER_IVOUT3_OFFSET, *feedback_ivin++);
		READ_REGISTER_ULONG(CIPHER_IVOUT4_OFFSET, *feedback_ivin);
	}

	#ifdef _REVERSE_BYTE_SEQ_
		reverse_16char(cipher_out_tmp);
		if ( feedback_ivin_tmp != NULL )	//ctr mode 
			 reverse_16char(feedback_ivin_tmp);
	#endif

	return 0;
}
Пример #21
0
/*
 * @implemented
 */
VOID
NTAPI
KeStallExecutionProcessor(IN ULONG Microseconds)
{
    SP804_CONTROL_REGISTER ControlRegister;
    
    /* Enable the timer */
    WRITE_REGISTER_ULONG(TIMER1_LOAD, Microseconds);
    
    /* Configure the timer */
    ControlRegister.AsUlong = 0;
    ControlRegister.OneShot = TRUE;
    ControlRegister.Wide = TRUE;
    ControlRegister.Periodic = TRUE;
    ControlRegister.Enabled = TRUE;
    WRITE_REGISTER_ULONG(TIMER1_CONTROL, ControlRegister.AsUlong);
    
    /* Now we will loop until the timer reached 0 */
    while (READ_REGISTER_ULONG(TIMER1_VALUE));
}
Пример #22
0
//
// Spinlock to wait for Tx finish
//
HRESULT 
__SoraHwWaitTxDone(PSORA_RADIO pRadio)
{
    HRESULT    hr = S_OK;
    __REG32_TX_CTRL TXControl;
    int TimeOut = 1000000;
    do
    {
        TimeOut--;
        if (TimeOut < 1)
        {
            hr = E_TX_TIMEOUT;
            break;
        }
        _mm_pause();
        
        TXControl.Value = 
            READ_REGISTER_ULONG((PULONG)&((pRadio->__ctrl_reg.pRadioRegs->TXControl)));
    } while (!TXControl.Bits.TXDone); // wait finish or timeout
    return hr;
}
Пример #23
0
NTSTATUS
PLxEvtInterruptDisable(
    IN WDFINTERRUPT Interrupt,
    IN WDFDEVICE    Device
    )
/*++

Routine Description:

    Called by the framework at DIRQL before Deregistering the ISR with the kernel
    by calling IoDisconnectInterrupt.

Return Value:

    NTSTATUS
--*/
{
    PDEVICE_EXTENSION  devExt;

    union {
        INT_CSR   bits;
        ULONG     ulong;
    } intCSR;

    TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INTERRUPT,
                "PLxEvtInterruptDisable: Interrupt 0x%p, Device 0x%p\n",
                Interrupt, Device);

    devExt  = PLxGetDeviceContext(WdfInterruptGetDevice(Interrupt));

    intCSR.ulong = READ_REGISTER_ULONG( (PULONG) &devExt->Regs->Int_Csr );

    intCSR.bits.PciIntEnable = FALSE;

    WRITE_REGISTER_ULONG( (PULONG) &devExt->Regs->Int_Csr,
                          intCSR.ulong );

    return STATUS_SUCCESS;
}
Пример #24
0
void SORA_HW_READ_RADIO_POWER_STATUS(OUT PSORA_RADIO pRadio)
{
    ULONG    oldFlag = pRadio->__status.__Flags;
    __REG32_RADIO_STATUS RadioStatus;
    KIRQL OldIrql;

    KeAcquireSpinLock(&pRadio->__HWOpLock, &OldIrql);
    RadioStatus.Value = 
        READ_REGISTER_ULONG((PULONG)&pRadio->__ctrl_reg.pRadioRegs->RadioStatus);
    KeReleaseSpinLock(&pRadio->__HWOpLock, OldIrql);

    if ((oldFlag & __RADIO_STATUS_ALIVE) != RadioStatus.Bits.RadioAlive) //Alive status change
    {
        KeSetEvent(&pRadio->PnPEvent, 1, FALSE);
        if (RadioStatus.Bits.RadioAlive)
        {
            __SetRadioAlive(pRadio);
        }
        else
        {
            __SetRadioDead(pRadio);
        }   
    }
}
Пример #25
0
BOOLEAN
PLxEvtInterruptIsr(
    IN WDFINTERRUPT Interrupt,
    IN ULONG        MessageID
    )
/*++
Routine Description:

    Interrupt handler for this driver. Called at DIRQL level when the
    device or another device sharing the same interrupt line asserts
    the interrupt. The driver first checks the device to make sure whether
    this interrupt is generated by its device and if so clear the interrupt
    register to disable further generation of interrupts and queue a
    DPC to do other I/O work related to interrupt - such as reading
    the device memory, starting a DMA transaction, coping it to
    the request buffer and completing the request, etc.

Arguments:

    Interupt   - Handle to WDFINTERRUPT Object for this device.
    MessageID  - MSI message ID (always 0 in this configuration)

Return Value:

     TRUE   --  This device generated the interrupt.
     FALSE  --  This device did not generated this interrupt.

--*/
{
    PDEVICE_EXTENSION   devExt;
    BOOLEAN             isRecognized = FALSE;

    union {
        INT_CSR bits;
        ULONG   ulong;
    } intCsr;

    UNREFERENCED_PARAMETER(MessageID);

    //TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INTERRUPT,
    //            "--> PLxInterruptHandler");

    devExt  = PLxGetDeviceContext(WdfInterruptGetDevice(Interrupt));

    //
    // Read the Interrupt CSR register (INTCSR)
    //
    intCsr.ulong = READ_REGISTER_ULONG( (PULONG) &devExt->Regs->Int_Csr );

    //
    // Is DMA channel 0 (Write-side) Active?
    //
    if (intCsr.bits.DmaChan0IntActive) {

        TraceEvents(TRACE_LEVEL_INFORMATION,  DBG_INTERRUPT,
                    " Interrupt for DMA Channel 0 (write)");

        devExt->IntCsr.bits.DmaChan0IntActive = TRUE;

        //
        // Clear this interrupt.
        //
        devExt->Dma0Csr.uchar =
            READ_REGISTER_UCHAR( (PUCHAR) &devExt->Regs->Dma0_Csr );

        devExt->Dma0Csr.bits.Clear = TRUE;

        WRITE_REGISTER_UCHAR( (PUCHAR) &devExt->Regs->Dma0_Csr,
                              devExt->Dma0Csr.uchar );

        isRecognized = TRUE;
    }

    //
    // Is DMA channel 1 (Read-side) Active?
    //
    if (intCsr.bits.DmaChan1IntActive) {

        TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INTERRUPT,
                    " Interrupt for DMA Channel 1 (read)");

        devExt->IntCsr.bits.DmaChan1IntActive = TRUE;

        //
        // Clear this interrupt.
        //
        devExt->Dma1Csr.uchar =
            READ_REGISTER_UCHAR( (PUCHAR) &devExt->Regs->Dma1_Csr );

        devExt->Dma1Csr.bits.Clear = TRUE;

        WRITE_REGISTER_UCHAR( (PUCHAR) &devExt->Regs->Dma1_Csr,
                              devExt->Dma1Csr.uchar );

        isRecognized = TRUE;
    }

    if ((isRecognized) &&
        ((devExt->Dma0Csr.bits.Done) ||
         (devExt->Dma1Csr.bits.Done))) {
        //
        // A read or a write or both is done. Queue a DPC.
        //
        WdfInterruptQueueDpcForIsr( devExt->Interrupt );
    }

    //TraceEvents(TRACE_LEVEL_INFORMATION, DBG_INTERRUPT,
    //            "<-- PLxInterruptHandler");

    return isRecognized;
}
Пример #26
0
VOID
HalReturnToFirmware(
    IN FIRMWARE_REENTRY Routine
    )

/*++

Routine Description:

    This function returns control to the specified firmware routine.
    In most cases it generates a soft reset by asserting the reset line
    through the keyboard controller (STRIKER and DUO). However, for
    FALCON we will use the Port92 register in the 82374 to generate
    a software reset (restart) through the ALT_RESET signal.

    Arguments:

	Routine - Supplies a value indicating which firmware routine to invoke.

Return Value:

    Does not return.

--*/

{

    KIRQL OldIrql;


    //
    // Mask interrupts
    //

    KeRaiseIrql(HIGH_LEVEL, &OldIrql);

    //
    // Do the right thing!
    //

    switch (Routine) {

	    case HalHaltRoutine:

		//
		// Hang looping.
		//	

		for (;;) {
		}

	     case HalPowerDownRoutine:

		 //
		 // Power down the system
		 //

		 {
		     ULONG EPCValue;
		     ULONG EPC = (ULONG)HalpEisaControlBase + EXTERNAL_PMP_CONTROL_OFFSET;

		     EPCValue = READ_REGISTER_ULONG( EPC );
                     EPCValue &= ~EPC_POWER;
		     WRITE_REGISTER_ULONG( EPC, EPCValue );
		     EPCValue |= EPC_POWER;
		     WRITE_REGISTER_ULONG( EPC, EPCValue );
		 }

	    case HalRestartRoutine:
	    case HalRebootRoutine:
	    case HalInteractiveModeRoutine:

		//
		// Reset ISA Display Adapter to 80x25 color text mode.
		//

		HalpResetX86DisplayAdapter();

		//
		// Enable Port92 register in 82374
		//	

		WRITE_REGISTER_UCHAR( &((PEISA_CONTROL)HalpEisaControlBase)->Reserved1[0], 0x4F);
		WRITE_REGISTER_UCHAR( &((PEISA_CONTROL)HalpEisaControlBase)->Reserved1[1], 0x7F);

		//
		// Generate soft reset through ALT_RESET signal from 82374
		//

		WRITE_REGISTER_UCHAR( &((PEISA_CONTROL)HalpEisaControlBase)->Reserved2[2], 0);
		WRITE_REGISTER_UCHAR( &((PEISA_CONTROL)HalpEisaControlBase)->Reserved2[2], 0x01);

		//
		// Hang
		//

		for (;;) {
		}

	    default:
	        KdPrint(("HalReturnToFirmware invalid argument\n"));
	        KeLowerIrql(OldIrql);
	        DbgBreakPoint();

    }

}
Пример #27
0
ULONG
HalpEccError(
    IN ULONG EifrRegister
    )

/*++

Routine Description:

    This routine check ecc error and error log put in NVRAM.

Arguments:

    EifrRegister - EIFR register value in IOB.

Return Value:

    return value is the following error occured.
      1: ecc 1bit error.
      2: ecc 2bit error.
      0: other error.

--*/

{
    ULONG returnValue;
    ULONG sicSet;
    ULONG sicOffset;
    USHORT infoOffset;
    USHORT writeOffset;
    ULONG eif0Buffer;
    ULONG sts2Buffer;
    ULONG sdlmBuffer;
    ULONG buffer; // S001
    ULONG i;	    // S002
    ULONG errAddr;  // S002
    UCHAR dataBuf[36];
    UCHAR infoBuf[24];
    UCHAR tempBuf[24];

    HalpECC1bitScfrBuffer = READ_REGISTER_ULONG( &( IOB_CONTROL )->SCFR.Long );
    IOB_DUMMY_READ;

    //
    // check interrupt from where.
    //

    if ( ((PEIFR_REGISTER)&EifrRegister)->SIC1ERR == 1){
        sicSet = 1;
        eif0Buffer = READ_REGISTER_ULONG(
		 &( SIC_ERR_CONTROL_OR( SIC_NO2_OFFSET ) )->EIF0.Long );
	SIC_DUMMY_READ;
	if(eif0Buffer & 0x000000c0){
	    sicOffset = SIC_NO2_OFFSET;
        } else {
	    sicOffset = SIC_NO3_OFFSET;
        }
    }else{
        sicSet = 0;
        eif0Buffer = READ_REGISTER_ULONG(
		 &( SIC_ERR_CONTROL_OR( SIC_NO0_OFFSET ) )->EIF0.Long );
	SIC_DUMMY_READ;
	if(eif0Buffer & 0x000000c0){
	    sicOffset = SIC_NO0_OFFSET;
        } else {
	    sicOffset = SIC_NO1_OFFSET;
        }
    }

    //
    // read diagnosis registers.
    //

    eif0Buffer = READ_REGISTER_ULONG(
		    &( SIC_ERR_CONTROL_OR( sicOffset ) )->EIF0.Long );
    SIC_DUMMY_READ;
    sts2Buffer = READ_REGISTER_ULONG(
		    &( SIC_ERR_CONTROL_OR( sicOffset ) )->STS2.Long );
    SIC_DUMMY_READ;
    sdlmBuffer = READ_REGISTER_ULONG(
		    &( SIC_DATA_CONTROL_OR( sicOffset ) )->SDLM.Long );
    SIC_DUMMY_READ;

    //
    // Check ECC 1bit or 2bit err
    //

    if( (eif0Buffer & 0x08000000) &&
       ((eif0Buffer & 0xf0000000) == 0) &&
       ((EifrRegister & 0xf3600000) == 0) ){
	returnValue= SIC_ECC_1BIT_ERROR;
        infoOffset=ECC_1BIT_ERROR_LOG_INFO_OFFSET;
    } else if (eif0Buffer & 0x00000040){
	returnValue= SIC_ECC_2BIT_ERROR;
        infoOffset=ECC_2BIT_ERROR_LOG_INFO_OFFSET;
    } else {
	return(SIC_OTHER_ERROR);
    }

    HalNvramRead( NVRAM_STATE_FLG_OFFSET, 1, dataBuf );
    HalNvramRead( NVRAM_MAGIC_NO_OFFSET, 4, tempBuf );

    // S002 vvv
    switch(returnValue) {

    case SIC_ECC_2BIT_ERROR:
	if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){

	    HalNvramRead( (ULONG)infoOffset, 20, infoBuf);

	    ((pECC2_ERR_REC)dataBuf)->record_flag = ECC_LOG_VALID_FLG;

	    GET_PADDR( (((pECC2_ERR_REC)dataBuf)->err_address), sts2Buffer, sicSet);

	    GET_TIME(tempBuf);
	    RtlMoveMemory( (PVOID)( ((pECC2_ERR_REC)dataBuf)->when_happened ),
			  (PVOID)tempBuf,
			  TIME_STAMP_SIZE
			  );

	    ((pECC2_ERR_REC)dataBuf)->syndrome = sdlmBuffer;

	    ((pECC2_ERR_REC)dataBuf)->specified_group =
	        (UCHAR)( ((PSTS2_REGISTER)&sts2Buffer)->ARE + sicSet * 4);

	    ((pECC2_ERR_REC)dataBuf)->specified_simm =
	        (UCHAR)( ((PSTS2_REGISTER)&sts2Buffer)->SIMN );

	    writeOffset = ((pECC2_ERR_AREA_INFO)infoBuf)->offset_latest
		         +((pECC2_ERR_AREA_INFO)infoBuf)->size_rec;

	    if( writeOffset >= ((pECC2_ERR_AREA_INFO)infoBuf)->offset_2biterr
	                      +((pECC2_ERR_AREA_INFO)infoBuf)->size_rec
	                      *((pECC2_ERR_AREA_INFO)infoBuf)->num_rec ) {
		writeOffset = ((pECC2_ERR_AREA_INFO)infoBuf)->offset_2biterr;
	    }

	    HalNvramWrite( (ULONG)writeOffset,
			  sizeof(ECC2_ERR_REC),
			  (PVOID)dataBuf);

	    HalNvramWrite( ECC_2BIT_ERROR_LOG_INFO_LATEST_OFFSET,
			   sizeof(USHORT),
			   (PVOID)&writeOffset);
	}
	break;


    case SIC_ECC_1BIT_ERROR:

	if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){

	    HalNvramRead( (ULONG)infoOffset, 20, infoBuf);

	    //
	    // Disable and clear ECC 1bit error.
	    //

	    DONT_NOTIFY_ECC1BIT(HalpECC1bitScfrBuffer); // S003

	    if(sicSet == 0){
		WRITE_REGISTER_ULONG( SDCR_SET0_ADDR, 0x0 );
	    } else {
		WRITE_REGISTER_ULONG( SDCR_SET1_ADDR, 0x0 );
	    }

	    do {
		buffer = READ_REGISTER_ULONG(
			     &( SIC_ERR_CONTROL_OR( sicOffset ) )->EIF0.Long );
		SIC_DUMMY_READ;
	    } while ( (buffer & 0x08000000) != 0 );

	    WRITE_REGISTER_ULONG( &( IOB_CONTROL )->EIFR.Long,
				 EifrRegister & 0x0c000000 );

	    //
	    // Check New error or Old error.
	    //

	    GET_PADDR( errAddr, sts2Buffer, sicSet);
	    HalpReadAndWritePhysicalAddr( errAddr ); // S003

	    for( i=0; i<((pECC1_ERR_AREA_INFO)infoBuf)->num_rec; i++) {
		HalNvramRead( (ULONG)( ((pECC1_ERR_AREA_INFO)infoBuf)->size_rec * i
				      +((pECC1_ERR_AREA_INFO)infoBuf)->offset_1biterr),
			      sizeof(ECC1_ERR_REC),
			      (PVOID)dataBuf);
		if ( (errAddr == ((pECC1_ERR_REC)dataBuf)->err_address) &&
		     ( (((pECC1_ERR_REC)dataBuf)->record_flag & 0x1) != 0) ) {
		    break;
		}
	    }
	    
	    if( i != ((pECC1_ERR_AREA_INFO)infoBuf)->num_rec ) {
		break;
	    }

	    //
	    // wait 20 us.
	    //

	    KeStallExecutionProcessor(20);

	    //
	    // Enable ECC 1bit error.
	    //

	    NOTIFY_ECC1BIT(HalpECC1bitScfrBuffer); // S003

	    //
	    // Check ECC 1bit error.
	    //

	    HalpReadPhysicalAddr( errAddr );

	    buffer = READ_REGISTER_ULONG(
			 &( SIC_ERR_CONTROL_OR( sicOffset ) )->EIF0.Long );
	    SIC_DUMMY_READ;

	    if( (buffer & 0x08000000) == 0 ) {
		break;
	    }

	    //
	    // ECC 1bit error occur again.
	    //

	    ((pECC1_ERR_REC)dataBuf)->record_flag = ECC_LOG_VALID_FLG;

	    ((pECC1_ERR_REC)dataBuf)->err_address = errAddr;

	    GET_TIME(tempBuf);
	    RtlMoveMemory( (PVOID)( ((pECC1_ERR_REC)dataBuf)->when_happened ),
			  (PVOID)tempBuf,
			  TIME_STAMP_SIZE
			  );

	    ((pECC1_ERR_REC)dataBuf)->syndrome = sdlmBuffer;

	    ((pECC1_ERR_REC)dataBuf)->specified_group =
		(UCHAR)( ((PSTS2_REGISTER)&sts2Buffer)->ARE + sicSet * 4);

	    ((pECC1_ERR_REC)dataBuf)->specified_simm =
		(UCHAR)( ((PSTS2_REGISTER)&sts2Buffer)->SIMN );

	    writeOffset = ((pECC1_ERR_AREA_INFO)infoBuf)->offset_latest
		+((pECC1_ERR_AREA_INFO)infoBuf)->size_rec;

	    if( writeOffset >= ((pECC1_ERR_AREA_INFO)infoBuf)->offset_1biterr
	       +((pECC1_ERR_AREA_INFO)infoBuf)->size_rec
	       *((pECC1_ERR_AREA_INFO)infoBuf)->num_rec ) {
		writeOffset = ((pECC1_ERR_AREA_INFO)infoBuf)->offset_1biterr;
	    }

	    HalNvramWrite( (ULONG)writeOffset,
			  sizeof(ECC1_ERR_REC),
			  (PVOID)dataBuf);
	    HalNvramWrite( ECC_1BIT_ERROR_LOG_INFO_LATEST_OFFSET,
			  sizeof(USHORT),
			  (PVOID)&writeOffset);
	}

	break;
    }

    if(returnValue == SIC_ECC_1BIT_ERROR) {

	DONT_NOTIFY_ECC1BIT(HalpECC1bitScfrBuffer); // S003

	if(sicSet == 0){
	    WRITE_REGISTER_ULONG( SDCR_SET0_ADDR, 0x0 );
	} else {
	    WRITE_REGISTER_ULONG( SDCR_SET1_ADDR, 0x0 );
	}

	do {
	    eif0Buffer = READ_REGISTER_ULONG(
			     &( SIC_ERR_CONTROL_OR( sicOffset ) )->EIF0.Long );
	    SIC_DUMMY_READ;
	} while ( (eif0Buffer & 0x08000000) != 0 );

	WRITE_REGISTER_ULONG( &( IOB_CONTROL )->EIFR.Long,
			     EifrRegister & 0x0c000000 );
	// S004 vvv
	do {
	    eif0Buffer = READ_REGISTER_ULONG(
			     &( SIC_ERR_CONTROL_OR( sicOffset ) )->EIF0.Long );
	    SIC_DUMMY_READ;
	    buffer = READ_REGISTER_ULONG( &( IOB_CONTROL )->EIFR.Long );
	    IOB_DUMMY_READ;
	} while ( ((buffer & 0x0c000000) != 0) && ((eif0Buffer & 0xf8000000) == 0) );
	// S004 ^^^

	if(HalpECC1bitDisableFlag > 0) {
	    HalpECC1bitDisableFlag--;
	    if(HalpECC1bitDisableFlag > 0) {
		NOTIFY_ECC1BIT(HalpECC1bitScfrBuffer); // S003
	    }
	    // S003 vvv
	    else {
	        HalpECC1bitDisableTime = ECC_1BIT_ERROR_DISABLE_TIME;
		HalpECC1bitDisableFlag = 0;
	    }
	    // S003 ^^^
	}
    }
    // S002 ^^^

    return(returnValue);
}    
Пример #28
0
BOOLEAN
HalpInitializeInterrupts (
    VOID
)

/*++

Routine Description:

    This function initializes interrupts for a Jazz or Duo MIPS system.

    N.B. This function is only called during phase 0 initialization.

Arguments:

    None.

Return Value:

    A value of TRUE is returned if the initialization is successfully
    completed. Otherwise a value of FALSE is returned.

--*/

{

    ULONG 	DataLong;
    ULONG 	Index;
    PKPRCB 	Prcb;
    ULONG	Address;
    ENTRYLO	HalpPte[2];
    TIMER_CONTROL timerControl;


    //
    // Get the address of the processor control block for the current
    // processor.
    //

    Prcb = PCR->Prcb;

    //
    // Initialize the IRQL translation tables in the PCR. These tables are
    // used by the interrupt dispatcher to determine the new IRQL and the
    // mask value that is to be loaded into the PSR. They are also used by
    // the routines that raise and lower IRQL to load a new mask value into
    // the PSR.
    //

    for (Index = 0; Index < sizeof(HalpIrqlMask); Index += 1) {
        PCR->IrqlMask[Index] = HalpIrqlMask[Index];
    }

    for (Index = 0; Index < sizeof(HalpIrqlTable); Index += 1) {
        PCR->IrqlTable[Index] = HalpIrqlTable[Index];
    }

    //
    // Disable all system level interrupts which
    // includes all IO (PCI/EISA) device interrupts.
    //

    WRITE_REGISTER_ULONG(HalpPmpIntCtrl, 0);

    //
    // If processor 0 is being initialized, then clear all builtin device
    // interrupt enables.
    //

    if (Prcb->Number == 0) {
        HalpBuiltinInterruptEnable = 0;
    }

    //
    // Read IntStatus
    //

    DataLong = READ_REGISTER_ULONG(HalpPmpIntStatus)  & INT_STATUS_AMASK;

    //
    // If there are any pending interrupts to processor A,
    // then read the *Ack registers to clear the offending
    // condition. We will need to map registers on-the-fly
    // here iff there are any pending interrupts to be serviced.
    //

    if (DataLong) {

        do {

            //
            // Clear pending IO interrupts
            //

            if (DataLong & INT_STATUS_IOA) {

                HalpMapSysCtrlReg(PMP(IO_INT_ACK_PHYSICAL_BASE), 0, SYS_CONTROL_VIRTUAL_BASE);
                READ_REGISTER_ULONG(SYS_CONTROL_VIRTUAL_BASE + REG_OFFSET(PMP(IO_INT_ACK_PHYSICAL_BASE)));
                HalpUnMapSysCtrlReg();

            }

            //
            // Clear pending IP interrupts
            //

            if (DataLong & INT_STATUS_IPA) {

                HalpMapSysCtrlReg(PMP(IP_INT_ACK_PHYSICAL_BASE), 0, SYS_CONTROL_VIRTUAL_BASE);
                READ_REGISTER_ULONG(SYS_CONTROL_VIRTUAL_BASE + REG_OFFSET(PMP(IP_INT_ACK_PHYSICAL_BASE)));
                HalpUnMapSysCtrlReg();

            }

            //
            // Clear pending PCI interrupts
            //

            if (DataLong & (INT_STATUS_PA | INT_STATUS_PNI)) {

                HalpMapSysCtrlReg(PMP(PCI_ERR_ACK_PHYSICAL_BASE), 0, SYS_CONTROL_VIRTUAL_BASE);
                READ_REGISTER_ULONG(SYS_CONTROL_VIRTUAL_BASE + REG_OFFSET(PMP(PCI_ERR_ACK_PHYSICAL_BASE)));
                HalpUnMapSysCtrlReg();

            }

            //
            // Clear pending MCU interrupts
            //

            if (DataLong & (INT_STATUS_MA | INT_STATUS_MNI)) {

                HalpMapSysCtrlReg(PMP(MEM_ERR_ACK_PHYSICAL_BASE), 0, SYS_CONTROL_VIRTUAL_BASE);
                READ_REGISTER_ULONG(SYS_CONTROL_VIRTUAL_BASE + REG_OFFSET(PMP(MEM_ERR_ACK_PHYSICAL_BASE)));
                HalpUnMapSysCtrlReg();

            }

            //
            // Clear pending Timer interrupts
            //

            if (DataLong & INT_STATUS_ITA) {

                HalpMapSysCtrlReg(PMP(INT_CLR_CTRL_PHYSICAL_BASE), 0, SYS_CONTROL_VIRTUAL_BASE);
                READ_REGISTER_ULONG(SYS_CONTROL_VIRTUAL_BASE + REG_OFFSET(PMP(INT_CLR_CTRL_PHYSICAL_BASE)));
                HalpUnMapSysCtrlReg();

            }

        } while ((READ_REGISTER_ULONG(HalpPmpIntStatus) & INT_STATUS_AMASK) != 0);

    }

    //
    // For FALCON: all interrupts, except the R4x00 timer and
    // software interrupts, come into the kernel at the same
    // level due to the manner in which interrupts are delivered
    // to the processor and controlled by the IP field in the
    // R4x00 cause register.
    //
    // This means that we need a master interrupt handler whose
    // job is to (1) determine the source of the interrupt and
    // (2) invoke the correct interrupt handler to service the
    // request.
    //
    // Instead of managing a separate data structure for interrupt
    // vectors, we will still install all interupt handlers at their
    // normal positions within the IDT, eventhough they will be not
    // be directly invoked by the kernel but rather by the master
    // interrupt handler named HalpInterruptDispatch. Please
    // refere to the fxintr.s file for more details on how this scheme
    // will work.
    //

    PCR->InterruptRoutine[FALCON_LEVEL] 	= HalpInterruptDispatch;

    //
    // Likewise, we need a similar routine for IO device interrupts
    // to transfer control to the correct handler based on the IRQ
    // vector returned by the 82374. This handler is the first level
    // handler in the HAL for any IO interrupt, regardless of whether
    // the interrupt is from a PCI device or an EISA/ISA device.
    //

    PCR->InterruptRoutine[IO_DEVICE_LEVEL]	= HalpIoInterruptDispatch;

    //
    // We also need to install the Memory and PCI interrupt handlers
    // that deal with errors such as parity and ECC, etc. These handlers
    // are invoked by the master interrupt handler but are in the IDT
    // for completeness. These same handlers should serve as the error
    // handlers for bus errors (i.e., synchronous errors as opposed to
    // asynchronous interrupts).
    //

    PCR->InterruptRoutine[MEMORY_LEVEL] 	= HalpMemoryInterrupt;
    PCR->InterruptRoutine[PCI_LEVEL] 	= HalpPciInterrupt;

    //
    // Install IP interrupt routine in PCR structure.
    //

    PCR->InterruptRoutine[IPI_LEVEL] = HalpIpiInterrupt;

    //
    // If processor 0 is being initialized, then connect the interval timer
    // interrupt to the stall interrupt routine so the stall execution count
    // can be computed during phase 1 initialization. Otherwise, connect the
    // interval timer interrupt to the appropriate interrupt service routine
    // and set stall execution count from the computation made on processor
    // 0.
    //

    PCR->InterruptRoutine[CLOCK2_LEVEL] 		= HalpStallInterrupt;
    PCR->InterruptRoutine[IRQL0_VECTOR] 		= HalpStallInterrupt;

    //
    // If processor 0 is being initialized, then connect the count/compare
    // interrupt to the count interrupt routine to handle early count/compare
    // interrupts during phase 1 initialization. Otherwise, connect the
    // count\comapre interrupt to the appropriate interrupt service routine.
    //

    PCR->InterruptRoutine[PROFILE_LEVEL] = HalpCountInterrupt;

    //
    // Initialize the interval timer to interrupt at the specified interval.
    //
    // Note that for the first version of the PMP chip, the timer control
    // and the interrupt signal will only be controllable through the 82374
    // and visible through the standard IRQ* signals. However, in the second
    // version of the PMP chip, the interrupt signal will actually be a
    // separate interrupt signal not part of the IRQ architecture of the
    // 82374. This signal will actually be delivered by Timer 1, Counter 2
    // in the 82374 which is normally used to generate speaker tone(s).
    // We can play this trick because this timer runs off the same clock as
    // the normal system timer (Timer 1, Counter 0). The difference between
    // the two timers are that the system timer is wired to IRQ0 permanently
    // and is always enabled, while the speaker timer is not part of the
    // IRQ architecture and must be enabled by software through port 0x61
    // (NMI Status and Control Register).
    //
    //
    // For the first version of the PMP chip, we actually need to initialize
    // the cascaded interrupt controllers in the 82374 before we can enable
    // interrupts for the interval timer (or any other IO device). This is
    // because the interval timer circuitry is in the 82374 and is part of
    // the standard IRQ* architecture. In the second version of the PMP chip,
    // the timer interrupt is a separate signal and we can avoid having to
    // initialize the 82374 interrupt controllers during this phase.
    //

    //
    // Map the system timer control registers
    // located in the 82374 through EISA control
    // space using one of the wired entries in
    // the TLB. We will relinquish this entry when
    // HalpMapIoSpace() is called and maps Eisa
    // control space using MmMapIoSpace().
    //

    HalpMapSysCtrlReg(EISA_CONTROL_PHYSICAL_BASE, 0, SYS_CONTROL_VIRTUAL_BASE);
    HalpEisaControlBase = (PVOID)SYS_CONTROL_VIRTUAL_BASE;

    //
    // Initialize the interrupt controllers.
    //

    HalpInitializeEisaInterrupts((PEISA_CONTROL)HalpEisaControlBase);

    //
    // Initialize interval timer
    //
    //	Timer 1, Counter 2, Mode 3 (Square Wave), Binary Countdown
    //

    timerControl.BcdMode = 0;
    timerControl.Mode = TM_SQUARE_WAVE;
    timerControl.SelectByte = SB_LSB_THEN_MSB;

    if ( HalpPmpRevision < 3 ) {
        //
        // PMP V2 uses Counter 0, IRQ0.
        //

        timerControl.SelectCounter = SELECT_COUNTER_0;

        WRITE_REGISTER_UCHAR(&((PEISA_CONTROL)HalpEisaControlBase)->CommandMode1, *((PUCHAR) &timerControl));

        //
        // Set the system clock timer to the correct frequency.
        //

        WRITE_REGISTER_UCHAR(&((PEISA_CONTROL)HalpEisaControlBase)->Timer1, (UCHAR)CLOCK_INTERVAL);
        WRITE_REGISTER_UCHAR(&((PEISA_CONTROL)HalpEisaControlBase)->Timer1, (UCHAR)(CLOCK_INTERVAL >> 8));

    } else {
Пример #29
0
ULONG
HalpEccError(
    IN ULONG EccDiagnostic,
    IN ULONG MemoryFailed
    )

/*++

Routine Description:

    This routine check ecc error and error log put in NVRAM.

Arguments:

    EccDiagnostic - EccDiagnostic Register value
    MemoryFailed - MemoryFailed Register value


Return Value:

    return value is the following error occured.
      1: ecc 1bit error.
      2: ecc 2bit error.
      0: other error.

--*/

{
    ULONG returnValue;
    USHORT infoOffset;
    USHORT writeOffset;
    ULONG buffer; // S001
    ULONG i;	    // S002
    UCHAR dataBuf[36];
    UCHAR infoBuf[24];
    UCHAR tempBuf[24];
    KIRQL OldIrql;
    ULONG DataWord;
    ULONG Number;

    //
    // Check for Ecc 2bit/1bit error
    //

    if (EccDiagnostic & 0x44000000) {
        returnValue = STORM_ECC_2BIT_ERROR;
        infoOffset=ECC_2BIT_ERROR_LOG_INFO_OFFSET;
    } else if (EccDiagnostic & 0x22000000) {
	returnValue = STORM_ECC_1BIT_ERROR;
        infoOffset=ECC_1BIT_ERROR_LOG_INFO_OFFSET;
    } else {
        return 0; // Probably Error bit was disappered.
    }

    HalNvramRead( NVRAM_STATE_FLG_OFFSET, 1, dataBuf );
    HalNvramRead( NVRAM_MAGIC_NO_OFFSET, 4, tempBuf );

    // S002 vvv
    switch(returnValue) {

    case STORM_ECC_2BIT_ERROR:

	//
	// Disable and clear ECC 1bit error.
	//

	(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
	    EccDiagnostic.u.LargeInteger.LowPart
		= 0x00ee0000;
	KeFlushWriteBuffer();

	// set Flag indicate ECC 2bit error.

	HalpEcc2bitErrorFlag = 1;

	//
	// Log to NVRAM
	//

	// check for nvram was valid.

	if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){

	    HalNvramRead( (ULONG)infoOffset, 20, infoBuf);

	    ((pECC2_ERR_REC)dataBuf)->record_flag = ECC_LOG_VALID_FLG;
	    
	    ((pECC2_ERR_REC)dataBuf)->err_address = MemoryFailed & 0xfffffff0;
	    // Error Address was 16Byte Alined.

	    GET_TIME(tempBuf);
	    RtlMoveMemory( (PVOID)( ((pECC2_ERR_REC)dataBuf)->when_happened ),
			  (PVOID)tempBuf,
			  TIME_STAMP_SIZE
			  );

	    ((pECC2_ERR_REC)dataBuf)->syndrome = EccDiagnostic;
	    
	    ((pECC2_ERR_REC)dataBuf)->specified_group =
		HalpFindMemoryGroup(MemoryFailed);

	    ((pECC2_ERR_REC)dataBuf)->specified_simm = 0;

	    writeOffset = ((pECC2_ERR_AREA_INFO)infoBuf)->offset_latest
		         +((pECC2_ERR_AREA_INFO)infoBuf)->size_rec;

	    if( writeOffset >= ((pECC2_ERR_AREA_INFO)infoBuf)->offset_2biterr
	                      +((pECC2_ERR_AREA_INFO)infoBuf)->size_rec
	                      *((pECC2_ERR_AREA_INFO)infoBuf)->num_rec ) {
		writeOffset = ((pECC2_ERR_AREA_INFO)infoBuf)->offset_2biterr;
	    }

	    HalNvramWrite( (ULONG)writeOffset,
			  sizeof(ECC2_ERR_REC),
			  (PVOID)dataBuf);

	    HalNvramWrite( ECC_2BIT_ERROR_LOG_INFO_LATEST_OFFSET,
			   sizeof(USHORT),
			   (PVOID)&writeOffset);
	}
	return returnValue; // S004

    case STORM_ECC_1BIT_ERROR:

	//
	// If MemoryFailed address
	// is over 512M Nothing can do.
	// 
	if ((MemoryFailed & 0xfffffff0) > 0x1fffffff) {
	    return returnValue;
	}

	//
	// Disable and clear ECC 1bit error.
	//

	Number = KeGetCurrentPrcb()->Number;
	(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
	    EccDiagnostic.u.LargeInteger.LowPart
		= 0x00ee0000;
	KeFlushWriteBuffer();
// M003 +++
	//
	// serialize ecc 1bit logging routine
	//

	for (;;) {
	    KiAcquireSpinLock(&Ecc1bitRoutineLock);
	    if (HalpEcc1bitCount[!Number] == 0) {

		//
		// Increment HalpEcc1bitCount
		//

		HalpEcc1bitCount[Number]++;
		KiReleaseSpinLock(&Ecc1bitRoutineLock);    
		break;
	    }
	    KiReleaseSpinLock(&Ecc1bitRoutineLock);    
	}
// M003 ---

	switch(HalpEcc1bitCount[Number]) {

	case 1:

	    HalpEcc1bitTotalCount++; // M002


	    HalpOldMemoryFailed[Number] = MemoryFailed;
	    
	    //
	    // ReWrite error address
	    // if error address is over 512M 
	    // Nothing can do.
	    // 

	    KiAcquireSpinLock(&Ecc1bitDisableLock);

	    // disable ecc 1bit error again.

	    (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
	        EccDiagnostic.u.LargeInteger.LowPart
		    = 0x00ee0000;
	    KeFlushWriteBuffer();

	    DataWord = READ_REGISTER_ULONG(
		            KSEG1_BASE
			    | (MemoryFailed & 0xfffffff0)
			    );
	    WRITE_REGISTER_ULONG(
                 KSEG1_BASE
	         | (MemoryFailed & 0xfffffff0),
	         DataWord
		 );

	    KiReleaseSpinLock(&Ecc1bitDisableLock);

	    //
	    // Wait 20 us.
	    //

	    KeStallExecutionProcessor(20);

	    //
	    // Enable and clear ECC 1bit error.
	    //

	    KiAcquireSpinLock(&Ecc1bitDisableLock);
	    (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
		EccDiagnostic.u.LargeInteger.LowPart
		    = 0x00cc0000;
	    KeFlushWriteBuffer();
	    KiReleaseSpinLock(&Ecc1bitDisableLock);

	    //
	    // ReRead error address
	    // if error address is over 512M 
	    // Nothing can do.
	    // 
	    // if Ecc 1bit error occur again , DataBusError will occur.
	    //

	    DataWord = READ_REGISTER_ULONG(
                           KSEG1_BASE
			   | (MemoryFailed & 0xfffffff0)
			   );

	    // decrement ecc 1bit count

	    HalpEcc1bitCount[Number]--;

	    return(returnValue);

	case 2:
	    
	    if (HalpOldMemoryFailed[Number] != MemoryFailed) {
		break;
	    }
	    if (MemoryFailed & 2) {
		
		// if multi error 
		// nothing can do.
		
		break;
	    }
	    
	    
	    if( ((dataBuf[0] & 0xff) == NVRAM_VALID) && ( *(PULONG)tempBuf == NVRAM_MAGIC ) ){
		
		
		//
		// Search for wheather error address was already logged
		//
		
		HalNvramRead( (ULONG)infoOffset, 20, infoBuf);
		
		for( i=0; i<((pECC1_ERR_AREA_INFO)infoBuf)->num_rec; i++) {
		    HalNvramRead( (ULONG)( ((pECC1_ERR_AREA_INFO)infoBuf)->
					  size_rec * i
					  +((pECC1_ERR_AREA_INFO)infoBuf)->
					  offset_1biterr),
				 sizeof(ECC1_ERR_REC),
				 (PVOID)dataBuf);
		    if ( ((MemoryFailed & 0xfffffff0) 
			  == ((pECC1_ERR_REC)dataBuf)->err_address) &&
			( (((pECC1_ERR_REC)dataBuf)->record_flag & 0x1) != 0) ) {
			break;
		    }
		}
		
		if( i != ((pECC1_ERR_AREA_INFO)infoBuf)->num_rec ) {
		    break;
		}
		
		//
		//	Log to NVRAM
		//
		
		// check for nvram was valid.
		
		((pECC1_ERR_REC)dataBuf)->record_flag = ECC_LOG_VALID_FLG;
		
		((pECC1_ERR_REC)dataBuf)->err_address = MemoryFailed & 0xfffffff0;
		// Error Address was 16Byte Alined.
		
		GET_TIME(tempBuf);
		RtlMoveMemory( (PVOID)( ((pECC1_ERR_REC)dataBuf)->when_happened ),
			      (PVOID)tempBuf,
			      TIME_STAMP_SIZE
			      );
		
		((pECC1_ERR_REC)dataBuf)->syndrome = EccDiagnostic;
		
		((pECC1_ERR_REC)dataBuf)->specified_group =
		    HalpFindMemoryGroup(MemoryFailed);

		((pECC1_ERR_REC)dataBuf)->specified_simm = 0;
		
		writeOffset = ((pECC1_ERR_AREA_INFO)infoBuf)->offset_latest
		    +((pECC1_ERR_AREA_INFO)infoBuf)->size_rec;
		
		if( writeOffset >= ((pECC1_ERR_AREA_INFO)infoBuf)->offset_1biterr
		   +((pECC1_ERR_AREA_INFO)infoBuf)->size_rec
		   *((pECC1_ERR_AREA_INFO)infoBuf)->num_rec ) {
		    writeOffset = ((pECC1_ERR_AREA_INFO)infoBuf)->offset_1biterr;
		}
		
		HalNvramWrite( (ULONG)writeOffset,
			      sizeof(ECC1_ERR_REC),
			      (PVOID)dataBuf);
		HalNvramWrite( ECC_1BIT_ERROR_LOG_INFO_LATEST_OFFSET,
			      sizeof(USHORT),
			      (PVOID)&writeOffset);
	    }
	    

	    // disable ecc 1bit error again.

	    (ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
	        EccDiagnostic.u.LargeInteger.LowPart
	        = 0x00ee0000;
	    KeFlushWriteBuffer();

	    // decrement ecc 1bit count

	    HalpEcc1bitCount[Number]--;
	
	    return(returnValue);
	}
	
	//
	// Enable and clear ECC 1bit error.
	//
	
	KiAcquireSpinLock(&Ecc1bitDisableLock);
	(ULONG)((PDMA_REGISTERS)DMA_VIRTUAL_BASE)->
	    EccDiagnostic.u.LargeInteger.LowPart
		= 0x00cc0000;
	KeFlushWriteBuffer();
	KiReleaseSpinLock(&Ecc1bitDisableLock);


	// decrement ecc 1bit count

	HalpEcc1bitCount[Number]--;
	
	return(returnValue);
    }    
}
Пример #30
0
UCHAR
HalpFindMemoryGroup(
    IN ULONG MemoryFailed
    )

/*++

Routine Description:

    This routine finds MemoryGroup of MemoryFaled address

Arguments:

    MemoryFailed - MemoryFailed Register value


Return Value:

    if MemoryFaied is within any Goup, return MemoryGroup Number.

    Otherwise, return 0xff

--*/

{
    UCHAR returnValue = 0xff;
    UCHAR i;
    ULONG startAddr;
    ULONG length;
    ULONG simmType;
    ULONG dataWord;

    //
    // find MemoryGroup from MemoryGroup[0:3] register.
    //
    // MemoryGroup[0:3] register 
    //
    // [31] Reserved
    // [30:22] Starting address
    // [21:04] Reserved
    // [03:02] SIMM type
    //         01=Single-sided 11=Double-sided other=Reserved
    // [01:00] SIMM size
    // 	       00= 1M 01=4M 10=16M 11=64M SIMM
    // 
    // note: 1 memory group is have 4 SIMM's
    // 

    for (i = 0; i < 4; i++) {
	dataWord = READ_REGISTER_ULONG(&DMA_CONTROL->MemoryConfig[i]);

	// check SIMM type is valid

	switch (dataWord & 0xc) {

	case 4:	
	    simmType = 1;
	    break;
	    
	case 0xc:
	    simmType = 2;
	    break;

	default:
	    simmType = 3;
	}
	
	if (simmType == 3) {
	    continue;
	}

	// compute amount of MemoryGoup SIMM length;

	length = (0x400000 << ((dataWord & 3) * 2)) * simmType;

	// compute MemoryGoup SIMM start address;

	startAddr = dataWord & 0x7fc00000;

        // check if MemoryFailed is within this MemoryGroup

	if ( (startAddr <=  MemoryFailed)
	    && (MemoryFailed < (length + startAddr))) {
	    returnValue = i;
	    break;
	}
    }
    return returnValue;

}