Exemplo n.º 1
0
BOOLEAN
KdPortInitialize (
    PDEBUG_PARAMETERS DebugParameters,
    PLOADER_PARAMETER_BLOCK LoaderBlock,
    BOOLEAN Initialize
    )

/*++

Routine Description:

    This routine initializes the serial port used by the kernel debugger
    and must be called during system initialization.

Arguments:

    DebugParameter - Supplies a pointer to the debug port parameters.

    LoaderBlock - Supplies a pointer to the loader parameter block.

    Initialize - Specifies a boolean value that determines whether the
        debug port is initialized or just the debug port parameters
        are captured.

Return Value:

    A value of TRUE is returned is the port was successfully initialized.
    Otherwise, a value of FALSE is returned.

--*/

{

    PCONFIGURATION_COMPONENT_DATA ConfigurationEntry;
    UCHAR DataByte;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
    PCM_SERIAL_DEVICE_DATA DeviceData;
    ULONG KdPortEntry;
    PCM_PARTIAL_RESOURCE_LIST List;
    ULONG MatchKey;
    ULONG BaudRate;
    ULONG BaudClock;

    //
    // Find the configuration information for the first serial port.
    //

    if (LoaderBlock != NULL) {
        MatchKey = 0;
        ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
                                                      ControllerClass,
                                                      SerialController,
                                                      &MatchKey);

    } else {
        ConfigurationEntry = NULL;
    }

    if (DebugParameters->BaudRate != 0) {
        BaudRate = DebugParameters->BaudRate;
    } else {
        BaudRate = 19200;
    }

    //
    // If the serial configuration entry was found, then set baud clock
    // for 8000000.
    //

    BaudClock = 8000000;
    if (ConfigurationEntry != NULL) {
        List = (PCM_PARTIAL_RESOURCE_LIST)ConfigurationEntry->ConfigurationData;
        Descriptor = &List->PartialDescriptors[List->Count];
        DeviceData = (PCM_SERIAL_DEVICE_DATA)Descriptor;
        if ((DeviceData->BaudClock == 1843200) ||
            (DeviceData->BaudClock == 4233600) ||
            (DeviceData->BaudClock == 8000000)) {
            BaudClock = DeviceData->BaudClock;
        }
    }

    HalpGetDivisorFromBaud(
        BaudClock,
        BaudRate,
        &HalpBaudRateDivisor
        );

    //
    // If the debugger is not being enabled, then return.
    //

    if (Initialize == FALSE) {
        return TRUE;
    }

    //
    // Map the serial port into the system virtual address space by loading
    // a TB entry.
    //

    HalpPte[0].PFN = SP_PHYSICAL_BASE >> PAGE_SHIFT;
    HalpPte[0].G = 1;
    HalpPte[0].V = 1;
    HalpPte[0].D = 1;

#if defined(R3000)

    //
    // Set the TB entry and set the noncached bit in the PTE that will
    // map the serial controller.
    //

    KdPortEntry = KDPORT_ENTRY;
    HalpPte[0].N = 1;

#endif

#if defined(R4000)

    //
    // Allocate a TB entry, set the uncached policy in the PTE that will
    // map the serial controller, and initialize the second PTE.
    //

    KdPortEntry = HalpAllocateTbEntry();
    HalpPte[0].C = UNCACHED_POLICY;

    HalpPte[1].PFN = 0;
    HalpPte[1].G = 1;
    HalpPte[1].V = 0;
    HalpPte[1].D = 0;
    HalpPte[1].C = 0;

#endif

    KdComPortInUse=(PUCHAR)SERIAL0_PHYSICAL_BASE;

    //
    // Map the serial controller through a fixed TB entry.
    //

    KeFillFixedEntryTb((PHARDWARE_PTE)&HalpPte[0],
                       (PVOID)SP_VIRTUAL_BASE,
                       KdPortEntry);

    //
    // Clear the divisor latch, clear all interrupt enables, and reset and
    // disable the FIFO's.
    //

    WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, 0x0);
    WRITE_REGISTER_UCHAR(&SP_WRITE->InterruptEnable, 0x0);
    DataByte = 0;
    ((PSP_FIFO_CONTROL)(&DataByte))->ReceiveFifoReset = 1;
    ((PSP_FIFO_CONTROL)(&DataByte))->TransmitFifoReset = 1;
    WRITE_REGISTER_UCHAR(&SP_WRITE->FifoControl, DataByte);

    //
    // Set the divisor latch and set the baud rate to 19200 baud.
    //
    ((PSP_LINE_CONTROL)(&DataByte))->DivisorLatch = 1;
    WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, DataByte);
    WRITE_REGISTER_UCHAR(&SP_WRITE->TransmitBuffer, (UCHAR)(HalpBaudRateDivisor&0xff));
    WRITE_REGISTER_UCHAR(&SP_WRITE->InterruptEnable, (UCHAR)(HalpBaudRateDivisor>>8));

    //
    // Clear the divisor latch and set the character size to eight bits
    // with one stop bit and no parity checking.
    //

    DataByte = 0;
    ((PSP_LINE_CONTROL)(&DataByte))->CharacterSize = EIGHT_BITS;
    WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, DataByte);

    //
    // Set data terminal ready and request to send.
    //

    DataByte = 0;
    ((PSP_MODEM_CONTROL)(&DataByte))->DataTerminalReady = 1;
    ((PSP_MODEM_CONTROL)(&DataByte))->RequestToSend = 1;
    WRITE_REGISTER_UCHAR(&SP_WRITE->ModemControl, DataByte);

    //
    // Free the TB entry if one was allocated.
    //

#if defined(R4000)

    HalpFreeTbEntry();

#endif

    return TRUE;
}
Exemplo n.º 2
0
NTSTATUS
CmpInitializeHardwareConfiguration(
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )
/*++

Routine Description:

    This routine creates \\Registry\Machine\Hardware node in
    the registry and calls SetupTree routine to put the hardware
    information to the registry.

Arguments:

    LoaderBlock - supplies a pointer to the LoaderBlock passed in from the
                  OS Loader.

Returns:

    NTSTATUS code for sucess or reason of failure.

--*/
{
    NTSTATUS Status;
    OBJECT_ATTRIBUTES ObjectAttributes;
    HANDLE BaseHandle;
    PCONFIGURATION_COMPONENT_DATA ConfigurationRoot;
    ULONG Disposition;

    ConfigurationRoot = (PCONFIGURATION_COMPONENT_DATA)LoaderBlock->ConfigurationRoot;
    if (ConfigurationRoot) {

#ifdef _X86_

        //
        //  The following strings found in the registry identify obscure,
        //  yet market dominant, non PC/AT compatible i386 machine in Japan.
        //

#define MACHINE_TYPE_FUJITSU_FMR_NAME_A    "FUJITSU FMR-"
#define MACHINE_TYPE_NEC_PC98_NAME_A       "NEC PC-98"

        {
            PCONFIGURATION_COMPONENT_DATA SystemNode;
            ULONG JapanMachineId;

            //
            // For Japan, we have to special case some non PC/AT machines, so
            // determine at this time what kind of platform we are on:
            //
            // NEC PC9800 Compatibles/Fujitsu FM-R Compatibles/IBM PC/AT Compatibles
            //
            // Default is PC/AT compatible.
            //

            JapanMachineId = MACHINE_TYPE_PC_AT_COMPATIBLE;

            //
            // Find the hardware description node
            //

            SystemNode = KeFindConfigurationEntry(ConfigurationRoot,
                                                  SystemClass,
                                                  MaximumType,
                                                  NULL);

            //
            // Did we find something?
            //

            if (SystemNode) {

                //
                // Check platform from identifier string
                //

                if (RtlCompareMemory(SystemNode->ComponentEntry.Identifier,
                                     MACHINE_TYPE_NEC_PC98_NAME_A,
                                     sizeof(MACHINE_TYPE_NEC_PC98_NAME_A) - 1) ==
                    sizeof(MACHINE_TYPE_NEC_PC98_NAME_A) - 1) {

                    //
                    // we are running on NEC PC-9800 comaptibles.
                    //

                    JapanMachineId = MACHINE_TYPE_PC_9800_COMPATIBLE;
                    SetNEC_98;

                } else if (RtlCompareMemory(SystemNode->ComponentEntry.Identifier,
                                            MACHINE_TYPE_FUJITSU_FMR_NAME_A,
                                            sizeof(MACHINE_TYPE_FUJITSU_FMR_NAME_A) - 1) ==
                           sizeof(MACHINE_TYPE_FUJITSU_FMR_NAME_A) - 1) {

                    //
                    // we are running on Fujitsu FMR comaptibles.
                    //

                    JapanMachineId = MACHINE_TYPE_FMR_COMPATIBLE;
                }
            }

            //
            //  Now 'or' this value into the kernel global.
            //

            KeI386MachineType |= JapanMachineId;
        }
#endif //_X86_

        //
        // Create \\Registry\Machine\Hardware\DeviceMap
        //

        InitializeObjectAttributes(
            &ObjectAttributes,
            &CmRegistryMachineHardwareDeviceMapName,
            0,
            (HANDLE)NULL,
            NULL
            );
        ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

        Status = NtCreateKey(                   // Paht may already exist
                    &BaseHandle,
                    KEY_READ | KEY_WRITE,
                    &ObjectAttributes,
                    TITLE_INDEX_VALUE,
                    NULL,
                    0,
                    &Disposition
                    );

        if (!NT_SUCCESS(Status)) {
            return(Status);
        }

        NtClose(BaseHandle);

        ASSERT(Disposition == REG_CREATED_NEW_KEY);

        //
        // Create \\Registry\Machine\Hardware\Description and use the
        // returned handle as the BaseHandle to build the hardware tree.
        //

        InitializeObjectAttributes(
            &ObjectAttributes,
            &CmRegistryMachineHardwareDescriptionName,
            0,
            (HANDLE)NULL,
            NULL
            );
        ObjectAttributes.Attributes |= OBJ_CASE_INSENSITIVE;

        Status = NtCreateKey(                   // Path may already exist
                    &BaseHandle,
                    KEY_READ | KEY_WRITE,
                    &ObjectAttributes,
                    TITLE_INDEX_VALUE,
                    NULL,
                    0,
                    &Disposition
                    );

        if (!NT_SUCCESS(Status)) {
            return(Status);
        }

        ASSERT(Disposition == REG_CREATED_NEW_KEY);

        //
        // Allocate 16K bytes memory from paged pool for constructing
        // configuration data for controller component.
        // NOTE:  The configuration Data for controller component
        //    usually takes less than 100 bytes.  But on EISA machine, the
        //    EISA configuration information takes more than 10K and up to
        //    64K.  I believe 16K is the reasonable number to handler 99.9%
        //    of the machines.  Therefore, 16K is the initial value.
        //

        CmpConfigurationData = (PCM_FULL_RESOURCE_DESCRIPTOR)ExAllocatePool(
                                            PagedPool,
                                            CmpConfigurationAreaSize
                                            );

        if (CmpConfigurationData == NULL) {
            return(STATUS_INSUFFICIENT_RESOURCES);
        }

        //
        // Call SetupConfigurationTree routine to go over each component
        // of the tree and add component information to registry database.
        //

        Status = CmpSetupConfigurationTree(ConfigurationRoot,
                                           BaseHandle,
                                           -1,
                                           (ULONG)-1
                                           );
        ExFreePool((PVOID)CmpConfigurationData);
        NtClose(BaseHandle);
        return(Status);
    } else {
        return(STATUS_SUCCESS);
    }
}
Exemplo n.º 3
0
BOOLEAN
KdPortInitialize (
    PDEBUG_PARAMETERS DebugParameters,
    PLOADER_PARAMETER_BLOCK LoaderBlock,
    BOOLEAN Initialize
    )

/*++

Routine Description:

    This routine initializes the serial port used by the kernel debugger
    and must be called during system initialization.

Arguments:

    DebugParameter - Supplies a pointer to the debug port parameters.

    LoaderBlock - Supplies a pointer to the loader parameter block.

    Initialize - Specifies a boolean value that determines whether the
        debug port is initialized or just the debug port parameters
        are captured.

Return Value:

    A value of TRUE is returned is the port was successfully initialized.
    Otherwise, a value of FALSE is returned.

--*/

{

    PCONFIGURATION_COMPONENT_DATA ConfigurationEntry;
    UCHAR DataByte;
    PCM_PARTIAL_RESOURCE_DESCRIPTOR Descriptor;
    PCM_SERIAL_DEVICE_DATA DeviceData;
    PCM_PARTIAL_RESOURCE_LIST List;
    ULONG MatchKey;
    ULONG BaudRate;
    ULONG BaudClock;


    //
    // Find the configuration information for the first serial port.
    //

    if (LoaderBlock != NULL) {
        MatchKey = 0;
        ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
                                                      ControllerClass,
                                                      SerialController,
                                                      &MatchKey);

    } else {
        ConfigurationEntry = NULL;
    }

    if (DebugParameters->BaudRate != 0) {
        BaudRate = DebugParameters->BaudRate;
    } else {
        BaudRate = 19200;
    }

    //
    // If the serial configuration entry was not found or the frequency
    // specified is not supported, then default the baud clock to 800000.
    //

    BaudClock = 8000000;
    if (ConfigurationEntry != NULL) {
        List = (PCM_PARTIAL_RESOURCE_LIST)ConfigurationEntry->ConfigurationData;
        Descriptor = &List->PartialDescriptors[List->Count];
        DeviceData = (PCM_SERIAL_DEVICE_DATA)Descriptor;
        if ((DeviceData->BaudClock == 1843200) ||
            (DeviceData->BaudClock == 4233600) ||
            (DeviceData->BaudClock == 8000000)) {
            BaudClock = DeviceData->BaudClock;
        }
    }

    HalpGetDivisorFromBaud(
        BaudClock,
        BaudRate,
        &HalpBaudRateDivisor
        );

    //
    // If the debugger is not being enabled, then return.
    //

    if (Initialize == FALSE) {
        return TRUE;
    }

    KdComPortInUse=(PUCHAR)SERIAL0_PHYSICAL_BASE;


    //
    // Clear the divisor latch, clear all interrupt enables, and reset and
    // disable the FIFO's.
    //

    WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, 0x0);
    WRITE_REGISTER_UCHAR(&SP_WRITE->InterruptEnable, 0x0);
    DataByte = 0;
    ((PSP_FIFO_CONTROL)(&DataByte))->ReceiveFifoReset = 1;
    ((PSP_FIFO_CONTROL)(&DataByte))->TransmitFifoReset = 1;
    WRITE_REGISTER_UCHAR(&SP_WRITE->FifoControl, DataByte);

    //
    // Set the divisor latch and set the baud rate.
    //
    ((PSP_LINE_CONTROL)(&DataByte))->DivisorLatch = 1;
    WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, DataByte);
    WRITE_REGISTER_UCHAR(&SP_WRITE->TransmitBuffer,(UCHAR)(HalpBaudRateDivisor&0xFF));

    WRITE_REGISTER_UCHAR(&SP_WRITE->InterruptEnable,(UCHAR)(HalpBaudRateDivisor>>8));

    //
    // Clear the divisor latch and set the character size to eight bits
    // with one stop bit and no parity checking.
    //

    DataByte = 0;
    ((PSP_LINE_CONTROL)(&DataByte))->CharacterSize = EIGHT_BITS;
    WRITE_REGISTER_UCHAR(&SP_WRITE->LineControl, DataByte);

    //
    // Set data terminal ready and request to send.
    //

    DataByte = 0;
    ((PSP_MODEM_CONTROL)(&DataByte))->DataTerminalReady = 1;
    ((PSP_MODEM_CONTROL)(&DataByte))->RequestToSend = 1;
    WRITE_REGISTER_UCHAR(&SP_WRITE->ModemControl, DataByte);

    //
    // Free the TB entry if one was allocated.
    //
    return TRUE;
}
Exemplo n.º 4
0
BOOLEAN
HalpInitializeDisplay0 (
    IN PLOADER_PARAMETER_BLOCK LoaderBlock
    )

/*++

Routine Description:

    This routine maps the video memory and control registers into the user
    part of the idle process address space, initializes the video control
    registers, and clears the video screen.

Arguments:

    LoaderBlock - Supplies a pointer to the loader parameter block.

Return Value:

    If the initialization is successfully completed, than a value of TRUE
    is returned. Otherwise, a value of FALSE is returned.

--*/

{
    PCONFIGURATION_COMPONENT_DATA ConfigurationEntry;
    PVIDEO_BOARD_INFO VideoBoard;
    LONG  Index;
    ULONG MatchKey;

    //
    // Find the configuration entry for the first display controller.
    //

    MatchKey = 0;
    ConfigurationEntry = KeFindConfigurationEntry(LoaderBlock->ConfigurationRoot,
                                                  ControllerClass,
                                                  DisplayController,
                                                  &MatchKey);

    if (ConfigurationEntry == NULL) {
        return FALSE;
    }

    //
    // Determine which video controller is present in the system.
    // N.B. Be carefull with debug prints during Phase 0, it
    //      will kill the initial break point request from the debugger ...
    //


    for( Index=0, VideoBoard = KnownVideoBoards; Index < numVideoBoards; Index++, VideoBoard++) {

        if (!strcmp( ConfigurationEntry->ComponentEntry.Identifier,
                     VideoBoard->FirmwareString
                     ))  {
            HalpVideoBoard = VideoBoard->VideoBoard;
            HalpVideoChip  = VideoBoard->VideoChip;
            HalpDisplayControllerSetup = VideoBoard->ControllerSetup;
            break;
        }
    }

    if (Index >= numVideoBoards) {
        HalpVideoBoard = VIDEO_BOARD_UNKNOWN;
        HalpVideoChip  = VIDEO_CHIP_UNKNOWN;
        HalpDisplayControllerSetup = HalpDoNoSetup;
       
        //
        // let's see, if the bios emulator can initialize the card ....
        //

        HalpDisplayWidth = 80;
        HalpDisplayText  = 25;
        return TRUE;
    }

    //
    // Initialize the display controller.
    //

    HalpDisplayControllerSetup();

    HalpFirstBoot = FALSE;

    return TRUE;
}