Author: cgutman
Date: Tue Mar 27 06:26:38 2012
New Revision: 56242
URL: http://svn.reactos.org/svn/reactos?rev=56242&view=rev
Log:
[TXTSETUP]
- Add *PNP0A08
[ACPI]
- Handle the PNP0A08 in a couple of missed cases
- Finally, PCI should work on systems that use the new PNP0A08 ID for identifying a PCI Express root bus
Modified:
trunk/reactos/boot/bootdata/txtsetup.sif
trunk/reactos/drivers/bus/acpi/buspdo.c
Modified: trunk/reactos/boot/bootdata/txtsetup.sif
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/boot/bootdata/txtsetup.sif…
==============================================================================
--- trunk/reactos/boot/bootdata/txtsetup.sif [iso-8859-1] (original)
+++ trunk/reactos/boot/bootdata/txtsetup.sif [iso-8859-1] Tue Mar 27 06:26:38 2012
@@ -62,6 +62,7 @@
[HardwareIdsDatabase]
;*PNP0A00 = isapnp
*PNP0A03 = pci
+*PNP0A08 = pci
*PNP0C08 = acpi
;PCI\CC_0601 = isapnp
PCI\CC_0604 = pci
Modified: trunk/reactos/drivers/bus/acpi/buspdo.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/drivers/bus/acpi/buspdo.c?…
==============================================================================
--- trunk/reactos/drivers/bus/acpi/buspdo.c [iso-8859-1] (original)
+++ trunk/reactos/drivers/bus/acpi/buspdo.c [iso-8859-1] Tue Mar 27 06:26:38 2012
@@ -594,7 +594,8 @@
Temp = L"ACPI Embedded Controller";
else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0B") != 0)
Temp = L"ACPI Fan";
- else if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0)
+ else if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 ||
+ wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0 )
Temp = L"PCI Root Bridge";
else if (wcsstr(DeviceData->HardwareIDs, L"PNP0C0A") != 0)
Temp = L"ACPI Battery";
@@ -666,7 +667,8 @@
/* A bus number resource is not included in the list of current resources
* for the root PCI bus so we manually query one here and if we find it
* we create a resource list and add a bus number descriptor to it */
- if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0)
+ if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 ||
+ wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0)
{
acpi_bus_get_device(DeviceData->AcpiHandle, &device);
@@ -1169,7 +1171,8 @@
}
/* Handle the PCI root manually */
- if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0)
+ if (wcsstr(DeviceData->HardwareIDs, L"PNP0A03") != 0 ||
+ wcsstr(DeviceData->HardwareIDs, L"PNP0A08") != 0)
{
return Irp->IoStatus.Status;
}
Author: sginsberg
Date: Mon Mar 26 13:00:16 2012
New Revision: 56234
URL: http://svn.reactos.org/svn/reactos?rev=56234&view=rev
Log:
[NTOS]
- Fix a crazy bug in KiTrap0EHandler, it didn't enable interrupts unless it trapped when interrupts were already disabled (during a page fault during page fault handling, for example). This seems to have worked because the old non-newcc version of MiReadPage appears to rely on a page fault to bring the paged out page in. Thanks Timo.
Modified:
trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
Modified: trunk/reactos/ntoskrnl/ke/i386/traphdlr.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/i386/traphdlr.…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/i386/traphdlr.c [iso-8859-1] Mon Mar 26 13:00:16 2012
@@ -1183,27 +1183,23 @@
while (TRUE);
}
}
-
+
/* Save CR2 */
Cr2 = __readcr2();
-
- /* HACK: Check if interrupts are disabled and enable them */
+
+ /* Enable interupts */
+ _enable();
+
+ /* Check if we faulted with interrupts disabled */
if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
{
- /* Enable interupts */
- _enable();
-#ifdef HACK_ABOVE_FIXED
- if (!(TrapFrame->EFlags & EFLAGS_INTERRUPT_MASK))
- {
- /* This is illegal */
- KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
- Cr2,
- -1,
- TrapFrame->ErrCode & 2 ? TRUE : FALSE,
- TrapFrame->Eip,
- TrapFrame);
- }
-#endif
+ /* This is completely illegal, bugcheck the system */
+ KeBugCheckWithTf(IRQL_NOT_LESS_OR_EQUAL,
+ Cr2,
+ -1,
+ TrapFrame->ErrCode & 2 ? TRUE : FALSE,
+ TrapFrame->Eip,
+ TrapFrame);
}
/* Check for S-LIST fault in kernel mode */
Author: sir_richard
Date: Mon Mar 26 07:41:47 2012
New Revision: 56233
URL: http://svn.reactos.org/svn/reactos?rev=56233&view=rev
Log:
[NTOS]: Add support for determining transition vs. demand zero faults (the former should not yet happen).
[NTOS]: Add a function for removing transition pages from either the standby or modified page lists (not yet used).
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pagfault.…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pagfault.c [iso-8859-1] Mon Mar 26 07:41:47 2012
@@ -446,6 +446,151 @@
NTSTATUS
NTAPI
+MiResolveTransitionFault(IN PVOID FaultingAddress,
+ IN PMMPTE PointerPte,
+ IN PEPROCESS CurrentProcess,
+ IN KIRQL OldIrql,
+ OUT PVOID *InPageBlock)
+{
+ PFN_NUMBER PageFrameIndex;
+ PMMPFN Pfn1;
+ MMPTE TempPte;
+ PMMPTE PointerToPteForProtoPage;
+ USHORT NewRefCount;
+ DPRINT1("Transition fault on 0x%p with PTE 0x%lx in process %s\n", FaultingAddress, PointerPte, CurrentProcess->ImageFileName);
+
+ /* Windowss does this check */
+ ASSERT(*InPageBlock == NULL);
+
+ /* ARM3 doesn't support this path */
+ ASSERT(OldIrql != MM_NOIRQL);
+
+ /* Capture the PTE and make sure it's in transition format */
+ TempPte = *PointerPte;
+ ASSERT((TempPte.u.Soft.Valid == 0) &&
+ (TempPte.u.Soft.Prototype == 0) &&
+ (TempPte.u.Soft.Transition == 1));
+
+ /* Get the PFN and the PFN entry */
+ PageFrameIndex = TempPte.u.Trans.PageFrameNumber;
+ DPRINT1("Transition PFN: %lx\n", PageFrameIndex);
+ Pfn1 = MiGetPfnEntry(PageFrameIndex);
+
+ /* One more transition fault! */
+ InterlockedIncrement(&KeGetCurrentPrcb()->MmTransitionCount);
+
+ /* This is from ARM3 -- Windows normally handles this here */
+ ASSERT(Pfn1->u4.InPageError == 0);
+
+ /* Not supported in ARM3 */
+ ASSERT(Pfn1->u3.e1.ReadInProgress == 0);
+
+ /* Windows checks there's some free pages and this isn't an in-page error */
+ ASSERT(MmAvailablePages >= 0);
+ ASSERT(Pfn1->u4.InPageError == 0);
+
+ /* Was this a transition page in the valid list, or free/zero list? */
+ if (Pfn1->u3.e1.PageLocation == ActiveAndValid)
+ {
+ /* All Windows does here is a bunch of sanity checks */
+ DPRINT1("Transition in active list\n");
+ ASSERT((Pfn1->PteAddress >= MiAddressToPte(MmPagedPoolStart)) &&
+ (Pfn1->PteAddress <= MiAddressToPte(MmPagedPoolEnd)));
+ ASSERT(Pfn1->u2.ShareCount != 0);
+ ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
+ }
+ else
+ {
+ /* Otherwise, the page is removed from its list */
+ DPRINT1("Transition page in free/zero list\n");
+ MiUnlinkPageFromList(Pfn1);
+
+ /* Windows does these checks -- perhaps a macro? */
+ ASSERT(Pfn1->u2.ShareCount == 0);
+ ASSERT(Pfn1->u2.ShareCount == 0);
+ ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
+
+ /* Check if this was a prototype PTE */
+ if ((Pfn1->u3.e1.PrototypePte == 1) &&
+ (Pfn1->OriginalPte.u.Soft.Prototype == 1))
+ {
+ DPRINT1("Prototype floating page not yet supported\n");
+ ASSERT(FALSE);
+ }
+
+ /* FIXME: Update counter */
+
+ /* We must be the first reference */
+ NewRefCount = InterlockedIncrement16((PSHORT)&Pfn1->u3.e2.ReferenceCount);
+ ASSERT(NewRefCount == 1);
+ }
+
+ /* At this point, there should no longer be any in-page errors */
+ ASSERT(Pfn1->u4.InPageError == 0);
+
+ /* Check if this was a PFN with no more share references */
+ if (Pfn1->u2.ShareCount == 0)
+ {
+ /* Windows checks for these... maybe a macro? */
+ ASSERT(Pfn1->u3.e2.ReferenceCount != 0);
+ ASSERT(Pfn1->u2.ShareCount == 0);
+
+ /* Was this the last active reference to it */
+ DPRINT1("Page share count is zero\n");
+ if (Pfn1->u3.e2.ReferenceCount == 1)
+ {
+ /* The page should be leaking somewhere on the free/zero list */
+ DPRINT1("Page reference count is one\n");
+ ASSERT(Pfn1->u3.e1.PageLocation != ActiveAndValid);
+ if ((Pfn1->u3.e1.PrototypePte == 1) &&
+ (Pfn1->OriginalPte.u.Soft.Prototype == 1))
+ {
+ /* Do extra processing if it was a prototype page */
+ DPRINT1("Prototype floating page not yet supported\n");
+ ASSERT(FALSE);
+ }
+
+ /* FIXME: Update counter */
+ }
+ }
+
+ /* Bump the share count and make the page valid */
+ Pfn1->u2.ShareCount++;
+ Pfn1->u3.e1.PageLocation = ActiveAndValid;
+
+ /* Prototype PTEs are in paged pool, which itself might be in transition */
+ if (FaultingAddress >= MmSystemRangeStart)
+ {
+ /* Check if this is a paged pool PTE in transition state */
+ PointerToPteForProtoPage = MiAddressToPte(PointerPte);
+ TempPte = *PointerToPteForProtoPage;
+ if ((TempPte.u.Hard.Valid == 0) && (TempPte.u.Soft.Transition == 1))
+ {
+ /* This isn't yet supported */
+ DPRINT1("Double transition fault not yet supported\n");
+ ASSERT(FALSE);
+ }
+ }
+
+ /* Build the transition PTE -- maybe a macro? */
+ ASSERT(PointerPte->u.Hard.Valid == 0);
+ ASSERT(PointerPte->u.Trans.Prototype == 0);
+ ASSERT(PointerPte->u.Trans.Transition == 1);
+ TempPte.u.Long = (PointerPte->u.Long & ~0xFFF) |
+ (MmProtectToPteMask[PointerPte->u.Trans.Protection]) |
+ MiDetermineUserGlobalPteMask(PointerPte);
+
+ /* FIXME: Set dirty bit */
+
+ /* Write the valid PTE */
+ MI_WRITE_VALID_PTE(PointerPte, TempPte);
+
+ /* Return success */
+ return STATUS_PAGE_FAULT_TRANSITION;
+}
+
+NTSTATUS
+NTAPI
MiResolveProtoPteFault(IN BOOLEAN StoreInstruction,
IN PVOID Address,
IN PMMPTE PointerPte,
@@ -457,10 +602,11 @@
IN KIRQL OldIrql,
IN PVOID TrapInformation)
{
- MMPTE TempPte;
+ MMPTE TempPte, PteContents;
PMMPFN Pfn1;
PFN_NUMBER PageFrameIndex;
NTSTATUS Status;
+ PVOID InPageBlock = NULL;
/* Must be called with an invalid, prototype PTE, with the PFN lock held */
ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
@@ -497,19 +643,50 @@
return STATUS_ACCESS_VIOLATION;
}
- /* This is the only thing we support right now */
- ASSERT(TempPte.u.Soft.PageFileHigh == 0);
- ASSERT(TempPte.u.Proto.ReadOnly == 0);
- ASSERT(PointerPte > MiHighestUserPte);
+ /* Check for access rights on the PTE proper */
+ PteContents = *PointerPte;
+ if (PteContents.u.Soft.PageFileHigh != MI_PTE_LOOKUP_NEEDED)
+ {
+ if (!PteContents.u.Proto.ReadOnly)
+ {
+ /* FIXME: CHECK FOR ACCESS AND COW */
+ }
+ }
+ else
+ {
+ /* FIXME: Should check for COW */
+ }
+
+ /* Check for clone PTEs */
+ if (PointerPte <= MiHighestUserPte) ASSERT(Process->CloneRoot == NULL);
+
+ /* We don't support mapped files yet */
ASSERT(TempPte.u.Soft.Prototype == 0);
- ASSERT(TempPte.u.Soft.Transition == 0);
-
- /* Resolve the demand zero fault */
- Status = MiResolveDemandZeroFault(Address,
- PointerProtoPte,
- Process,
- OldIrql);
- ASSERT(NT_SUCCESS(Status));
+
+ /* We might however have transition PTEs */
+ if (TempPte.u.Soft.Transition == 1)
+ {
+ /* Resolve the transition fault */
+ ASSERT(OldIrql != MM_NOIRQL);
+ Status = MiResolveTransitionFault(Address,
+ PointerProtoPte,
+ Process,
+ OldIrql,
+ &InPageBlock);
+ ASSERT(NT_SUCCESS(Status));
+ }
+ else
+ {
+ /* We also don't support paged out pages */
+ ASSERT(TempPte.u.Soft.PageFileHigh == 0);
+
+ /* Resolve the demand zero fault */
+ Status = MiResolveDemandZeroFault(Address,
+ PointerProtoPte,
+ Process,
+ OldIrql);
+ ASSERT(NT_SUCCESS(Status));
+ }
/* Complete the prototype PTE fault -- this will release the PFN lock */
ASSERT(PointerPte->u.Hard.Valid == 0);
Modified: trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c
URL: http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/pfnlist.c [iso-8859-1] Mon Mar 26 07:41:47 2012
@@ -225,6 +225,124 @@
// MI_PFN_CURRENT_USAGE = MI_USAGE_NOT_SET;
// memcpy(MI_PFN_CURRENT_PROCESS_NAME, "Not Set", 16);
#endif
+}
+
+VOID
+NTAPI
+MiUnlinkPageFromList(IN PMMPFN Pfn)
+{
+ PMMPFNLIST ListHead;
+ PFN_NUMBER OldFlink, OldBlink;
+
+ /* Make sure the PFN lock is held */
+ ASSERT(KeGetCurrentIrql() == DISPATCH_LEVEL);
+
+ /* ARM3 should only call this for dead pages */
+ ASSERT(Pfn->u3.e2.ReferenceCount == 0);
+
+ /* Transition pages are supposed to be standby/modified/nowrite */
+ ListHead = MmPageLocationList[Pfn->u3.e1.PageLocation];
+ ASSERT(ListHead->ListName >= StandbyPageList);
+
+ /* Check if this was standby, or modified */
+ if (ListHead == &MmStandbyPageListHead)
+ {
+ /* Should not be a ROM page */
+ ASSERT(Pfn->u3.e1.Rom == 0);
+
+ /* Get the exact list */
+ ListHead = &MmStandbyPageListByPriority[Pfn->u4.Priority];
+
+ /* See if we hit any thresholds */
+ if (MmAvailablePages == MmHighMemoryThreshold)
+ {
+ /* Clear the high memory event */
+ KeClearEvent(MiHighMemoryEvent);
+ }
+ else if (MmAvailablePages == MmLowMemoryThreshold)
+ {
+ /* Signal the low memory event */
+ KeSetEvent(MiLowMemoryEvent, 0, FALSE);
+ }
+
+ /* Decrease transition page counter */
+ ASSERT(Pfn->u3.e1.PrototypePte == 1); /* Only supported ARM3 case */
+ MmTransitionSharedPages--;
+
+ /* One less page */
+ if (--MmAvailablePages < MmMinimumFreePages)
+ {
+ /* FIXME: Should wake up the MPW and working set manager, if we had one */
+ DPRINT1("Running low on pages: %d remaining\n", MmAvailablePages);
+
+ /* Call RosMm and see if it can release any pages for us */
+ MmRebalanceMemoryConsumers();
+ }
+ }
+ else if (ListHead == &MmModifiedPageListHead)
+ {
+ /* Only shared memory (page-file backed) modified pages are supported */
+ ASSERT(Pfn->OriginalPte.u.Soft.Prototype == 0);
+
+ /* Decrement the counters */
+ ListHead->Total--;
+ MmTotalPagesForPagingFile--;
+
+ /* Pick the correct colored list */
+ ListHead = &MmModifiedPageListByColor[0];
+
+ /* Decrease transition page counter */
+ ASSERT(Pfn->u3.e1.PrototypePte == 1); /* Only supported ARM3 case */
+ MmTransitionSharedPages--;
+ }
+ else if (ListHead == &MmModifiedNoWritePageListHead)
+ {
+ /* List not yet supported */
+ ASSERT(FALSE);
+ }
+
+ /* Nothing should be in progress and the list should not be empty */
+ ASSERT(Pfn->u3.e1.WriteInProgress == 0);
+ ASSERT(Pfn->u3.e1.ReadInProgress == 0);
+ ASSERT(ListHead->Total != 0);
+
+ /* Get the forward and back pointers */
+ OldFlink = Pfn->u1.Flink;
+ OldBlink = Pfn->u2.Blink;
+
+ /* Check if the next entry is the list head */
+ if (OldFlink != LIST_HEAD)
+ {
+ /* It is not, so set the backlink of the actual entry, to our backlink */
+ MI_PFN_ELEMENT(OldFlink)->u2.Blink = OldBlink;
+ }
+ else
+ {
+ /* Set the list head's backlink instead */
+ ListHead->Blink = OldBlink;
+ }
+
+ /* Check if the back entry is the list head */
+ if (OldBlink != LIST_HEAD)
+ {
+ /* It is not, so set the backlink of the actual entry, to our backlink */
+ MI_PFN_ELEMENT(OldBlink)->u1.Flink = OldFlink;
+ }
+ else
+ {
+ /* Set the list head's backlink instead */
+ ListHead->Flink = OldFlink;
+ }
+
+ /* ReactOS Hack */
+ Pfn->OriginalPte.u.Long = 0;
+
+ /* We are not on a list anymore */
+ Pfn->u1.Flink = Pfn->u2.Blink = 0;
+ ASSERT_LIST_INVARIANT(ListHead);
+
+ /* Remove one entry from the list */
+ ListHead->Total--;
}
PFN_NUMBER