Author: ros-arm-bringup
Date: Sat Jun 14 17:02:50 2008
New Revision: 33967
URL:
http://svn.reactos.org/svn/reactos?rev=33967&view=rev
Log:
- Fix stupid IRQL/Interrupt handling code that someone wrote ;):
- Get rid of KeSwapIrql -- both lower and higher IRQL handling was treated the same!
- We can now re-activate the assert in the IRQL code
- Disable interrupts before changing the interrupt mask!!!
- And re-enable them solely if they were enabled.
- Clear interrupts mask before setting a new one -- raising isn't always additive!
- Fix KiInterruptHandler to perform operations in the right order.
- Finish implementing interrupt exit code.
- Code KeArmStatusRegisterGet to read CPSR and interrupt status.
- Make debug prints a lot more readable and dont trying to acquire the stack during pool
allocations.
- Setup the clock interval timer!!!
- This code regresses progress but makes stuf fwork right. We'll get better after
implementing the stall interrupt.
Modified:
trunk/reactos/hal/hal/hal_arm.def
trunk/reactos/hal/halarm/generic/hal.c
trunk/reactos/include/reactos/armddk.h
trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h
trunk/reactos/ntoskrnl/include/internal/arm/ke.h
trunk/reactos/ntoskrnl/ke/arm/kiinit.c
trunk/reactos/ntoskrnl/ke/arm/trap.s
trunk/reactos/ntoskrnl/ke/arm/trapc.c
trunk/reactos/ntoskrnl/mm/arm/stubs.c
trunk/reactos/ntoskrnl/mm/ppool.c
Modified: trunk/reactos/hal/hal/hal_arm.def
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/hal/hal_arm.def?rev=33…
==============================================================================
--- trunk/reactos/hal/hal/hal_arm.def [iso-8859-1] (original)
+++ trunk/reactos/hal/hal/hal_arm.def [iso-8859-1] Sat Jun 14 17:02:50 2008
@@ -81,7 +81,6 @@
KeFlushWriteBuffer
KeGetCurrentIrql
KeLowerIrql
-KeSwapIrql
KeQueryPerformanceCounter
KeRaiseIrql
KeRaiseIrqlToDpcLevel
Modified: trunk/reactos/hal/halarm/generic/hal.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/hal/halarm/generic/hal.c?r…
==============================================================================
--- trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] (original)
+++ trunk/reactos/hal/halarm/generic/hal.c [iso-8859-1] Sat Jun 14 17:02:50 2008
@@ -392,7 +392,6 @@
if (strstr(CommandLine, "BREAK")) DbgBreakPoint();
}
}
-
//
// INTs on the Versatile:
@@ -491,6 +490,14 @@
#define VICSOFTINT (PVOID)0xE0040018
#define VICSOFTINTCLEAR (PVOID)0xE004001C
+#define TIMER_LOAD (PVOID)0xE00E2000
+#define TIMER_VALUE (PVOID)0xE00E2004
+#define TIMER_CONTROL (PVOID)0xE00E2008
+#define TIMER_INT_CLEAR (PVOID)0xE00E200C
+#define TIMER_INT_STATUS (PVOID)0xE00E2010
+#define TIMER_INT_MASK (PVOID)0xE00E2014
+#define TIMER_BACKGROUND_LOAD (PVOID)0xE00E2018
+
#define _clz(a) \
({ ULONG __value, __arg = (a); \
@@ -513,6 +520,11 @@
HalpStallInterrupt(VOID)
{
DPRINT1("STALL INTERRUPT!!!\n");
+
+ //
+ // Clear the interrupt
+ //
+ WRITE_REGISTER_ULONG(TIMER_INT_CLEAR, 1);
while (TRUE);
}
@@ -520,20 +532,39 @@
HalpInitializeInterrupts(VOID)
{
PKPCR Pcr = (PKPCR)KeGetPcr();
+ ULONG ClockInterval;
//
// Fill out the IRQL mappings
//
RtlCopyMemory(Pcr->IrqlTable, HalpIrqlTable, sizeof(Pcr->IrqlTable));
RtlCopyMemory(Pcr->IrqlMask, HalpMaskTable, sizeof(Pcr->IrqlMask));
-// Pcr->IrqlTable = HalpIrqlTable;
- // Pcr->IrqlMask = HalpMaskTable;
//
// Setup the clock and profile interrupt
//
Pcr->InterruptRoutine[CLOCK2_LEVEL] = HalpStallInterrupt;
// Pcr->InterruptRoutine[PROFILE_LEVEL] = HalpCountInterrupt;
+
+ //
+ // Configure the interval to 10ms
+ // (INTERVAL (10ms) * TIMCLKfreq (1MHz))
+ // --------------------------------------- == 10^4
+ // (TIMCLKENXdiv (1) * PRESCALEdiv (1))
+ //
+ ClockInterval = 0x2710;
+
+ //
+ // Enable the timer
+ //
+ WRITE_REGISTER_ULONG(TIMER_LOAD, ClockInterval);
+ WRITE_REGISTER_ULONG(TIMER_CONTROL,
+ 0 << 0 | // wrapping mode
+ 1 << 1 | // 32-bit mode
+ 0 << 2 | // 0 stages of prescale, divided by 1
+ 1 << 5 | // enable interrupt
+ 1 << 6 | // periodic mode
+ 1 << 7); // enable it
}
ULONG HalpCurrentTimeIncrement, HalpNextTimeIncrement, HalpNextIntervalCount;
@@ -1068,11 +1099,14 @@
KfLowerIrql(IN KIRQL NewIrql)
{
ULONG InterruptMask;
+ ARM_STATUS_REGISTER Flags;
PKPCR Pcr = (PKPCR)KeGetPcr();
//
// Validate the new IRQL
//
+ Flags = KeArmStatusRegisterGet();
+ _disable();
ASSERT(NewIrql <= Pcr->CurrentIrql);
//
@@ -1084,7 +1118,7 @@
// Setup the interrupt mask for this IRQL
//
InterruptMask = KeGetPcr()->IrqlTable[NewIrql];
- DPRINT1("New IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
+ DPRINT1("[LOWER] IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
//
// Clear interrupts associated to the old IRQL
@@ -1101,6 +1135,7 @@
// Save the new IRQL
//
Pcr->CurrentIrql = NewIrql;
+ if (!Flags.IrqDisable) _enable();
}
KIRQL
@@ -1109,11 +1144,14 @@
{
KIRQL OldIrql;
ULONG InterruptMask;
+ ARM_STATUS_REGISTER Flags;
PKPCR Pcr = (PKPCR)KeGetPcr();
//
// Save the current IRQL
//
+ Flags = KeArmStatusRegisterGet();
+ _disable();
OldIrql = Pcr->CurrentIrql;
//
@@ -1125,8 +1163,13 @@
// Setup the interrupt mask for this IRQL
//
InterruptMask = KeGetPcr()->IrqlTable[NewIrql];
- DPRINT1("New IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
- //ASSERT(NewIrql >= OldIrql);
+ DPRINT1("[RAISE] IRQL: %d InterruptMask: %lx\n", NewIrql, InterruptMask);
+ ASSERT(NewIrql >= OldIrql);
+
+ //
+ // Clear interrupts associated to the old IRQL
+ //
+ WRITE_REGISTER_ULONG(VICINTENCLEAR, 0xFFFFFFFF);
//
// Set the new interrupt mask
@@ -1138,6 +1181,7 @@
// Save the new IRQL
//
Pcr->CurrentIrql = NewIrql;
+ if (!Flags.IrqDisable) _enable();
return OldIrql;
}
@@ -1268,15 +1312,6 @@
}
KIRQL
-KeSwapIrql(IN KIRQL Irql)
-{
- //
- // Call the generic routine
- //
- return KfRaiseIrql(Irql);
-}
-
-KIRQL
KeRaiseIrqlToDpcLevel(VOID)
{
//
@@ -1317,7 +1352,6 @@
//
HalpTestCleanSupported = (IdRegister.Architecture == 6);
}
-
VOID
HalSweepDcache(VOID)
Modified: trunk/reactos/include/reactos/armddk.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/armddk.h?r…
==============================================================================
--- trunk/reactos/include/reactos/armddk.h [iso-8859-1] (original)
+++ trunk/reactos/include/reactos/armddk.h [iso-8859-1] Sat Jun 14 17:02:50 2008
@@ -128,7 +128,12 @@
// IRQL Support on ARM is similar to MIPS/ALPHA
//
KIRQL
-KeSwapIrql(
+KfRaiseIrql(
+ IN KIRQL NewIrql
+);
+
+VOID
+KfLowerIrql(
IN KIRQL NewIrql
);
@@ -142,8 +147,8 @@
VOID
);
-#define KeLowerIrql(NewIrql) KeSwapIrql(NewIrql)
-#define KeRaiseIrql(NewIrql, OldIrql) *(OldIrql) = KeSwapIrql(NewIrql)
+#define KeLowerIrql(NewIrql) KfLowerIrql(NewIrql)
+#define KeRaiseIrql(NewIrql, OldIrql) *(OldIrql) = KfRaiseIrql(NewIrql)
//
// Cache clean and flush
Modified: trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/arm/intrin_i.h [iso-8859-1] Sat Jun 14
17:02:50 2008
@@ -74,6 +74,14 @@
return Value;
}
+FORCEINLINE
+ARM_STATUS_REGISTER
+KeArmStatusRegisterGet(VOID)
+{
+ ARM_STATUS_REGISTER Value;
+ __asm__ __volatile__ ("mrs %0, cpsr" : "=r"(Value.AsUlong) : :
"cc");
+ return Value;
+}
FORCEINLINE
VOID
Modified: trunk/reactos/ntoskrnl/include/internal/arm/ke.h
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/include/internal/…
==============================================================================
--- trunk/reactos/ntoskrnl/include/internal/arm/ke.h [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/include/internal/arm/ke.h [iso-8859-1] Sat Jun 14 17:02:50
2008
@@ -23,6 +23,31 @@
};
ULONG AsUlong;
} ARM_TTB_REGISTER;
+
+typedef union _ARM_STATUS_REGISTER
+{
+
+ struct
+ {
+ ULONG Mode:5;
+ ULONG State:1;
+ ULONG FiqDisable:1;
+ ULONG IrqDisable:1;
+ ULONG ImpreciseAbort:1;
+ ULONG Endianness:1;
+ ULONG Sbz:6;
+ ULONG GreaterEqual:4;
+ ULONG Sbz1:4;
+ ULONG Java:1;
+ ULONG Sbz2:2;
+ ULONG StickyOverflow:1;
+ ULONG Overflow:1;
+ ULONG CarryBorrowExtend:1;
+ ULONG Zero:1;
+ ULONG NegativeLessThan:1;
+ };
+ ULONG AsUlong;
+} ARM_STATUS_REGISTER;
typedef union _ARM_DOMAIN_REGISTER
{
Modified: trunk/reactos/ntoskrnl/ke/arm/kiinit.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/kiinit.c?r…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/kiinit.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/arm/kiinit.c [iso-8859-1] Sat Jun 14 17:02:50 2008
@@ -273,7 +273,7 @@
//
// Raise to Dispatch
//
- KeSwapIrql(DISPATCH_LEVEL);
+ KfRaiseIrql(DISPATCH_LEVEL);
//
// Set the Idle Priority to 0. This will jump into Phase 1
@@ -290,7 +290,7 @@
//
// Raise back to HIGH_LEVEL
//
- KeSwapIrql(HIGH_LEVEL);
+ KfRaiseIrql(HIGH_LEVEL);
}
VOID
Modified: trunk/reactos/ntoskrnl/ke/arm/trap.s
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trap.s?rev…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/trap.s [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/arm/trap.s [iso-8859-1] Sat Jun 14 17:02:50 2008
@@ -323,10 +323,32 @@
IntExit:
//
- // FIXME: TODO
- //
- b .
-
+ // Skip IRQL
+ //
+ add sp, sp, #(4)
+
+ //
+ // Get the SPSR and restore it
+ //
+ ldr r0, [sp], #4
+ msr spsr_all, r0
+
+ //
+ // Restore the registers
+ //
+ ldmia sp, {r0-r14}^
+ mov r0, r0
+
+ //
+ // Advance in the trap frame
+ //
+ add sp, sp, #(4*15)
+
+ //
+ // Restore program execution state
+ //
+ ldmia sp, {sp, lr, pc}^
+ b .
ENTRY_END KiInterruptException
NESTED_ENTRY KiFastInterruptException
Modified: trunk/reactos/ntoskrnl/ke/arm/trapc.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/ke/arm/trapc.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/ke/arm/trapc.c [iso-8859-1] Sat Jun 14 17:02:50 2008
@@ -199,9 +199,7 @@
// Check if we have a thread to swap to
//
if (Pcr->Prcb->NextThread)
- {
- DPRINT1("Switching threads!\n");
-
+ {
//
// Next is now current
//
@@ -219,7 +217,6 @@
//
// Make the old thread ready
//
- DPRINT1("Queueing the ready thread\n");
KxQueueReadyThread(OldThread, Pcr->Prcb);
//
@@ -241,6 +238,12 @@
KIRQL OldIrql, Irql;
ULONG InterruptCause, InterruptMask;
PKPCR Pcr;
+
+ //
+ // Increment interrupt count
+ //
+ Pcr = (PKPCR)KeGetPcr();
+ Pcr->Prcb->InterruptCount++;
//
// Get the old IRQL
@@ -252,62 +255,49 @@
// Get the interrupt source
//
InterruptCause = HalGetInterruptSource();
- DPRINT1("Interrupt (%x) @ %p %p\n", InterruptCause, TrapFrame->SvcLr,
TrapFrame->Pc);
- DPRINT1("OLD IRQL: %x\n", OldIrql);
+ DPRINT1("[INT] (%x) @ %p %p\n", InterruptCause, TrapFrame->SvcLr,
TrapFrame->Pc);
//
// Get the new IRQL and Interrupt Mask
//
- Pcr = (PKPCR)KeGetPcr();
Irql = Pcr->IrqlMask[InterruptCause];
InterruptMask = Pcr->IrqlTable[Irql];
- DPRINT1("IRQL (%x) MASK (%x)\n", Irql, InterruptMask);
-
- //
- // Make sure the IRQL is valid
- //
- if (OldIrql < Irql)
- {
- //
- // We should just return, probably
- //
- DPRINT1("IRQL Race!\n");
- while (TRUE);
- }
-
+
+ //
+ // Raise to the new IRQL
+ //
+ KfRaiseIrql(Irql);
+
//
// Check if this interrupt is at DISPATCH or higher
//
if (Irql > DISPATCH_LEVEL)
- {
- //
- // ISR Handling Code
- //
- DPRINT1("ISR!\n");
- while (TRUE);
- }
-
- //
- // We know this is APC or DPC.
- // Clear the software interrupt.
- // Reenable interrupts and update the IRQL
- //
- HalClearSoftwareInterrupt(Irql);
+ {
+ //
+ // FIXME: Switch to interrupt stack
+ //
+ DPRINT1("[ISR]\n");
+ }
+ else
+ {
+ //
+ // We know this is APC or DPC.
+ //
+ DPRINT1("[DPC/APC]\n");
+ HalClearSoftwareInterrupt(Irql);
+ }
+
+ //
+ // Call the registered interrupt routine
+ //
+ Pcr->InterruptRoutine[Irql]();
+ DPRINT1("[ISR RETURN]\n");
+
+ //
+ // Re-enable interrupts and return IRQL
+ //
+ KeLowerIrql(OldIrql);
_enable();
- Pcr->CurrentIrql = Irql;
-
- //
- // Increment interrupt count
- //
- Pcr->Prcb->InterruptCount++;
-
- //
- // Call the registered interrupt routine
- //
- DPRINT1("Calling handler\n");
- Pcr->InterruptRoutine[Irql]();
- DPRINT1("Done!\n");
- while (TRUE);
}
NTSTATUS
@@ -315,8 +305,8 @@
{
NTSTATUS Status;
PVOID Address = (PVOID)KeArmFaultAddressRegisterGet();
- DPRINT1("Data Abort (%x) @ %p %p\n", Address, TrapFrame->SvcLr,
TrapFrame->Pc);
- DPRINT1("Abort Reason: %d\n", KeArmFaultStatusRegisterGet());
+ DPRINT1("[ABORT] (%x) @ %p/%p/%p\n",
+ KeArmFaultStatusRegisterGet(), Address, TrapFrame->SvcLr,
TrapFrame->Pc);
//
// Check if this is a page fault
@@ -327,10 +317,10 @@
Address,
KernelMode,
TrapFrame);
- DPRINT1("Status: %x\n", Status);
if (Status == STATUS_SUCCESS) return Status;
}
+ UNIMPLEMENTED;
while (TRUE);
return STATUS_SUCCESS;
}
@@ -358,7 +348,7 @@
// Get the system call ID
//
Id = Instruction & 0xFFFFF;
- DPRINT1("System call (%X) from thread: %p (%d) \n", Id, Thread,
Thread->PreviousMode);
+ DPRINT1("[SWI] (%x) %p (%d) \n", Id, Thread, Thread->PreviousMode);
//
// Get the descriptor table
@@ -367,7 +357,6 @@
Offset = ((Id >> SERVICE_TABLE_SHIFT) & SERVICE_TABLE_MASK);
ServiceTable += Offset;
DescriptorTable = (PVOID)ServiceTable;
- DPRINT1("Descriptor Table: %p (Count %d)\n", DescriptorTable,
DescriptorTable->Limit);
//
// Get the service call number and validate it
@@ -386,8 +375,6 @@
// Save the function responsible for handling this system call
//
SystemCall = (PVOID)DescriptorTable->Base[Number];
- DPRINT1("Handler: %p\n", SystemCall);
- DPRINT1("NtClose: %p\n", NtClose);
//
// Check if this is a GUI call
@@ -404,10 +391,8 @@
//
// Check how many arguments this system call takes
//
- DPRINT1("Number: %d\n", Number);
ArgumentCount = DescriptorTable->Number[Number] / 4;
ASSERT(ArgumentCount <= 20);
- DPRINT1("Argument Count: %d\n", ArgumentCount);
//
// Copy the register-arguments first
@@ -421,7 +406,6 @@
//
Arguments[i] = *Argument;
Argument++;
- DPRINT1("Argument %d: %x\n", i, Arguments[i]);
}
//
@@ -432,7 +416,6 @@
//
// FIXME: Validate the user stack
//
- DPRINT1("User stack: %p\n", TrapFrame->UserSp);
//
// Copy the rest
@@ -445,7 +428,6 @@
//
Arguments[i] = *Argument;
Argument++;
- DPRINT1("Argument %d: %x\n", i, Arguments[i]);
}
}
@@ -461,7 +443,6 @@
PKTHREAD Thread;
KPROCESSOR_MODE PreviousMode;
ULONG Instruction;
- DPRINT1("SWI @ %p %p \n", TrapFrame->Pc, TrapFrame->UserLr);
//
// Get the current thread
Modified: trunk/reactos/ntoskrnl/mm/arm/stubs.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/arm/stubs.c?re…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/arm/stubs.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/arm/stubs.c [iso-8859-1] Sat Jun 14 17:02:50 2008
@@ -350,8 +350,7 @@
MMPTE TempPte, TempPde;
NTSTATUS Status;
PFN_NUMBER Pfn;
- DPRINT1("MmCreateVirtualMappingForKernel(%x, %x, %x, %d)\n",
- Address, Protection, *Pages, PageCount);
+ DPRINT1("[KMAP]: %p %d\n", Address, PageCount);
ASSERT(Address >= MmSystemRangeStart);
//
@@ -466,9 +465,6 @@
IN PPFN_TYPE Pages,
IN ULONG PageCount)
{
- DPRINT1("MmCreateVirtualMappingUnsafe(%p %x, %x, %x, %d)\n",
- Process, Address, Protection, *Pages, PageCount);
-
//
// Are we only handling the kernel?
//
@@ -499,9 +495,7 @@
IN ULONG PageCount)
{
ULONG i;
- DPRINT1("MmCreateVirtualMapping(%p %x, %x, %x, %d)\n",
- Process, Address, Protection, *Pages, PageCount);
-
+
//
// Loop each page
//
@@ -556,7 +550,6 @@
{
PHYSICAL_ADDRESS PhysicalAddress = {{0}};
PMMPTE PointerPte;
- DPRINT1("MmGetPhysicalAddress(%lx)\n", Address);
//
// Early boot PCR check
@@ -570,7 +563,6 @@
ASSERT(PointerPte->u.Hard.L1.Section.Type == SectionPte);
PhysicalAddress.QuadPart = PointerPte->u.Hard.L1.Section.BaseAddress;
PhysicalAddress.QuadPart <<= CPT_SHIFT;
- DPRINT1("Base: %p\n", PhysicalAddress.LowPart);
PhysicalAddress.LowPart += BYTE_OFFSET(Address);
return PhysicalAddress;
}
@@ -605,7 +597,6 @@
PMMPTE PointerPte, FirstPte, LastPte;
MMPTE TempPte;
PVOID Address;
- DPRINT1("MmCreateHyperspaceMapping(%lx)\n", Page);
//
// Loop hyperspace PTEs (1MB)
@@ -650,7 +641,7 @@
//
Address = HYPER_SPACE + ((PointerPte - FirstPte) * PAGE_SIZE);
KiFlushSingleTb(FALSE, Address);
- DPRINT1("MmCreateHyperspaceMapping(%lx)\n", Address);
+ DPRINT1("[HMAP]: %p %lx\n", Address, Page);
return Address;
}
@@ -660,7 +651,7 @@
{
PFN_TYPE Pfn;
PMMPTE PointerPte;
- DPRINT1("MmDeleteHyperspaceMapping(%lx)\n", Address);
+ DPRINT1("[HUNMAP]: %p\n", Address);
//
// Get the PTE
@@ -740,7 +731,6 @@
PHYSICAL_ADDRESS BoundaryAddressMultiple;
PVOID BaseAddress;
NTSTATUS Status;
- DPRINT1("MiInitPageDirectoryMap()\n");
//
// Create memory area for the PTE area
Modified: trunk/reactos/ntoskrnl/mm/ppool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ppool.c?rev=33…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ppool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ppool.c [iso-8859-1] Sat Jun 14 17:02:50 2008
@@ -29,7 +29,12 @@
#define R_PRINT_ADDRESS(addr) KeRosPrintAddress(addr)
#define R_PANIC() KeBugCheck(0)
#define R_DEBUG DbgPrint
+
+#ifdef _ARM_
+#define R_GET_STACK_FRAMES(ptr,cnt)
+#else
#define R_GET_STACK_FRAMES(ptr,cnt) RtlWalkFrameChain((PVOID*)ptr,cnt, 0)
+#endif
#include "rpoolmgr.h"