diff --git a/reactos/hal/hal/hal_arm.def b/reactos/hal/hal/hal_arm.def
index 3eae6a20af2..343bb68829e 100644
--- a/reactos/hal/hal/hal_arm.def
+++ b/reactos/hal/hal/hal_arm.def
@@ -42,6 +42,7 @@ HalGetAdapter
HalGetBusData
HalGetBusDataByOffset
HalGetEnvironmentVariable
+HalGetInterruptSource
HalGetInterruptVector
HalHandleNMI
HalInitSystem
diff --git a/reactos/hal/halarm/generic/hal.c b/reactos/hal/halarm/generic/hal.c
index 995c2d28d57..ff0d2de9cc1 100644
--- a/reactos/hal/halarm/generic/hal.c
+++ b/reactos/hal/halarm/generic/hal.c
@@ -414,7 +414,7 @@ HalpGetParameters(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
// CLOCK_LEVEL - 0x10 (everything disabled except 4)
// POWER_LEVEL, IPI_LEVEL, HIGH_LEVEL - 0x00 (everything disabled)
-ULONG HalpIrqlTable[] =
+ULONG HalpIrqlTable[HIGH_LEVEL + 1] =
{
0xFFFFFFFF, // IRQL 0 PASSIVE_LEVEL
0xFFFFFFFD, // IRQL 1 APC_LEVEL
@@ -450,6 +450,64 @@ ULONG HalpIrqlTable[] =
0x00, // IRQL 31 HIGH_LEVEL
};
+UCHAR HalpMaskTable[HIGH_LEVEL + 1] =
+{
+ PROFILE_LEVEL,
+ APC_LEVEL,
+ DISPATCH_LEVEL,
+ IPI_LEVEL,
+ CLOCK2_LEVEL,
+ 3,
+ 4,
+ 5,
+ 6,
+ 7,
+ 8,
+ 9,
+ 10,
+ 11,
+ 12,
+ 13,
+ 14,
+ 15,
+ 16,
+ 17,
+ 18,
+ 19,
+ 20,
+ 21,
+ 22,
+ 23,
+ 24,
+ 25,
+ 26,
+ 26,
+ 26
+};
+
+#define VICINTSTATUS (PVOID)0xE0040000
+#define VICINTENABLE (PVOID)0xE0040010
+#define VICINTENCLEAR (PVOID)0xE0040014
+#define VICSOFTINT (PVOID)0xE0040018
+#define VICSOFTINTCLEAR (PVOID)0xE004001C
+
+
+#define _clz(a) \
+({ ULONG __value, __arg = (a); \
+ asm ("clz\t%0, %1": "=r" (__value): "r" (__arg)); \
+ __value; })
+
+ULONG
+HalGetInterruptSource(VOID)
+{
+ ULONG InterruptStatus;
+
+ //
+ // Get the interrupt status, and return the highest bit set
+ //
+ InterruptStatus = READ_REGISTER_ULONG(VICINTSTATUS);
+ return 31 - _clz(InterruptStatus);
+}
VOID
HalpStallInterrupt(VOID)
@@ -461,20 +519,16 @@ HalpStallInterrupt(VOID)
VOID
HalpInitializeInterrupts(VOID)
{
- ULONG i;
PKPCR Pcr = (PKPCR)KeGetPcr();
//
// Fill out the IRQL mappings
//
- for (i = 0; i < (HIGH_LEVEL + 1); i++)
- {
- //
- // Save the valeue in the PCR
- //
- Pcr->IrqlTable[i] = HalpIrqlTable[i];
- }
-
+ 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
//
@@ -484,10 +538,6 @@ HalpInitializeInterrupts(VOID)
ULONG HalpCurrentTimeIncrement, HalpNextTimeIncrement, HalpNextIntervalCount;
-#define VICINTENABLE (PVOID)0xE0040010
-#define VICINTENCLEAR (PVOID)0xE0040014
-#define VICSOFTINT (PVOID)0xE0040018
-#define VICSOFTINTCLEAR (PVOID)0xE004001C
/*
* @implemented
@@ -714,14 +764,39 @@ HalRequestSoftwareInterrupt(IN KIRQL Request)
WRITE_REGISTER_ULONG(VICSOFTINT, Interrupt);
}
-VOID FASTCALL
-HalClearSoftwareInterrupt(
- IN KIRQL Request)
+VOID
+FASTCALL
+HalClearSoftwareInterrupt(IN KIRQL Request)
{
- UNIMPLEMENTED;
+ ULONG Interrupt = 0;
+
+ //
+ // Get the interrupt that maches this IRQL level
+ //
+ switch (Request)
+ {
+ case APC_LEVEL:
+
+ Interrupt = 1 << 1;
+ break;
+
+ case DISPATCH_LEVEL:
+
+ Interrupt = 1 << 2;
+ break;
+
+ default:
+
+ ASSERT(FALSE);
+ }
+
+ //
+ // Force a software interrupt
+ //
+ DPRINT1("About to kill interrupt mask: %d\n", Interrupt);
+ WRITE_REGISTER_ULONG(VICSOFTINTCLEAR, Interrupt);
}
-
VOID
NTAPI
HalReturnToFirmware(
diff --git a/reactos/include/ndk/arm/ketypes.h b/reactos/include/ndk/arm/ketypes.h
index cbb52eed4b9..10486e25b5a 100644
--- a/reactos/include/ndk/arm/ketypes.h
+++ b/reactos/include/ndk/arm/ketypes.h
@@ -78,8 +78,8 @@ typedef struct _KTRAP_FRAME
ULONG SvcSp;
ULONG SvcLr;
ULONG Pc;
-// UCHAR OldIrql;
-// UCHAR PreviousMode;
+ ULONG OldIrql;
+// UCHAR PreviousMode;
// ULONG Fpscr;
// ULONG FpExc;
// ULONG S[33];
diff --git a/reactos/include/psdk/intrin_arm.h b/reactos/include/psdk/intrin_arm.h
index 43808d2db7e..22395e8872e 100644
--- a/reactos/include/psdk/intrin_arm.h
+++ b/reactos/include/psdk/intrin_arm.h
@@ -83,6 +83,12 @@ static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volat
return a;
}
+
+static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
+{
+ return _InterlockedExchange(Target, Value);
+}
+
static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)
{
char x;
@@ -276,5 +282,13 @@ static __inline__ __attribute__((always_inline)) void _enable(void)
);
}
+#ifndef __MSVCRT__
+static __inline__ __attribute__((always_inline)) unsigned long _rotl(const unsigned long value, const unsigned char shift)
+{
+ return (((value) << ((int)(shift))) | ((value) >> (32 - (int)(shift))));
+}
+#endif
+
+
#endif
/* EOF */
diff --git a/reactos/include/reactos/armddk.h b/reactos/include/reactos/armddk.h
index fd51cfc13f5..e562106f697 100644
--- a/reactos/include/reactos/armddk.h
+++ b/reactos/include/reactos/armddk.h
@@ -53,7 +53,9 @@ typedef struct _KFLOATING_SAVE
// On ARM, it's actually readable from user-mode, much like KUSER_SHARED_DATA
//
#ifdef _WINNT_H
-#define PKINTERRUPT_ROUTINE PVOID // Hack!
+typedef
+VOID
+(*PKINTERRUPT_ROUTINE)(VOID);
#endif
typedef struct _KPCR
{
@@ -85,7 +87,7 @@ typedef struct _KPCR
PVOID InstructionBusError;
ULONG CachePolicy;
ULONG AlignedCachePolicy;
-// UCHAR IrqlMask[64];
+ UCHAR IrqlMask[HIGH_LEVEL + 1];
ULONG IrqlTable[HIGH_LEVEL + 1];
UCHAR CurrentIrql;
KAFFINITY SetMember;
diff --git a/reactos/lib/sdk/crt/string/scanf.c b/reactos/lib/sdk/crt/string/scanf.c
index 1612eeb33c4..e0ba480eb67 100644
--- a/reactos/lib/sdk/crt/string/scanf.c
+++ b/reactos/lib/sdk/crt/string/scanf.c
@@ -33,7 +33,7 @@
#define debugstr_a
#endif
-extern FILE _iob[];
+//extern FILE _iob[];
/* helper function for *scanf. Returns the value of character c in the
* given base, or -1 if the given character is not a digit of the base.
diff --git a/reactos/ntoskrnl/ex/resource.c b/reactos/ntoskrnl/ex/resource.c
index 25ed81d41f9..ad3e7c516a9 100644
--- a/reactos/ntoskrnl/ex/resource.c
+++ b/reactos/ntoskrnl/ex/resource.c
@@ -895,7 +895,7 @@ ExAcquireResourceSharedLite(IN PERESOURCE Resource,
{
KLOCK_QUEUE_HANDLE LockHandle;
ERESOURCE_THREAD Thread;
- POWNER_ENTRY Owner;
+ POWNER_ENTRY Owner = NULL;
BOOLEAN FirstEntryBusy;
/* Get the thread */
diff --git a/reactos/ntoskrnl/ke/arm/kiinit.c b/reactos/ntoskrnl/ke/arm/kiinit.c
index e92e4cc01cf..8c5c1e71010 100644
--- a/reactos/ntoskrnl/ke/arm/kiinit.c
+++ b/reactos/ntoskrnl/ke/arm/kiinit.c
@@ -142,7 +142,7 @@ KiInitializeKernel(IN PKPROCESS InitProcess,
//
// Point to the same template
//
- Pcr->InterruptRoutine[i] = &KxUnexpectedInterrupt.DispatchCode;
+ Pcr->InterruptRoutine[i] = (PVOID)&KxUnexpectedInterrupt.DispatchCode;
}
//
diff --git a/reactos/ntoskrnl/ke/arm/stubs_asm.s b/reactos/ntoskrnl/ke/arm/stubs_asm.s
index c5d12e463bf..ea6442f09b7 100644
--- a/reactos/ntoskrnl/ke/arm/stubs_asm.s
+++ b/reactos/ntoskrnl/ke/arm/stubs_asm.s
@@ -42,7 +42,6 @@ GENERATE_ARM_STUB RtlInitializeContext
//
// Internal Ke Arch-Specific Helpers
//
-GENERATE_ARM_STUB KiDispatchInterrupt
GENERATE_ARM_STUB KiSaveProcessorControlState
GENERATE_ARM_STUB KiInitializeUserApc
GENERATE_ARM_STUB KeDisableInterrupts
@@ -69,3 +68,4 @@ GENERATE_ARM_STUB DebugService2
GENERATE_ARM_STUB RtlpGetStackLimits
GENERATE_ARM_STUB KdpGdbStubInit
+GENERATE_ARM_STUB MmDbgTranslatePhysicalAddress
diff --git a/reactos/ntoskrnl/ke/arm/trap.s b/reactos/ntoskrnl/ke/arm/trap.s
index 77f1322b589..faf2c584d51 100644
--- a/reactos/ntoskrnl/ke/arm/trap.s
+++ b/reactos/ntoskrnl/ke/arm/trap.s
@@ -141,6 +141,11 @@
//
mov r2, sp
+ //
+ // Dummy OldIrql
+ //
+ //str r0, [sp, #-4]!
+
//
// Save the abort lr
//
@@ -217,6 +222,91 @@ AbortExit:
NESTED_ENTRY KiInterruptException
PROLOG_END KiInterruptException
+ //
+ // Fixup lr
+ //
+ sub lr, lr, #4
+
+ //
+ // Save the bottom 4 registers
+ //
+ stmdb sp, {r0-r3}
+
+ //
+ // Save the IRQ lr, sp, spsr, cpsr
+ //
+ mov r0, lr
+ mov r1, sp
+ mrs r2, cpsr
+ mrs r3, spsr
+
+ //
+ // Switch to SVC mode
+ //
+ bic r2, r2, #CPSR_MODES
+ orr r2, r2, #CPSR_SVC_MODE
+ msr cpsr_c, r2
+
+ //
+ // Save the SVC sp before we modify it
+ //
+ mov r2, sp
+
+ //
+ // Dummy OldIrql
+ //
+ //str r0, [sp, #-4]!
+
+ //
+ // Save the IRQ lr
+ //
+ str r0, [sp, #-4]!
+
+ //
+ // Save the SVC lr and sp
+ //
+ str lr, [sp, #-4]!
+ str r2, [sp, #-4]!
+
+ //
+ // Restore the saved SPSR
+ //
+ msr spsr_all, r3
+
+ //
+ // Restore our 4 registers
+ //
+ ldmdb r1, {r0-r3}
+
+ //
+ // Make space for the trap frame
+ //
+ sub sp, sp, #(4*15) // TrapFrameLength
+
+ //
+ // Save user-mode registers
+ //
+ stmia sp, {r0-r12}
+ add r0, sp, #(4*13)
+ stmia r0, {r13-r14}^
+ mov r0, r0
+
+ //
+ // Save SPSR
+ //
+ mrs r0, spsr_all
+ str r0, [sp, #-4]!
+
+ //
+ // Call the C handler
+ //
+ adr lr, IntExit
+ mov r0, sp
+ mov r1, #0
+ ldr pc, =KiInterruptHandler
+
+IntExit:
+
//
// FIXME: TODO
//
diff --git a/reactos/ntoskrnl/ke/arm/trapc.c b/reactos/ntoskrnl/ke/arm/trapc.c
index 3a3f67e4cbb..852d82fd97d 100644
--- a/reactos/ntoskrnl/ke/arm/trapc.c
+++ b/reactos/ntoskrnl/ke/arm/trapc.c
@@ -28,6 +28,166 @@ KiSystemCall(
/* FUNCTIONS ******************************************************************/
+ULONG
+HalGetInterruptSource(VOID);
+
+VOID FASTCALL
+HalClearSoftwareInterrupt(IN KIRQL Request);
+
+VOID
+KiDispatchInterrupt(VOID)
+{
+ PKPCR Pcr;
+ PKTHREAD NewThread, OldThread;
+
+ //
+ // Get the PCR and disable interrupts
+ //
+ Pcr = (PKPCR)KeGetPcr();
+ _disable();
+
+ //
+ //Check if we have to deliver DPCs, timers, or deferred threads
+ //
+ if ((Pcr->Prcb->DpcData[0].DpcQueueDepth) ||
+ (Pcr->Prcb->TimerRequest) ||
+ (Pcr->Prcb->DeferredReadyListHead.Next))
+ {
+ //
+ // FIXME: TODO
+ //
+ DPRINT1("DPC/Timer Delivery!\n");
+ while (TRUE);
+ }
+
+ //
+ // Re-enable interrupts
+ //
+ _enable();
+
+ //
+ // Check for quantum end
+ //
+ if (Pcr->Prcb->QuantumEnd)
+ {
+ //
+ // FIXME: TODO
+ //
+ DPRINT1("Quantum End!\n");
+ while (TRUE);
+ return;
+ }
+
+ //
+ // Check if we have a thread to swap to
+ //
+ if (Pcr->Prcb->NextThread)
+ {
+ DPRINT1("Switching threads!\n");
+
+ //
+ // Next is now current
+ //
+ OldThread = Pcr->Prcb->CurrentThread;
+ NewThread = Pcr->Prcb->NextThread;
+ Pcr->Prcb->CurrentThread = NewThread;
+ Pcr->Prcb->NextThread = NULL;
+
+ //
+ // Update thread states
+ //
+ NewThread->State = Running;
+ OldThread->WaitReason = WrDispatchInt;
+
+ //
+ // Make the old thread ready
+ //
+ DPRINT1("Queueing the ready thread\n");
+ KxQueueReadyThread(OldThread, Pcr->Prcb);
+
+ //
+ // Swap to the new thread
+ //
+ DPRINT1("Swapping context!\n");
+ //KiSwapContextInternal();
+ while (TRUE);
+ }
+}
+
+VOID
+KiInterruptHandler(IN PKTRAP_FRAME TrapFrame,
+ IN ULONG Reserved)
+{
+ KIRQL OldIrql, Irql;
+ ULONG InterruptCause, InterruptMask;
+ PKPCR Pcr;
+
+ //
+ // Get the old IRQL
+ //
+ OldIrql = TrapFrame->OldIrql;
+
+ //
+ // Get the interrupt source
+ //
+ InterruptCause = HalGetInterruptSource();
+ DPRINT1("Interrupt (%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);
+ //}
+
+ //
+ // 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);
+ _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
KiDataAbortHandler(IN PKTRAP_FRAME TrapFrame)
{
diff --git a/reactos/ntoskrnl/ntoskrnl-generic.rbuild b/reactos/ntoskrnl/ntoskrnl-generic.rbuild
index 4bd37e0325d..51c35f9c41a 100644
--- a/reactos/ntoskrnl/ntoskrnl-generic.rbuild
+++ b/reactos/ntoskrnl/ntoskrnl-generic.rbuild
@@ -403,6 +403,11 @@
psctx.c
+
+
+ psctx.c
+
+
debug.c
job.c
kill.c
diff --git a/reactos/ntoskrnl/ps/arm/psctx.c b/reactos/ntoskrnl/ps/arm/psctx.c
new file mode 100644
index 00000000000..c23a3d9aa1e
--- /dev/null
+++ b/reactos/ntoskrnl/ps/arm/psctx.c
@@ -0,0 +1,47 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/ps/arm/pxctx.c
+ * PURPOSE: Process Manager: Set/Get Context for ARM
+ * PROGRAMMERS: ReactOS Portable Systems Group
+ */
+
+/* INCLUDES *******************************************************************/
+
+#include
+#define NDEBUG
+#include
+
+/* FUNCTIONS ******************************************************************/
+
+VOID
+NTAPI
+PspGetContext(IN PKTRAP_FRAME TrapFrame,
+ IN PVOID NonVolatileContext,
+ IN OUT PCONTEXT Context)
+{
+ PAGED_CODE();
+}
+
+VOID
+NTAPI
+PspSetContext(OUT PKTRAP_FRAME TrapFrame,
+ OUT PVOID NonVolatileContext,
+ IN PCONTEXT Context,
+ IN KPROCESSOR_MODE Mode)
+{
+ PAGED_CODE();
+}
+
+VOID
+NTAPI
+PspGetOrSetContextKernelRoutine(IN PKAPC Apc,
+ IN OUT PKNORMAL_ROUTINE* NormalRoutine,
+ IN OUT PVOID* NormalContext,
+ IN OUT PVOID* SystemArgument1,
+ IN OUT PVOID* SystemArgument2)
+{
+ UNIMPLEMENTED;
+}
+
+/* EOF */