Beispiel #1
0
INT
NTAPI
LlbHwKbdRead(VOID)
{
    /* Read current data on keyboard */
    return READ_REGISTER_UCHAR(PL050_KMIDATA);
}
Beispiel #2
0
UCHAR
NTAPI
ScsiPortReadRegisterUchar(
    IN PUCHAR Register)
{
    return READ_REGISTER_UCHAR(Register);
}
Beispiel #3
0
UCHAR
NTAPI
VideoPortReadRegisterUchar(
    PUCHAR Register)
{
    return READ_REGISTER_UCHAR(Register);
}
Beispiel #4
0
UCHAR
ScsiPortReadRegisterUchar(
    IN PUCHAR Register
)

/*++

Routine Description:

    Read from the specificed 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_UCHAR(Register));

}
Beispiel #5
0
VOID
HalpEnvironmentSetChecksum (
    VOID
)

/*++

Routine Description:

    This routine sets the NVRAM environment area checksum.

    N.B. The NVRAM must be mapped before this routine is called.

Arguments:

    None.

Return Value:

    None.

--*/

{

    ULONG Checksum;
    PUCHAR Environment;
    ULONG Index;
    PNV_CONFIGURATION NvConfiguration;

    //
    // Compute the NVRAM environment area checksum.
    //

    NvConfiguration = (PNV_CONFIGURATION)NVRAM_MEMORY_BASE;
    Environment = &NvConfiguration->Environment[0];
    Checksum = 0;
    for (Index = 0; Index < LENGTH_OF_ENVIRONMENT; Index += 1) {
        Checksum += (ULONG)READ_REGISTER_UCHAR(&Environment[Index]);
    }

    //
    // Write the NVRAM environment area checksum.
    //

    WRITE_REGISTER_UCHAR(&NvConfiguration->Checksum2[0],
                         (UCHAR)(Checksum & 0xFF));

    WRITE_REGISTER_UCHAR(&NvConfiguration->Checksum2[1],
                         (UCHAR)((Checksum >> 8) & 0xFF));

    WRITE_REGISTER_UCHAR(&NvConfiguration->Checksum2[2],
                         (UCHAR)((Checksum >> 16) & 0xFF));

    WRITE_REGISTER_UCHAR(&NvConfiguration->Checksum2[3],
                         (UCHAR)(Checksum >> 24));

    return;
}
UCHAR
HWREG<UCHAR>::Read(
    VOID
    )
{
    volatile UCHAR *addr = &m_Value;
    UCHAR v = READ_REGISTER_UCHAR((PUCHAR)addr);
    return v;
}
Beispiel #7
0
VOID
HalpResetCirrusChip(
    VOID
    )
/*+++
  
   This function resets/loads default values to the Cirrus Chip
   extended registers for use with extended text mode (80x50)

   Register values found in the cirrus manual, appendix D5

---*/
{
    UCHAR byte;

    WRITE_REGISTER_UCHAR(VGA_SEQ_IDX,  0x01);             // Screen off
    byte = READ_REGISTER_UCHAR(VGA_SEQ_DATA);
    WRITE_REGISTER_UCHAR(VGA_SEQ_DATA, (byte | 0x20));    // stop the sequencer

    // extended sequencer and crtc regs for cirrus

    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x1206);           // unlock the extended registers
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0007);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x4008);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x5709);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x180a);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x660b);

	// new modifs
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x3b1b);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x000f);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0016);
    WRITE_REGISTER_USHORT(VGA_CRT_IDX, 0x001b);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0007);
    WRITE_REGISTER_USHORT(VGA_GRAPH_IDX, 0x0009);
    WRITE_REGISTER_USHORT(VGA_GRAPH_IDX, 0x000a);
    WRITE_REGISTER_USHORT(VGA_GRAPH_IDX, 0x000b);
	// end new modifs

    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0010);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0011);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0012);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0013);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0018);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x0119);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x001a);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x3b1b);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x2f1c);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x301d);
    WRITE_REGISTER_USHORT(VGA_SEQ_IDX, 0x331e);

}
Beispiel #8
0
VOID
KdPortPutByte (
    IN UCHAR Output
    )

/*++

Routine Description:

    This routine puts a byte to the serial port used by the kernel debugger.

    N.B. It is assumed that the IRQL has been raised to the highest level,
        and necessary multiprocessor synchronization has been performed
        before this routine is called.

Arguments:

    Output - Supplies the output data byte.

Return Value:

    None.

--*/

{

    UCHAR DataByte;

    //
    // Wait for transmit ready.
    //

    do {
        DataByte = READ_REGISTER_UCHAR(&SP_READ->LineStatus);
    } while (((PSP_LINE_STATUS)(&DataByte))->TransmitHoldingEmpty == 0);

    //
    // Wait for data set ready.
    //

//    do {
//        DataByte = READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
//    } while (((PSP_MODEM_STATUS)(&DataByte))->DataSetReady == 0);

    //
    // Transmit data.
    //

    WRITE_REGISTER_UCHAR(&SP_WRITE->TransmitBuffer, Output);
    return;
}
Beispiel #9
0
VOID
NTAPI
LlbHwKbdSend(IN ULONG Value)
{
    ULONG Status;

    /* Wait for ready signal */    
    do
    {
        /* Read TX buffer state */
        Status = READ_REGISTER_UCHAR(PL050_KMISTAT);
    } while (!(Status & KMISTAT_TXEMPTY));
    
    /* Send value */
    WRITE_REGISTER_UCHAR(PL050_KMIDATA, Value);
}
Beispiel #10
0
UCHAR
HalpReadClockRegister (
    UCHAR Register
    )

/*++

Routine Description:

    This routine reads the specified realtime clock register.

Arguments:

    Register - Supplies the number of the register whose value is read.

Return Value:

    The value of the register is returned as the function value.

--*/

{

    //
    // Insert the realtime clock register number, and write the value back
    // to the EISA NMI enable register. This selects the realtime clock register
    // that is read.  Note this is a write only register and the EISA NMI
    // is always enabled.
    //

    //
    // TEMPTEMP Disable NMI's for now because this is causing machines in the
    // build lab to get NMI's during boot.
    //

    Register |= 0x80;


    WRITE_REGISTER_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable,
                         Register);

    //
    // Read the realtime clock register value.
    //

    return READ_REGISTER_UCHAR((PUCHAR)HalpRealTimeClockBase);
}
Beispiel #11
0
VOID
KdpReadIoSpaceExtended (
    IN PDBGKD_MANIPULATE_STATE64 m,
    IN PSTRING AdditionalData,
    IN PCONTEXT Context
    )

/*++

Routine Description:

    This function is called in response of a read io space extended state
    manipulation message.  Its function is to read system io
    locations.

Arguments:

    m - Supplies the state manipulation message.

    AdditionalData - Supplies any additional data for the message.

    Context - Supplies the current context.

Return Value:

    None.

--*/

{
    PDBGKD_READ_WRITE_IO_EXTENDED64 a = &m->u.ReadWriteIoExtended;
    ULONG Length;
    STRING MessageHeader;
    PUCHAR b;
    PUSHORT s;
    PULONG l;
    ULONG BusNumber;
    ULONG AddressSpace;
    ULONG SavedAddressSpace;
    PHYSICAL_ADDRESS IoAddress;
    ULONG DataSize;
    PHYSICAL_ADDRESS TranslatedAddress;
    INTERFACE_TYPE InterfaceType;

    MessageHeader.Length = sizeof(*m);
    MessageHeader.Buffer = (PCHAR)m;

    ASSERT(AdditionalData->Length == 0);

    m->ReturnStatus = STATUS_SUCCESS;

    InterfaceType = a->InterfaceType;
    BusNumber = a->BusNumber;
    AddressSpace = SavedAddressSpace = a->AddressSpace;
    IoAddress.QuadPart = (ULONG_PTR)a->IoAddress;
    DataSize = a->DataSize;

    //
    // Zero the return data value.
    //

    a->DataValue = 0;

    //
    // Translate the bus address to the physical system address
    // or QVA.
    //

    if( !HalTranslateBusAddress( InterfaceType,
                                 BusNumber,
                                 IoAddress,
                                 &AddressSpace,
                                 &TranslatedAddress ) ){
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
        goto SendReadIoSpaceExtendedResponse;
    }

    //
    // N.B. - for the moment we will only support QVAs ie. when AddressSpace
    //        is one.  It may be in later systems that we will have to
    //        check the address space, map it, perform the virtual read
    //        unmap, and then return the data - only we will have to be
    //        careful about what Irql we are to make sure the memory mgmt
    //        stuff will all work
    //

    if( !AddressSpace ){
        m->ReturnStatus = STATUS_INVALID_PARAMETER;
        goto SendReadIoSpaceExtendedResponse;
    }

    //
    // Do the IO space read using the appropriate HAL routines based upon
    // the original address space and the data size requested.
    //

    if( !SavedAddressSpace ){

        //
        // Memory (buffer) space on the bus
        //

        switch( DataSize ){

        case 1:
            a->DataValue = READ_REGISTER_UCHAR( (PUCHAR)(ULONG_PTR) TranslatedAddress.QuadPart );
            break;

        case 2:
            a->DataValue = READ_REGISTER_USHORT((PUSHORT)(ULONG_PTR) TranslatedAddress.QuadPart );
            break;

        case 4:
            a->DataValue = READ_REGISTER_ULONG((PULONG)(ULONG_PTR) TranslatedAddress.QuadPart );
            break;

        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
        }

    } else {

        //
        // I/O space on the bus
        //

        switch( DataSize ){

        case 1:
            a->DataValue = READ_PORT_UCHAR( (PUCHAR)(ULONG_PTR) TranslatedAddress.QuadPart );
            break;

        case 2:
            a->DataValue = READ_PORT_USHORT( (PUSHORT)(ULONG_PTR) TranslatedAddress.QuadPart );
            break;

        case 4:
            a->DataValue = READ_PORT_ULONG( (PULONG)(ULONG_PTR) TranslatedAddress.QuadPart );
            break;

        default:
            m->ReturnStatus = STATUS_INVALID_PARAMETER;
        }
    }



SendReadIoSpaceExtendedResponse:

    KdpSendPacket(
        PACKET_TYPE_KD_STATE_MANIPULATE,
        &MessageHeader,
        NULL
        );
}
Beispiel #12
0
ULONG
KdPortGetByte (
    OUT PUCHAR Input
    )

/*++

Routine Description:

    This routine gets a byte from the serial port used by the kernel
    debugger.

    N.B. It is assumed that the IRQL has been raised to the highest
        level, and necessary multiprocessor synchronization has been
        performed before this routine is called.

Arguments:

    Input - Supplies a pointer to a variable that receives the input
        data byte.

Return Value:

    CP_GET_SUCCESS is returned if a byte is successfully read from the
        kernel debugger line.

    CP_GET_ERROR is returned if error encountered during reading.

    CP_GET_NODATA is returned if timeout.

--*/

{

    UCHAR DataByte;
    ULONG TimeoutCount;

    //
    // Wait until data is available in the receive buffer.
    //

    TimeoutCount = TIMEOUT_COUNT;
    do {
        KeStallExecutionProcessor(1);
        DataByte = READ_REGISTER_UCHAR(&SP_READ->LineStatus);
        if (TimeoutCount-- == 0) {
            return CP_GET_NODATA;
        }
    } while (((PSP_LINE_STATUS)(&DataByte))->DataReady == 0);

    //
    // Read input byte and store in callers buffer.
    //

    *Input = READ_REGISTER_UCHAR(&SP_READ->ReceiveBuffer);

    //
    // Return function value as the not of the error indicators.
    //

    if (((PSP_LINE_STATUS)(&DataByte))->ParityError ||
        ((PSP_LINE_STATUS)(&DataByte))->FramingError ||
        ((PSP_LINE_STATUS)(&DataByte))->OverrunError ||
        ((PSP_LINE_STATUS)(&DataByte))->BreakIndicator) {
        return CP_GET_ERROR;
    } else {
        return CP_GET_SUCCESS;
    }
}
Beispiel #13
0
ARC_STATUS
HalpFindEnvironmentVariable (
    IN PCHAR Variable,
    OUT PULONG VariableIndex,
    OUT PULONG ValueIndex
)

/*++

Routine Description:

    This routine performs a case insensitive search of the NVRAM environment
    area for the specified variable name.

    N.B. The NVRAM must be mapped before this routine is called.


Arguments:

    Variable - Supplies a pointer to a zero terminated string containing an
        environment variable name.

Return Value:

    ESUCCESS is returned if the specified variable name is located. Otherwise,
    ENOENT is returned.

--*/

{

    PUCHAR Environment;
    ULONG Index;
    PUCHAR Name;

    //
    // If the variable name is null, then return no entry found.
    //

    if (*Variable == 0) {
        return ENOENT;
    }

    //
    // Search the environment section of the NVRAM for a variable name match.
    //

    Environment = &((PNV_CONFIGURATION)NVRAM_MEMORY_BASE)->Environment[0];
    Index = 0;
    do {

        //
        // Set name to the beginning of the variable name and record the
        // current index value.
        //

        Name = Variable;
        *VariableIndex = Index;

        //
        // Search until the end of the current environment variable, the
        // end of the specified variable name, or the end of the NVRAM is
        // reached.
        //

        while ((Index < LENGTH_OF_ENVIRONMENT) &&
                (READ_REGISTER_UCHAR(&Environment[Index]) != 0) && (*Name != 0)) {
            if (READ_REGISTER_UCHAR(&Environment[Index]) != UpCase(*Name)) {
                break;
            }

            Name += 1;
            Index += 1;
        }

        //
        // Check for a match which is signified by the end of the variable
        // name and the equal separator in the current environment variable.
        //

        if ((*Name == 0) && (READ_REGISTER_UCHAR(&Environment[Index]) == '=')) {
            *ValueIndex = Index + 1;
            return ESUCCESS;
        }

        //
        // Advance to the start of the next variable.
        //

        while ((Index < LENGTH_OF_ENVIRONMENT) &&
                (READ_REGISTER_UCHAR(&Environment[Index]) != 0)) {
            Index += 1;
        }

        Index += 1;
    } while (Index < LENGTH_OF_ENVIRONMENT);

    return ENOENT;
}
Beispiel #14
0
ULONG
HalpGetByte (
    IN PCHAR Input,
    IN BOOLEAN Wait
    )

/*++

Routine Description:

    This routine gets a byte from the serial port used by the kernel
    debugger.

Arguments:

    Input - Supplies a pointer to a variable that receives the input
        data byte.

    Wait - Supplies a boolean value that detemines whether a timeout
        is applied to the input operation.

Return Value:

    CP_GET_SUCCESS is returned if a byte is successfully read from the
        kernel debugger line.

    CP_GET_ERROR is returned if an error is encountered during reading.

    CP_GET_NODATA is returned if timeout occurs.

--*/

{

    SP_LINE_STATUS LsrByte;
    UCHAR DataByte;
    ULONG TimeoutCount;


    //
    // Attempt to read a byte from the debugger port until a byte is
    // available or until a timeout occurs.
    //

    TimeoutCount = Wait ? TIMEOUT_COUNT : 1;
    do {
        TimeoutCount -= 1;
        //
        // Wait until data is available in the receive buffer.
        //

        KeStallExecutionProcessor(1);
        LsrByte = KdReadLsr(TRUE);
        if (LsrByte.DataReady == 0) {
            continue;
        }

        //
        // Read input byte and store in callers buffer.
        //

        *Input = READ_REGISTER_UCHAR(&SP_READ->ReceiveBuffer);

        //
        // If using modem controls, then skip any incoming data while
        // ReceiveData not set.
        //

        if (KdUseModemControl) {
            DataByte = READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
            if ( ((PSP_MODEM_STATUS)&DataByte)->ReceiveDetect == 0) {
                continue;
            }
        }

        //
        // Return function value as the not of the error indicators.
        //
        if (LsrByte.ParityError ||
            LsrByte.FramingError ||
            LsrByte.OverrunError ||
            LsrByte.BreakIndicator) {
            return CP_GET_ERROR;
        }

        return CP_GET_SUCCESS;
    } while(TimeoutCount != 0);

    return CP_GET_NODATA;
}
Beispiel #15
0
VOID
KdPortPutByte (
    IN UCHAR Output
    )

/*++

Routine Description:

    This routine puts a byte to the serial port used by the kernel debugger.

    N.B. It is assumed that the IRQL has been raised to the highest level,
        and necessary multiprocessor synchronization has been performed
        before this routine is called.

Arguments:

    Output - Supplies the output data byte.

Return Value:

    None.

--*/

{

    UCHAR DataByte;
    PSP_MODEM_STATUS LsrByte;

    if (KdUseModemControl) {
        //
        // Modem control, make sure DSR, CTS and CD are all set before
        // sending any data.
        //

        for (; ;) {
            DataByte = READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
            if ( ((PSP_MODEM_STATUS)&DataByte)->ClearToSend  &&
                 ((PSP_MODEM_STATUS)&DataByte)->DataSetReady  &&
                 ((PSP_MODEM_STATUS)&DataByte)->ReceiveDetect ) {
                    break;
            }

            KdReadLsr(FALSE);
        }
    }

    //
    // Wait for transmit ready.
    //

    while (KdReadLsr(FALSE).TransmitHoldingEmpty == 0 );

    //
    // Wait for data set ready.
    //

//    do {
//        LsrByte = (PSP_MODEM_STATUS) READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
//    } while (((PSP_MODEM_STATUS)(&LsrByte))->DataSetReady == 0);

    //
    // Transmit data.
    //

    WRITE_REGISTER_UCHAR(&SP_WRITE->TransmitBuffer, Output);
    return;
}
Beispiel #16
0
BOOLEAN
HalpHandleExternalInterrupt(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext,
    IN PVOID TrapFrame
    )

/*++

Routine Description:

    This routine is entered as the result of an interrupt being generated
    via the vector that is connected to an interrupt object that describes
    the SIO device interrupts. Its function is to call the second
    level interrupt dispatch routine and acknowledge the interrupt at the SIO
    controller.

    N.B. This routine is entered and left with external interrupts disabled.


Arguments:

    Interrupt - Supplies a pointer to the interrupt object.

    ServiceContext - Supplies a pointer to the SIO interrupt acknowledge
        register.

      None.

Return Value:

    Returns the value returned from the second level routine.

--*/

{
    PSECONDARY_DISPATCH SioHandler;
    PKINTERRUPT SioInterrupt;
    USHORT interruptVector;
    BOOLEAN returnValue;
    UCHAR OldIrql;
    USHORT Isr;
    UCHAR Irql;


    //
    // Read the interrupt vector.
    //

    interruptVector = READ_REGISTER_UCHAR(HalpInterruptBase);

    //
    // check for nmi interrupt before we raise irql since we would raise to a
    // bogus level
    //

    if (interruptVector == 0xFF) {

       HalpHandleMachineCheck(NULL, NULL);
    }

    //
    // check for spurious interrupt
    //

    if (interruptVector == SPURIOUS_VECTOR) {

       WRITE_REGISTER_UCHAR(&((PEISA_CONTROL)HalpIoControlBase)->Interrupt1ControlPort0,
                            0x0B);
       Isr = READ_REGISTER_UCHAR(&((PEISA_CONTROL)HalpIoControlBase)->Interrupt1ControlPort0);
       if (!(Isr & 0x80)) {

       //
       // Spurious interrupt
       //

#if DBG
         //DbgPrint("A spurious interrupt occurred. \n");
         HalpSpuriousInterruptCount++;
#endif
         return(0);

       }
    }

    if (interruptVector > HIGHEST_8259_VECTOR) {
#if DBG
         DbgPrint("A bogus interrupt (0x%02x) occurred. \n", interruptVector);
         HalpBogusInterruptCount++;
#endif
      return (0);
    }

    //
    // Translate vector to IRQL and raise IRQL
    //

    Irql = HalpTranslateVectorToIrql(interruptVector);
    KeRaiseIrql( Irql, &OldIrql);

    //
    // Dispatch to the secondary interrupt service routine.
    //

    SioHandler = (PSECONDARY_DISPATCH)
                    PCR->InterruptRoutine[DEVICE_VECTORS + interruptVector];
    SioInterrupt = CONTAINING_RECORD(SioHandler,
                                      KINTERRUPT,
                                      DispatchCode[0]);

    returnValue = SioHandler(SioInterrupt,
                              SioInterrupt->ServiceContext,
                              TrapFrame
                              );

    //
    // Dismiss the interrupt in the SIO interrupt controllers.
    //

    //
    // If this is a cascaded interrupt then the interrupt must be dismissed in
    // both controllers.
    //

    if (interruptVector & 0x08) {

        WRITE_REGISTER_UCHAR(
            &((PEISA_CONTROL) HalpIoControlBase)->Interrupt2ControlPort0,
            NONSPECIFIC_END_OF_INTERRUPT
            );

    }

    WRITE_REGISTER_UCHAR(
        &((PEISA_CONTROL) HalpIoControlBase)->Interrupt1ControlPort0,
        NONSPECIFIC_END_OF_INTERRUPT
        );

    //
    // Lower IRQL but disable external interrupts.
    // Return to caller with interrupts disabled.
    //


    HalpResetIrqlAfterInterrupt(OldIrql);

    return(returnValue);

}
Beispiel #17
0
BOOLEAN
HalHandleNMI(
    IN PKINTERRUPT Interrupt,
    IN PVOID ServiceContext
    )
/*++

Routine Description:

   This function is called when an EISA NMI occurs.  It prints the 
   appropriate status information and bugchecks.

Arguments:

   Interrupt - Supplies a pointer to the interrupt object

   ServiceContext - Bug number to call bugcheck with.

Return Value:

   Returns TRUE.

--*/
{
    UCHAR   StatusByte;
    UCHAR   EisaPort;
    ULONG   port;
    ULONG   AddressSpace = 1; // 1 = I/O address space
    BOOLEAN Status;
    PHYSICAL_ADDRESS BusAddress;
    PHYSICAL_ADDRESS TranslatedAddress;
    UCHAR Datum;
    
    NMIcount++;

    //
    // Set the Eisa NMI disable bit. We do this to mask further NMI 
    // interrupts while we're servicing this one.
    //
    Datum = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&Datum))->NmiDisable = 1;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, Datum);
#ifdef HALDBG
    DbgPrint("HalpIntializeNMI: wrote 0x%x to NmiEnable\n\r", Datum);
#endif

    StatusByte =
        READ_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus);

    if (StatusByte & 0x80) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Parity Check / Parity Error\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
#else
        //
        // jwlfix - For the present, we're commenting out an NMI parity
        //          error bugcheck, until investigation into its causes
        //          yields a better solution.
        //
        //    HalDisplayString ("NMI: Parity Check / Parity Error\n");
        //    KeBugCheck(NMI_HARDWARE_FAILURE);
        //    return (TRUE);
#endif
    }

    Datum = READ_REGISTER_UCHAR((PUCHAR)HalpServerControlQva );
    if (((PMIKASA_SRV)(&Datum))->HaltIncoming == 0 ||
        ((PMIKASA_SRV)(&Datum))->TempFail == 1     ||
        ((PMIKASA_SRV)(&Datum))->Fan1Fault == 0    ||
        ((PMIKASA_SRV)(&Datum))->Fan2Fault == 0) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Server management NMI\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
        DbgPrint("HalHandleNMI:    Server Management Byte = 0x%x\r\n", Datum);
#else
        //
        // jwlfix - All the above conditions are for handling server 
        //          management features.  Implementing more than simple 
        //          dismissal waits upon definition of desired behavior 
        //          by platform designers or Microsoft Windows NT 
        //          requirements for server behavior.
#endif
    }

    if (StatusByte & 0x40) {
#ifdef HALDBG
        DbgPrint("HalHandleNMI: Channel Check / IOCHK\n");
        DbgPrint("HalHandleNMI:    StatusByte = 0x%x\r\n", StatusByte);
#else
        HalDisplayString ("NMI: Channel Check / IOCHK\n");
        KeBugCheck(NMI_HARDWARE_FAILURE);
        return (TRUE);
#endif
    }

#if 0
     // jwlfix - This code can be added in later, as we have need
     //          for it.  It's good to have it here, for when it
     //          might be of use.
     //
     // This is an Eisa machine, check for extnded nmi information...
     //

     StatusByte = READ_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl);

     if (StatusByte & 0x80) {
         HalDisplayString ("NMI: Fail-safe timer\n");
     }

     if (StatusByte & 0x40) {
         HalDisplayString ("NMI: Bus Timeout\n");
     }

     if (StatusByte & 0x20) {
         HalDisplayString ("NMI: Software NMI generated\n");
     }

     //
     // Look for any Eisa expansion board.  See if it asserted NMI.
     //
     // jwlfix - The following doesn't work, at this moment; it's 
     //          likey the 12-bit shift, which should be a 5-bit 
     //          shift on Mikasa.
     //

     BusAddress.HighPart = 0;

     for (EisaPort = 0; EisaPort <= 0xf; EisaPort++)
     {
         BusAddress.LowPart = (EisaPort << 12) + 0xC80;

         Status = HalTranslateBusAddress(Eisa,  // InterfaceType
                                         0,     // BusNumber
                                         BusAddress,
                                         &AddressSpace,  // 1=I/O address space
                                         &TranslatedAddress); // QVA
         if (Status == FALSE)
         {
             UCHAR pbuf[80];
             sprintf(pbuf,
                     "Unable to translate bus address %x for EISA slot %d\n",
                     BusAddress.LowPart, EisaPort);
             HalDisplayString(pbuf);
             KeBugCheck(NMI_HARDWARE_FAILURE);
         }

         port = TranslatedAddress.LowPart;

         WRITE_PORT_UCHAR ((PUCHAR) port, 0xff);
         StatusByte = READ_PORT_UCHAR ((PUCHAR) port);

         if ((StatusByte & 0x80) == 0) {
             //
             // Found valid Eisa board,  Check to see if its
             // IOCHKERR is asserted.
             //

             StatusByte = READ_PORT_UCHAR ((PUCHAR) port+4);
             if (StatusByte & 0x2) {
                 EisaNMIMsg[25] = (EisaPort > 9 ? 'A'-10 : '0') + EisaPort;
                 HalDisplayString (EisaNMIMsg);
                 KeBugCheck(NMI_HARDWARE_FAILURE);
             }
         }
     }
#ifdef HALDBG
    // Reset extended NMI interrupts (for debugging purposes only).
    WRITE_PORT_UCHAR(
      &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl, 0x00);
    WRITE_PORT_UCHAR(
      &((PEISA_CONTROL) HalpEisaControlBase)->ExtendedNmiResetControl, 0x02);
#endif
#endif

#ifdef HALDBG
    DbgPrint("HalHandleNMI: Resetting PERR#; NMI count = %d\r\n", NMIcount);
#endif

    //
    // Reset PERR# and disable it.
    //
    WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0x04);

    //
    //   now enable it again.
    //
    WRITE_PORT_UCHAR(&((PEISA_CONTROL) HalpEisaControlBase)->NmiStatus, 0);

    //
    // Clear the Eisa NMI disable bit. This re-enables NMI interrupts,
    // now that we're done servicing this one.
    //
    Datum = READ_PORT_UCHAR(
                    &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable);
    ((PNMI_ENABLE)(&Datum))->NmiDisable = 0;
    WRITE_PORT_UCHAR(
        &((PEISA_CONTROL) HalpEisaControlBase)->NmiEnable, Datum);
#ifdef HALDBG
    DbgPrint("HalpIntializeNMI: wrote 0x%x to NmiEnable\n\r", Datum);
#endif

    return(TRUE);
}
Beispiel #18
0
ULONG
x86BiosReadIoSpace (
    IN XM_OPERATION_DATATYPE DataType,
    IN USHORT PortNumber
    )

/*++

Routine Description:

    This function reads from emulated I/O space.

Arguments:

    DataType - Supplies the datatype for the read operation.

    PortNumber - Supplies the port number in I/O space to read from.

Return Value:

    The value read from I/O space is returned as the function value.

    N.B. If an aligned operation is specified, then the individual
        bytes are read from the specified port one at a time and
        assembled into the specified datatype.

--*/

{

    ULONG           Result;
    ULONG           PciBusNumber;
    PCI_SLOT_NUMBER SlotNumber;

    union {
        PUCHAR Byte;
        PUSHORT Word;
        PULONG Long;
    } u;

    //
    // Compute port address and read port.
    //

    //
    // If PortNumber is in ISA Motherboard space, then overide the base address of
    // the IO space with ISA space, otherwise, use the base address passed in on
    // initialization.
    //

    if (PortNumber < 0x1000 && ((PortNumber & 0x3ff) < 0x100)) {
        u.Long = (PULONG)((ULONG)HalpEisaControlBase[0] + PortNumber);
    } else {
        u.Long = (PULONG)(x86BiosIoSpace + PortNumber);
    }

    if (DataType == BYTE_DATA) {
        Result = READ_REGISTER_UCHAR(u.Byte);

    } else if (DataType == LONG_DATA) {

        //
        // If PortNumber is attempting to access the PCI config registers defined for X86 systems,
        // intercept them, and make the appropriate HAL call to get the PCI confoguration data.
        //

        if (PortNumber == 0xcf8) {
            Result = HalpPciConfigAddress;
        } else if (PortNumber == 0xcfc && (HalpPciConfigAddress & 0x80000000)) {
            PciBusNumber = (HalpPciConfigAddress >> 16) & 0xff;
            SlotNumber.u.AsULONG = 0;
            SlotNumber.u.bits.DeviceNumber = (HalpPciConfigAddress >> 11) & 0x1f;
            SlotNumber.u.bits.FunctionNumber = (HalpPciConfigAddress >> 8) & 0x07;
            HalGetBusDataByOffset (PCIConfiguration,
                                   PciBusNumber,
                                   SlotNumber.u.AsULONG,
                                   &Result,
                                   HalpPciConfigAddress & 0xfc,
                                   4
                                   );

        } else {
            if (((ULONG)u.Long & 0x3) != 0) {
Beispiel #19
0
BOOLEAN
NTAPI
LlbHwKbdReady(VOID)
{
    return READ_REGISTER_UCHAR(PL050_KMISTAT) & KMISTAT_RXFULL;
}
Beispiel #20
0
ARC_STATUS
HalSetEnvironmentVariable (
    IN PCHAR Variable,
    IN PCHAR Value
)

/*++

Routine Description:

    This function creates an environment variable with the specified value.

Arguments:

    Variable - Supplies a pointer to an environment variable name.

    Value - Supplies a pointer to the environment variable value.

Return Value:

    ESUCCESS is returned if the environment variable is created. Otherwise,
    ENOMEM is returned.

--*/

{

    UCHAR Character;
    PUCHAR Environment;
    KIRQL OldIrql;
    ENTRYLO SavedPte[2];
    ARC_STATUS Status;
    ULONG TopIndex;
    ULONG VariableIndex;
    ULONG VariableLength;
    ULONG ValueEnd;
    ULONG ValueIndex;
    ULONG ValueLength;

#if DBG
    DbgPrint("NVRAM 1S\n");
#endif

    //
    // Map the NVRAM into the address space of the current process.
    //

    OldIrql = HalpMapNvram(&SavedPte[0]);
    Environment = &((PNV_CONFIGURATION)NVRAM_MEMORY_BASE)->Environment[0];

    //
    // If the checksum does not match, then set status to an I/O error.
    //

    if (HalpEnvironmentCheckChecksum() != ESUCCESS) {
        Status = EIO;
        goto Unmap;
    }

    //
    // Determine the top of the environment area by scanning backwards until
    // the a non-null character is found or the beginning of the environment
    // area is reached.
    //

    for (TopIndex = (LENGTH_OF_ENVIRONMENT - 1); TopIndex > 0; TopIndex -= 1) {
        if (READ_REGISTER_UCHAR(&Environment[TopIndex]) != '\0') {
            break;
        }
    }

    //
    // If the environment area contains any data, then adjust the top index
    // to the first free byte.
    //

    if (TopIndex != 0) {
        TopIndex += 2;
    }

    //
    // Compute the length of the variable name and the variable value.
    //

    VariableLength = strlen(Variable) + 1;
    ValueLength = strlen(Value) + 1;

    //
    // Check to determine if the specified variable is currently defined.
    //

    if (HalpFindEnvironmentVariable(Variable,
                                    &VariableIndex,
                                    &ValueIndex) == ESUCCESS) {

        //
        // The specified variable is currently defined. Determine the end
        // of the variable value by scanning forward to the zero termination
        // byte.
        //

        ValueEnd = ValueIndex;
        while (READ_REGISTER_UCHAR(&Environment[ValueEnd]) != '\0') {
            ValueEnd += 1;
        }

        ValueEnd += 1;

        //
        // If there is enough free space for the new variable value, then
        // remove the current variable name and value from the environment
        // area, insert the new variable value at the end of the environment
        // if it is not null, and set the status to success. Otherwise, set
        // the status to no space available.
        //

        if ((ValueEnd - ValueIndex + LENGTH_OF_ENVIRONMENT - TopIndex) >= ValueLength) {
            while (ValueEnd != TopIndex) {
                Character = READ_REGISTER_UCHAR(&Environment[ValueEnd]);
                WRITE_REGISTER_UCHAR(&Environment[VariableIndex], Character);
                ValueEnd += 1;
                VariableIndex += 1;
            }

            ValueIndex = VariableIndex;
            while (ValueIndex != TopIndex) {
                WRITE_REGISTER_UCHAR(&Environment[ValueIndex], '\0');
                ValueIndex += 1;
            }

            //
            // If the new variable value is not null, then copy the variable
            // name and the variable value into the enviroment area.
            //

            if (*Value != '\0') {

                //
                // copy the variable name to the environment area.
                //

                do {
                    WRITE_REGISTER_UCHAR(&Environment[VariableIndex], UpCase(*Variable));
                    VariableIndex += 1;
                    Variable += 1;
                } while (*Variable != '\0');

                //
                // Insert separator character and copy variable value to the
                // environment area.
                //

                WRITE_REGISTER_UCHAR(&Environment[VariableIndex], '=');
                VariableIndex += 1;
                do {
                    WRITE_REGISTER_UCHAR(&Environment[VariableIndex], *Value);
                    VariableIndex += 1;
                    Value += 1;
                } while (*Value != '\0');
            }

            Status = ESUCCESS;

        } else {
            Status = ENOSPC;
        }

    } else {

        //
        // The specified variable does not currently have a value. If the
        // specified variable is null or has no value, then set the status
        // to success. Otherwise, if the free area is not large enough to
        // hold the new variable name and its value, then set the status to
        // no space available. Otherwise, insert the variable name and value
        // at the end of the environment area and set the status to success.
        //

        if ((*Variable == '\0') || (*Value == '\0')) {
            Status = ESUCCESS;

        } else if ((LENGTH_OF_ENVIRONMENT - TopIndex) <
                   (VariableLength + ValueLength)) {
            Status = ENOSPC;

        } else {

            //
            // copy the variable name to the environment area.
            //

            do {
                WRITE_REGISTER_UCHAR(&Environment[TopIndex], UpCase(*Variable));
                TopIndex += 1;
                Variable += 1;
            } while (*Variable != '\0');

            //
            // Insert separator character and copy variable value to the
            // environment area.
            //

            WRITE_REGISTER_UCHAR(&Environment[TopIndex], '=');
            TopIndex += 1;
            do {
                WRITE_REGISTER_UCHAR(&Environment[TopIndex], *Value);
                TopIndex += 1;
                Value += 1;
            } while (*Value != '\0');

            Status = ESUCCESS;
        }
    }

    //
    // Compute the new checksum and write to the environment area.
    //

    HalpEnvironmentSetChecksum();

    //
    // Unmap the NVRAM from the address space of the current process.
    //

Unmap:
    HalpUnmapNvram(&SavedPte[0], OldIrql);
#if DBG
    DbgPrint("NVRAM 1E\n");
#endif


    return Status;
}
Beispiel #21
0
ARC_STATUS
HalGetEnvironmentVariable (
    IN PCHAR Variable,
    IN USHORT Length,
    OUT PCHAR Buffer
)

/*++

Routine Description:

    This function locates an environment variable and returns its value.

Arguments:

    Variable - Supplies a pointer to a zero terminated environment variable
        name.

    Length - Supplies the length of the value buffer in bytes.

    Buffer - Supplies a pointer to a buffer that receives the variable value.

Return Value:

    ESUCCESS is returned if the enviroment variable is located. Otherwise,
    ENOENT is returned.

--*/

{

    PUCHAR Environment;
    ULONG Index;
    KIRQL OldIrql;
    ENTRYLO SavedPte[2];
    ARC_STATUS Status;
    ULONG ValueIndex;
    ULONG VariableIndex;

#if defined(DBG1)
    DbgPrint("NVRAM 0S\n");
#endif


    //
    // Map the NVRAM into the address space of the current process.
    //

    OldIrql = HalpMapNvram(&SavedPte[0]);

    //
    // If the checksum does not match or the specified variable cannot
    // be located, then set the status to no entry found. Otherwise, copy
    // the respective variable value to the specified output buffer.
    //

    Environment = &((PNV_CONFIGURATION)NVRAM_MEMORY_BASE)->Environment[0];
    if ((HalpEnvironmentCheckChecksum() != ESUCCESS) ||
            (HalpFindEnvironmentVariable(Variable,
                                         &VariableIndex,
                                         &ValueIndex) != ESUCCESS)) {

        Status = ENOENT;

    } else {

        //
        // Copy the specified value to the output buffer.
        //

        for (Index = 0; Index < Length; Index += 1) {
            *Buffer = READ_REGISTER_UCHAR(&Environment[ValueIndex]);
            if (*Buffer == 0) {
                break;
            }

            Buffer += 1;
            ValueIndex += 1;
        }

        //
        // If the length terminated the loop, then return not enough memory.
        // Otherwise, return success.
        //

        if (Index == Length) {
            Status = ENOMEM;

        } else {
            Status = ESUCCESS;
        }
    }

    //
    // Unmap the NVRAM from the address space of the current process and
    // return the function status.
    //

    HalpUnmapNvram(&SavedPte[0], OldIrql);

#if defined(DBG1)
    DbgPrint("NVRAM 0E\n");
#endif

    return Status;
}
Beispiel #22
0
BOOLEAN
HalMakeBeep(
    IN ULONG Frequency
    )

/*++

Routine Description:

    This function sets the frequency of the speaker, causing it to sound a
    tone. The tone will sound until the speaker is explicitly turned off,
    so the driver is responsible for controlling the duration of the tone.

Arguments:

    Frequency - Supplies the frequency of the desired tone. A frequency of
        0 means the speaker should be shut off.

Return Value:

    TRUE  - Operation was successful (frequency within range or zero).
    FALSE - Operation was unsuccessful (frequency was out of range).
            Current tone (if any) is unchanged.

--*/

{

    KIRQL OldIrql;
    NMI_STATUS NmiStatus;
    PEISA_CONTROL controlBase = HalpEisaControlBase;
    TIMER_CONTROL timerControl;
    ULONG newCount;
    BOOLEAN Result;


    if ( HalpPmpRevision >= 3 ) {
	//
	// For PMP V3, we are NOT using speaker timer in ESC for speaker tone.
	// Need to add code to generate via sound card.
	//
	Result = TRUE;
	return Result;
    }

    //
    // Raise IRQL to dispatch level and acquire the beep spin lock.
    //

    KeAcquireSpinLock(&HalpBeepLock, &OldIrql);

    //
    // Stop the speaker.
    //

    *((PUCHAR)&NmiStatus) = READ_REGISTER_UCHAR(&controlBase->NmiStatus);
    NmiStatus.SpeakerGate = 0;
    NmiStatus.SpeakerData = 0;
    WRITE_REGISTER_UCHAR(&controlBase->NmiStatus, *((PUCHAR)&NmiStatus));

    //
    // If the specified frequency is zero, then the speaker is to be stopped.
    //

    if (Frequency == 0) {
        Result = TRUE;

    } else {

        //
        // If the new count has a magnitude less than 65,536 (0x10000), then
        // set the speaker time to the correct mode. Otherwise, return a value
        // of FALSE sinc ethe frequency is out of range.
        //

        newCount = TIMER_CLOCK_IN / Frequency;
        if (newCount >= 0x10000) {
            Result = FALSE;

        } else {

            //
            // Set the speaker timer to the correct mode.
            //

            timerControl.BcdMode = 0;
            timerControl.Mode = TM_SQUARE_WAVE;
            timerControl.SelectByte = SB_LSB_THEN_MSB;
            timerControl.SelectCounter = SELECT_COUNTER_2;
            WRITE_REGISTER_UCHAR(&controlBase->CommandMode1, *((PUCHAR) &timerControl));

            //
            // Set the speaker timer to the correct mode.
            //

            WRITE_REGISTER_UCHAR(&controlBase->SpeakerTone, (UCHAR)(newCount & 0xff));
            WRITE_REGISTER_UCHAR(&controlBase->SpeakerTone, (UCHAR)(newCount >> 8));

            //
            // Start the speaker.
            //

            NmiStatus.SpeakerGate = 1;
            NmiStatus.SpeakerData = 1;
            WRITE_REGISTER_UCHAR(&controlBase->NmiStatus, *((PUCHAR) &NmiStatus));
            Result = TRUE;
        }
    }

    //
    // Release the beep spin lock and lower IRQL to its previous value.
    //

    KeReleaseSpinLock(&HalpBeepLock, OldIrql);

    return Result;
}
Beispiel #23
0
BOOLEAN
HalpCreateSioStructures (
    VOID
    )

/*++

Routine Description:

    This routine initializes the structures necessary for SIO operations
    and connects the intermediate interrupt dispatcher.

Arguments:

    None.

Return Value:

    If the second level interrupt dispatcher is connected, then a value of
    TRUE is returned. Otherwise, a value of FALSE is returned.

--*/

{

    UCHAR DataByte;
    KIRQL oldIrql;


    //
    // Initialize the Machine Check interrupt handler
    //

    if (HalpEnableInterruptHandler(&HalpMachineCheckInterrupt,
                                   HalpHandleMachineCheck,
                                   NULL,
                                   NULL,
                                   MACHINE_CHECK_VECTOR,
                                   MACHINE_CHECK_LEVEL,
                                   MACHINE_CHECK_LEVEL,
                                   Latched,
                                   FALSE,
                                   0,
                                   FALSE,
                                   InternalUsage,
                                   MACHINE_CHECK_VECTOR
                                   ) == FALSE) {
        KeBugCheck(HAL_INITIALIZATION_FAILED);
    }

    //
    // Enable NMI IOCHK# and PCI SERR#
    //

    DataByte = READ_REGISTER_UCHAR(&((PEISA_CONTROL)HalpIoControlBase)->NmiStatus);
    WRITE_REGISTER_UCHAR(&((PEISA_CONTROL)HalpIoControlBase)->NmiStatus,
                        DataByte & ~DISABLE_IOCHK_NMI & ~DISABLE_PCI_SERR_NMI);

    //
    // Clear the SIO NMI disable bit.  This bit is the high order of the
    // NMI enable register.
    //

    DataByte = 0;


    WRITE_REGISTER_UCHAR(
      &((PEISA_CONTROL) HalpIoControlBase)->NmiEnable,
      DataByte
      );

    //
    // Connect the external interrupt handler
    //

    PCR->InterruptRoutine[EXTERNAL_INTERRUPT_VECTOR] = (PKINTERRUPT_ROUTINE) HalpHandleExternalInterrupt;

    //
    // register the interrupt vector
    //

    HalpRegisterVector(InternalUsage,
                       EXTERNAL_INTERRUPT_VECTOR,
                       EXTERNAL_INTERRUPT_VECTOR,
                       HIGH_LEVEL);




    // Connect directly to the decrementer handler.  This is done
    // directly rather than thru HalpEnableInterruptHandler due to
    // special handling required because the handler calls KdPollBreakIn().
    //

    PCR->InterruptRoutine[DECREMENT_VECTOR] = (PKINTERRUPT_ROUTINE) HalpHandleDecrementerInterrupt;


    //
    // Initialize and connect the Timer 1 interrupt (IRQ0)
    //

    if (HalpEnableInterruptHandler( &HalpProfileInterrupt,
                           (PKSERVICE_ROUTINE) HalpHandleProfileInterrupt,
                           (PVOID) NULL,
                           (PKSPIN_LOCK)NULL,
                           PROFILE_VECTOR,
                           PROFILE_LEVEL,
                           PROFILE_LEVEL,
                           Latched,
                           TRUE,
                           0,
                           FALSE,
                           DeviceUsage,
                           PROFILE_VECTOR
                           ) == FALSE) {
        KeBugCheck(HAL_INITIALIZATION_FAILED);
    }


    //
    // Disable Timer 1; only used by profiling
    //

    HalDisableSystemInterrupt(PROFILE_VECTOR, PROFILE_LEVEL);

    //
    // Set default profile rate
    //

    HalSetProfileInterval(5000);

    //
    // Raise the IRQL while the SIO interrupt controller is initialized.
    //

    KeRaiseIrql(CLOCK2_LEVEL, &oldIrql);

    //
    // Initialize any planar registers
    //

    HalpInitPlanar();

    
    //
    // Enable the clock interrupt
    //
    HalpUpdateDecrementer(1000);        // Get those decrementer ticks going


    //
    // Set ISA bus interrupt affinity.
    //

    HalpIsaBusAffinity = PCR->SetMember;


    //
    // Restore IRQL level.
    //

    KeLowerIrql(oldIrql);


    //
    // DMA command - set assert level
    //

    DataByte = READ_REGISTER_UCHAR(&((PEISA_CONTROL)HalpIoControlBase)->Dma1BasePort.DmaStatus);
    WRITE_REGISTER_UCHAR(&((PEISA_CONTROL)HalpIoControlBase)->Dma1BasePort.DmaStatus,
                        DataByte & ~DACK_ASSERT_HIGH & ~DREQ_ASSERT_LOW);

    //
    // Initialize the DMA mode registers to a default value.
    // Disable all of the DMA channels except channel 4 which is that
    // cascade of channels 0-3.
    //

    WRITE_REGISTER_UCHAR(
        &((PEISA_CONTROL) HalpIoControlBase)->Dma1BasePort.AllMask,
        0x0F
        );

    WRITE_REGISTER_UCHAR(
        &((PEISA_CONTROL) HalpIoControlBase)->Dma2BasePort.AllMask,
        0x0E
        );

    return(TRUE);
}
Beispiel #24
0
        } else if (PortNumber == 0xcfc && (HalpPciConfigAddress & 0x80000000)) {
            PciBusNumber = (HalpPciConfigAddress >> 16) & 0xff;
            SlotNumber.u.AsULONG = 0;
            SlotNumber.u.bits.DeviceNumber = (HalpPciConfigAddress >> 11) & 0x1f;
            SlotNumber.u.bits.FunctionNumber = (HalpPciConfigAddress >> 8) & 0x07;
            HalGetBusDataByOffset (PCIConfiguration,
                                   PciBusNumber,
                                   SlotNumber.u.AsULONG,
                                   &Result,
                                   HalpPciConfigAddress & 0xfc,
                                   4
                                   );

        } else {
            if (((ULONG)u.Long & 0x3) != 0) {
                Result = (READ_REGISTER_UCHAR(u.Byte + 0)) |
                         (READ_REGISTER_UCHAR(u.Byte + 1) << 8) |
                         (READ_REGISTER_UCHAR(u.Byte + 2) << 16) |
                         (READ_REGISTER_UCHAR(u.Byte + 3) << 24);

            } else {
                Result = READ_REGISTER_ULONG(u.Long);
            }
        }

    } else {
        if (((ULONG)u.Word & 0x1) != 0) {
            Result = (READ_REGISTER_UCHAR(u.Byte + 0)) |
                     (READ_REGISTER_UCHAR(u.Byte + 1) << 8);

        } else {
Beispiel #25
0
ARC_STATUS
HalGetEnvironmentVariable (
    IN PCHAR Variable,
    IN USHORT Length,
    OUT PCHAR Buffer
)

/*++

Routine Description:

    This function locates an environment variable and returns its value.

Arguments:

    Variable - Supplies a pointer to a zero terminated environment variable
        name.

    Length - Supplies the length of the value buffer in bytes.

    Buffer - Supplies a pointer to a buffer that receives the variable value.

Return Value:

    ESUCCESS is returned if the enviroment variable is located. Otherwise,
    ENOENT is returned.

NOTE:
    This implementation returns the error code ENOMEM if the output buffer
    is too small.

--*/

{

    PUCHAR Environment_var;
    ULONG Index;
    ARC_STATUS Status;

    //
    // retrieve the variable
    //

    Environment_var = (PUCHAR)ArcGetEnvironmentVariable(Variable);

    if (Environment_var == (PUCHAR)NULL) {

        Status = ENOENT;

    } else {

        //
        // Copy the specified value to the output buffer.
        //

        for (Index = 0; Index < Length; Index += 1) {
            *Buffer = READ_REGISTER_UCHAR(Environment_var);
            if (*Buffer == 0) {
                break;
            }

            Buffer += 1;
            Environment_var += 1;
        }

        //
        // If the length terminated the loop, then return not enough memory.
        // Otherwise, return success.
        //

        if (Index == Length) {
            Status = ENOMEM;

        } else {
            Status = ESUCCESS;
        }
    }

    return Status;
}
Beispiel #26
0
VOID
DrainTransmit( PDIGI_CONTROLLER_EXTENSION ControllerExt,
               PDIGI_DEVICE_EXTENSION DeviceExt,
               PIRP Irp )
/*++

Routine Description:

   We do the necessary checks to determine if the controller has
   transmitted all the data it has been given.

   The check basically is:

      if( CIN == COUT
          TIN == TOUT
          TBusy == 0 )
          transmit buffer is empty.


   NOTE: Care should be taken when using this function, and at
         what dispatch level it is being called from.  I don't do any
         synch'ing with the WriteQueue in the DeviceObject.  So it is
         potentially possible that data could keep getting put on the
         controller while the function is waiting for it to drain.

Arguments:

   ControllerExt - a pointer to this devices controllers extension.

   DeviceObject - a pointer to this devices object.

   Irp - Pointer to the current Irp request whose context this function
         is being called.  This allows us to determine if the Irp
         has been cancelled.

Return Value:


--*/
{
   PFEP_CHANNEL_STRUCTURE ChInfo;
   PCOMMAND_STRUCT CommandQ;
   COMMAND_STRUCT CmdStruct;
   UCHAR TBusy;
   ULONG count;

   USHORT OrgTout, Tin, Tout;

   TIME DelayInterval;


   ChInfo = (PFEP_CHANNEL_STRUCTURE)(ControllerExt->VirtualAddress +
                                     DeviceExt->ChannelInfo.Offset);

   EnableWindow( ControllerExt, DeviceExt->ChannelInfo.Window );
   Tin = READ_REGISTER_USHORT( &ChInfo->tin );
   Tout = READ_REGISTER_USHORT( &ChInfo->tout );
   TBusy = READ_REGISTER_UCHAR( &ChInfo->tbusy );
   DisableWindow( ControllerExt );

   OrgTout = Tout;

   //
   // Get the command queue info
   //
   CommandQ = ((PCOMMAND_STRUCT)(ControllerExt->VirtualAddress + FEP_CIN));

   EnableWindow( ControllerExt, ControllerExt->Global.Window );
   READ_REGISTER_BUFFER_UCHAR( (PUCHAR)CommandQ,
                               (PUCHAR)&CmdStruct,
                               sizeof(CmdStruct) );
   DisableWindow( ControllerExt );

   //
   // Delay for 10 milliseconds
   //
#if rmm < 807
   DelayInterval = RtlConvertLongToLargeInteger( -10 * 10000 );
#else
   DelayInterval.QuadPart = -10 * 10000;
#endif

   count = 0;

   while( ((Tin != Tout) ||
          (TBusy) ||
          (CmdStruct.cmHead != CmdStruct.cmTail)) &&
          !Irp->Cancel )
   {
      ASSERT( KeGetCurrentIrql() < DISPATCH_LEVEL ); // not DPC, or KeDelay won't ever return
      KeDelayExecutionThread( KernelMode,
                              FALSE,
                              &DelayInterval );

      EnableWindow( ControllerExt, DeviceExt->ChannelInfo.Window );
      Tin = READ_REGISTER_USHORT( &ChInfo->tin );
      Tout = READ_REGISTER_USHORT( &ChInfo->tout );
      TBusy = READ_REGISTER_UCHAR( &ChInfo->tbusy );
      DisableWindow( ControllerExt );

      EnableWindow( ControllerExt, ControllerExt->Global.Window );
      READ_REGISTER_BUFFER_UCHAR( (PUCHAR)CommandQ,
                                  (PUCHAR)&CmdStruct,
                                  sizeof(CmdStruct) );
      DisableWindow( ControllerExt );

      if( Tout != OrgTout )
      {
         count = 0;
         OrgTout = Tout;
      }

      if( count++ > 2500 )
      {
         //
         // We have waited for 25 seconds and haven't seen the transmit
         // buffer change.  Assume we are in a deadlock flow control state
         // and exit!
         //

         //
         // We go ahead and flush the transmit queue because a close
         // may be following soon, and we don't want it to have to
         // wait again.  Basically, it had its chance to drain.
         //
         FlushTransmitBuffer( ControllerExt, DeviceExt );

         break;
      }

   }

}  // end DrainTransmit
Beispiel #27
0
SP_LINE_STATUS
KdReadLsr (
    IN BOOLEAN WaitReason
    )

/*++

Routine Description:

    Returns current line status.

    If status which is being waited for is ready, then the function
    checks the current modem status and causes a possible display update
    of the current statuses.

Arguments:

    WaitReason - Supplies a boolean value that determines whether the line
        status is required for a receive or transmit.

Return Value:

    The current line status is returned as the function value.

--*/

{

    static  UCHAR RingFlag = 0;
    UCHAR   DataLsr, DataMsr;


    //
    // Get the line status for a recevie or a transmit.
    //

    DataLsr = READ_REGISTER_UCHAR(&SP_READ->LineStatus);
    if (WaitReason) {

        //
        // Get line status for receive data.
        //

        if (((PSP_LINE_STATUS)&DataLsr)->DataReady) {
            return *((PSP_LINE_STATUS)&DataLsr);
        }

    } else {

        //
        // Get line status for transmit empty.
        //

        if (((PSP_LINE_STATUS)&DataLsr)->TransmitEmpty) {
            return *((PSP_LINE_STATUS)&DataLsr);
        }
    }

    DataMsr = READ_REGISTER_UCHAR(&SP_READ->ModemStatus);
    RingFlag |= ((PSP_MODEM_STATUS)&DataMsr)->RingIndicator ? 1 : 2;
    if (RingFlag == 3) {

        //
        // The ring indicate line has toggled, use modem control from
        // now on.
        //

        KdUseModemControl = TRUE;
    }


    return *((PSP_LINE_STATUS) &DataLsr);
}
Beispiel #28
0
USHORT NBytesInRecvBuffer( PDIGI_CONTROLLER_EXTENSION ControllerExt,
                           PDIGI_DEVICE_EXTENSION DeviceExt )
/*++

Routine Description:

   Determine the number of actual bytes in the receive buffer.  This routine
   takes into account DOSMODE on the controller.

Arguments:

   ControllerExt - pointer to the controller extension information
                   assosicated with DeviceExt.

   DeviceExt - pointer to the device specific information.

Return Value:

   Number of bytes in the receive buffer.

--*/
{
   PUCHAR ControllerBuffer;
   PFEP_CHANNEL_STRUCTURE ChInfo;
   USHORT AmountInQueue;
   USHORT Rin, Rout, Rmax;
   USHORT DosMode;
   UCHAR ReceivedByte, SecondReceivedByte;

   ControllerBuffer = ControllerExt->VirtualAddress + DeviceExt->RxSeg.Offset;

   ChInfo = (PFEP_CHANNEL_STRUCTURE)(ControllerExt->VirtualAddress +
                                     DeviceExt->ChannelInfo.Offset);

   EnableWindow( ControllerExt, DeviceExt->ChannelInfo.Window );
   Rout = READ_REGISTER_USHORT( &ChInfo->rout );
   Rin = READ_REGISTER_USHORT( &ChInfo->rin );
   Rmax = READ_REGISTER_USHORT( &ChInfo->rmax );
   DosMode = READ_REGISTER_USHORT( &ChInfo->iflag );
   DisableWindow( ControllerExt );

   DosMode &= IFLAG_DOSMODE;

   if( !DosMode )
   {
      AmountInQueue = Rin - Rout;
      if( (SHORT)AmountInQueue < 0)
         AmountInQueue += (Rmax + 1);

      return( AmountInQueue );
   }

   AmountInQueue = 0;

   EnableWindow( ControllerExt, DeviceExt->RxSeg.Window );

   DigiDump( DIGIIOCTL,
             ("      NRecvRoutine: Rin = 0x%x, Rout = 0x%x\n",
              Rin,
              Rout) );

   while( Rout != Rin )
   {
      ReceivedByte = READ_REGISTER_UCHAR( (ControllerBuffer + Rout) );

      Rout++;
      Rout &= Rmax;
      AmountInQueue++;

      DigiDump( DIGIIOCTL,
                ("      NRecvByte = 0x%x, Rout = 0x%x\n",
                 ReceivedByte,
                 Rout) );

      //
      // We need to process out DigiBoard specific 0xFF.
      //
      if( ReceivedByte == 0xFF )
      {
         //
         // We have some special processing to do!
         //

         //
         // Is there a second character available??
         //
         if( Rout == Rin )
         {
            //
            // The second character isn't available!
            //
            AmountInQueue--;
            DigiDump( DIGIIOCTL,
                      ("      NRecvRoutine, 2nd byte not available!\n" ) );

            break;
         }
         else
         {
            //
            // Get the 2nd characters
            //
            SecondReceivedByte = READ_REGISTER_UCHAR( (ControllerBuffer + Rout) );
            Rout++;
            Rout &= Rmax;

            if( SecondReceivedByte == 0xFF )
            {
               //
               // We actually received a 0xFF in the data stream.
               //
               DigiDump( DIGIIOCTL,
                         ("      NRecvRoutine, Actually recv'ed 0xFF\n" ) );
               continue;

            }
            else
            {
               //
               // This is Line Status information.  Is the last
               // character available??
               //
               if( Rin == Rout )
               {
                  //
                  // The 3rd byte isn't available
                  //
                  AmountInQueue--;
                  DigiDump( DIGIIOCTL,
                            ("      NRecvRoutine, 3rd byte not available!\n" ) );
                  break;
               }

               Rout++;
               Rout &= Rmax;

            }

         }
      }
   }

   DisableWindow( ControllerExt );

   DigiDump( DIGIIOCTL,
             ("      NRecvRoutine, return RecvBytes = %d!\n",
              AmountInQueue ) );
   return( AmountInQueue );

}  // end NBytesInRecvBuffer
Beispiel #29
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;
}
Beispiel #30
0
ARC_STATUS
HalpEnvironmentCheckChecksum (
    VOID
)

/*++

Routine Description:

    This routine checks the NVRAM environment area checksum.

    N.B. The NVRAM must be mapped before this routine is called.

Arguments:

    None.

Return Value:

    ESUCCESS is returned if the checksum matches. Otherwise, EIO is returned.

--*/

{

    ULONG Checksum1;
    ULONG Checksum2;
    PUCHAR Environment;
    ULONG Index;
    PNV_CONFIGURATION NvConfiguration;

    //
    // Compute the NVRAM environment area checksum.
    //

    NvConfiguration = (PNV_CONFIGURATION)NVRAM_MEMORY_BASE;
    Environment = &NvConfiguration->Environment[0];
    Checksum1 = 0;
    for (Index = 0; Index < LENGTH_OF_ENVIRONMENT; Index += 1) {
        Checksum1 += (ULONG)READ_REGISTER_UCHAR(&Environment[Index]);
    }

    //
    // Merge the checksum bytes from the NVRAM and compare to computed value.
    //

    Checksum2 = (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[0]) |
                (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[1]) << 8 |
                (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[2]) << 16 |
                (ULONG)READ_REGISTER_UCHAR(&NvConfiguration->Checksum2[3]) << 24;

    //
    // If the checksum mismatches, then return an I/O error. Otherwise,
    // return a success status.
    //

    if (Checksum1 != Checksum2) {
        return EIO;

    } else {
        return ESUCCESS;
    }
}