Exemplo n.º 1
0
UINT32
BlAcpiGetNumberOfProcessors(
    VOID
    )
//++
//
//  Routine Description:
//
//    This function returns the number of processors.
//
//  Return Value:
//
//    Number of processors.
//
//--

{
    PACPI_MADT_ENTRY Entry;
    PCHAR Limit;
    PACPI_PROCESSOR_LOCAL_APIC LocalApic;
    PCHAR Next;
    UINT32 NumberOfProcessors;

    if (BlAcpiMadt == NULL) {

        return 1;
    }

    Next = (PCHAR) &BlAcpiMadt->ApicStructures[0];
    Limit = ((PCHAR) BlAcpiMadt) + BlAcpiMadt->Length;
    NumberOfProcessors = 0;

    while (Next < Limit) {

        Entry = (PACPI_MADT_ENTRY) Next;

        if ((Entry->Type == ACPI_APIC_TYPE_PROCESSOR_LOCAL) &&
            (Entry->Length >= sizeof(ACPI_PROCESSOR_LOCAL_APIC))) {

            LocalApic = (PACPI_PROCESSOR_LOCAL_APIC) Next;

            if (LocalApic->u1.s1.Enabled != FALSE) {

#if ACPI_VERBOSE

                BlRtlPrintf("ACPI: AcpiProcessorId=%u , LocalApicId=%u\n",
                            LocalApic->AcpiProcessorId,
                            LocalApic->ApicId);

#endif

                NumberOfProcessors += 1;
            }
        }

        Next += Entry->Length;
    }

    return NumberOfProcessors;
}
Exemplo n.º 2
0
VOID
BlAcpiResetSystem(
    VOID
    )

//++
//
//  Routine Description:
//
//    This function resets the system through the ACPI reset register.
//
//--

{
    if ((BlAcpiFadt->Revision < 2) ||
        (BlAcpiFadt->Length < (FIELD_OFFSET(ACPI_FADT, ResetValue) + sizeof(UINT8))) ||
        ((BlAcpiFadt->Flags & ACPI_FADT_FLAGS_RESET_SUPPORTED) == 0)
        ) {

#if ACPI_VERBOSE

        BlRtlPrintf("ACPI: Reset register is not supported! [FADT v%u]\n", BlAcpiFadt->Revision);

#endif

        return;
    }

#if ACPI_VERBOSE

    BlRtlPrintf("ACPI: Reset register type is %u.\n", BlAcpiFadt->ResetRegister.AddressSpaceId);

#endif

    switch (BlAcpiFadt->ResetRegister.AddressSpaceId) {

        case ACPI_GAS_IO: {

            BlRtlWritePort8((UINT16) BlAcpiFadt->ResetRegister.Address, BlAcpiFadt->ResetValue);

            break;
        }
    }
}
Exemplo n.º 3
0
PACPI_SRAT
BlAcpiLocateSrat(
    PACPI_RSDT Rsdt
    )

//++
//
//  Routine Description:
//
//    This function locates the ACPI SRAT structure.
//
//  Arguments:
//
//    Rsdt    - Supplies a pointer to the ACPI RSDT structure.
//
//  Return Value:
//
//    ACPI SRAT structure, if located.
//    NULL, otherwise.
//
//--

{
    UINT32 Index;
    PACPI_SRAT Srat;
    UINT32 NumberOfTables;

    NumberOfTables = (Rsdt->Length - FIELD_OFFSET(ACPI_RSDT, Entry)) / sizeof(Rsdt->Entry[0]);

    for (Index = 0; Index < NumberOfTables; Index += 1) {

        Srat = (PACPI_SRAT) (ULONG_PTR) Rsdt->Entry[Index];

        if ((Srat->Signature[0] == 'S') &&
            (Srat->Signature[1] == 'R') &&
            (Srat->Signature[2] == 'A') &&
            (Srat->Signature[3] == 'T') &&
            (Srat->Length >= sizeof(ACPI_SRAT)) &&
            (BlRtlComputeChecksum8(Srat, Srat->Length) == 0)) {
#if ACPI_VERBOSE
                BlRtlPrintf("ACPI: Found SRAT Table\n");
#endif

            return Srat;
        }
    }

    return NULL;
}
Exemplo n.º 4
0
VOID
BlPeLoadImage(
    PVOID LoadBase,
    PVOID Image,
    PVOID *EntryPoint
    )

//++
//
//  Routine Description:
//
//    This function loads the specified image.
//
//  Arguments:
//
//    Image       - Supplies a pointer to the image to load.
//
//    EntryPoint  - Receives a pointer to the entry point of the image.
//
//--

{
    ULONG_PTR BytesToCopy;
    PIMAGE_DOS_HEADER DosHeader;
    UINT32 Index;
    PIMAGE_NT_HEADERS NtHeader;
    PIMAGE_SECTION_HEADER Section;
    ULONG_PTR VirtualBase;
    ULONG_PTR RelocDiff;

    VirtualBase = (ULONG_PTR) LoadBase;
    DosHeader = (PIMAGE_DOS_HEADER) Image;

    if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE) {

        BlRtlPrintf("PECOFF: Missing MZ!\n");
        BlRtlHalt();
    }

    NtHeader = (PIMAGE_NT_HEADERS) ((ULONG_PTR) Image + DosHeader->e_lfanew);

    if (NtHeader->Signature != IMAGE_NT_SIGNATURE) {

        BlRtlPrintf("PECOFF: Missing PE!\n");
        BlRtlHalt();
    }

    if (NtHeader->FileHeader.NumberOfSections == 0) {

        BlRtlPrintf("PECOFF: No sections!\n");
        BlRtlHalt();
    }

    if ((NtHeader->OptionalHeader.ImageBase % PAGE_SIZE) != 0) {

        BlRtlPrintf("PECOFF: Not page aligned.\n");
        BlRtlHalt();
    }

    BlRtlCopyMemory((PVOID) VirtualBase,
                    Image,
                    NtHeader->OptionalHeader.SizeOfHeaders);

    Section = (PIMAGE_SECTION_HEADER) (((ULONG_PTR) &NtHeader->OptionalHeader) + NtHeader->FileHeader.SizeOfOptionalHeader);

    for (Index = 0; Index < NtHeader->FileHeader.NumberOfSections; Index += 1) {

        BlRtlZeroMemory((PVOID) (VirtualBase + Section[Index].VirtualAddress), Section[Index].Misc.VirtualSize);

        if (Section[Index].SizeOfRawData < Section[Index].Misc.VirtualSize) {

            BytesToCopy = Section[Index].SizeOfRawData;

        } else {

            BytesToCopy = Section[Index].Misc.VirtualSize;
        }

        BlRtlCopyMemory((PVOID) (VirtualBase + Section[Index].VirtualAddress),
                        (PVOID) (((ULONG_PTR) Image) + Section[Index].PointerToRawData),
                        BytesToCopy);

#if PECOFF_VERBOSE

        {
            CHAR Temp[IMAGE_SIZEOF_SHORT_NAME + 1];

            BlRtlCopyMemory(Temp,
                            Section[Index].Name,
                            IMAGE_SIZEOF_SHORT_NAME);

            Temp[IMAGE_SIZEOF_SHORT_NAME] = 0;

            BlRtlPrintf("PECOFF: %p ... %p (%p ... %p) %s\n",
                        VirtualBase + Section[Index].VirtualAddress,
                        VirtualBase + Section[Index].VirtualAddress + Section[Index].Misc.VirtualSize - 1,
                        (((ULONG_PTR) Image) + Section[Index].PointerToRawData),
                        (((ULONG_PTR) Image) + Section[Index].PointerToRawData) + BytesToCopy,
                        Temp);
        }

#endif

    }

    RelocDiff = VirtualBase - (ULONG_PTR)NtHeader->OptionalHeader.ImageBase;

    if (RelocDiff != 0) {

        PUINT8 RelocList;
        PUINT8 RelocListEnd;
        PIMAGE_BASE_RELOCATION Block;

        RelocList = (PUINT8) (VirtualBase + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].VirtualAddress);
        RelocListEnd = RelocList + NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_BASERELOC].Size;

#if PECOFF_VERBOSE

        BlRtlPrintf("PECOFF: Relocs: %p ... %p\n", RelocList, RelocListEnd);

#endif

        while (RelocList < RelocListEnd) {

            Block = (PIMAGE_BASE_RELOCATION) RelocList;

            BlPeApplyFixupBlock(Block, VirtualBase, RelocDiff);

            RelocList += Block->SizeOfBlock;
        }
    }

    *EntryPoint = (PVOID) (VirtualBase + NtHeader->OptionalHeader.AddressOfEntryPoint);

    return;
}
Exemplo n.º 5
0
VOID
BlPeApplyFixupBlock(
    PIMAGE_BASE_RELOCATION Block,
    ULONG_PTR VirtualBase,
    ULONG_PTR RelocDiff
    )

//++
//
//  Routine Description:
//
//    This function applies all of the base fixups in the specified block to the image.
//
//  Arguments:
//
//    Block       - Supplies a pointer to the base relocation fixup block.
//
//    VirtualBase - Supplies the target address of the image.
//
//    RelocDiff   - Supplies the offset of the image target address from the base address.
//
//--

{
    PUINT16 Reloc;
    PUINT16 BlockEnd;
    ULONG_PTR BlockBase;
    ULONG_PTR Target;

    Reloc = Block->TypeOffset;
    BlockEnd = (PUINT16) ( ((PUINT8) Block) + Block->SizeOfBlock);
    BlockBase = VirtualBase + Block->VirtualAddress;

#if PECOFF_VERBOSE

    BlRtlPrintf("PECOFF: Reloc Block %p:\n", Block->VirtualAddress);

#endif

    for (; Reloc < BlockEnd; Reloc++) {

        Target = BlockBase + (*Reloc & 0xfff);

#if PECOFF_VERBOSE

        switch (*Reloc >> 12) {

            case IMAGE_REL_BASED_ABSOLUTE: {

                BlRtlPrintf("PECOFF:  %p: abs:%x \r", (PUINT32) Target, * (PUINT32) Target);
                break;
            }

            case IMAGE_REL_BASED_HIGHLOW: {

                BlRtlPrintf("PECOFF:  %p: r32:%x->%x \r", (PUINT32) Target, * (PUINT32) Target, * (PUINT32) Target + (UINT32) RelocDiff);
                break;
            }

            case IMAGE_REL_BASED_DIR64: {

                BlRtlPrintf("PECOFF:  %p: r64:%lx->%lx \r", (PUINT64) Target, * (PUINT64) Target, * (PUINT64) Target + (UINT64) RelocDiff);
                break;
            }

            default: {

                BlRtlPrintf("PECOFF:  %p: %x ??? \r", (PUINT32) Target, Reloc[0] >> 12);
                break;
            }
        }

#endif

        switch (*Reloc >> 12) {
            case IMAGE_REL_BASED_ABSOLUTE: {

                break;
            }

            case IMAGE_REL_BASED_HIGHLOW: {

                * (PUINT32) Target += (UINT32) RelocDiff;
                break;
            }

            case IMAGE_REL_BASED_DIR64: {

                * (PUINT64 *) Target += (UINT64) RelocDiff;
                break;
            }

            default: {

                BlRtlPrintf("PECOFF: Illegal relocation.\n");
                BlRtlHalt();
            }
        }
    }
}
Exemplo n.º 6
0
VOID
BlPeGetVirtualRange(
    PVOID Image,
    PVOID *VirtualBase,
    ULONG_PTR *VirtualSize
    )

//++
//
//  Routine Description:
//
//    This function queries the virtual range for the specified image.
//
//  Arguments:
//
//    Image       - Supplies a pointer to the image.
//
//    VirtualBase - Receives the virtual base address of the image.
//
//    VirtualSize - Receives the virtual size of the image.
//
//--

{
    PIMAGE_DOS_HEADER DosHeader;
    UINT32 Index;
    PIMAGE_NT_HEADERS NtHeader;
    PIMAGE_SECTION_HEADER Section;
    UINT32 SectionEnd;

    DosHeader = (PIMAGE_DOS_HEADER) Image;

    if (DosHeader->e_magic != IMAGE_DOS_SIGNATURE) {

        BlRtlPrintf("PECOFF: Invalid image!\n");
        BlRtlHalt();
    }

    NtHeader = (PIMAGE_NT_HEADERS) ((ULONG_PTR) Image + DosHeader->e_lfanew);

    if (NtHeader->Signature != IMAGE_NT_SIGNATURE) {

        BlRtlPrintf("PECOFF: Invalid image!\n");
        BlRtlHalt();
    }

    if (NtHeader->FileHeader.NumberOfSections == 0) {

        BlRtlPrintf("PECOFF: Invalid image!\n");
        BlRtlHalt();
    }

    if ((NtHeader->OptionalHeader.ImageBase % PAGE_SIZE) != 0) {

        BlRtlPrintf("PECOFF: Invalid image!\n");
        BlRtlHalt();
    }

    *VirtualBase = (PVOID) NtHeader->OptionalHeader.ImageBase;
    *VirtualSize = 0;

    Section = (PIMAGE_SECTION_HEADER) (((ULONG_PTR) &NtHeader->OptionalHeader) + NtHeader->FileHeader.SizeOfOptionalHeader);

    for (Index = 0; Index < NtHeader->FileHeader.NumberOfSections; Index += 1) {

        SectionEnd = Section[Index].VirtualAddress + Section[Index].Misc.VirtualSize;

        if (SectionEnd > *VirtualSize) {

            *VirtualSize = SectionEnd;
        }
    }

    *VirtualSize = ROUND_UP_TO_PAGES(*VirtualSize);

    return;
}
Exemplo n.º 7
0
VOID
BlAcpiInitialize(
    VOID
    )

//++
//
//  Routine Description:
//
//    This function initializes ACPI support for the boot loader.
//
//--

{
    BlAcpiRsdp = BlAcpiLocateRsdp();

    if (BlAcpiRsdp == NULL) {

        BlRtlPrintf("ACPI: No RSDP!\n");
        BlRtlHalt();
    }

    BlAcpiRsdpAddress = (PVOID) BlAcpiRsdp;

    BlAcpiRsdt = BlAcpiLocateRsdt(BlAcpiRsdp);

    if (BlAcpiRsdt == NULL) {

        BlRtlPrintf("ACPI: No RSDT!\n");
        BlRtlHalt();
    }

    BlAcpiFadt = BlAcpiLocateFadt(BlAcpiRsdt);

    if (BlAcpiFadt == NULL) {

        BlRtlPrintf("ACPI: No FADT!\n");
        //BlRtlHalt();
    }

    BlAcpiMadt = BlAcpiLocateMadt(BlAcpiRsdt);

    if (BlAcpiMadt == NULL) {

        BlAcpiNumberOfProcessors = 1;

    } else {

        BlAcpiNumberOfProcessors = BlAcpiGetNumberOfProcessors();
    }

    if (BlAcpiNumberOfProcessors == 0) {

        BlRtlPrintf("ACPI: No local APIC!\n");
        BlRtlHalt();
    }

    BlAcpiSrat = BlAcpiLocateSrat(BlAcpiRsdt);
    if (BlAcpiSrat != NULL) {
        BlAcpiDumpSratEntries();
    }


#if ACPI_VERBOSE

    BlRtlPrintf("ACPI: RSDP @ %p\n"
                "ACPI: RSDT @ %p\n"
                "ACPI: FADT @ %p [Revision=%u , Length=%u]\n"
                "ACPI: MADT @ %p\n"
                "ACPI: %u processor(s)\n",
                BlAcpiRsdp,
                BlAcpiRsdt,
                BlAcpiFadt,
                BlAcpiFadt->Revision,
                BlAcpiFadt->Length,
                BlAcpiMadt,
                BlAcpiNumberOfProcessors);

#endif

    //
    // Map APIC page uncached.
    //

    if ((BlAcpiMadt != NULL) && (BlAcpiMadt->LocalApicAddress != 0)) {

#if ACPI_VERBOSE

        BlRtlPrintf("ACPI: APIC mapped @ %p.\n", BlAcpiMadt->LocalApicAddress);

#endif

        BlMmMapVirtualRange((PVOID) (ULONG_PTR) BlAcpiMadt->LocalApicAddress,
                            (PVOID) (ULONG_PTR) BlAcpiMadt->LocalApicAddress,
                            PAGE_SIZE,
                            TRUE,
                            FALSE,
                            FALSE);
    }
}
Exemplo n.º 8
0
VOID
BlAcpiDumpSratEntries(
    VOID
    )
//++
//
//  Routine Description:
//
//    This function prints out the SRAT table.
//--
{
    PACPI_SRAT_ENTRY Entry;
    PCHAR Limit;
    PACPI_SRAT_PROC_AFFINITY_ENTRY ProcAffinityEntry;
    PACPI_SRAT_MEM_AFFINITY_ENTRY MemAffinityEntry;
    PCHAR Next;
    UINT32 hbits;
    UINT32 totalbits;

    if (BlAcpiSrat == NULL) {
        BlRtlPrintf("ACPI: No Srat??\n");
        return;
    }
#if ACPI_VERBOSE
    BlRtlPrintf("SRAT:\n");
#endif

    Next = (PCHAR) &BlAcpiSrat->SratStructures[0];
    Limit = ((PCHAR) BlAcpiSrat) + BlAcpiSrat->Length;

    while (Next < Limit) {

        Entry = (PACPI_SRAT_ENTRY) Next;

        if ((Entry->Type == ACPI_SRAT_TYPE_PROC_AFFINITY_ENTRY) &&
            (Entry->Length >= sizeof(ACPI_SRAT_PROC_AFFINITY_ENTRY))) {

            ProcAffinityEntry = (PACPI_SRAT_PROC_AFFINITY_ENTRY) Next;
#if ACPI_VERBOSE
            BlRtlPrintf(" Processor:\n");
#endif
            hbits = 0;
            hbits += ProcAffinityEntry->ProximityDomainHighTwentyFourBits[0] << 24;
            hbits += ProcAffinityEntry->ProximityDomainHighTwentyFourBits[1] << 16;
            hbits += ProcAffinityEntry->ProximityDomainHighTwentyFourBits[2] << 8;
            totalbits = hbits | ProcAffinityEntry->ProximityDomainLowEightBits;
#if ACPI_VERBOSE
            BlRtlPrintf("  HighDomain 0x%06x LowDomain 0x%02x totalbits 0x%08x\n",
                        hbits, ProcAffinityEntry->ProximityDomainLowEightBits,
                        totalbits);
            BlRtlPrintf("  ApicID: %d flags 0x%08x\n", ProcAffinityEntry->ApicID,
                        ProcAffinityEntry->Flags);
#endif
        }
        else if ((Entry->Type == ACPI_SRAT_TYPE_MEM_AFFINITY_ENTRY) &&
                   (Entry->Length >= sizeof(ACPI_SRAT_MEM_AFFINITY_ENTRY))) {

            MemAffinityEntry = (PACPI_SRAT_MEM_AFFINITY_ENTRY) Next;
#if ACPI_VERBOSE
            BlRtlPrintf(" Memory:\n");
            BlRtlPrintf("  BaseAddress 0x%08x.%08x ..  0x%08x.%08x",
                        MemAffinityEntry->BaseAddressHigh, MemAffinityEntry->BaseAddressLow,
                        MemAffinityEntry->LengthHigh, MemAffinityEntry->LengthLow);
            BlRtlPrintf("  Domain %d  Flags 0x%08x\n",
                        MemAffinityEntry->ProximityDomain,
                        MemAffinityEntry->Flags);
#endif
        }

        Next += Entry->Length;
    }
}