Esempio n. 1
0
VOID
NTAPI
HalpUnmapRealModeMemory(VOID)
{
    ULONG i;
    PHARDWARE_PTE Pte;

    //
    // Loop the first meg of memory
    //
    for (i = 0; i < 0x100000; i += PAGE_SIZE)
    {
        //
        // Invalidate each PTE
        //
        Pte = HalAddressToPte(i);
        Pte->Valid = 0;
        Pte->Write = 0;
        Pte->Owner = 0;
        Pte->PageFrameNumber = 0;
    }

    //
    // Restore the PDE for the lowest megabyte of memory
    //
    Pte = HalAddressToPde(0);
    *Pte = HalpSavedPte;
    Pte->PageFrameNumber = HalpSavedPfn;

    //
    // Flush the TLB
    //
    HalpFlushTLB();
}
Esempio n. 2
0
VOID
NTAPI
HalpUnmapVirtualAddressVista(IN PVOID VirtualAddress,
                             IN PFN_COUNT PageCount,
                             IN BOOLEAN FlushCurrentTLB)
{
    PHARDWARE_PTE PointerPte;
    ULONG i;

    /* Only accept valid addresses */
    if (VirtualAddress < (PVOID)MM_HAL_VA_START) return;

    /* Align it down to page size */
    VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress & ~(PAGE_SIZE - 1));

    /* Loop PTEs */
    PointerPte = HalAddressToPte(VirtualAddress);
    for (i = 0; i < PageCount; i++)
    {
        *(PULONG)PointerPte = 0;
        PointerPte++;
    }

    /* Flush the TLB */
    if (FlushCurrentTLB)
        HalpFlushTLB();

    /* Put the heap back */
    if (HalpHeapStart > VirtualAddress) HalpHeapStart = VirtualAddress;
}
Esempio n. 3
0
File: apic.c Progetto: GYGit/reactos
VOID
NTAPI
ApicInitializeIOApic(VOID)
{
    PHARDWARE_PTE Pte;
    IOAPIC_REDIRECTION_REGISTER ReDirReg;
    UCHAR Index;
    ULONG Vector;

    /* Map the I/O Apic page */
    Pte = HalAddressToPte(IOAPIC_BASE);
    Pte->PageFrameNumber = IOAPIC_PHYS_BASE / PAGE_SIZE;
    Pte->Valid = 1;
    Pte->Write = 1;
    Pte->Owner = 1;
    Pte->CacheDisable = 1;
    Pte->Global = 1;
    _ReadWriteBarrier();

    /* Setup a redirection entry */
    ReDirReg.Vector = 0xFF;
    ReDirReg.DeliveryMode = APIC_MT_Fixed;
    ReDirReg.DestinationMode = APIC_DM_Physical;
    ReDirReg.DeliveryStatus = 0;
    ReDirReg.Polarity = 0;
    ReDirReg.RemoteIRR = 0;
    ReDirReg.TriggerMode = APIC_TGM_Edge;
    ReDirReg.Mask = 1;
    ReDirReg.Reserved = 0;
    ReDirReg.Destination = 0;

    /* Loop all table entries */
    for (Index = 0; Index < 24; Index++)
    {
        /* Initialize entry */
        IOApicWrite(IOAPIC_REDTBL + 2 * Index, ReDirReg.Long0);
        IOApicWrite(IOAPIC_REDTBL + 2 * Index + 1, ReDirReg.Long1);
    }

    /* Init the vactor to index table */
    for (Vector = 0; Vector <= 255; Vector++)
    {
        HalpVectorToIndex[Vector] = 0xFF;
    }

    // HACK: Allocate all IRQs, should rather do that on demand
    for (Index = 0; Index <= 15; Index++)
    {
        /* Map the IRQs to IRQLs like with the PIC */
        HalpAllocateSystemInterrupt(Index, 27 - Index);
    }

    /* Enable the timer interrupt */
    ReDirReg.Vector = APIC_CLOCK_VECTOR;
    ReDirReg.DeliveryMode = APIC_MT_Fixed;
    ReDirReg.DestinationMode = APIC_DM_Physical;
    ReDirReg.TriggerMode = APIC_TGM_Edge;
    ReDirReg.Mask = 0;
    ReDirReg.Destination = ApicRead(APIC_ID);
    IOApicWrite(IOAPIC_REDTBL + 2 * APIC_CLOCK_INDEX, ReDirReg.Long0);

    ApicSendEOI();
}
Esempio n. 4
0
BOOLEAN
NTAPI
HalpBiosDisplayReset(VOID)
{
    ULONG Flags;
    PHARDWARE_PTE IdtPte;
    BOOLEAN RestoreWriteProtection = FALSE;

    //
    // Disable interrupts
    //
    Flags = __readeflags();
    _disable();

    //
    // Map memory available to the V8086 real-mode code
    //
    HalpMapRealModeMemory();

    // 
    // On P5, the first 7 entries of the IDT are write protected to work around
    // the cmpxchg8b lock errata. Unprotect them here so we can set our custom
    // invalid op-code handler.
    //
    IdtPte = HalAddressToPte(((PKIPCR)KeGetPcr())->IDT);
    RestoreWriteProtection = IdtPte->Write != 0;
    IdtPte->Write = 1;

    //
    // Use special invalid opcode and GPF trap handlers
    //
    HalpSwitchToRealModeTrapHandlers();

    //
    // Configure the IOPM and TSS
    //
    HalpSetupRealModeIoPermissionsAndTask();

    //
    // Now jump to real mode
    //
    HalpBiosCall();

    //
    // Restore kernel trap handlers
    //
    HalpRestoreTrapHandlers();

    //
    // Restore write permission
    //
    IdtPte->Write = RestoreWriteProtection;

    //
    // Restore TSS and IOPM
    //
    HalpRestoreIoPermissionsAndTask();
    
    //
    // Restore low memory mapping
    //
    HalpUnmapRealModeMemory();

    //
    // Restore interrupts if they were previously enabled
    //
    __writeeflags(Flags);
    return TRUE;
}
Esempio n. 5
0
VOID
NTAPI
HalpMapRealModeMemory(VOID)
{
    PHARDWARE_PTE Pte, V86Pte;
    ULONG i;

    //
    // Get the page table directory for the lowest meg of memory
    //
    Pte = HalAddressToPde(0);
    HalpSavedPfn = Pte->PageFrameNumber;
    HalpSavedPte = *Pte;

    //
    // Map it to the HAL reserved region and make it valid
    //
    Pte->Valid = 1;
    Pte->Write = 1;
    Pte->Owner = 1;
    Pte->PageFrameNumber = (HalAddressToPde(0xFFC00000))->PageFrameNumber;

    //
    // Flush the TLB
    //
    HalpFlushTLB();

    //
    // Now loop the first meg of memory
    //
    for (i = 0; i < 0x100000; i += PAGE_SIZE)
    {
        //
        // Identity map it
        //
        Pte = HalAddressToPte(i);
        Pte->PageFrameNumber = i >> PAGE_SHIFT;
        Pte->Valid = 1;
        Pte->Write = 1;
        Pte->Owner = 1;
    }

    //
    // Now get the entry for our real mode V86 code and the target
    //
    Pte = HalAddressToPte(0x20000);
    V86Pte = HalAddressToPte(&HalpRealModeStart);
    do
    {
        //
        // Map the physical address into our real-mode region
        //
        Pte->PageFrameNumber = V86Pte->PageFrameNumber;
        
        //
        // Keep going until we've reached the end of our region
        //
        Pte++;
        V86Pte++;
    } while (V86Pte <= HalAddressToPte(&HalpRealModeEnd));

    //
    // Flush the TLB
    //
    HalpFlushTLB();
}
Esempio n. 6
0
PVOID
NTAPI
HalpMapPhysicalMemory64Vista(IN PHYSICAL_ADDRESS PhysicalAddress,
                             IN PFN_COUNT PageCount,
                             IN BOOLEAN FlushCurrentTLB)
{
    PHARDWARE_PTE PointerPte;
    PFN_NUMBER UsedPages = 0;
    PVOID VirtualAddress, BaseAddress;

    /* Start at the current HAL heap base */
    BaseAddress = HalpHeapStart;
    VirtualAddress = BaseAddress;

    /* Loop until we have all the pages required */
    while (UsedPages < PageCount)
    {
        /* If this overflows past the HAL heap, it means there's no space */
        if (VirtualAddress == NULL) return NULL;

        /* Get the PTE for this address */
        PointerPte = HalAddressToPte(VirtualAddress);

        /* Go to the next page */
        VirtualAddress = (PVOID)((ULONG_PTR)VirtualAddress + PAGE_SIZE);

        /* Check if the page is available */
        if (PointerPte->Valid)
        {
            /* PTE has data, skip it and start with a new base address */
            BaseAddress = VirtualAddress;
            UsedPages = 0;
            continue;
        }

        /* PTE is available, keep going on this run */
        UsedPages++;
    }

    /* Take the base address of the page plus the actual offset in the address */
    VirtualAddress = (PVOID)((ULONG_PTR)BaseAddress +
                             BYTE_OFFSET(PhysicalAddress.LowPart));

    /* If we are starting at the heap, move the heap */
    if (BaseAddress == HalpHeapStart)
    {
        /* Past this allocation */
        HalpHeapStart = (PVOID)((ULONG_PTR)BaseAddress + (PageCount * PAGE_SIZE));
    }

    /* Loop pages that can be mapped */
    while (UsedPages--)
    {
        /* Fill out the PTE */
        PointerPte = HalAddressToPte(BaseAddress);
        PointerPte->PageFrameNumber = (PFN_NUMBER)(PhysicalAddress.QuadPart >> PAGE_SHIFT);
        PointerPte->Valid = 1;
        PointerPte->Write = 1;

        /* Move to the next address */
        PhysicalAddress.QuadPart += PAGE_SIZE;
        BaseAddress = (PVOID)((ULONG_PTR)BaseAddress + PAGE_SIZE);
    }

    /* Flush the TLB and return the address */
    if (FlushCurrentTLB)
        HalpFlushTLB();

    return VirtualAddress;
}