Author: arty
Date: Wed Jan 3 12:31:26 2007
New Revision: 25280
URL:
http://svn.reactos.org/svn/reactos?rev=25280&view=rev
Log:
- Reserve and map a page for Pcr
- Some stubs (KeInitExceptions, KeInitInterrupts, ...)
- Normalize segments and bats
Added:
branches/powerpc/reactos/ntoskrnl/ke/powerpc/cpu.c
branches/powerpc/reactos/ntoskrnl/ke/powerpc/exp.c
branches/powerpc/reactos/ntoskrnl/ke/powerpc/kiinit.c
branches/powerpc/reactos/ntoskrnl/ke/powerpc/mmu.c
branches/powerpc/reactos/ntoskrnl/ke/powerpc/ppc_irq.c
Modified:
branches/powerpc/reactos/ntoskrnl/ntoskrnl.rbuild
Added: branches/powerpc/reactos/ntoskrnl/ke/powerpc/cpu.c
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/ntoskrnl/ke/pow…
==============================================================================
--- branches/powerpc/reactos/ntoskrnl/ke/powerpc/cpu.c (added)
+++ branches/powerpc/reactos/ntoskrnl/ke/powerpc/cpu.c Wed Jan 3 12:31:26 2007
@@ -1,0 +1,277 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/ke/i386/cpu.c
+ * PURPOSE: Routines for CPU-level support
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+/* CPU Features and Flags */
+ULONG KeProcessorArchitecture;
+ULONG KeProcessorLevel;
+ULONG KeProcessorRevision;
+ULONG KeFeatureBits;
+ULONG KeLargestCacheLine = 0x40;
+ULONG KeDcacheFlushCount = 0;
+ULONG KeIcacheFlushCount = 0;
+ULONG KiDmaIoCoherency = 0;
+CHAR KeNumberProcessors;
+KAFFINITY KeActiveProcessors = 1;
+BOOLEAN KiSMTProcessorsPresent;
+
+/* CPU Signatures */
+#if 0
+CHAR CmpIntelID[] = "GenuineIntel";
+CHAR CmpAmdID[] = "AuthenticAMD";
+CHAR CmpCyrixID[] = "CyrixInstead";
+CHAR CmpTransmetaID[] = "GenuineTMx86";
+CHAR CmpCentaurID[] = "CentaurHauls";
+CHAR CmpRiseID[] = "RiseRiseRise";
+#endif
+
+/* SUPPORT ROUTINES FOR MSVC COMPATIBILITY ***********************************/
+
+VOID
+NTAPI
+CPUID(IN ULONG CpuInfo[4],
+ IN ULONG InfoType)
+{
+ RtlZeroMemory(CpuInfo, sizeof(CpuInfo));
+}
+
+VOID
+WRMSR(IN ULONG Register,
+ IN LONGLONG Value)
+{
+}
+
+LONGLONG
+RDMSR(IN ULONG Register)
+{
+ LARGE_INTEGER LargeVal;
+ LargeVal.QuadPart = 0;
+ return LargeVal.QuadPart;
+}
+
+/* FUNCTIONS *****************************************************************/
+
+VOID
+NTAPI
+KiSetProcessorType(VOID)
+{
+}
+
+ULONG
+NTAPI
+KiGetCpuVendor(VOID)
+{
+ return 0;
+}
+
+ULONG
+NTAPI
+KiGetFeatureBits(VOID)
+{
+ ULONG FeatureBits = 0;
+ /* Return the Feature Bits */
+ return FeatureBits;
+}
+
+VOID
+NTAPI
+KiGetCacheInformation(VOID)
+{
+}
+
+VOID
+NTAPI
+KiSetCR0Bits(VOID)
+{
+}
+
+VOID
+NTAPI
+KiInitializeTSS2(IN PKTSS Tss,
+ IN PKGDTENTRY TssEntry OPTIONAL)
+{
+}
+
+VOID
+NTAPI
+KiInitializeTSS(IN PKTSS Tss)
+{
+}
+
+VOID
+FASTCALL
+Ki386InitializeTss(IN PKTSS Tss,
+ IN PKIDTENTRY Idt,
+ IN PKGDTENTRY Gdt)
+{
+}
+
+VOID
+NTAPI
+KeFlushCurrentTb(VOID)
+{
+}
+
+VOID
+NTAPI
+KiSaveProcessorControlState(IN PKPROCESSOR_STATE ProcessorState)
+{
+}
+
+VOID
+NTAPI
+KiInitializeMachineType(VOID)
+{
+}
+
+ULONG_PTR
+NTAPI
+KiLoadFastSyscallMachineSpecificRegisters(IN ULONG_PTR Context)
+{
+ return 0;
+}
+
+VOID
+NTAPI
+KiRestoreFastSyscallReturnState(VOID)
+{
+}
+
+ULONG_PTR
+NTAPI
+Ki386EnableDE(IN ULONG_PTR Context)
+{
+ return 0;
+}
+
+ULONG_PTR
+NTAPI
+Ki386EnableFxsr(IN ULONG_PTR Context)
+{
+ return 0;
+}
+
+ULONG_PTR
+NTAPI
+Ki386EnableXMMIExceptions(IN ULONG_PTR Context)
+{
+ /* FIXME: Support this */
+ DPRINT1("Your machine supports XMMI exceptions but ReactOS
doesn't\n");
+ return 0;
+}
+
+VOID
+NTAPI
+KiI386PentiumLockErrataFixup(VOID)
+{
+ /* FIXME: Support this */
+ DPRINT1("WARNING: Your machine has a CPU bug that ReactOS can't
bypass!\n");
+}
+
+/* PUBLIC FUNCTIONS **********************************************************/
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+KeSaveFloatingPointState(OUT PKFLOATING_SAVE Save)
+{
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+KeRestoreFloatingPointState(IN PKFLOATING_SAVE Save)
+{
+ return STATUS_SUCCESS;
+}
+
+/*
+ * @implemented
+ */
+ULONG
+NTAPI
+KeGetRecommendedSharedDataAlignment(VOID)
+{
+ /* Return the global variable */
+ return KeLargestCacheLine;
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeFlushEntireTb(IN BOOLEAN Invalid,
+ IN BOOLEAN AllProcessors)
+{
+ KIRQL OldIrql;
+
+ /* Raise the IRQL for the TB Flush */
+ OldIrql = KeRaiseIrqlToSynchLevel();
+
+#ifdef CONFIG_SMP
+ /* FIXME: Support IPI Flush */
+#error Not yet implemented!
+#endif
+
+ /* Flush the TB for the Current CPU */
+ //KeFlushCurrentTb();
+
+ /* Return to Original IRQL */
+ KeLowerIrql(OldIrql);
+}
+
+/*
+ * @implemented
+ */
+VOID
+NTAPI
+KeSetDmaIoCoherency(IN ULONG Coherency)
+{
+ /* Save the coherency globally */
+ KiDmaIoCoherency = Coherency;
+}
+
+/*
+ * @implemented
+ */
+KAFFINITY
+NTAPI
+KeQueryActiveProcessors(VOID)
+{
+ PAGED_CODE();
+
+ /* Simply return the number of active processors */
+ return KeActiveProcessors;
+}
+
+/*
+ * @implemented
+ */
+VOID
+__cdecl
+KeSaveStateForHibernate(IN PKPROCESSOR_STATE State)
+{
+ /* Capture the context */
+ RtlCaptureContext(&State->ContextFrame);
+
+ /* Capture the control state */
+ KiSaveProcessorControlState(State);
+}
Added: branches/powerpc/reactos/ntoskrnl/ke/powerpc/exp.c
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/ntoskrnl/ke/pow…
==============================================================================
--- branches/powerpc/reactos/ntoskrnl/ke/powerpc/exp.c (added)
+++ branches/powerpc/reactos/ntoskrnl/ke/powerpc/exp.c Wed Jan 3 12:31:26 2007
@@ -1,0 +1,114 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/ke/i386/exp.c
+ * PURPOSE: Exception Dispatching and Context<->Trap Frame Conversion
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Gregor Anich
+ * Skywing (skywing(a)valhallalegends.com)
+ */
+
+/* INCLUDES ******************************************************************/
+
+#include <ntoskrnl.h>
+#define NDEBUG
+#include <debug.h>
+
+/* FUNCTIONS *****************************************************************/
+
+_SEH_DEFINE_LOCALS(KiCopyInfo)
+{
+ volatile EXCEPTION_RECORD SehExceptRecord;
+};
+
+_SEH_FILTER(KiCopyInformation)
+{
+ _SEH_ACCESS_LOCALS(KiCopyInfo);
+
+ /* Copy the exception records and return to the handler */
+ RtlMoveMemory((PVOID)&_SEH_VAR(SehExceptRecord),
+ _SEH_GetExceptionPointers()->ExceptionRecord,
+ sizeof(EXCEPTION_RECORD));
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+
+VOID
+INIT_FUNCTION
+NTAPI
+KeInitExceptions(VOID)
+{
+}
+
+ULONG
+NTAPI
+KiEspFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
+{
+ return 0;
+}
+
+VOID
+NTAPI
+KiEspToTrapFrame(IN PKTRAP_FRAME TrapFrame,
+ IN ULONG Esp)
+{
+}
+
+ULONG
+NTAPI
+KiSsFromTrapFrame(IN PKTRAP_FRAME TrapFrame)
+{
+ return 0;
+}
+
+VOID
+NTAPI
+KiSsToTrapFrame(IN PKTRAP_FRAME TrapFrame,
+ IN ULONG Ss)
+{
+}
+
+USHORT
+NTAPI
+KiTagWordFnsaveToFxsave(USHORT TagWord)
+{
+ return 0;
+}
+
+VOID
+NTAPI
+KeContextToTrapFrame(IN PCONTEXT Context,
+ IN OUT PKEXCEPTION_FRAME ExceptionFrame,
+ IN OUT PKTRAP_FRAME TrapFrame,
+ IN ULONG ContextFlags,
+ IN KPROCESSOR_MODE PreviousMode)
+{
+}
+
+VOID
+NTAPI
+KeTrapFrameToContext(IN PKTRAP_FRAME TrapFrame,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN OUT PCONTEXT Context)
+{
+}
+
+VOID
+NTAPI
+KiDispatchException(IN PEXCEPTION_RECORD ExceptionRecord,
+ IN PKEXCEPTION_FRAME ExceptionFrame,
+ IN PKTRAP_FRAME TrapFrame,
+ IN KPROCESSOR_MODE PreviousMode,
+ IN BOOLEAN FirstChance)
+{
+}
+
+/*
+ * @implemented
+ */
+NTSTATUS
+NTAPI
+KeRaiseUserException(IN NTSTATUS ExceptionCode)
+{
+ return STATUS_SUCCESS;
+}
+
Added: branches/powerpc/reactos/ntoskrnl/ke/powerpc/kiinit.c
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/ntoskrnl/ke/pow…
==============================================================================
--- branches/powerpc/reactos/ntoskrnl/ke/powerpc/kiinit.c (added)
+++ branches/powerpc/reactos/ntoskrnl/ke/powerpc/kiinit.c Wed Jan 3 12:31:26 2007
@@ -1,0 +1,339 @@
+/*
+ * PROJECT: ReactOS Kernel
+ * LICENSE: GPL - See COPYING in the top level directory
+ * FILE: ntoskrnl/ke/powerpc/kiinit.c
+ * PURPOSE: Kernel Initialization for x86 CPUs
+ * PROGRAMMERS: Alex Ionescu (alex.ionescu(a)reactos.org)
+ * Art Yerkes (ayerkes(a)speakeasy.net)
+ */
+
+/* INCLUDES *****************************************************************/
+
+#include <ntoskrnl.h>
+#include <reactos/ppcboot.h>
+
+#define NDEBUG
+#include <debug.h>
+
+/* GLOBALS *******************************************************************/
+
+extern LOADER_MODULE KeLoaderModules[64];
+extern ULONG KeLoaderModuleCount;
+KPRCB PrcbData[MAXIMUM_PROCESSORS];
+
+/* FUNCTIONS *****************************************************************/
+
+extern void SetPhysByte(ULONG_PTR address, char value);
+
+VOID
+DrawDigit(struct _boot_infos_t *BootInfo, ULONG Digit, int x, int y)
+{
+ int i,j,k;
+
+ for( i = 0; i < 7; i++ ) {
+ for( j = 0; j < 8; j++ ) {
+ for( k = 0; k < BootInfo->dispDeviceDepth/8; k++ ) {
+ SetPhysByte(((ULONG_PTR)BootInfo->dispDeviceBase)+
+ k +
+ (((j+x) * (BootInfo->dispDeviceDepth/8)) +
+ ((i+y) * (BootInfo->dispDeviceRowBytes))),
+ BootInfo->dispFont[Digit][i*8+j] == 'X' ? 255 : 0);
+ }
+ }
+ }
+}
+
+VOID
+DrawNumber(struct _boot_infos_t *BootInfo, ULONG Number, int x, int y)
+{
+ int i;
+
+ for( i = 0; i < 8; i++, Number<<=4 ) {
+ DrawDigit(BootInfo,(Number>>28)&0xf,x+(i*8),y);
+ }
+}
+
+VOID
+DrawString(struct _boot_infos_t *BootInfo, const char *str, int x, int y)
+{
+ int i, xx;
+
+ for( i = 0; str[i]; i++ ) {
+ xx = x + (i * 8);
+ if( str[i] >= '0' && str[i] <= '9' )
+ DrawDigit(BootInfo, str[i] - '0', xx, y);
+ else if( str[i] >= 'A' && str[i] <= 'Z' )
+ DrawDigit(BootInfo, str[i] - 'A' + 10, xx, y);
+ else if( str[i] >= 'a' && str[i] <= 'z' )
+ DrawDigit(BootInfo, str[i] - 'a' + 10, xx, y);
+ else
+ DrawDigit(BootInfo, 37, xx, y);
+ }
+}
+
+VOID
+NTAPI
+KiInitializePcr(IN ULONG ProcessorNumber,
+ IN PKIPCR Pcr,
+ IN PKTHREAD IdleThread,
+ IN PVOID DpcStack)
+{
+ TRACE;
+ Pcr->MajorVersion = PCR_MAJOR_VERSION;
+ TRACE;
+ Pcr->MinorVersion = PCR_MINOR_VERSION;
+ TRACE;
+ Pcr->CurrentIrql = PASSIVE_LEVEL;
+ TRACE;
+ Pcr->Prcb = PrcbData;
+ TRACEXY(Pcr->Prcb, PrcbData);
+ Pcr->Prcb->MajorVersion = 1;
+ TRACE;
+ Pcr->Prcb->MinorVersion = 1;
+ TRACE;
+ Pcr->Prcb->Number = 0; /* UP for now */
+ TRACE;
+ Pcr->Prcb->SetMember = 1;
+ TRACE;
+ Pcr->Prcb->BuildType = 0;
+ TRACE;
+ Pcr->Prcb->DpcStack = DpcStack;
+ TRACE;
+ KiProcessorBlock[ProcessorNumber] = Pcr->Prcb;
+ TRACEXY(0xd00d,0xbeef);
+}
+
+extern ULONG KiGetFeatureBits();
+extern VOID KiSetProcessorType();
+extern VOID KiGetCacheInformation();
+
+VOID
+NTAPI
+KiInitializeKernel(IN PKPROCESS InitProcess,
+ IN PKTHREAD InitThread,
+ IN PVOID IdleStack,
+ IN PKPRCB Prcb,
+ IN CCHAR Number,
+ IN PROS_LOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ ULONG FeatureBits;
+ LARGE_INTEGER PageDirectory;
+ PVOID DpcStack;
+
+ /* Detect and set the CPU Type */
+ KiSetProcessorType();
+
+ /* Initialize the Power Management Support for this PRCB */
+ PoInitializePrcb(Prcb);
+
+ /* Get the processor features for the CPU */
+ FeatureBits = KiGetFeatureBits();
+
+ /* Save feature bits */
+ Prcb->FeatureBits = FeatureBits;
+
+ /* Get cache line information for this CPU */
+ KiGetCacheInformation();
+
+ /* Initialize spinlocks and DPC data */
+ KiInitSpinLocks(Prcb, Number);
+
+ /* Check if this is the Boot CPU */
+ if (!Number)
+ {
+ /* Set Node Data */
+ KeNodeBlock[0] = &KiNode0;
+ Prcb->ParentNode = KeNodeBlock[0];
+ KeNodeBlock[0]->ProcessorMask = Prcb->SetMember;
+
+ /* Set boot-level flags */
+ KeProcessorArchitecture = 0;
+ KeProcessorLevel = (USHORT)Prcb->CpuType;
+ KeFeatureBits = FeatureBits;
+
+ /* Set the current MP Master KPRCB to the Boot PRCB */
+ Prcb->MultiThreadSetMaster = Prcb;
+
+ /* Initialize portable parts of the OS */
+ KiInitSystem();
+
+ /* Initialize the Idle Process and the Process Listhead */
+ InitializeListHead(&KiProcessListHead);
+ PageDirectory.QuadPart = 0;
+ KeInitializeProcess(InitProcess,
+ 0,
+ 0xFFFFFFFF,
+ &PageDirectory,
+ TRUE);
+ InitProcess->QuantumReset = MAXCHAR;
+ }
+ else
+ {
+ /* FIXME */
+ DPRINT1("SMP Boot support not yet present\n");
+ }
+
+#if 0
+ /* Setup the Idle Thread */
+ KeInitializeThread(InitProcess,
+ InitThread,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ IdleStack);
+#endif
+ InitThread->NextProcessor = Number;
+ InitThread->Priority = HIGH_PRIORITY;
+ InitThread->State = Running;
+ InitThread->Affinity = 1 << Number;
+ InitThread->WaitIrql = DISPATCH_LEVEL;
+ InitProcess->ActiveProcessors = 1 << Number;
+
+ /* Set up the thread-related fields in the PRCB */
+ //Prcb->CurrentThread = InitThread;
+ Prcb->NextThread = NULL;
+ //Prcb->IdleThread = InitThread;
+
+ /* Initialize the Kernel Executive */
+ ExpInitializeExecutive(0, (PLOADER_PARAMETER_BLOCK)LoaderBlock);
+
+ /* Only do this on the boot CPU */
+ if (!Number)
+ {
+ /* Calculate the time reciprocal */
+ KiTimeIncrementReciprocal =
+ KiComputeReciprocal(KeMaximumIncrement,
+ &KiTimeIncrementShiftCount);
+
+ /* Update DPC Values in case they got updated by the executive */
+ Prcb->MaximumDpcQueueDepth = KiMaximumDpcQueueDepth;
+ Prcb->MinimumDpcRate = KiMinimumDpcRate;
+ Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
+
+ /* Allocate the DPC Stack */
+ DpcStack = MmCreateKernelStack(FALSE);
+ if (!DpcStack) KeBugCheckEx(NO_PAGES_AVAILABLE, 1, 0, 0, 0);
+ Prcb->DpcStack = DpcStack;
+ }
+
+ /* Free Initial Memory */
+ MiFreeInitMemory();
+
+ while (1)
+ {
+ LARGE_INTEGER Timeout;
+ Timeout.QuadPart = 0x7fffffffffffffffLL;
+ KeDelayExecutionThread(KernelMode, FALSE, &Timeout);
+ }
+
+ /* Bug Check and loop forever if anything failed */
+ KEBUGCHECK(0);
+ for(;;);
+}
+
+/* translate address */
+int PpcVirt2phys( int virt, int inst );
+/* Add a new page table entry for the indicated mapping */
+BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 );
+void SetBat( int bat, int inst, int hi, int lo );
+void SetSR( int n, int val );
+
+/* Use this for early boot additions to the page table */
+VOID
+NTAPI
+KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
+{
+ ULONG Cpu, PhysicalPage, i;
+ PKIPCR Pcr = (PKIPCR)KPCR_BASE;
+ PKPRCB Prcb;
+
+ /* Zero bats for now ... We may use these for something later */
+ for( i = 0; i < 4; i++ ) {
+ SetBat( i, 0, 0, 0 );
+ SetBat( i, 1, 0, 0 );
+ }
+
+ /* Set up segs for normal paged address space. */
+ for( i = 0; i < 16; i++ ) {
+ SetSR(i, i);
+ }
+
+ /* Save the loader block and get the current CPU */
+ //KeLoaderBlock = LoaderBlock;
+ Cpu = KeNumberProcessors;
+ if (!Cpu)
+ {
+ /* Skippable initialization for secondary processor */
+ /* We'll allocate a page from the end of the kernel area for KPCR. This code will
probably
+ * change when we get SMP support.
+ */
+ ULONG LastPage =
ROUND_UP(KeLoaderModules[KeLoaderModuleCount-1].ModEnd,1<<PAGE_SHIFT);
+ PhysicalPage = PpcVirt2phys(LastPage, FALSE);
+ InsertPageEntry((ULONG)Pcr, PhysicalPage, 0, 0);
+ *((PULONG)Pcr) = -1;
+ if(!((PULONG)Pcr)) {
+ TRACEXY(0xCABBA9E, 0xC0FFEE);
+ while(1);
+ }
+ }
+
+ /* Skip initial setup if this isn't the Boot CPU */
+ if (Cpu) goto AppCpuInit;
+
+ /* Initialize the PCR */
+ RtlZeroMemory(Pcr, PAGE_SIZE);
+ KiInitializePcr(Cpu,
+ Pcr,
+ &KiInitialThread.Tcb,
+ KiDoubleFaultStack);
+
+ TRACE;
+ /* Set us as the current process */
+ KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
+
+ TRACE;
+ /* Setup CPU-related fields */
+AppCpuInit:
+ TRACE;
+ Prcb = Pcr->Prcb;
+ Pcr->Number = Cpu;
+ Pcr->SetMember = 1 << Cpu;
+ Prcb->SetMember = 1 << Cpu;
+
+ TRACE;
+ /* Initialize the Processor with HAL */
+ HalInitializeProcessor(Cpu, LoaderBlock);
+
+ TRACE;
+ /* Set active processors */
+ KeActiveProcessors |= Pcr->SetMember;
+ KeNumberProcessors++;
+
+ TRACE;
+ /* Initialize the Debugger for the Boot CPU */
+ if (!Cpu) KdInitSystem (0, LoaderBlock);
+
+ TRACE;
+ /* Check for break-in */
+ if (KdPollBreakIn())
+ {
+ DbgBreakPointWithStatus(1);
+ }
+
+ TRACE;
+ /* Raise to HIGH_LEVEL */
+ KfRaiseIrql(HIGH_LEVEL);
+
+ TRACE;
+ /* Call main kernel intialization */
+ KiInitializeKernel(&KiInitialProcess.Pcb,
+ &KiInitialThread.Tcb,
+ P0BootStack,
+ Prcb,
+ Cpu,
+ (PVOID)LoaderBlock);
+ TRACE;
+}
+
Added: branches/powerpc/reactos/ntoskrnl/ke/powerpc/mmu.c
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/ntoskrnl/ke/pow…
==============================================================================
--- branches/powerpc/reactos/ntoskrnl/ke/powerpc/mmu.c (added)
+++ branches/powerpc/reactos/ntoskrnl/ke/powerpc/mmu.c Wed Jan 3 12:31:26 2007
@@ -1,0 +1,397 @@
+#include <ntoskrnl.h>
+
+inline int GetMSR() {
+ register int res asm ("r3");
+ __asm__("mfmsr 3");
+ return res;
+}
+
+inline int GetDEC() {
+ register int res asm ("r3");
+ __asm__("mfdec 3");
+ return res;
+}
+
+extern int GetPhys(int Addr);
+extern void SetPhys(int Addr, int Val);
+
+__asm__("\t.globl GetPhys\n"
+ "GetPhys:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "xori 3,3,4\n\t" /* Undo effects of LE without swapping */
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "isync\n\t"
+ "sync\n\t"
+ "lwz 3,0(3)\n\t" /* Get actual value at phys addr r3 */
+ "mtmsr 5\n\t"
+ "isync\n\t"
+ "sync\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+__asm__("\t.globl SetPhys\n"
+ "SetPhys:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "xori 3,3,4\n\t" /* Undo effects of LE without swapping */
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "stw 4,0(3)\n\t" /* Set actual value at phys addr r3 */
+ "dcbst 0,3\n\t"
+ "mtmsr 5\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "mr 3,4\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+__asm__("\t.globl SetPhysByte\n"
+ "SetPhysByte:\t\n"
+ "mflr 0\n\t"
+ "stwu 0,-16(1)\n\t"
+ "mfmsr 5\n\t"
+ "xori 3,3,7\n\t" /* Undo effects of LE without swapping */
+ "andi. 6,5,0xffef\n\t"/* turn off MSR[DR] */
+ "mtmsr 6\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "stb 4,0(3)\n\t" /* Set actual value at phys addr r3 */
+ "dcbst 0,3\n\t"
+ "mtmsr 5\n\t"
+ "sync\n\t"
+ "eieio\n\t"
+ "mr 3,4\n\t"
+ "lwz 0,0(1)\n\t"
+ "addi 1,1,16\n\t"
+ "mtlr 0\n\t"
+ "blr"
+ );
+
+inline int GetSR(int n) {
+ register int res asm ("r3");
+ switch( n ) {
+ case 0:
+ __asm__("mfsr 3,0");
+ break;
+ case 1:
+ __asm__("mfsr 3,1");
+ break;
+ case 2:
+ __asm__("mfsr 3,2");
+ break;
+ case 3:
+ __asm__("mfsr 3,3");
+ break;
+ case 4:
+ __asm__("mfsr 3,4");
+ break;
+ case 5:
+ __asm__("mfsr 3,5");
+ break;
+ case 6:
+ __asm__("mfsr 3,6");
+ break;
+ case 7:
+ __asm__("mfsr 3,7");
+ break;
+ case 8:
+ __asm__("mfsr 3,8");
+ break;
+ case 9:
+ __asm__("mfsr 3,9");
+ break;
+ case 10:
+ __asm__("mfsr 3,10");
+ break;
+ case 11:
+ __asm__("mfsr 3,11");
+ break;
+ case 12:
+ __asm__("mfsr 3,12");
+ break;
+ case 13:
+ __asm__("mfsr 3,13");
+ break;
+ case 14:
+ __asm__("mfsr 3,14");
+ break;
+ case 15:
+ __asm__("mfsr 3,15");
+ break;
+ }
+ return res;
+}
+
+inline void SetSR(int n, int val) {
+ switch( n ) {
+ case 0:
+ __asm__("mtsr 4,0");
+ break;
+ case 1:
+ __asm__("mtsr 4,1");
+ break;
+ case 2:
+ __asm__("mtsr 4,2");
+ break;
+ case 3:
+ __asm__("mtsr 4,3");
+ break;
+ case 4:
+ __asm__("mtsr 4,4");
+ break;
+ case 5:
+ __asm__("mtsr 4,5");
+ break;
+ case 6:
+ __asm__("mtsr 4,6");
+ break;
+ case 7:
+ __asm__("mtsr 4,7");
+ break;
+ case 8:
+ __asm__("mtsr 4,8");
+ break;
+ case 9:
+ __asm__("mtsr 4,9");
+ break;
+ case 10:
+ __asm__("mtsr 4,10");
+ break;
+ case 11:
+ __asm__("mtsr 4,11");
+ break;
+ case 12:
+ __asm__("mtsr 4,12");
+ break;
+ case 13:
+ __asm__("mtsr 4,13");
+ break;
+ case 14:
+ __asm__("mtsr 4,14");
+ break;
+ case 15:
+ __asm__("mtsr 4,15");
+ break;
+ }
+}
+
+inline void GetBat( int bat, int inst, int *batHi, int *batLo ) {
+ register int bh asm("r3"), bl asm("r4");
+ if( inst ) {
+ switch( bat ) {
+ case 0:
+ __asm__("mfibatu 3,0");
+ __asm__("mfibatl 4,0");
+ break;
+ case 1:
+ __asm__("mfibatu 3,1");
+ __asm__("mfibatl 4,1");
+ break;
+ case 2:
+ __asm__("mfibatu 3,2");
+ __asm__("mfibatl 4,2");
+ break;
+ case 3:
+ __asm__("mfibatu 3,3");
+ __asm__("mfibatl 4,3");
+ break;
+ }
+ } else {
+ switch( bat ) {
+ case 0:
+ __asm__("mfdbatu 3,0");
+ __asm__("mfdbatl 4,0");
+ break;
+ case 1:
+ __asm__("mfdbatu 3,1");
+ __asm__("mfdbatl 4,1");
+ break;
+ case 2:
+ __asm__("mfdbatu 3,2");
+ __asm__("mfdbatl 4,2");
+ break;
+ case 3:
+ __asm__("mfdbatu 3,3");
+ __asm__("mfdbatl 4,3");
+ break;
+ }
+ }
+ *batHi = bh;
+ *batLo = bl;
+}
+
+inline void SetBat( int bat, int inst, int batHi, int batLo ) {
+ register int bh asm("r3"), bl asm("r4");
+ bh = batHi;
+ bl = batLo;
+ if( inst ) {
+ switch( bat ) {
+ case 0:
+ __asm__("mtibatu 0,3");
+ __asm__("mtibatl 0,4");
+ break;
+ case 1:
+ __asm__("mtibatu 1,3");
+ __asm__("mtibatl 1,4");
+ break;
+ case 2:
+ __asm__("mtibatu 2,3");
+ __asm__("mtibatl 2,4");
+ break;
+ case 3:
+ __asm__("mtibatu 3,3");
+ __asm__("mtibatl 3,4");
+ break;
+ }
+ } else {
+ switch( bat ) {
+ case 0:
+ __asm__("mtdbatu 0,3");
+ __asm__("mtdbatl 0,4");
+ break;
+ case 1:
+ __asm__("mtdbatu 1,3");
+ __asm__("mtdbatl 1,4");
+ break;
+ case 2:
+ __asm__("mtdbatu 2,3");
+ __asm__("mtdbatl 2,4");
+ break;
+ case 3:
+ __asm__("mtdbatu 3,3");
+ __asm__("mtdbatl 3,4");
+ break;
+ }
+ }
+ __asm__("isync\n\tsync");
+}
+
+inline int GetSDR1() {
+ register int res asm("r3");
+ __asm__("mfsdr1 3");
+ return res;
+}
+
+inline void SetSDR1( int sdr ) {
+#if 0
+ int i,j;
+#endif
+ __asm__("mtsdr1 3");
+#if 0
+ __asm__("sync");
+ __asm__("isync");
+ __asm__("ptesync");
+
+ for( i = 0; i < 256; i++ ) {
+ j = i << 12;
+ __asm__("tlbie %0,0" : : "r" (j));
+ }
+ __asm__("eieio");
+ __asm__("tlbsync");
+ __asm__("ptesync");
+#endif
+}
+
+inline int BatHit( int bath, int batl, int virt ) {
+ int mask = 0xfffe0000 & ~((batl & 0x3f) << 17);
+ return (batl & 0x40) && ((virt & mask) == (bath & mask));
+}
+
+inline int BatTranslate( int bath, int batl, int virt ) {
+ return (virt & 0x007fffff) | (batl & 0xfffe0000);
+}
+
+/* translate address */
+int PpcVirt2phys( int virt, int inst ) {
+ int msr = GetMSR();
+ int txmask = inst ? 0x20 : 0x10;
+ int i, bath, batl, sr, sdr1, physbase, vahi, valo;
+ int npteg, hash, hashmask, ptehi, ptelo, ptegaddr;
+ int vsid, pteh, ptevsid, pteapi;
+
+ if( msr & txmask ) {
+ sr = GetSR( virt >> 28 );
+ vsid = sr & 0xfffffff;
+ vahi = vsid >> 4;
+ valo = (vsid << 28) | (virt & 0xfffffff);
+ if( sr & 0x80000000 ) {
+ return valo;
+ }
+
+ for( i = 0; i < 4; i++ ) {
+ GetBat( i, inst, &bath, &batl );
+ if( BatHit( bath, batl, virt ) ) {
+ return BatTranslate( bath, batl, virt );
+ }
+ }
+
+ sdr1 = GetSDR1();
+
+ physbase = sdr1 & ~0xffff;
+ hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
+ hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
+ npteg = hashmask + 1;
+
+ for( pteh = 0; pteh < 0x80; pteh += 64, hash ^= 0x7ffff ) {
+ ptegaddr = ((hashmask & hash) * 64) + physbase;
+
+ for( i = 0; i < 8; i++ ) {
+ ptehi = GetPhys( ptegaddr + (i * 8) );
+ ptelo = GetPhys( ptegaddr + (i * 8) + 4 );
+
+ ptevsid = (ptehi >> 7) & 0xffffff;
+ pteapi = ptehi & 0x3f;
+
+ if( (ptehi & 64) != pteh ) continue;
+ if( ptevsid != (vsid & 0xffffff) ) continue;
+ if( pteapi != ((virt >> 22) & 0x3f) ) continue;
+
+ return (ptelo & 0xfffff000) | (virt & 0xfff);
+ }
+ }
+ return -1;
+ } else {
+ return virt;
+ }
+}
+
+/* Add a new page table entry for the indicated mapping */
+BOOLEAN InsertPageEntry( int virt, int phys, int slot, int _sdr1 ) {
+ int i, ptehi, ptelo;
+ int sdr1 = _sdr1 ? _sdr1 : GetSDR1();
+ int sr = GetSR( (virt >> 28) & 0xf );
+ int vsid = sr & 0xfffffff;
+ int physbase = sdr1 & ~0xffff;
+ int hashmask = ((sdr1 & 0x1ff) << 10) | 0x3ff;
+ int valo = (vsid << 28) | (virt & 0xfffffff);
+ int hash = (vsid & 0x7ffff) ^ ((valo >> 12) & 0xffff);
+ int ptegaddr = ((hashmask & hash) * 64) + physbase;
+
+ for( i = 0; i < 8; i++ ) {
+ ptehi = GetPhys( ptegaddr + (i * 8) );
+
+ if( (slot != i) && (ptehi & 0x80000000) ) continue;
+
+ ptehi = (1 << 31) | (vsid << 7) | ((virt >> 22) & 0x3f);
+ ptelo = phys & ~0xfff;
+
+ SetPhys( ptegaddr + (i * 8), ptehi );
+ SetPhys( ptegaddr + (i * 8) + 4, ptelo );
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
Added: branches/powerpc/reactos/ntoskrnl/ke/powerpc/ppc_irq.c
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/ntoskrnl/ke/pow…
==============================================================================
--- branches/powerpc/reactos/ntoskrnl/ke/powerpc/ppc_irq.c (added)
+++ branches/powerpc/reactos/ntoskrnl/ke/powerpc/ppc_irq.c Wed Jan 3 12:31:26 2007
@@ -1,0 +1,739 @@
+/* $Id$
+ *
+ * COPYRIGHT: See COPYING in the top level directory
+ * PROJECT: ReactOS kernel
+ * FILE: ntoskrnl/ke/i386/irq.c
+ * PURPOSE: IRQ handling
+ *
+ * PROGRAMMERS: David Welch (welch(a)mcmail.com)
+ */
+
+/*
+ * NOTE: In general the PIC interrupt priority facilities are used to
+ * preserve the NT IRQL semantics, global interrupt disables are only used
+ * to keep the PIC in a consistent state
+ *
+ */
+
+/* INCLUDES ****************************************************************/
+
+#include <ntoskrnl.h>
+
+#define NDEBUG
+#include <internal/debug.h>
+
+extern KDPC KiExpireTimerDpc;
+extern ULONG KiMaximumDpcQueueDepth;
+extern ULONG KiMinimumDpcRate;
+extern ULONG KiAdjustDpcThreshold;
+extern ULONG KiIdealDpcRate;
+extern LONG KiTickOffset;
+extern ULONG KeMaximumIncrement;
+extern ULONG KeMinimumIncrement;
+extern ULONG KeTimeAdjustment;
+extern BOOLEAN KiClockSetupComplete;
+
+/* GLOBALS *****************************************************************/
+
+/* Interrupt handler list */
+
+#define NR_TRAPS 16
+#ifdef CONFIG_SMP
+
+#define INT_NAME2(intnum) KiUnexpectedInterrupt##intnum
+
+#define BUILD_INTERRUPT_HANDLER(intnum) \
+VOID INT_NAME2(intnum)(VOID);
+
+#define D(x,y) \
+ BUILD_INTERRUPT_HANDLER(x##y)
+
+#define D16(x) \
+ D(x,0) D(x,1) D(x,2) D(x,3) \
+ D(x,4) D(x,5) D(x,6) D(x,7) \
+ D(x,8) D(x,9) D(x,A) D(x,B) \
+ D(x,C) D(x,D) D(x,E) D(x,F)
+
+D16(3) D16(4) D16(5) D16(6)
+D16(7) D16(8) D16(9) D16(A)
+D16(B) D16(C) D16(D) D16(E)
+D16(F)
+
+#define L(x,y) \
+ (ULONG)& INT_NAME2(x##y)
+
+#define L16(x) \
+ L(x,0), L(x,1), L(x,2), L(x,3), \
+ L(x,4), L(x,5), L(x,6), L(x,7), \
+ L(x,8), L(x,9), L(x,A), L(x,B), \
+ L(x,C), L(x,D), L(x,E), L(x,F)
+
+static ULONG irq_handler[ROUND_UP(NR_TRAPS, 16)] = {
+ L16(3), L16(4), L16(5), L16(6),
+ L16(7), L16(8), L16(9), L16(A),
+ L16(B), L16(C), L16(D), L16(E)
+};
+
+#undef L
+#undef L16
+#undef D
+#undef D16
+
+#else /* CONFIG_SMP */
+
+void trap_handler_0(void);
+void trap_handler_1(void);
+void trap_handler_2(void);
+void trap_handler_3(void);
+void trap_handler_4(void);
+void trap_handler_5(void);
+void trap_handler_6(void);
+void trap_handler_7(void);
+void trap_handler_8(void);
+void trap_handler_9(void);
+void trap_handler_10(void);
+void trap_handler_11(void);
+void trap_handler_12(void);
+void trap_handler_13(void);
+void trap_handler_14(void);
+void trap_handler_15(void);
+
+static unsigned int trap_handler[NR_TRAPS] __attribute__((unused)) =
+{
+ (int)&trap_handler_0,
+ (int)&trap_handler_1,
+ (int)&trap_handler_2,
+ (int)&trap_handler_3,
+ (int)&trap_handler_4,
+ (int)&trap_handler_5,
+ (int)&trap_handler_6,
+ (int)&trap_handler_7,
+ (int)&trap_handler_8,
+ (int)&trap_handler_9,
+ (int)&trap_handler_10,
+ (int)&trap_handler_11,
+ (int)&trap_handler_12,
+ (int)&trap_handler_13,
+ (int)&trap_handler_14,
+ (int)&trap_handler_15,
+};
+
+#endif /* CONFIG_SMP */
+
+/*
+ * PURPOSE: Object describing each isr
+ * NOTE: The data in this table is only modified at passsive level but can
+ * be accessed at any irq level.
+ */
+
+typedef struct
+{
+ LIST_ENTRY ListHead;
+ KSPIN_LOCK Lock;
+ ULONG Count;
+}
+ISR_TABLE, *PISR_TABLE;
+
+#ifdef CONFIG_SMP
+static ISR_TABLE IsrTable[NR_TRAPS][MAXIMUM_PROCESSORS];
+#else
+static ISR_TABLE IsrTable[NR_TRAPS][1];
+#endif
+
+#define TAG_ISR_LOCK TAG('I', 'S', 'R', 'L')
+
+/* FUNCTIONS ****************************************************************/
+
+VOID
+INIT_FUNCTION
+NTAPI
+KeInitInterrupts (VOID)
+{
+ int i, j;
+
+ /*
+ * Setup the IDT entries to point to the interrupt handlers
+ */
+ for (i=0;i<NR_TRAPS;i++)
+ {
+#ifdef CONFIG_SMP
+ for (j = 0; j < MAXIMUM_PROCESSORS; j++)
+#else
+ j = 0;
+#endif
+ {
+ InitializeListHead(&IsrTable[i][j].ListHead);
+ KeInitializeSpinLock(&IsrTable[i][j].Lock);
+ IsrTable[i][j].Count = 0;
+ }
+ }
+}
+
+static VOID
+KeIRQTrapFrameToTrapFrame(PKIRQ_TRAPFRAME IrqTrapFrame,
+ PKTRAP_FRAME TrapFrame)
+{
+}
+
+static VOID
+KeTrapFrameToIRQTrapFrame(PKTRAP_FRAME TrapFrame,
+ PKIRQ_TRAPFRAME IrqTrapFrame)
+{
+}
+
+/*
+ * NOTE: On Windows this function takes exactly one parameter and EBP is
+ * guaranteed to point to KTRAP_FRAME. The function is used only
+ * by HAL, so there's no point in keeping that prototype.
+ *
+ * @implemented
+ */
+VOID
+STDCALL
+KeUpdateRunTime(IN PKTRAP_FRAME TrapFrame,
+ IN KIRQL Irql)
+{
+ PKPRCB Prcb = KeGetCurrentPrcb();
+ PKTHREAD CurrentThread;
+ PKPROCESS CurrentProcess;
+
+ /* Make sure we don't go further if we're in early boot phase. */
+ if (!(Prcb) || !(Prcb->CurrentThread)) return;
+
+ /* Get the current thread and process */
+ CurrentThread = Prcb->CurrentThread;
+ CurrentProcess = CurrentThread->ApcState.Process;
+
+ /* Check if we came from user mode */
+ if (TrapFrame->PreviousMode != KernelMode)
+ {
+ /* Update user times */
+ CurrentThread->UserTime++;
+ InterlockedIncrement((PLONG)&CurrentProcess->UserTime);
+ Prcb->UserTime++;
+ }
+ else
+ {
+ /* Check IRQ */
+ if (Irql > DISPATCH_LEVEL)
+ {
+ /* This was an interrupt */
+ Prcb->InterruptTime++;
+ }
+ else if ((Irql < DISPATCH_LEVEL) || !(Prcb->DpcRoutineActive))
+ {
+ /* This was normal kernel time */
+ CurrentThread->KernelTime++;
+ InterlockedIncrement((PLONG)&CurrentProcess->KernelTime);
+ }
+ else if (Irql == DISPATCH_LEVEL)
+ {
+ /* This was DPC time */
+ Prcb->DpcTime++;
+ }
+
+ /* Update CPU kernel time in all cases */
+ Prcb->KernelTime++;
+ }
+
+ /* Set the last DPC Count and request rate */
+ Prcb->DpcLastCount = Prcb->DpcData[0].DpcCount;
+ Prcb->DpcRequestRate = ((Prcb->DpcData[0].DpcCount - Prcb->DpcLastCount) +
+ Prcb->DpcRequestRate) / 2;
+
+ /* Check if we should request a DPC */
+ if ((Prcb->DpcData[0].DpcQueueDepth) && !(Prcb->DpcRoutineActive))
+ {
+ /* Request one */
+ HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+
+ /* Update the depth if needed */
+ if ((Prcb->DpcRequestRate < KiIdealDpcRate) &&
+ (Prcb->MaximumDpcQueueDepth > 1))
+ {
+ /* Decrease the maximum depth by one */
+ Prcb->MaximumDpcQueueDepth--;
+ }
+ }
+ else
+ {
+ /* Decrease the adjustment threshold */
+ if (!(--Prcb->AdjustDpcThreshold))
+ {
+ /* We've hit 0, reset it */
+ Prcb->AdjustDpcThreshold = KiAdjustDpcThreshold;
+
+ /* Check if we've hit queue maximum */
+ if (KiMaximumDpcQueueDepth != Prcb->MaximumDpcQueueDepth)
+ {
+ /* Increase maximum by one */
+ Prcb->MaximumDpcQueueDepth++;
+ }
+ }
+ }
+
+ /*
+ * If we're at end of quantum request software interrupt. The rest
+ * is handled in KiDispatchInterrupt.
+ *
+ * NOTE: If one stays at DISPATCH_LEVEL for a long time the DPC routine
+ * which checks for quantum end will not be executed and decrementing
+ * the quantum here can result in overflow. This is not a problem since
+ * we don't care about the quantum value anymore after the QuantumEnd
+ * flag is set.
+ */
+ if ((CurrentThread->Quantum -= 3) <= 0)
+ {
+ Prcb->QuantumEnd = TRUE;
+ HalRequestSoftwareInterrupt(DISPATCH_LEVEL);
+ }
+}
+
+
+/*
+ * NOTE: On Windows this function takes exactly zero parameters and EBP is
+ * guaranteed to point to KTRAP_FRAME. Also [esp+0] contains an IRQL.
+ * The function is used only by HAL, so there's no point in keeping
+ * that prototype.
+ *
+ * @implemented
+ */
+VOID
+STDCALL
+KeUpdateSystemTime(IN PKTRAP_FRAME TrapFrame,
+ IN KIRQL Irql,
+ IN ULONG Increment)
+{
+ LONG OldOffset;
+ LARGE_INTEGER Time;
+ ASSERT(KeGetCurrentIrql() == PROFILE_LEVEL);
+ if (!KiClockSetupComplete) return;
+
+ /* Update interrupt time */
+ Time.LowPart = SharedUserData->InterruptTime.LowPart;
+ Time.HighPart = SharedUserData->InterruptTime.High1Time;
+ Time.QuadPart += Increment;
+ SharedUserData->InterruptTime.High2Time = Time.u.HighPart;
+ SharedUserData->InterruptTime.LowPart = Time.u.LowPart;
+ SharedUserData->InterruptTime.High1Time = Time.u.HighPart;
+
+ /* Increase the tick offset */
+ KiTickOffset -= Increment;
+ OldOffset = KiTickOffset;
+
+ /* Check if this isn't a tick yet */
+ if (KiTickOffset > 0)
+ {
+ /* Expire timers */
+ KeInsertQueueDpc(&KiExpireTimerDpc, 0, 0);
+ }
+ else
+ {
+ /* Setup time structure for system time */
+ Time.LowPart = SharedUserData->SystemTime.LowPart;
+ Time.HighPart = SharedUserData->SystemTime.High1Time;
+ Time.QuadPart += KeTimeAdjustment;
+ SharedUserData->SystemTime.High2Time = Time.HighPart;
+ SharedUserData->SystemTime.LowPart = Time.LowPart;
+ SharedUserData->SystemTime.High1Time = Time.HighPart;
+
+ /* Setup time structure for tick time */
+ Time.LowPart = KeTickCount.LowPart;
+ Time.HighPart = KeTickCount.High1Time;
+ Time.QuadPart += 1;
+ KeTickCount.High2Time = Time.HighPart;
+ KeTickCount.LowPart = Time.LowPart;
+ KeTickCount.High1Time = Time.HighPart;
+ SharedUserData->TickCount.High2Time = Time.HighPart;
+ SharedUserData->TickCount.LowPart = Time.LowPart;
+ SharedUserData->TickCount.High1Time = Time.HighPart;
+
+ /* Update tick count in shared user data as well */
+ SharedUserData->TickCountLowDeprecated++;
+
+ /* Queue a DPC that will expire timers */
+ KeInsertQueueDpc(&KiExpireTimerDpc, 0, 0);
+ }
+
+ /* Update process and thread times */
+ if (OldOffset <= 0)
+ {
+ /* This was a tick, calculate the next one */
+ KiTickOffset += KeMaximumIncrement;
+ KeUpdateRunTime(TrapFrame, Irql);
+ }
+}
+
+VOID STDCALL
+KiInterruptDispatch2 (ULONG vector, KIRQL old_level)
+/*
+ * FUNCTION: Calls all the interrupt handlers for a given irq.
+ * ARGUMENTS:
+ * vector - The number of the vector to call handlers for.
+ * old_level - The irql of the processor when the irq took place.
+ * NOTES: Must be called at DIRQL.
+ */
+{
+ PKINTERRUPT isr;
+ PLIST_ENTRY current;
+ KIRQL oldlvl;
+ PISR_TABLE CurrentIsr;
+
+ DPRINT("I(0x%.08x, 0x%.08x)\n", vector, old_level);
+
+ /*
+ * Iterate the list until one of the isr tells us its device interrupted
+ */
+ CurrentIsr = &IsrTable[vector][(ULONG)KeGetCurrentProcessorNumber()];
+
+ KiAcquireSpinLock(&CurrentIsr->Lock);
+
+ CurrentIsr->Count++;
+ current = CurrentIsr->ListHead.Flink;
+
+ while (current != &CurrentIsr->ListHead)
+ {
+ isr = CONTAINING_RECORD(current,KINTERRUPT,InterruptListEntry);
+ oldlvl = KeAcquireInterruptSpinLock(isr);
+ if (isr->ServiceRoutine(isr, isr->ServiceContext))
+ {
+ KeReleaseInterruptSpinLock(isr, oldlvl);
+ break;
+ }
+ KeReleaseInterruptSpinLock(isr, oldlvl);
+ current = current->Flink;
+ }
+ KiReleaseSpinLock(&CurrentIsr->Lock);
+}
+
+VOID
+KiInterruptDispatch3 (ULONG vector, PKIRQ_TRAPFRAME Trapframe)
+/*
+ * FUNCTION: Calls the irq specific handler for an irq
+ * ARGUMENTS:
+ * irq = IRQ that has interrupted
+ */
+{
+ KIRQL old_level;
+ KTRAP_FRAME KernelTrapFrame;
+ PKTHREAD CurrentThread;
+ PKTRAP_FRAME OldTrapFrame=NULL;
+
+ /*
+ * At this point we have interrupts disabled, nothing has been done to
+ * the PIC.
+ */
+
+ KeGetCurrentPrcb()->InterruptCount++;
+
+ /*
+ * Notify the rest of the kernel of the raised irq level. For the
+ * default HAL this will send an EOI to the PIC and alter the IRQL.
+ */
+ if (!HalBeginSystemInterrupt (vector,
+ vector,
+ &old_level))
+ {
+ return;
+ }
+
+
+ /*
+ * Enable interrupts
+ * NOTE: Only higher priority interrupts will get through
+ */
+ _enable();
+
+#ifndef CONFIG_SMP
+ if (vector == 0)
+ {
+ KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
+ KeUpdateSystemTime(&KernelTrapFrame, old_level, 100000);
+ }
+ else
+#endif
+ {
+ /*
+ * Actually call the ISR.
+ */
+ KiInterruptDispatch2(vector, old_level);
+ }
+
+ /*
+ * End the system interrupt.
+ */
+ _disable();
+
+ if (old_level==PASSIVE_LEVEL)
+ {
+ HalEndSystemInterrupt (APC_LEVEL, 0);
+
+ CurrentThread = KeGetCurrentThread();
+ if (CurrentThread!=NULL && CurrentThread->ApcState.UserApcPending)
+ {
+ DPRINT("PID: %d, TID: %d CS %04x/%04x\n",
+ ((PETHREAD)CurrentThread)->ThreadsProcess->UniqueProcessId,
+ ((PETHREAD)CurrentThread)->Cid.UniqueThread,
+ Trapframe->Cs,
+ CurrentThread->TrapFrame ? CurrentThread->TrapFrame->Cs : 0);
+ if (CurrentThread->TrapFrame == NULL)
+ {
+ OldTrapFrame = CurrentThread->TrapFrame;
+ KeIRQTrapFrameToTrapFrame(Trapframe, &KernelTrapFrame);
+ CurrentThread->TrapFrame = &KernelTrapFrame;
+ }
+
+ _enable();
+ KiDeliverApc(UserMode, NULL, NULL);
+ _disable();
+
+ ASSERT(KeGetCurrentThread() == CurrentThread);
+ if (CurrentThread->TrapFrame == &KernelTrapFrame)
+ {
+ KeTrapFrameToIRQTrapFrame(&KernelTrapFrame, Trapframe);
+ CurrentThread->TrapFrame = OldTrapFrame;
+ }
+ }
+ KeLowerIrql(PASSIVE_LEVEL);
+ }
+ else
+ {
+ HalEndSystemInterrupt (old_level, 0);
+ }
+
+}
+
+static VOID
+KeDumpIrqList(VOID)
+{
+ PKINTERRUPT current;
+ PLIST_ENTRY current_entry;
+ LONG i, j;
+ KIRQL oldlvl;
+ BOOLEAN printed;
+
+ for (i=0;i<NR_TRAPS;i++)
+ {
+ printed = FALSE;
+ KeRaiseIrql(i,&oldlvl);
+
+ for (j=0; j < KeNumberProcessors; j++)
+ {
+ KiAcquireSpinLock(&IsrTable[i][j].Lock);
+
+ current_entry = IsrTable[i][j].ListHead.Flink;
+ current = CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
+ while (current_entry!=&(IsrTable[i][j].ListHead))
+ {
+ if (printed == FALSE)
+ {
+ printed = TRUE;
+ DPRINT("For irq %x:\n",i);
+ }
+ DPRINT(" Isr %x\n",current);
+ current_entry = current_entry->Flink;
+ current =
CONTAINING_RECORD(current_entry,KINTERRUPT,InterruptListEntry);
+ }
+ KiReleaseSpinLock(&IsrTable[i][j].Lock);
+ }
+ KeLowerIrql(oldlvl);
+ }
+}
+
+/*
+ * @implemented
+ */
+BOOLEAN
+STDCALL
+KeConnectInterrupt(PKINTERRUPT InterruptObject)
+{
+ KIRQL oldlvl,synch_oldlvl;
+ PKINTERRUPT ListHead;
+ ULONG Vector;
+ PISR_TABLE CurrentIsr;
+ BOOLEAN Result;
+
+ DPRINT("KeConnectInterrupt()\n");
+
+ Vector = InterruptObject->Vector;
+
+ if (Vector < 0 || Vector >= NR_TRAPS)
+ return FALSE;
+
+ ASSERT (InterruptObject->Number < KeNumberProcessors);
+
+ KeSetSystemAffinityThread(1 << InterruptObject->Number);
+
+ CurrentIsr = &IsrTable[Vector][(ULONG)InterruptObject->Number];
+
+ KeRaiseIrql(Vector,&oldlvl);
+ KiAcquireSpinLock(&CurrentIsr->Lock);
+
+ /*
+ * Check if the vector is already in use that we can share it
+ */
+ if (!IsListEmpty(&CurrentIsr->ListHead))
+ {
+ ListHead =
CONTAINING_RECORD(CurrentIsr->ListHead.Flink,KINTERRUPT,InterruptListEntry);
+ if (InterruptObject->ShareVector == FALSE || ListHead->ShareVector==FALSE)
+ {
+ KiReleaseSpinLock(&CurrentIsr->Lock);
+ KeLowerIrql(oldlvl);
+ KeRevertToUserAffinityThread();
+ return FALSE;
+ }
+ }
+
+ synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
+
+ DPRINT("%x %x\n",CurrentIsr->ListHead.Flink,
CurrentIsr->ListHead.Blink);
+
+ Result = HalEnableSystemInterrupt(Vector, InterruptObject->Irql,
InterruptObject->Mode);
+ if (Result)
+ {
+
InsertTailList(&CurrentIsr->ListHead,&InterruptObject->InterruptListEntry);
+ DPRINT("%x %x\n",InterruptObject->InterruptListEntry.Flink,
InterruptObject->InterruptListEntry.Blink);
+ }
+
+ InterruptObject->Connected = TRUE;
+ KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
+
+ /*
+ * Release the table spinlock
+ */
+ KiReleaseSpinLock(&CurrentIsr->Lock);
+ KeLowerIrql(oldlvl);
+
+ KeDumpIrqList();
+
+ KeRevertToUserAffinityThread();
+
+ return Result;
+}
+
+/*
+ * @implemented
+ *
+ * FUNCTION: Releases a drivers isr
+ * ARGUMENTS:
+ * InterruptObject = isr to release
+ */
+BOOLEAN
+STDCALL
+KeDisconnectInterrupt(PKINTERRUPT InterruptObject)
+{
+ KIRQL oldlvl,synch_oldlvl;
+ PISR_TABLE CurrentIsr;
+ BOOLEAN State;
+
+ DPRINT1("KeDisconnectInterrupt\n");
+ ASSERT (InterruptObject->Number < KeNumberProcessors);
+
+ /* Set the affinity */
+ KeSetSystemAffinityThread(1 << InterruptObject->Number);
+
+ /* Get the ISR Tabe */
+ CurrentIsr = &IsrTable[InterruptObject->Vector]
+ [(ULONG)InterruptObject->Number];
+
+ /* Raise IRQL to required level and lock table */
+ KeRaiseIrql(InterruptObject->Vector,&oldlvl);
+ KiAcquireSpinLock(&CurrentIsr->Lock);
+
+ /* Check if it's actually connected */
+ if ((State = InterruptObject->Connected))
+ {
+ /* Lock the Interrupt */
+ synch_oldlvl = KeAcquireInterruptSpinLock(InterruptObject);
+
+ /* Remove this one, and check if all are gone */
+ RemoveEntryList(&InterruptObject->InterruptListEntry);
+ if (IsListEmpty(&CurrentIsr->ListHead))
+ {
+ /* Completely Disable the Interrupt */
+ HalDisableSystemInterrupt(InterruptObject->Vector,
InterruptObject->Irql);
+ }
+
+ /* Disconnect it */
+ InterruptObject->Connected = FALSE;
+
+ /* Release the interrupt lock */
+ KeReleaseInterruptSpinLock(InterruptObject, synch_oldlvl);
+ }
+ /* Release the table spinlock */
+ KiReleaseSpinLock(&CurrentIsr->Lock);
+ KeLowerIrql(oldlvl);
+
+ /* Go back to default affinity */
+ KeRevertToUserAffinityThread();
+
+ /* Return Old Interrupt State */
+ return State;
+}
+
+/*
+ * @implemented
+ */
+VOID
+STDCALL
+KeInitializeInterrupt(PKINTERRUPT Interrupt,
+ PKSERVICE_ROUTINE ServiceRoutine,
+ PVOID ServiceContext,
+ PKSPIN_LOCK SpinLock,
+ ULONG Vector,
+ KIRQL Irql,
+ KIRQL SynchronizeIrql,
+ KINTERRUPT_MODE InterruptMode,
+ BOOLEAN ShareVector,
+ CHAR ProcessorNumber,
+ BOOLEAN FloatingSave)
+{
+ /* Set the Interrupt Header */
+ Interrupt->Type = InterruptObject;
+ Interrupt->Size = sizeof(KINTERRUPT);
+
+ /* Check if we got a spinlock */
+ if (SpinLock)
+ {
+ Interrupt->ActualLock = SpinLock;
+ }
+ else
+ {
+ /* This means we'll be usin the built-in one */
+ KeInitializeSpinLock(&Interrupt->SpinLock);
+ Interrupt->ActualLock = &Interrupt->SpinLock;
+ }
+
+ /* Set the other settings */
+ Interrupt->ServiceRoutine = ServiceRoutine;
+ Interrupt->ServiceContext = ServiceContext;
+ Interrupt->Vector = Vector;
+ Interrupt->Irql = Irql;
+ Interrupt->SynchronizeIrql = SynchronizeIrql;
+ Interrupt->Mode = InterruptMode;
+ Interrupt->ShareVector = ShareVector;
+ Interrupt->Number = ProcessorNumber;
+ Interrupt->FloatingSave = FloatingSave;
+
+ /* Disconnect it at first */
+ Interrupt->Connected = FALSE;
+}
+
+VOID KePrintInterruptStatistic(VOID)
+{
+ LONG i, j;
+
+ for (j = 0; j < KeNumberProcessors; j++)
+ {
+ DPRINT1("CPU%d:\n", j);
+ for (i = 0; i < NR_TRAPS; i++)
+ {
+ if (IsrTable[i][j].Count)
+ {
+ DPRINT1(" Irq %x(%d): %d\n", i, i, IsrTable[i][j].Count);
+ }
+ }
+ }
+}
+
+/* EOF */
Modified: branches/powerpc/reactos/ntoskrnl/ntoskrnl.rbuild
URL:
http://svn.reactos.org/svn/reactos/branches/powerpc/reactos/ntoskrnl/ntoskr…
==============================================================================
--- branches/powerpc/reactos/ntoskrnl/ntoskrnl.rbuild (original)
+++ branches/powerpc/reactos/ntoskrnl/ntoskrnl.rbuild Wed Jan 3 12:31:26 2007
@@ -49,6 +49,9 @@
<if property="ARCH" value="powerpc">
<directory name="powerpc">
<file first="true">main_asm.S</file>
+ <file>mmu.c</file>
+ <file>cpu.c</file>
+ <file>exp.c</file>
<file>kiinit.c</file>
<file>ppc_irq.c</file>
</directory>