mirror of
https://github.com/ApfelTeeSaft/reactos.git
synced 2026-08-28 19:26:16 +00:00
All remaining changes from the PPC branch. Not well tested yet. Many things
are indeed still stubs or WIP code. Some people have been interested in helping out from some time and I'm sorry I haven't been able to do this merge finally for a while. svn path=/trunk/; revision=29407
This commit is contained in:
+1
-1
@@ -401,7 +401,7 @@ ifeq ($(ARCH),powerpc)
|
||||
PREAUTO += $(OFW_INTERFACE_SERVICE_FILES) $(PPCMMU_TARGETS)
|
||||
endif
|
||||
|
||||
$(ROS_AUTOMAKE): $(RBUILD_TARGET) $(PREAUTO) $(XMLBUILDFILES)
|
||||
$(ROS_AUTOMAKE): $(RBUILD_TARGET) $(XMLBUILDFILES) | $(PREAUTO)
|
||||
${mkdir} $(OUTPUT_)media$(SEP)inf 2>$(NUL)
|
||||
$(ECHO_RBUILD)
|
||||
$(Q)$(RBUILD_TARGET) $(RBUILD_FLAGS) $(ROS_RBUILDFLAGS) mingw
|
||||
|
||||
@@ -13,6 +13,8 @@
|
||||
<define name="_X86_" />
|
||||
<define name="__i386__" />
|
||||
|
||||
<property name="NTOSKRNL_SHARED" value="-Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared"/>
|
||||
|
||||
<if property="GDB" value="0">
|
||||
<if property="OPTIMIZE" value="1">
|
||||
<compilerflag>-Os</compilerflag>
|
||||
|
||||
+25
-21
@@ -9,27 +9,31 @@
|
||||
|
||||
<xi:include href="ReactOS-generic.rbuild" />
|
||||
|
||||
<property name="OFWLDR_LINKFORMAT" value="-L$(INTERMEDIATE)/lib/ppcmmu -lppcmmu_code -lppcmmu -nostdlib -nostartfiles"/>
|
||||
<property name="OFWLDR_LINKFORMAT" value="-L$(INTERMEDIATE)/lib/ppcmmu -lppcmmu_code -nostdlib -nostartfiles -lgcc -Wl,-e,__start -Wl,-Ttext,0xe00000 -N"/>
|
||||
<property name="NTOSKRNL_SHARED" value="-Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles"/>
|
||||
|
||||
<define name="_M_PPC" />
|
||||
<define name="_PPC_" />
|
||||
<define name="__PowerPC__" />
|
||||
<define name="_REACTOS_" />
|
||||
<define name="stdcall" empty="true" />
|
||||
<define name="__stdcall__" empty="true" />
|
||||
<define name="fastcall" empty="true" />
|
||||
<define name="cdecl" empty="true" />
|
||||
<define name="__cdecl__" empty="true" />
|
||||
<define name="dllimport" empty="true" />
|
||||
<define name="WORDS_BIGENDIAN" empty="true" />
|
||||
<define name="MB_CUR_MAX">1</define>
|
||||
<define name="_BSDTYPES_DEFINED"/>
|
||||
<compilerflag>-fshort-wchar</compilerflag>
|
||||
<compilerflag>-fsigned-char</compilerflag>
|
||||
<compilerflag>-mfull-toc</compilerflag>
|
||||
<compilerflag>-meabi</compilerflag>
|
||||
<compilerflag>-O2</compilerflag>
|
||||
<compilerflag>-Wno-strict-aliasing</compilerflag>
|
||||
<compilerflag>-Wno-trampolines</compilerflag>
|
||||
<define name="_M_PPC" />
|
||||
<define name="_PPC_" />
|
||||
<define name="__PowerPC__" />
|
||||
<define name="_REACTOS_" />
|
||||
<define name="stdcall" empty="true" />
|
||||
<define name="__stdcall__" empty="true" />
|
||||
<define name="fastcall" empty="true" />
|
||||
<define name="cdecl" empty="true" />
|
||||
<define name="__cdecl__" empty="true" />
|
||||
<define name="dllimport" empty="true" />
|
||||
<define name="WORDS_BIGENDIAN" empty="true" />
|
||||
<define name="__MSVCRT__" empty="true" />
|
||||
<define name="__NO_CTYPE_INLINES" />
|
||||
<define name="__DECLSPEC_SUPPORTED" />
|
||||
<define name="__MINGW_IMPORT">extern</define>
|
||||
<define name="_CRTIMP" empty="true" />
|
||||
<define name="'__declspec(x)'" empty="true" />
|
||||
<compilerflag>-fshort-wchar</compilerflag>
|
||||
<compilerflag>-fsigned-char</compilerflag>
|
||||
<compilerflag>-mfull-toc</compilerflag>
|
||||
<compilerflag>-meabi</compilerflag>
|
||||
<compilerflag>-O2</compilerflag>
|
||||
<compilerflag>-Wno-strict-aliasing</compilerflag>
|
||||
|
||||
</project>
|
||||
|
||||
@@ -28,10 +28,18 @@ _start:
|
||||
lwz %r3,ofw_call_addr@l(%r3)
|
||||
cmpw %r3,%r31 /* Zero? */
|
||||
mr %r3,%r31
|
||||
beq bootme
|
||||
beq initfp
|
||||
|
||||
lis %r3,call_ofw@ha
|
||||
addi %r3,%r3,call_ofw@l
|
||||
b bootme
|
||||
|
||||
initfp:
|
||||
/* Enabling FP at this point won't hurt, and the varargs scheme we're
|
||||
* using now requires it. */
|
||||
mfmsr %r0
|
||||
ori %r0,%r0,8192
|
||||
mtmsr %r0
|
||||
|
||||
bootme:
|
||||
blr
|
||||
|
||||
@@ -591,9 +591,11 @@ void MachInit(const char *CmdLine) {
|
||||
}
|
||||
|
||||
if( strlen(BootPart) == 0 ) {
|
||||
len = ofw_getprop(chosen_package, "bootpath",
|
||||
BootPath, sizeof(BootPath));
|
||||
|
||||
if (ofproxy)
|
||||
len = ofw_getprop(chosen_package, "bootpath",
|
||||
BootPath, sizeof(BootPath));
|
||||
else
|
||||
len = 0;
|
||||
if( len < 0 ) len = 0;
|
||||
BootPath[len] = 0;
|
||||
printf( "Boot Path: %s\n", BootPath );
|
||||
|
||||
@@ -26,6 +26,7 @@
|
||||
<library>cmlib</library>
|
||||
<library>rtl</library>
|
||||
<library>libcntpr</library>
|
||||
<library>ppcmmu</library>
|
||||
</module>
|
||||
</if>
|
||||
</group>
|
||||
|
||||
@@ -242,7 +242,7 @@ BOOLEAN FatOpenVolume(ULONG DriveNumber, ULONG VolumeStartSector, ULONG Partitio
|
||||
//
|
||||
// Check the boot sector magic
|
||||
//
|
||||
if (! ISFATX(FatType) && SWAPW(FatVolumeBootSector->BootSectorMagic) != 0xaa55)
|
||||
if (! ISFATX(FatType) && FatVolumeBootSector->BootSectorMagic != 0xaa55)
|
||||
{
|
||||
sprintf(ErrMsg, "Invalid boot sector magic on drive 0x%x (expected 0xaa55 found 0x%x)",
|
||||
DriveNumber, FatVolumeBootSector->BootSectorMagic);
|
||||
|
||||
@@ -34,11 +34,17 @@
|
||||
#define STACK16ADDR 0x7000 /* The 16-bit stack top will be at 0000:7000 */
|
||||
#define STACK32ADDR 0x78000 /* The 32-bit stack top will be at 7000:8000, or 0x78000 */
|
||||
|
||||
#ifdef _M_IX86
|
||||
#define BIOSCALLBUFFER 0x78000 /* Buffer to store temporary data for any Int386() call */
|
||||
#define BIOSCALLBUFSEGMENT 0x7800 /* Buffer to store temporary data for any Int386() call */
|
||||
#define BIOSCALLBUFOFFSET 0x0000 /* Buffer to store temporary data for any Int386() call */
|
||||
#define FILESYSBUFFER 0x80000 /* Buffer to store file system data (e.g. cluster buffer for FAT) */
|
||||
#define DISKREADBUFFER 0x90000 /* Buffer to store data read in from the disk via the BIOS */
|
||||
#elif defined(_M_PPC)
|
||||
extern PVOID FsStaticBufferDisk, FsStaticBufferData;
|
||||
#define DISKREADBUFFER FsStaticBufferDisk
|
||||
#define FILESYSBUFFER FsStaticBufferData
|
||||
#endif
|
||||
|
||||
/* Makes "x" a global variable or label */
|
||||
#define EXTERN(x) .global x; x:
|
||||
|
||||
@@ -35,6 +35,10 @@
|
||||
-->
|
||||
<property name="MP" value="0" />
|
||||
|
||||
<!--
|
||||
New style kernel debugger
|
||||
-->
|
||||
<property name="_WINKD_" value="0" />
|
||||
|
||||
<!--
|
||||
Whether to compile in the integrated kernel debugger.
|
||||
|
||||
@@ -9327,6 +9327,35 @@ KeRaiseIrqlToSynchLevel(
|
||||
#define KeLowerIrql(a) KfLowerIrql(a)
|
||||
#define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a)
|
||||
|
||||
#elif defined(__PowerPC__)
|
||||
|
||||
NTHALAPI
|
||||
VOID
|
||||
FASTCALL
|
||||
KfLowerIrql(
|
||||
IN KIRQL NewIrql);
|
||||
|
||||
NTHALAPI
|
||||
KIRQL
|
||||
FASTCALL
|
||||
KfRaiseIrql(
|
||||
IN KIRQL NewIrql);
|
||||
|
||||
NTHALAPI
|
||||
KIRQL
|
||||
DDKAPI
|
||||
KeRaiseIrqlToDpcLevel(
|
||||
VOID);
|
||||
|
||||
NTHALAPI
|
||||
KIRQL
|
||||
DDKAPI
|
||||
KeRaiseIrqlToSynchLevel(
|
||||
VOID);
|
||||
|
||||
#define KeLowerIrql(a) KfLowerIrql(a)
|
||||
#define KeRaiseIrql(a,b) *(b) = KfRaiseIrql(a)
|
||||
|
||||
#else
|
||||
|
||||
NTKERNELAPI
|
||||
|
||||
@@ -28,6 +28,9 @@
|
||||
#ifndef KJK_INTRIN_PPC_H_
|
||||
#define KJK_INTRIN_PPC_H_
|
||||
|
||||
//#define PPC_QUAL static __inline__ __attribute__((always_inline))
|
||||
#define PPC_QUAL extern __inline__
|
||||
|
||||
#ifndef __GNUC__
|
||||
#error Unsupported compiler
|
||||
#endif
|
||||
@@ -50,98 +53,98 @@
|
||||
|
||||
#if (__GNUC__ * 10000 + __GNUC_MINOR__ * 100 + __GNUC_PATCHLEVEL__) > 40100
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
|
||||
PPC_QUAL char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
|
||||
PPC_QUAL short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
|
||||
PPC_QUAL long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
|
||||
PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
|
||||
PPC_QUAL void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
|
||||
{
|
||||
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value)
|
||||
PPC_QUAL long _InterlockedExchange(volatile long * const Target, const long Value)
|
||||
{
|
||||
/* NOTE: __sync_lock_test_and_set would be an acquire barrier, so we force a full barrier */
|
||||
__sync_synchronize();
|
||||
return __sync_lock_test_and_set(Target, Value);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
|
||||
PPC_QUAL void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
|
||||
{
|
||||
/* NOTE: ditto */
|
||||
__sync_synchronize();
|
||||
return __sync_lock_test_and_set(Target, Value);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
|
||||
PPC_QUAL long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
|
||||
{
|
||||
return __sync_fetch_and_add(Addend, Value);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)
|
||||
PPC_QUAL char _InterlockedAnd8(volatile char * const value, const char mask)
|
||||
{
|
||||
return __sync_fetch_and_and(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask)
|
||||
PPC_QUAL short _InterlockedAnd16(volatile short * const value, const short mask)
|
||||
{
|
||||
return __sync_fetch_and_and(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask)
|
||||
PPC_QUAL long _InterlockedAnd(volatile long * const value, const long mask)
|
||||
{
|
||||
return __sync_fetch_and_and(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask)
|
||||
PPC_QUAL char _InterlockedOr8(volatile char * const value, const char mask)
|
||||
{
|
||||
return __sync_fetch_and_or(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask)
|
||||
PPC_QUAL short _InterlockedOr16(volatile short * const value, const short mask)
|
||||
{
|
||||
return __sync_fetch_and_or(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask)
|
||||
PPC_QUAL long _InterlockedOr(volatile long * const value, const long mask)
|
||||
{
|
||||
return __sync_fetch_and_or(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask)
|
||||
PPC_QUAL char _InterlockedXor8(volatile char * const value, const char mask)
|
||||
{
|
||||
return __sync_fetch_and_xor(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask)
|
||||
PPC_QUAL short _InterlockedXor16(volatile short * const value, const short mask)
|
||||
{
|
||||
return __sync_fetch_and_xor(value, mask);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask)
|
||||
PPC_QUAL long _InterlockedXor(volatile long * const value, const long mask)
|
||||
{
|
||||
return __sync_fetch_and_xor(value, mask);
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
|
||||
PPC_QUAL char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
|
||||
{
|
||||
char retval = Comperand;
|
||||
__asm__ __volatile__ (
|
||||
@@ -158,7 +161,7 @@ static __inline__ __attribute__((always_inline)) char _InterlockedCompareExchang
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
|
||||
PPC_QUAL short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
|
||||
{
|
||||
short retval = Comperand;
|
||||
__asm__ __volatile__ (
|
||||
@@ -169,13 +172,30 @@ static __inline__ __attribute__((always_inline)) short _InterlockedCompareExchan
|
||||
" sthcx. %3,0,%1\n"
|
||||
" bne- 1b\n"
|
||||
"2: isync"
|
||||
: "=b" (retval)
|
||||
: "b" (Destination), "r" (Comperand), "r" (Exchange)
|
||||
: "cr0", "memory");
|
||||
: "=r" (retval)
|
||||
: "r" (Destination), "r" (Comperand), "r" (Exchange)
|
||||
: "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
|
||||
PPC_QUAL long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
|
||||
{
|
||||
short retval = Comperand;
|
||||
__asm__ __volatile__ (
|
||||
"sync\n"
|
||||
"1: lwarx %0,0,%1\n"
|
||||
" subf. %0,%2,%0\n"
|
||||
" bne 2f\n"
|
||||
" stwcx. %3,0,%1\n"
|
||||
" bne- 1b\n"
|
||||
"2: isync"
|
||||
: "=r" (retval)
|
||||
: "r" (Destination), "r" (Comperand), "r" (Exchange)
|
||||
: "memory");
|
||||
return retval;
|
||||
}
|
||||
|
||||
PPC_QUAL long long _InterlockedCompareExchange64(volatile long long * const Destination, const long long Exchange, const long long Comperand)
|
||||
{
|
||||
unsigned long lo32Retval = (unsigned long)((Comperand >> 0) & 0xFFFFFFFF);
|
||||
long hi32Retval = (unsigned long)((Comperand >> 32) & 0xFFFFFFFF);
|
||||
@@ -209,13 +229,13 @@ static __inline__ __attribute__((always_inline)) long long _InterlockedCompareEx
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
|
||||
PPC_QUAL void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
|
||||
{
|
||||
return (void *)_InterlockedCompareExchange
|
||||
((long *)Destination, (long) Exchange, (long) Comperand);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volatile long * const Target, const long Value)
|
||||
PPC_QUAL long _InterlockedExchange(volatile long * const Target, const long Value)
|
||||
{
|
||||
long retval;
|
||||
__asm__ __volatile__ (
|
||||
@@ -229,7 +249,7 @@ static __inline__ __attribute__((always_inline)) long _InterlockedExchange(volat
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
|
||||
PPC_QUAL void * _InterlockedExchangePointer(void * volatile * const Target, void * const Value)
|
||||
{
|
||||
void * retval;
|
||||
__asm__ __volatile__ (
|
||||
@@ -243,7 +263,7 @@ static __inline__ __attribute__((always_inline)) void * _InterlockedExchangePoin
|
||||
return retval;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
|
||||
PPC_QUAL long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
|
||||
{
|
||||
long x;
|
||||
long y = *Addend;
|
||||
@@ -259,7 +279,7 @@ static __inline__ __attribute__((always_inline)) long _InterlockedExchangeAdd(vo
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile char * const value, const char mask)
|
||||
PPC_QUAL char _InterlockedAnd8(volatile char * const value, const char mask)
|
||||
{
|
||||
char x;
|
||||
char y;
|
||||
@@ -276,7 +296,7 @@ static __inline__ __attribute__((always_inline)) char _InterlockedAnd8(volatile
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatile short * const value, const short mask)
|
||||
PPC_QUAL short _InterlockedAnd16(volatile short * const value, const short mask)
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
@@ -293,7 +313,7 @@ static __inline__ __attribute__((always_inline)) short _InterlockedAnd16(volatil
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile long * const value, const long mask)
|
||||
PPC_QUAL long _InterlockedAnd(volatile long * const value, const long mask)
|
||||
{
|
||||
long x;
|
||||
long y;
|
||||
@@ -310,7 +330,7 @@ static __inline__ __attribute__((always_inline)) long _InterlockedAnd(volatile l
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile char * const value, const char mask)
|
||||
PPC_QUAL char _InterlockedOr8(volatile char * const value, const char mask)
|
||||
{
|
||||
char x;
|
||||
char y;
|
||||
@@ -327,7 +347,7 @@ static __inline__ __attribute__((always_inline)) char _InterlockedOr8(volatile c
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile short * const value, const short mask)
|
||||
PPC_QUAL short _InterlockedOr16(volatile short * const value, const short mask)
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
@@ -344,7 +364,7 @@ static __inline__ __attribute__((always_inline)) short _InterlockedOr16(volatile
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile long * const value, const long mask)
|
||||
PPC_QUAL long _InterlockedOr(volatile long * const value, const long mask)
|
||||
{
|
||||
long x;
|
||||
long y;
|
||||
@@ -361,7 +381,7 @@ static __inline__ __attribute__((always_inline)) long _InterlockedOr(volatile lo
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile char * const value, const char mask)
|
||||
PPC_QUAL char _InterlockedXor8(volatile char * const value, const char mask)
|
||||
{
|
||||
char x;
|
||||
char y;
|
||||
@@ -378,7 +398,7 @@ static __inline__ __attribute__((always_inline)) char _InterlockedXor8(volatile
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatile short * const value, const short mask)
|
||||
PPC_QUAL short _InterlockedXor16(volatile short * const value, const short mask)
|
||||
{
|
||||
short x;
|
||||
short y;
|
||||
@@ -395,7 +415,7 @@ static __inline__ __attribute__((always_inline)) short _InterlockedXor16(volatil
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile long * const value, const long mask)
|
||||
PPC_QUAL long _InterlockedXor(volatile long * const value, const long mask)
|
||||
{
|
||||
long x;
|
||||
long y;
|
||||
@@ -412,7 +432,7 @@ static __inline__ __attribute__((always_inline)) long _InterlockedXor(volatile l
|
||||
return y;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandreset(volatile long * const a, const long b)
|
||||
PPC_QUAL unsigned char _interlockedbittestandreset(volatile long * const a, const long b)
|
||||
{
|
||||
long x;
|
||||
long y;
|
||||
@@ -430,7 +450,7 @@ static __inline__ __attribute__((always_inline)) unsigned char _interlockedbitte
|
||||
return (y & ~mask) != 0;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _interlockedbittestandset(volatile long * const a, const long b)
|
||||
PPC_QUAL unsigned char _interlockedbittestandset(volatile long * const a, const long b)
|
||||
{
|
||||
long x;
|
||||
long y;
|
||||
@@ -449,12 +469,12 @@ static __inline__ __attribute__((always_inline)) unsigned char _interlockedbitte
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedDecrement(volatile long * const lpAddend)
|
||||
PPC_QUAL long _InterlockedDecrement(volatile long * const lpAddend)
|
||||
{
|
||||
return _InterlockedExchangeAdd(lpAddend, -1) - 1;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedIncrement(volatile long * const lpAddend)
|
||||
PPC_QUAL long _InterlockedIncrement(volatile long * const lpAddend)
|
||||
{
|
||||
return _InterlockedExchangeAdd(lpAddend, 1) + 1;
|
||||
}
|
||||
@@ -463,34 +483,34 @@ static __inline__ __attribute__((always_inline)) long _InterlockedIncrement(vola
|
||||
/* NOTE: we don't set a memory clobber in the __stosX functions because Visual C++ doesn't */
|
||||
/* Note that the PPC store multiple operations may raise an exception in LE
|
||||
* mode */
|
||||
static __inline__ __attribute__((always_inline)) void __stosb(unsigned char * Dest, const unsigned char Data, unsigned long Count)
|
||||
PPC_QUAL void __stosb(unsigned char * Dest, const unsigned char Data, unsigned long Count)
|
||||
{
|
||||
memset(Dest, Data, Count);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __stosw(unsigned short * Dest, const unsigned short Data, unsigned long Count)
|
||||
PPC_QUAL void __stosw(unsigned short * Dest, const unsigned short Data, unsigned long Count)
|
||||
{
|
||||
while(Count--)
|
||||
*Dest++ = Data;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __stosd(unsigned long * Dest, const unsigned long Data, unsigned long Count)
|
||||
PPC_QUAL void __stosd(unsigned long * Dest, const unsigned long Data, unsigned long Count)
|
||||
{
|
||||
while(Count--)
|
||||
*Dest++ = Data;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __movsb(unsigned char * Destination, const unsigned char * Source, unsigned long Count)
|
||||
PPC_QUAL void __movsb(unsigned char * Destination, const unsigned char * Source, unsigned long Count)
|
||||
{
|
||||
memcpy(Destination, Source, Count);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __movsw(unsigned short * Destination, const unsigned short * Source, unsigned long Count)
|
||||
PPC_QUAL void __movsw(unsigned short * Destination, const unsigned short * Source, unsigned long Count)
|
||||
{
|
||||
memcpy(Destination, Source, Count * sizeof(*Source));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __movsd(unsigned long * Destination, const unsigned long * Source, unsigned long Count)
|
||||
PPC_QUAL void __movsd(unsigned long * Destination, const unsigned long * Source, unsigned long Count)
|
||||
{
|
||||
memcpy(Destination, Source, Count * sizeof(*Source));
|
||||
}
|
||||
@@ -499,25 +519,25 @@ static __inline__ __attribute__((always_inline)) void __movsd(unsigned long * De
|
||||
/*** FS segment addressing ***/
|
||||
/* On PowerPC, r13 points to TLS data, including the TEB at 0(r13) from what I
|
||||
* can tell */
|
||||
static __inline__ __attribute__((always_inline)) void __writefsbyte(const unsigned long Offset, const unsigned char Data)
|
||||
PPC_QUAL void __writefsbyte(const unsigned long Offset, const unsigned char Data)
|
||||
{
|
||||
char *addr;
|
||||
__asm__("\tadd %0,13,%1\n\tstb %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writefsword(const unsigned long Offset, const unsigned short Data)
|
||||
PPC_QUAL void __writefsword(const unsigned long Offset, const unsigned short Data)
|
||||
{
|
||||
char *addr;
|
||||
__asm__("\tadd %0,13,%1\n\tsth %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writefsdword(const unsigned long Offset, const unsigned long Data)
|
||||
PPC_QUAL void __writefsdword(const unsigned long Offset, const unsigned long Data)
|
||||
{
|
||||
char *addr;
|
||||
__asm__("\tadd %0,13,%1\n\tstw %2,0(%0)" : "=r" (addr) : "r" (Offset), "r" (Data));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char __readfsbyte(const unsigned long Offset)
|
||||
PPC_QUAL unsigned char __readfsbyte(const unsigned long Offset)
|
||||
{
|
||||
unsigned short result;
|
||||
__asm__("\tadd 7,13,%1\n"
|
||||
@@ -528,7 +548,7 @@ static __inline__ __attribute__((always_inline)) unsigned char __readfsbyte(cons
|
||||
return result;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned short __readfsword(const unsigned long Offset)
|
||||
PPC_QUAL unsigned short __readfsword(const unsigned long Offset)
|
||||
{
|
||||
unsigned short result;
|
||||
__asm__("\tadd 7,13,%1\n"
|
||||
@@ -539,7 +559,7 @@ static __inline__ __attribute__((always_inline)) unsigned short __readfsword(con
|
||||
return result;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __readfsdword(const unsigned long Offset)
|
||||
PPC_QUAL unsigned long __readfsdword(const unsigned long Offset)
|
||||
{
|
||||
unsigned long result;
|
||||
__asm__("\tadd 7,13,%1\n"
|
||||
@@ -550,41 +570,41 @@ static __inline__ __attribute__((always_inline)) unsigned long __readfsdword(con
|
||||
return result;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __incfsbyte(const unsigned long Offset)
|
||||
PPC_QUAL void __incfsbyte(const unsigned long Offset)
|
||||
{
|
||||
__writefsbyte(Offset, __readfsbyte(Offset)+1);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __incfsword(const unsigned long Offset)
|
||||
PPC_QUAL void __incfsword(const unsigned long Offset)
|
||||
{
|
||||
__writefsword(Offset, __readfsword(Offset)+1);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __incfsdword(const unsigned long Offset)
|
||||
PPC_QUAL void __incfsdword(const unsigned long Offset)
|
||||
{
|
||||
__writefsdword(Offset, __readfsdword(Offset)+1);
|
||||
}
|
||||
|
||||
/* NOTE: the bizarre implementation of __addfsxxx mimics the broken Visual C++ behavior */
|
||||
/* PPC Note: Not sure about the bizarre behavior. We'll try to emulate it later */
|
||||
static __inline__ __attribute__((always_inline)) void __addfsbyte(const unsigned long Offset, const unsigned char Data)
|
||||
PPC_QUAL void __addfsbyte(const unsigned long Offset, const unsigned char Data)
|
||||
{
|
||||
__writefsbyte(Offset, __readfsbyte(Offset) + Data);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __addfsword(const unsigned long Offset, const unsigned short Data)
|
||||
PPC_QUAL void __addfsword(const unsigned long Offset, const unsigned short Data)
|
||||
{
|
||||
__writefsword(Offset, __readfsword(Offset) + Data);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __addfsdword(const unsigned long Offset, const unsigned int Data)
|
||||
PPC_QUAL void __addfsdword(const unsigned long Offset, const unsigned int Data)
|
||||
{
|
||||
__writefsdword(Offset, __readfsdword(Offset) + Data);
|
||||
}
|
||||
|
||||
|
||||
/*** Bit manipulation ***/
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask)
|
||||
PPC_QUAL unsigned char _BitScanForward(unsigned long * const Index, const unsigned long Mask)
|
||||
{
|
||||
if(Mask == 0) return 0;
|
||||
else {
|
||||
@@ -601,7 +621,7 @@ static __inline__ __attribute__((always_inline)) unsigned char _BitScanForward(
|
||||
}
|
||||
|
||||
/* Thanks http://www.jjj.de/bitwizardry/files/bithigh.h */
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask)
|
||||
PPC_QUAL unsigned char _BitScanReverse(unsigned long * const Index, const unsigned long Mask)
|
||||
{
|
||||
unsigned long check = 16, checkmask;
|
||||
if(Mask == 0) return 0;
|
||||
@@ -621,82 +641,82 @@ static __inline__ __attribute__((always_inline)) unsigned char _BitScanReverse(
|
||||
}
|
||||
|
||||
/* NOTE: again, the bizarre implementation follows Visual C++ */
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _bittest(const long * const a, const long b)
|
||||
PPC_QUAL unsigned char _bittest(const long * const a, const long b)
|
||||
{
|
||||
return ((*a) & (1<<b)) != 0;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _bittestandcomplement(long * const a, const long b)
|
||||
PPC_QUAL unsigned char _bittestandcomplement(long * const a, const long b)
|
||||
{
|
||||
unsigned char ret = ((*a) & (1<<b)) != 0;
|
||||
(*a) ^= (1<<b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _bittestandreset(long * const a, const long b)
|
||||
PPC_QUAL unsigned char _bittestandreset(long * const a, const long b)
|
||||
{
|
||||
unsigned char ret = ((*a) & (1<<b)) != 0;
|
||||
(*a) &= ~(1<<b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _bittestandset(long * const a, const long b)
|
||||
PPC_QUAL unsigned char _bittestandset(long * const a, const long b)
|
||||
{
|
||||
unsigned char ret = ((*a) & (1<<b)) != 0;
|
||||
(*a) |= (1<<b);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _rotl8(const unsigned char value, const unsigned char shift)
|
||||
PPC_QUAL unsigned char _rotl8(const unsigned char value, const unsigned char shift)
|
||||
{
|
||||
return (value << shift) | (value >> (8-shift));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned short _rotl16(const unsigned short value, const unsigned char shift)
|
||||
PPC_QUAL unsigned short _rotl16(const unsigned short value, const unsigned char shift)
|
||||
{
|
||||
return (value << shift) | (value >> (16-shift));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned char _rotr8(const unsigned char value, const unsigned char shift)
|
||||
PPC_QUAL unsigned char _rotr8(const unsigned char value, const unsigned char shift)
|
||||
{
|
||||
return (value >> shift) | (value << (8-shift));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned short _rotr16(const unsigned short value, const unsigned char shift)
|
||||
PPC_QUAL unsigned short _rotr16(const unsigned short value, const unsigned char shift)
|
||||
{
|
||||
return (value >> shift) | (value << (16-shift));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)
|
||||
PPC_QUAL unsigned long long __ll_lshift(const unsigned long long Mask, int Bit)
|
||||
{
|
||||
return Mask << Bit;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long long __ll_rshift(const long long Mask, const int Bit)
|
||||
PPC_QUAL long long __ll_rshift(const long long Mask, const int Bit)
|
||||
{
|
||||
return Mask >> Bit;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
|
||||
PPC_QUAL unsigned long long __ull_rshift(const unsigned long long Mask, int Bit)
|
||||
{
|
||||
return Mask >> Bit;
|
||||
}
|
||||
|
||||
|
||||
/*** 64-bit math ***/
|
||||
static __inline__ __attribute__((always_inline)) long long __emul(const int a, const int b)
|
||||
PPC_QUAL long long __emul(const int a, const int b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __emulu(const unsigned int a, const unsigned int b)
|
||||
PPC_QUAL unsigned long long __emulu(const unsigned int a, const unsigned int b)
|
||||
{
|
||||
return a * b;
|
||||
}
|
||||
|
||||
|
||||
/*** Port I/O ***/
|
||||
static __inline__ __attribute__((always_inline)) unsigned char __inbyte(const unsigned short Port)
|
||||
PPC_QUAL unsigned char __inbyte(const unsigned short Port)
|
||||
{
|
||||
int ret;
|
||||
__asm__(
|
||||
@@ -711,7 +731,7 @@ static __inline__ __attribute__((always_inline)) unsigned char __inbyte(const un
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned short __inword(const unsigned short Port)
|
||||
PPC_QUAL unsigned short __inword(const unsigned short Port)
|
||||
{
|
||||
int ret;
|
||||
__asm__(
|
||||
@@ -726,7 +746,7 @@ static __inline__ __attribute__((always_inline)) unsigned short __inword(const u
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __indword(const unsigned short Port)
|
||||
PPC_QUAL unsigned long __indword(const unsigned short Port)
|
||||
{
|
||||
int ret;
|
||||
__asm__(
|
||||
@@ -741,28 +761,28 @@ static __inline__ __attribute__((always_inline)) unsigned long __indword(const u
|
||||
return ret;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __inbytestring(unsigned short Port, unsigned char * Buffer, unsigned long Count)
|
||||
PPC_QUAL void __inbytestring(unsigned short Port, unsigned char * Buffer, unsigned long Count)
|
||||
{
|
||||
while(Count--) {
|
||||
*Buffer++ = __inbyte(Port);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __inwordstring(unsigned short Port, unsigned short * Buffer, unsigned long Count)
|
||||
PPC_QUAL void __inwordstring(unsigned short Port, unsigned short * Buffer, unsigned long Count)
|
||||
{
|
||||
while(Count--) {
|
||||
*Buffer++ = __inword(Port);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __indwordstring(unsigned short Port, unsigned long * Buffer, unsigned long Count)
|
||||
PPC_QUAL void __indwordstring(unsigned short Port, unsigned long * Buffer, unsigned long Count)
|
||||
{
|
||||
while(Count--) {
|
||||
*Buffer++ = __indword(Port);
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outbyte(unsigned short const Port, const unsigned char Data)
|
||||
PPC_QUAL void __outbyte(unsigned short const Port, const unsigned char Data)
|
||||
{
|
||||
__asm__(
|
||||
"mfmsr 5\n\t"
|
||||
@@ -778,7 +798,7 @@ static __inline__ __attribute__((always_inline)) void __outbyte(unsigned short c
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outword(unsigned short const Port, const unsigned short Data)
|
||||
PPC_QUAL void __outword(unsigned short const Port, const unsigned short Data)
|
||||
{
|
||||
__asm__(
|
||||
"mfmsr 5\n\t"
|
||||
@@ -794,7 +814,7 @@ static __inline__ __attribute__((always_inline)) void __outword(unsigned short c
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outdword(unsigned short const Port, const unsigned long Data)
|
||||
PPC_QUAL void __outdword(unsigned short const Port, const unsigned long Data)
|
||||
{
|
||||
__asm__(
|
||||
"mfmsr 5\n\t"
|
||||
@@ -810,7 +830,7 @@ static __inline__ __attribute__((always_inline)) void __outdword(unsigned short
|
||||
);
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outbytestring(unsigned short const Port, const unsigned char * const Buffer, const unsigned long Count)
|
||||
PPC_QUAL void __outbytestring(unsigned short const Port, const unsigned char * const Buffer, const unsigned long Count)
|
||||
{
|
||||
unsigned long count = Count;
|
||||
const unsigned char *buffer = Buffer;
|
||||
@@ -819,7 +839,7 @@ static __inline__ __attribute__((always_inline)) void __outbytestring(unsigned s
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outwordstring(unsigned short const Port, const unsigned short * const Buffer, const unsigned long Count)
|
||||
PPC_QUAL void __outwordstring(unsigned short const Port, const unsigned short * const Buffer, const unsigned long Count)
|
||||
{
|
||||
unsigned long count = Count;
|
||||
const unsigned short *buffer = Buffer;
|
||||
@@ -828,7 +848,7 @@ static __inline__ __attribute__((always_inline)) void __outwordstring(unsigned s
|
||||
}
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __outdwordstring(unsigned short const Port, const unsigned long * const Buffer, const unsigned long Count)
|
||||
PPC_QUAL void __outdwordstring(unsigned short const Port, const unsigned long * const Buffer, const unsigned long Count)
|
||||
{
|
||||
unsigned long count = Count;
|
||||
const unsigned long *buffer = Buffer;
|
||||
@@ -839,13 +859,13 @@ static __inline__ __attribute__((always_inline)) void __outdwordstring(unsigned
|
||||
|
||||
|
||||
/*** System information ***/
|
||||
static __inline__ __attribute__((always_inline)) void __cpuid(int CPUInfo[], const int InfoType)
|
||||
PPC_QUAL void __cpuid(int CPUInfo[], const int InfoType)
|
||||
{
|
||||
unsigned long lo32;
|
||||
__asm__("mfpvr" : "=b" (lo32));
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void)
|
||||
PPC_QUAL unsigned long long __rdtsc(void)
|
||||
{
|
||||
unsigned long lo32;
|
||||
__asm__("mfdec %0" : "=b" (lo32));
|
||||
@@ -855,19 +875,19 @@ static __inline__ __attribute__((always_inline)) unsigned long long __rdtsc(void
|
||||
|
||||
/*** Interrupts ***/
|
||||
/* Finally decided to do this by enabling single step trap */
|
||||
static __inline__ __attribute__((always_inline)) void __debugbreak(void)
|
||||
PPC_QUAL void __debugbreak(void)
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __int2c(void)
|
||||
PPC_QUAL void __int2c(void)
|
||||
{
|
||||
/* Not sure yet */
|
||||
}
|
||||
|
||||
#ifndef _ENABLE_DISABLE_DEFINED
|
||||
#define _ENABLE_DISABLE_DEFINED
|
||||
static __inline__ __attribute__((always_inline)) void _disable(void)
|
||||
PPC_QUAL void _disable(void)
|
||||
{
|
||||
__asm__ __volatile__("mfmsr 0\n\t" \
|
||||
"li 8,0x7fff\n\t" \
|
||||
@@ -875,7 +895,7 @@ static __inline__ __attribute__((always_inline)) void _disable(void)
|
||||
"mtmsr 0\n\t");
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void _enable(void)
|
||||
PPC_QUAL void _enable(void)
|
||||
{
|
||||
__asm__ __volatile__("mfmsr 0\n\t" \
|
||||
"lis 8,0x8000@ha\n\t" \
|
||||
@@ -884,14 +904,14 @@ static __inline__ __attribute__((always_inline)) void _enable(void)
|
||||
}
|
||||
|
||||
/*** Protected memory management ***/
|
||||
static __inline__ __attribute__((always_inline)) unsigned long __readsdr1(void)
|
||||
PPC_QUAL unsigned long __readsdr1(void)
|
||||
{
|
||||
unsigned long value;
|
||||
__asm__("mfsdr1 %0" : "=b" (value));
|
||||
return value;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writesdr1(const unsigned long long Data)
|
||||
PPC_QUAL void __writesdr1(const unsigned long long Data)
|
||||
{
|
||||
__asm__("mtsdr1 %0" : : "b" (Data));
|
||||
}
|
||||
@@ -899,14 +919,14 @@ static __inline__ __attribute__((always_inline)) void __writesdr1(const unsigned
|
||||
/*** System operations ***/
|
||||
/* This likely has a different meaning from the X86 equivalent. We'll keep
|
||||
* the name cause it fits */
|
||||
static __inline__ __attribute__((always_inline)) unsigned long long __readmsr()
|
||||
PPC_QUAL unsigned long long __readmsr()
|
||||
{
|
||||
unsigned long temp;
|
||||
__asm__("mfmsr %0" : "=b" (temp));
|
||||
return temp;
|
||||
}
|
||||
|
||||
static __inline__ __attribute__((always_inline)) void __writemsr(const unsigned long Value)
|
||||
PPC_QUAL void __writemsr(const unsigned long Value)
|
||||
{
|
||||
__asm__("mtmsr %0" : : "b" (Value));
|
||||
}
|
||||
@@ -917,7 +937,7 @@ static __inline__ __attribute__((always_inline)) void __writemsr(const unsigned
|
||||
* We've reloaded anything in the data or instruction cache that might have
|
||||
* changed in real ram.
|
||||
*/
|
||||
static __inline__ __attribute__((always_inline)) void __wbinvd(void)
|
||||
PPC_QUAL void __wbinvd(void)
|
||||
{
|
||||
__asm__("eieio\n\t"
|
||||
"dcs\n\t"
|
||||
@@ -926,7 +946,7 @@ static __inline__ __attribute__((always_inline)) void __wbinvd(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
static __inline__ __attribute__((always_inline)) long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value)
|
||||
PPC_QUAL long _InterlockedAddLargeStatistic(volatile long long * const Addend, const long Value)
|
||||
{
|
||||
#if 0
|
||||
__asm__
|
||||
|
||||
@@ -2021,7 +2021,7 @@ typedef struct _ACL_SIZE_INFORMATION {
|
||||
} ACL_SIZE_INFORMATION;
|
||||
|
||||
/* FIXME: add more machines */
|
||||
#if defined(_X86_) || defined(unix)
|
||||
#if defined(_X86_) || defined(unix) && !defined(__PowerPC__)
|
||||
#define SIZE_OF_80387_REGISTERS 80
|
||||
#define CONTEXT_i386 0x10000
|
||||
#define CONTEXT_i486 0x10000
|
||||
@@ -2077,7 +2077,8 @@ typedef struct _CONTEXT {
|
||||
#define CONTEXT_INTEGER 4L
|
||||
#define CONTEXT_DEBUG_REGISTERS 8L
|
||||
#define CONTEXT_FULL (CONTEXT_CONTROL|CONTEXT_FLOATING_POINT|CONTEXT_INTEGER)
|
||||
typedef struct _CONTEXT {
|
||||
typedef struct _FLOATING_SAVE_AREA
|
||||
{
|
||||
double Fpr0;
|
||||
double Fpr1;
|
||||
double Fpr2;
|
||||
@@ -2111,6 +2112,10 @@ typedef struct _CONTEXT {
|
||||
double Fpr30;
|
||||
double Fpr31;
|
||||
double Fpscr;
|
||||
} FLOATING_SAVE_AREA;
|
||||
|
||||
typedef struct _CONTEXT {
|
||||
FLOATING_SAVE_AREA FloatSave;
|
||||
DWORD Gpr0;
|
||||
DWORD Gpr1;
|
||||
DWORD Gpr2;
|
||||
@@ -4101,6 +4106,11 @@ static __inline__ struct _TEB * NtCurrentTeb(void)
|
||||
return __readfsdword_winnt(0x18);
|
||||
}
|
||||
#endif
|
||||
#elif defined(_M_PPC)
|
||||
static __inline__ struct _TEB * NtCurrentTeb(void)
|
||||
{
|
||||
return __readfsdword_winnt(0x18);
|
||||
}
|
||||
#endif
|
||||
|
||||
#elif defined(__WATCOMC__)
|
||||
|
||||
@@ -25,6 +25,9 @@
|
||||
<directory name="inflib">
|
||||
<xi:include href="inflib/inflib.rbuild" />
|
||||
</directory>
|
||||
<directory name="ppcmmu">
|
||||
<xi:include href="ppcmmu/ppcmmu.rbuild" />
|
||||
</directory>
|
||||
<directory name="pseh">
|
||||
<xi:include href="pseh/pseh.rbuild" />
|
||||
</directory>
|
||||
|
||||
@@ -0,0 +1,82 @@
|
||||
// Copyright (c) 2004/2005 KJK::Hyperion
|
||||
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to dos so, subject to the following conditions:
|
||||
|
||||
// The above copyright notice and this permission notice shall be included in all
|
||||
// copies or substantial portions of the Software.
|
||||
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
// SOFTWARE.
|
||||
|
||||
.text
|
||||
|
||||
__readfsdword:
|
||||
add 7,13,3
|
||||
lwz 3,0(7)
|
||||
blr
|
||||
|
||||
__writefsdword:
|
||||
add 7,13,3
|
||||
stw 3,0(7)
|
||||
blr
|
||||
|
||||
.globl _SEHCleanHandlerEnvironment
|
||||
_SEHCleanHandlerEnvironment:
|
||||
blr
|
||||
|
||||
.globl _SEHCurrentRegistration
|
||||
_SEHCurrentRegistration:
|
||||
xor 3,0,0
|
||||
bl __readfsdword
|
||||
blr
|
||||
|
||||
.globl _SEHRegisterFrame
|
||||
_SEHRegisterFrame:
|
||||
xor 3,0,0
|
||||
bl __readfsdword # Get [fs:0]
|
||||
lwz 4,0(1) # Get next stack frame into r4
|
||||
stw 3,0(1) # put [fs:0] into old stack pos
|
||||
xor 3,0,0
|
||||
bl __writefsdword # put old stack frame into [fs:0] completing
|
||||
blr # the chain and return
|
||||
|
||||
.globl _SEHUnregisterFrame
|
||||
_SEHUnregisterFrame:
|
||||
xor 3,0,0
|
||||
bl __readfsdword # Get old next frame ptr
|
||||
stw 3,0(1) # Reset old stack frame
|
||||
blr
|
||||
|
||||
.globl _SEHGlobalUnwind
|
||||
_SEHGlobalUnwind:
|
||||
|
||||
.extern _SEHRtlUnwind
|
||||
|
||||
// RtlUnwind clobbers all the "don't clobber" registers, so we save them
|
||||
lwz 3,4(1)
|
||||
stwu 1,-132(1)
|
||||
stmw 2,-128(1)
|
||||
|
||||
xor 6,6,6
|
||||
xor 5,5,5
|
||||
lis 4,.RestoreRegisters@ha
|
||||
addi 4,4,.RestoreRegisters@l # Where to jump back to
|
||||
# We already have r3
|
||||
bl _SEHRtlUnwind
|
||||
|
||||
.RestoreRegisters:
|
||||
lmw 2,-128(1)
|
||||
addi 1,1,132
|
||||
blr
|
||||
|
||||
// EOF
|
||||
@@ -7,5 +7,10 @@
|
||||
<file>framebased.S</file>
|
||||
</directory>
|
||||
</if>
|
||||
<if property="ARCH" value="powerpc">
|
||||
<directory name="powerpc">
|
||||
<file>framebased.S</file>
|
||||
</directory>
|
||||
</if>
|
||||
<file>framebased.c</file>
|
||||
</module>
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
*
|
||||
*/
|
||||
|
||||
.globl RtlCompareMemory
|
||||
.globl RtlCompareMemoryUlong
|
||||
.globl RtlFillMemory
|
||||
.globl RtlFillMemoryUlong
|
||||
.globl RtlFillMemoryUlonglong
|
||||
.globl RtlMoveMemory
|
||||
.globl RtlZeroMemory
|
||||
.globl RtlPrefetchMemoryNonTemporal
|
||||
|
||||
RtlCompareMemory:
|
||||
1:
|
||||
mr 0,5
|
||||
|
||||
cmpwi 0,5,4
|
||||
blt 2f
|
||||
|
||||
lwz 6,0(3)
|
||||
lwz 7,0(3)
|
||||
addi 6,6,-7
|
||||
cmpwi 0,6,0
|
||||
bne 2f
|
||||
|
||||
addi 3,3,4
|
||||
addi 4,4,4
|
||||
subi 5,5,4
|
||||
b 1b
|
||||
|
||||
2:
|
||||
cmpwi 0,5,0
|
||||
beq 3f
|
||||
|
||||
lbz 6,0(3)
|
||||
lbz 7,0(4)
|
||||
addi 6,6,-7
|
||||
cmpwi 0,6,0
|
||||
bne 3f
|
||||
|
||||
addi 3,3,1
|
||||
addi 4,4,1
|
||||
subi 5,5,1
|
||||
b 2b
|
||||
|
||||
3:
|
||||
mr 4,0
|
||||
sub 3,4,5
|
||||
blr
|
||||
|
||||
RtlCompareMemoryUlong:
|
||||
or 6,3,4
|
||||
or 6,6,5
|
||||
andi. 6,6,3
|
||||
bne RtlCompareMemory
|
||||
xor 3,3,3
|
||||
blr
|
||||
|
||||
RtlFillMemory:
|
||||
rlwinm 6,5,8,0xff00
|
||||
rlwinm 7,5,0,0xff
|
||||
or 7,6,7
|
||||
rlwinm 5,7,16,0xffff0000
|
||||
or 5,7,5
|
||||
|
||||
1:
|
||||
cmpwi 0,4,4
|
||||
blt 2f
|
||||
|
||||
stw 5,0(3)
|
||||
|
||||
addi 3,3,4
|
||||
subi 4,4,4
|
||||
b 1b
|
||||
|
||||
2:
|
||||
cmpwi 0,4,0
|
||||
beq 3f
|
||||
|
||||
stb 5,0(3)
|
||||
|
||||
addi 3,3,1
|
||||
subi 4,4,1
|
||||
b 2b
|
||||
|
||||
3:
|
||||
blr
|
||||
|
||||
RtlFillMemoryUlong:
|
||||
b RtlFillMemory
|
||||
|
||||
RtlFillMemoryUlonglong:
|
||||
b RtlFillMemoryUlong
|
||||
|
||||
RtlMoveMemory:
|
||||
b memmove
|
||||
|
||||
RtlZeroMemory:
|
||||
mr 5,4
|
||||
xor 4,4,4
|
||||
b memset
|
||||
|
||||
RtlPrefetchMemoryNonTemporal:
|
||||
blr
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS Run-Time Library
|
||||
* PURPOSE: Byte swap functions
|
||||
* FILE: lib/rtl/i386/rtlswap.S
|
||||
* PROGRAMER: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
.globl RtlUshortByteSwap
|
||||
.globl RtlUlongByteSwap
|
||||
.globl RtlUlonglongByteSwap
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
RtlUshortByteSwap:
|
||||
/* Swap high and low bits */
|
||||
rlwinm 4,3,24,0xff
|
||||
rlwinm 5,3,8,0xff00
|
||||
or 3,4,5
|
||||
blr
|
||||
|
||||
RtlUlongByteSwap:
|
||||
rlwinm 4,3,8,0xff
|
||||
rlwinm 5,3,24,0xff000000
|
||||
or 4,4,5
|
||||
rlwinm 5,3,8,0xff0000
|
||||
rlwinm 3,3,24,0xff00
|
||||
or 3,4,5
|
||||
or 3,3,6
|
||||
blr
|
||||
|
||||
RtlUlonglongByteSwap:
|
||||
stwu 1,16(1)
|
||||
stw 4,4(1)
|
||||
bl RtlUlongByteSwap
|
||||
stw 3,4(1)
|
||||
lwz 3,4(1)
|
||||
bl RtlUlongByteSwap
|
||||
lwz 4,4(1)
|
||||
subi 1,1,16
|
||||
blr
|
||||
@@ -25,6 +25,8 @@
|
||||
<file>debug.c</file>
|
||||
<file>except.c</file>
|
||||
<file>interlocked.c</file>
|
||||
<file>rtlmem.s</file>
|
||||
<file>rtlswap.s</file>
|
||||
<file>thread.c</file>
|
||||
</directory>
|
||||
</if>
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
/* $Id: chkstk_asm.s 26099 2007-03-14 20:30:32Z ion $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* PURPOSE: Stack checker
|
||||
* FILE: lib/ntdll/rtl/i386/chkstk.s
|
||||
* PROGRAMER: arty
|
||||
*/
|
||||
|
||||
.globl _chkstk
|
||||
.globl _alloca_probe
|
||||
|
||||
/*
|
||||
_chkstk() is called by all stack allocations of more than 4 KB. It grows the
|
||||
stack in areas of 4 KB each, trying to access each area. This ensures that the
|
||||
guard page for the stack is hit, and the stack growing triggered
|
||||
*/
|
||||
_chkstk:
|
||||
_alloca_probe:
|
||||
/* return */
|
||||
blr
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS CRT
|
||||
* FILE: lib/crt/misc/i386/seh.S
|
||||
* PURPOSE: SEH Support for the CRT
|
||||
* PROGRAMMERS: arty
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ndk/asm.h>
|
||||
|
||||
#define DISPOSITION_DISMISS 0
|
||||
#define DISPOSITION_CONTINUE_SEARCH 1
|
||||
#define DISPOSITION_COLLIDED_UNWIND 3
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
.globl _global_unwind2
|
||||
.globl _local_unwind2
|
||||
.globl _abnormal_termination
|
||||
.globl _except_handler2
|
||||
.globl _except_handler3
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
unwind_handler:
|
||||
blr
|
||||
|
||||
_global_unwind2:
|
||||
blr
|
||||
|
||||
_local_unwind2:
|
||||
blr
|
||||
|
||||
_except_handler2:
|
||||
blr
|
||||
|
||||
_except_handler3:
|
||||
blr
|
||||
|
||||
//
|
||||
//
|
||||
// REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME REMOVE ME
|
||||
// sorry
|
||||
//
|
||||
//
|
||||
.globl RtlpGetStackLimits
|
||||
RtlpGetStackLimits:
|
||||
stwu 1,16(1)
|
||||
mflr 0
|
||||
|
||||
stw 0,4(1)
|
||||
stw 3,8(1)
|
||||
stw 4,12(1)
|
||||
|
||||
/* Get the current thread */
|
||||
lwz 3,KPCR_CURRENT_THREAD(13)
|
||||
|
||||
/* Get the stack limits */
|
||||
lwz 4,KTHREAD_STACK_LIMIT(3)
|
||||
lwz 5,KTHREAD_INITIAL_STACK(3)
|
||||
subi 5,5,SIZEOF_FX_SAVE_AREA
|
||||
|
||||
/* Return them */
|
||||
lwz 3,8(1)
|
||||
stw 4,0(3)
|
||||
|
||||
lwz 3,12(1)
|
||||
stw 5,0(3)
|
||||
|
||||
addi 1,1,16
|
||||
|
||||
/* return */
|
||||
blr
|
||||
@@ -19,8 +19,13 @@
|
||||
<file>seh.s</file>
|
||||
</directory>
|
||||
</if>
|
||||
<if property="ARCH" value="powerpc">
|
||||
<directory name="powerpc">
|
||||
<file>chkstk_asm.s</file>
|
||||
<file>seh.s</file>
|
||||
</directory>
|
||||
</if>
|
||||
</directory>
|
||||
|
||||
<directory name="math">
|
||||
<if property="ARCH" value="i386">
|
||||
<directory name="i386">
|
||||
|
||||
@@ -0,0 +1,834 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/config/i386/cmhardwr.c
|
||||
* PURPOSE: Configuration Manager - Hardware-Specific Code
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include "ntoskrnl.h"
|
||||
#include "../cm.h"
|
||||
#define NDEBUG
|
||||
#include "debug.h"
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
PCHAR CmpID1 = "PowerPC %u";
|
||||
PCHAR CmpID2 = "No Data";
|
||||
PCHAR CmpBiosStrings[] =
|
||||
{
|
||||
"Ver",
|
||||
"Rev",
|
||||
"Rel",
|
||||
"v0", "v1", "v2", "v3", "v4", "v5", "v6", "v7", "v8", "v9",
|
||||
"v 0", "v 1", "v 2", "v 3", "v 4", "v 5", "v 6", "v 7", "v 8", "v 9",
|
||||
NULL
|
||||
};
|
||||
|
||||
PCHAR CmpBiosBegin, CmpBiosSearchStart, CmpBiosSearchEnd;
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmpGetBiosDate(IN PCHAR BiosStart,
|
||||
IN ULONG BiosLength,
|
||||
IN PCHAR BiosDate,
|
||||
IN BOOLEAN FromBios)
|
||||
{
|
||||
CHAR LastDate[11] = {0}, CurrentDate[11];
|
||||
PCHAR p, pp;
|
||||
|
||||
/* Skip the signature and the magic, and loop the BIOS ROM */
|
||||
p = BiosStart + 2;
|
||||
pp = BiosStart + BiosLength - 5;
|
||||
while (p < pp)
|
||||
{
|
||||
/* Check for xx/yy/zz which we assume to be a date */
|
||||
if ((p[0] == '/') &&
|
||||
(p[3] == '/') &&
|
||||
(isdigit(p[-1])) &&
|
||||
(isdigit(p[1])) &&
|
||||
(isdigit(p[2])) &&
|
||||
(isdigit(p[4])) &&
|
||||
(isdigit(p[5])))
|
||||
{
|
||||
/* Copy the string proper */
|
||||
RtlMoveMemory(&CurrentDate[5], p - 2, 5);
|
||||
|
||||
/* Add a 0 if the month only has one digit */
|
||||
if (!isdigit(CurrentDate[5])) CurrentDate[5] = '0';
|
||||
|
||||
/* Now copy the year */
|
||||
CurrentDate[2] = p[4];
|
||||
CurrentDate[3] = p[5];
|
||||
CurrentDate[4] = CurrentDate[7] = CurrentDate[10] = ANSI_NULL;
|
||||
|
||||
/* If the date comes from the BIOS, check if it's a 4-digit year */
|
||||
if ((FromBios) &&
|
||||
(isdigit(p[6])) &&
|
||||
(isdigit(p[7])) &&
|
||||
((RtlEqualMemory(&p[4], "19", 2)) ||
|
||||
(RtlEqualMemory(&p[4], "20", 2))))
|
||||
{
|
||||
/* Copy the year proper */
|
||||
CurrentDate[0] = p[4];
|
||||
CurrentDate[1] = p[5];
|
||||
CurrentDate[2] = p[6];
|
||||
CurrentDate[3] = p[7];
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Otherwise, we'll just assume anything under 80 is 2000 */
|
||||
if (strtoul(&CurrentDate[2], NULL, 10) < 80)
|
||||
{
|
||||
/* Hopefully your BIOS wasn't made in 1979 */
|
||||
CurrentDate[0] = '2';
|
||||
CurrentDate[1] = '0';
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Anything over 80, was probably made in the 1900s... */
|
||||
CurrentDate[0] = '1';
|
||||
CurrentDate[1] = '9';
|
||||
}
|
||||
}
|
||||
|
||||
/* Add slashes were we previously had NULLs */
|
||||
CurrentDate[4] = CurrentDate[7] = '/';
|
||||
|
||||
/* Check which date is newer */
|
||||
if (memcmp(LastDate, CurrentDate, 10) < 0)
|
||||
{
|
||||
/* Found a newer date, select it */
|
||||
RtlMoveMemory(LastDate, CurrentDate, 10);
|
||||
}
|
||||
|
||||
p += 2;
|
||||
}
|
||||
p++;
|
||||
}
|
||||
|
||||
/* Make sure we found a date */
|
||||
if (LastDate[0])
|
||||
{
|
||||
/* Copy the year at the pp, and keep only the last two digits */
|
||||
RtlMoveMemory(BiosDate, &LastDate[5], 5);
|
||||
BiosDate[5] = '/';
|
||||
BiosDate[6] = LastDate[2];
|
||||
BiosDate[7] = LastDate[3];
|
||||
BiosDate[8] = ANSI_NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/* No date found, return empty string */
|
||||
BiosDate[0] = ANSI_NULL;
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
CmpGetBiosVersion(IN PCHAR BiosStart,
|
||||
IN ULONG BiosLength,
|
||||
IN PCHAR BiosVersion)
|
||||
{
|
||||
CHAR Buffer[128];
|
||||
PCHAR p, pp;
|
||||
USHORT i;
|
||||
|
||||
/* Check if we were given intitial data for the search */
|
||||
if (BiosStart)
|
||||
{
|
||||
/* Save it for later use */
|
||||
CmpBiosBegin = BiosStart;
|
||||
CmpBiosSearchStart = BiosStart + 1;
|
||||
CmpBiosSearchEnd = BiosStart + BiosLength - 2;
|
||||
}
|
||||
|
||||
/* Now loop the BIOS area */
|
||||
for (;;)
|
||||
{
|
||||
/* Start an initial search looking for numbers and periods */
|
||||
pp = NULL;
|
||||
while (CmpBiosSearchStart <= CmpBiosSearchEnd)
|
||||
{
|
||||
/* Check if we have an "x.y" version string */
|
||||
if ((*CmpBiosSearchStart == '.') &&
|
||||
(*(CmpBiosSearchStart + 1) >= '0') &&
|
||||
(*(CmpBiosSearchStart + 1) <= '9') &&
|
||||
(*(CmpBiosSearchStart - 1) >= '0') &&
|
||||
(*(CmpBiosSearchStart - 1) <= '9'))
|
||||
{
|
||||
/* Start looking in this area for the actual BIOS Version */
|
||||
pp = CmpBiosSearchStart;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Keep searching */
|
||||
CmpBiosSearchStart++;
|
||||
}
|
||||
}
|
||||
|
||||
/* Break out if we're went past the BIOS area */
|
||||
if (CmpBiosSearchStart > CmpBiosSearchEnd) return FALSE;
|
||||
|
||||
/* Move to the next 2 bytes */
|
||||
CmpBiosSearchStart += 2;
|
||||
|
||||
/* Null-terminate our scratch buffer and start the string here */
|
||||
Buffer[127] = ANSI_NULL;
|
||||
p = &Buffer[127];
|
||||
|
||||
/* Go back one character since we're doing this backwards */
|
||||
pp--;
|
||||
|
||||
/* Loop the identifier we found as long as it's valid */
|
||||
i = 0;
|
||||
while ((i++ < 127) &&
|
||||
(pp >= CmpBiosBegin) &&
|
||||
(*pp >= ' ') &&
|
||||
(*pp != '$'))
|
||||
{
|
||||
/* Copy the character */
|
||||
*--p = *pp--;
|
||||
}
|
||||
|
||||
/* Go past the last character since we went backwards */
|
||||
pp++;
|
||||
|
||||
/* Loop the strings we recognize */
|
||||
for (i = 0; CmpBiosStrings[i]; i++)
|
||||
{
|
||||
/* Check if a match was found */
|
||||
if (strstr(p, CmpBiosStrings[i])) goto Match;
|
||||
}
|
||||
}
|
||||
|
||||
Match:
|
||||
/* Skip until we find a space */
|
||||
for (; *pp == ' '; pp++);
|
||||
|
||||
/* Loop the final string */
|
||||
i = 0;
|
||||
do
|
||||
{
|
||||
/* Copy the character into the final string */
|
||||
BiosVersion[i] = *pp++;
|
||||
} while ((++i < 127) &&
|
||||
(pp <= (CmpBiosSearchEnd + 1)) &&
|
||||
(*pp >= ' ') &&
|
||||
(*pp != '$'));
|
||||
|
||||
/* Null-terminate the version string */
|
||||
BiosVersion[i] = ANSI_NULL;
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
CmpInitializeMachineDependentConfiguration(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
UNICODE_STRING KeyName, ValueName, Data, SectionName;
|
||||
OBJECT_ATTRIBUTES ObjectAttributes;
|
||||
ULONG HavePae, CacheSize, ViewSize, Length, TotalLength = 0, i, Disposition;
|
||||
NTSTATUS Status;
|
||||
HANDLE KeyHandle, BiosHandle, SystemHandle, FpuHandle, SectionHandle;
|
||||
CONFIGURATION_COMPONENT_DATA ConfigData;
|
||||
CHAR Buffer[128];
|
||||
ULONG ExtendedId = 0; //, Dummy;
|
||||
PKPRCB Prcb;
|
||||
USHORT IndexTable[MaximumType + 1] = {0};
|
||||
ANSI_STRING TempString;
|
||||
PCHAR PartialString = NULL, BiosVersion;
|
||||
CHAR CpuString[48];
|
||||
PVOID BaseAddress = NULL;
|
||||
LARGE_INTEGER ViewBase = {{0}};
|
||||
ULONG_PTR VideoRomBase;
|
||||
PCHAR CurrentVersion;
|
||||
extern UNICODE_STRING KeRosProcessorName, KeRosBiosDate, KeRosBiosVersion;
|
||||
extern UNICODE_STRING KeRosVideoBiosDate, KeRosVideoBiosVersion;
|
||||
|
||||
/* Open the SMSS Memory Management key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
|
||||
L"Control\\Session Manager\\Memory Management");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtOpenKey(&KeyHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Detect if PAE is enabled */
|
||||
HavePae = SharedUserData->ProcessorFeatures[PF_PAE_ENABLED];
|
||||
|
||||
/* Set the value */
|
||||
RtlInitUnicodeString(&ValueName, L"PhysicalAddressExtension");
|
||||
NtSetValueKey(KeyHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
&HavePae,
|
||||
sizeof(HavePae));
|
||||
|
||||
/* Close the key */
|
||||
NtClose(KeyHandle);
|
||||
}
|
||||
|
||||
/* Open the hardware description key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"\\Registry\\Machine\\Hardware\\Description\\System");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtOpenKey(&SystemHandle, KEY_READ | KEY_WRITE, &ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status)) return Status;
|
||||
|
||||
/* Create the BIOS Information key */
|
||||
RtlInitUnicodeString(&KeyName,
|
||||
L"\\Registry\\Machine\\SYSTEM\\CurrentControlSet\\"
|
||||
L"Control\\BIOSINFO");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = NtCreateKey(&BiosHandle,
|
||||
KEY_ALL_ACCESS,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
REG_OPTION_NON_VOLATILE,
|
||||
&Disposition);
|
||||
if (ExpInTextModeSetup)
|
||||
{
|
||||
if (!NT_SUCCESS(Status))
|
||||
BiosHandle = NULL;
|
||||
}
|
||||
else if (!NT_SUCCESS(Status))
|
||||
return Status;
|
||||
|
||||
/* Create the CPU Key, and check if it already existed */
|
||||
RtlInitUnicodeString(&KeyName, L"CentralProcessor");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&KeyName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
SystemHandle,
|
||||
NULL);
|
||||
Status = NtCreateKey(&KeyHandle,
|
||||
KEY_READ | KEY_WRITE,
|
||||
&ObjectAttributes,
|
||||
0,
|
||||
NULL,
|
||||
0,
|
||||
&Disposition);
|
||||
NtClose(KeyHandle);
|
||||
|
||||
/* The key shouldn't already exist */
|
||||
if (Disposition == REG_CREATED_NEW_KEY)
|
||||
{
|
||||
/* Allocate the configuration data for cmconfig.c */
|
||||
CmpConfigurationData = ExAllocatePoolWithTag(PagedPool,
|
||||
CmpConfigurationAreaSize,
|
||||
TAG_CM);
|
||||
if (!CmpConfigurationData) return STATUS_INSUFFICIENT_RESOURCES;
|
||||
|
||||
/* Loop all CPUs */
|
||||
for (i = 0; i < KeNumberProcessors; i++)
|
||||
{
|
||||
/* Get the PRCB */
|
||||
Prcb = KiProcessorBlock[i];
|
||||
|
||||
/* Setup the Configuration Entry for the Processor */
|
||||
RtlZeroMemory(&ConfigData, sizeof (ConfigData));
|
||||
ConfigData.ComponentEntry.Class = ProcessorClass;
|
||||
ConfigData.ComponentEntry.Type = CentralProcessor;
|
||||
ConfigData.ComponentEntry.Key = i;
|
||||
ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
|
||||
ConfigData.ComponentEntry.Identifier = Buffer;
|
||||
|
||||
/* Check if the CPU doesn't support CPUID */
|
||||
if (!Prcb->CpuID)
|
||||
{
|
||||
/* Build ID1-style string for older CPUs */
|
||||
sprintf(Buffer,
|
||||
CmpID1,
|
||||
Prcb->CpuType,
|
||||
(Prcb->CpuStep >> 8) + 'A',
|
||||
Prcb->CpuStep & 0xff);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Build ID2-style string for newer CPUs */
|
||||
sprintf(Buffer,
|
||||
CmpID2,
|
||||
Prcb->CpuType,
|
||||
(Prcb->CpuStep >> 8),
|
||||
Prcb->CpuStep & 0xff);
|
||||
}
|
||||
|
||||
/* Save the ID string length now that we've created it */
|
||||
ConfigData.ComponentEntry.IdentifierLength = strlen(Buffer) + 1;
|
||||
|
||||
/* Initialize the registry configuration node for it */
|
||||
Status = CmpInitializeRegistryNode(&ConfigData,
|
||||
SystemHandle,
|
||||
&KeyHandle,
|
||||
InterfaceTypeUndefined,
|
||||
0xFFFFFFFF,
|
||||
IndexTable);
|
||||
if (!NT_SUCCESS(Status)) return(Status);
|
||||
|
||||
{
|
||||
/* Setup the Configuration Entry for the FPU */
|
||||
RtlZeroMemory(&ConfigData, sizeof(ConfigData));
|
||||
ConfigData.ComponentEntry.Class = ProcessorClass;
|
||||
ConfigData.ComponentEntry.Type = FloatingPointProcessor;
|
||||
ConfigData.ComponentEntry.Key = i;
|
||||
ConfigData.ComponentEntry.AffinityMask = AFFINITY_MASK(i);
|
||||
ConfigData.ComponentEntry.Identifier = Buffer;
|
||||
|
||||
/* For 386 cpus, the CPU pp is the identifier */
|
||||
if (Prcb->CpuType == 3) strcpy(Buffer, "80387");
|
||||
|
||||
/* Save the ID string length now that we've created it */
|
||||
ConfigData.ComponentEntry.IdentifierLength = strlen(Buffer) + 1;
|
||||
|
||||
/* Initialize the registry configuration node for it */
|
||||
Status = CmpInitializeRegistryNode(&ConfigData,
|
||||
SystemHandle,
|
||||
&FpuHandle,
|
||||
InterfaceTypeUndefined,
|
||||
0xFFFFFFFF,
|
||||
IndexTable);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Failed, close the CPU handle and return */
|
||||
NtClose(KeyHandle);
|
||||
return Status;
|
||||
}
|
||||
|
||||
/* Close this new handle */
|
||||
NtClose(FpuHandle);
|
||||
|
||||
/* Stay on this CPU only */
|
||||
KeSetSystemAffinityThread(Prcb->SetMember);
|
||||
if (!Prcb->CpuID)
|
||||
{
|
||||
/* Uh oh, no CPUID! */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Check if we have extended CPUID that supports name ID */
|
||||
//Ki386Cpuid(0x80000000, &ExtendedId, &Dummy, &Dummy, &Dummy);
|
||||
if (ExtendedId >= 0x80000004)
|
||||
{
|
||||
/* Do all the CPUIDs requred to get the full name */
|
||||
PartialString = CpuString;
|
||||
for (ExtendedId = 2; ExtendedId <= 4; ExtendedId++)
|
||||
{
|
||||
#if 0
|
||||
/* Do the CPUID and save the name string */
|
||||
Ki386Cpuid(0x80000000 | ExtendedId,
|
||||
(PULONG)PartialString,
|
||||
(PULONG)PartialString + 1,
|
||||
(PULONG)PartialString + 2,
|
||||
(PULONG)PartialString + 3);
|
||||
#endif
|
||||
|
||||
/* Go to the next name string */
|
||||
PartialString += 16;
|
||||
}
|
||||
|
||||
/* Null-terminate it */
|
||||
CpuString[48] = ANSI_NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the cache size while we're still localized */
|
||||
CacheSize = 0; //((PKIPCR)KeGetPcr())->SecondLevelCacheSize;
|
||||
|
||||
/* Go back to user affinity */
|
||||
KeRevertToUserAffinityThread();
|
||||
|
||||
/* Check if we have a CPU Name */
|
||||
if (PartialString)
|
||||
{
|
||||
/* Convert it to Unicode */
|
||||
RtlInitAnsiString(&TempString, CpuString);
|
||||
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
|
||||
|
||||
/* Add it to the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"ProcessorNameString");
|
||||
Status = NtSetValueKey(KeyHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_SZ,
|
||||
Data.Buffer,
|
||||
Data.Length + sizeof(UNICODE_NULL));
|
||||
|
||||
/* ROS: Save a copy for bugzilla reporting */
|
||||
RtlCreateUnicodeString(&KeRosProcessorName, Data.Buffer);
|
||||
|
||||
/* Free the temporary buffer */
|
||||
RtlFreeUnicodeString(&Data);
|
||||
}
|
||||
|
||||
/* Check if we had a Vendor ID */
|
||||
if (Prcb->VendorString)
|
||||
{
|
||||
/* Convert it to Unicode */
|
||||
RtlInitAnsiString(&TempString, Prcb->VendorString);
|
||||
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
|
||||
|
||||
/* Add it to the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"VendorIdentifier");
|
||||
Status = NtSetValueKey(KeyHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_SZ,
|
||||
Data.Buffer,
|
||||
Data.Length + sizeof(UNICODE_NULL));
|
||||
|
||||
/* Free the temporary buffer */
|
||||
RtlFreeUnicodeString(&Data);
|
||||
}
|
||||
|
||||
/* Check if we have features bits */
|
||||
if (Prcb->FeatureBits)
|
||||
{
|
||||
/* Add them to the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"FeatureSet");
|
||||
Status = NtSetValueKey(KeyHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
&Prcb->FeatureBits,
|
||||
sizeof(Prcb->FeatureBits));
|
||||
}
|
||||
|
||||
/* Check if we detected the CPU Speed */
|
||||
if (Prcb->MHz)
|
||||
{
|
||||
/* Add it to the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"~MHz");
|
||||
Status = NtSetValueKey(KeyHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_DWORD,
|
||||
&Prcb->MHz,
|
||||
sizeof(Prcb->MHz));
|
||||
}
|
||||
|
||||
/* Check if we have an update signature */
|
||||
if (Prcb->UpdateSignature.QuadPart)
|
||||
{
|
||||
/* Add it to the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"Update Signature");
|
||||
Status = NtSetValueKey(KeyHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_BINARY,
|
||||
&Prcb->UpdateSignature,
|
||||
sizeof(Prcb->UpdateSignature));
|
||||
}
|
||||
|
||||
/* Close the processor handle */
|
||||
NtClose(KeyHandle);
|
||||
|
||||
/* FIXME: Detect CPU mismatches */
|
||||
}
|
||||
}
|
||||
|
||||
/* Free the configuration data */
|
||||
ExFreePool(CmpConfigurationData);
|
||||
}
|
||||
|
||||
/* Open physical memory */
|
||||
RtlInitUnicodeString(&SectionName, L"\\Device\\PhysicalMemory");
|
||||
InitializeObjectAttributes(&ObjectAttributes,
|
||||
&SectionName,
|
||||
OBJ_CASE_INSENSITIVE,
|
||||
NULL,
|
||||
NULL);
|
||||
Status = ZwOpenSection(&SectionHandle,
|
||||
SECTION_ALL_ACCESS,
|
||||
&ObjectAttributes);
|
||||
if (!NT_SUCCESS(Status)) goto Quickie;
|
||||
|
||||
/* Map the first 1KB of memory to get the IVT */
|
||||
ViewSize = PAGE_SIZE;
|
||||
Status = ZwMapViewOfSection(SectionHandle,
|
||||
NtCurrentProcess(),
|
||||
&BaseAddress,
|
||||
0,
|
||||
ViewSize,
|
||||
&ViewBase,
|
||||
&ViewSize,
|
||||
ViewUnmap,
|
||||
MEM_DOS_LIM,
|
||||
PAGE_READWRITE);
|
||||
if (!NT_SUCCESS(Status))
|
||||
{
|
||||
/* Assume default */
|
||||
VideoRomBase = 0xC0000;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Calculate the base address from the vector */
|
||||
VideoRomBase = (*((PULONG)BaseAddress + 0x10) >> 12) & 0xFFFF0;
|
||||
VideoRomBase += *((PULONG)BaseAddress + 0x10) & 0xFFF0;
|
||||
|
||||
/* Now get to the actual ROM Start and make sure it's not invalid*/
|
||||
VideoRomBase &= 0xFFFF8000;
|
||||
if (VideoRomBase < 0xC0000) VideoRomBase = 0xC0000;
|
||||
|
||||
/* And unmap the section */
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
}
|
||||
|
||||
/* Allocate BIOS Version pp Buffer */
|
||||
BiosVersion = ExAllocatePoolWithTag(PagedPool, PAGE_SIZE, TAG_CM);
|
||||
|
||||
/* Setup settings to map the 64K BIOS ROM */
|
||||
BaseAddress = 0;
|
||||
ViewSize = 16 * PAGE_SIZE;
|
||||
ViewBase.LowPart = 0xF0000;
|
||||
ViewBase.HighPart = 0;
|
||||
|
||||
/* Map it */
|
||||
Status = ZwMapViewOfSection(SectionHandle,
|
||||
NtCurrentProcess(),
|
||||
&BaseAddress,
|
||||
0,
|
||||
ViewSize,
|
||||
&ViewBase,
|
||||
&ViewSize,
|
||||
ViewUnmap,
|
||||
MEM_DOS_LIM,
|
||||
PAGE_READWRITE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Scan the ROM to get the BIOS Date */
|
||||
if (CmpGetBiosDate(BaseAddress, 16 * PAGE_SIZE, Buffer, TRUE))
|
||||
{
|
||||
/* Convert it to Unicode */
|
||||
RtlInitAnsiString(&TempString, Buffer);
|
||||
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
|
||||
|
||||
/* Write the date into the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"SystemBiosDate");
|
||||
Status = NtSetValueKey(SystemHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_SZ,
|
||||
Data.Buffer,
|
||||
Data.Length + sizeof(UNICODE_NULL));
|
||||
|
||||
/* Free the string */
|
||||
RtlFreeUnicodeString(&Data);
|
||||
|
||||
if (BiosHandle)
|
||||
{
|
||||
/* Get the BIOS Date Identifier */
|
||||
RtlCopyMemory(Buffer, (PCHAR)BaseAddress + (16*PAGE_SIZE - 11), 8);
|
||||
Buffer[8] = ANSI_NULL;
|
||||
|
||||
/* Convert it to unicode */
|
||||
RtlInitAnsiString(&TempString, Buffer);
|
||||
Status = RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Save it to the registry */
|
||||
Status = NtSetValueKey(BiosHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_SZ,
|
||||
Data.Buffer,
|
||||
Data.Length + sizeof(UNICODE_NULL));
|
||||
|
||||
/* ROS: Save a copy for bugzilla reporting */
|
||||
RtlCreateUnicodeString(&KeRosBiosDate, Data.Buffer);
|
||||
|
||||
/* Free the string */
|
||||
RtlFreeUnicodeString(&Data);
|
||||
}
|
||||
|
||||
/* Close the bios information handle */
|
||||
NtClose(BiosHandle);
|
||||
}
|
||||
}
|
||||
|
||||
/* Get the BIOS Version */
|
||||
if (CmpGetBiosVersion(BaseAddress, 16* PAGE_SIZE, Buffer))
|
||||
{
|
||||
/* Start at the beginning of our buffer */
|
||||
CurrentVersion = BiosVersion;
|
||||
do
|
||||
{
|
||||
/* Convert to Unicode */
|
||||
RtlInitAnsiString(&TempString, Buffer);
|
||||
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
|
||||
|
||||
/* Calculate the length of this string and copy it in */
|
||||
Length = Data.Length + sizeof(UNICODE_NULL);
|
||||
RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
|
||||
|
||||
/* Free the unicode string */
|
||||
RtlFreeUnicodeString(&Data);
|
||||
|
||||
/* Update the total length and see if we're out of space */
|
||||
TotalLength += Length;
|
||||
if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
|
||||
{
|
||||
/* One more string would push us out, so stop here */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Go to the next string inside the multi-string buffer */
|
||||
CurrentVersion += Length;
|
||||
|
||||
/* Query the next BIOS Version */
|
||||
} while (CmpGetBiosVersion(NULL, 0, Buffer));
|
||||
|
||||
/* Check if we found any strings at all */
|
||||
if (TotalLength)
|
||||
{
|
||||
/* Add the final null-terminator */
|
||||
*(PWSTR)CurrentVersion = UNICODE_NULL;
|
||||
TotalLength += sizeof(UNICODE_NULL);
|
||||
|
||||
/* Write the BIOS Version to the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"SystemBiosVersion");
|
||||
Status = NtSetValueKey(SystemHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_MULTI_SZ,
|
||||
BiosVersion,
|
||||
TotalLength);
|
||||
|
||||
/* ROS: Save a copy for bugzilla reporting */
|
||||
RtlCreateUnicodeString(&KeRosBiosVersion, (PWCH)BiosVersion);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unmap the section */
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
}
|
||||
|
||||
/* Now prepare for Video BIOS Mapping of 32KB */
|
||||
BaseAddress = 0;
|
||||
ViewSize = 8 * PAGE_SIZE;
|
||||
ViewBase.LowPart = VideoRomBase;
|
||||
ViewBase.HighPart = 0;
|
||||
|
||||
/* Map it */
|
||||
Status = ZwMapViewOfSection(SectionHandle,
|
||||
NtCurrentProcess(),
|
||||
&BaseAddress,
|
||||
0,
|
||||
ViewSize,
|
||||
&ViewBase,
|
||||
&ViewSize,
|
||||
ViewUnmap,
|
||||
MEM_DOS_LIM,
|
||||
PAGE_READWRITE);
|
||||
if (NT_SUCCESS(Status))
|
||||
{
|
||||
/* Scan the ROM to get the BIOS Date */
|
||||
if (CmpGetBiosDate(BaseAddress, 8 * PAGE_SIZE, Buffer, FALSE))
|
||||
{
|
||||
/* Convert it to Unicode */
|
||||
RtlInitAnsiString(&TempString, Buffer);
|
||||
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
|
||||
|
||||
/* Write the date into the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"VideoBiosDate");
|
||||
Status = NtSetValueKey(SystemHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_SZ,
|
||||
Data.Buffer,
|
||||
Data.Length + sizeof(UNICODE_NULL));
|
||||
|
||||
/* ROS: Save a copy for bugzilla reporting */
|
||||
RtlCreateUnicodeString(&KeRosVideoBiosDate, Data.Buffer);
|
||||
|
||||
/* Free the string */
|
||||
RtlFreeUnicodeString(&Data);
|
||||
}
|
||||
|
||||
/* Get the Video BIOS Version */
|
||||
if (CmpGetBiosVersion(BaseAddress, 8* PAGE_SIZE, Buffer))
|
||||
{
|
||||
/* Start at the beginning of our buffer */
|
||||
CurrentVersion = BiosVersion;
|
||||
do
|
||||
{
|
||||
/* Convert to Unicode */
|
||||
RtlInitAnsiString(&TempString, Buffer);
|
||||
RtlAnsiStringToUnicodeString(&Data, &TempString, TRUE);
|
||||
|
||||
/* Calculate the length of this string and copy it in */
|
||||
Length = Data.Length + sizeof(UNICODE_NULL);
|
||||
RtlMoveMemory(CurrentVersion, Data.Buffer, Length);
|
||||
|
||||
/* Free the unicode string */
|
||||
RtlFreeUnicodeString(&Data);
|
||||
|
||||
/* Update the total length and see if we're out of space */
|
||||
TotalLength += Length;
|
||||
if (TotalLength + 256 + sizeof(UNICODE_NULL) > PAGE_SIZE)
|
||||
{
|
||||
/* One more string would push us out, so stop here */
|
||||
break;
|
||||
}
|
||||
|
||||
/* Go to the next string inside the multi-string buffer */
|
||||
CurrentVersion += Length;
|
||||
|
||||
/* Query the next BIOS Version */
|
||||
} while (CmpGetBiosVersion(NULL, 0, Buffer));
|
||||
|
||||
/* Check if we found any strings at all */
|
||||
if (TotalLength)
|
||||
{
|
||||
/* Add the final null-terminator */
|
||||
*(PWSTR)CurrentVersion = UNICODE_NULL;
|
||||
TotalLength += sizeof(UNICODE_NULL);
|
||||
|
||||
/* Write the BIOS Version to the registry */
|
||||
RtlInitUnicodeString(&ValueName, L"VideoBiosVersion");
|
||||
Status = NtSetValueKey(SystemHandle,
|
||||
&ValueName,
|
||||
0,
|
||||
REG_MULTI_SZ,
|
||||
BiosVersion,
|
||||
TotalLength);
|
||||
|
||||
/* ROS: Save a copy for bugzilla reporting */
|
||||
RtlCreateUnicodeString(&KeRosVideoBiosVersion, (PWCH)BiosVersion);
|
||||
}
|
||||
}
|
||||
|
||||
/* Unmap the section */
|
||||
ZwUnmapViewOfSection(NtCurrentProcess(), BaseAddress);
|
||||
}
|
||||
|
||||
/* Close the section */
|
||||
ZwClose(SectionHandle);
|
||||
|
||||
/* Free the BIOS version string buffer */
|
||||
if (BiosVersion) ExFreePool(BiosVersion);
|
||||
|
||||
Quickie:
|
||||
/* Close the procesor handle */
|
||||
NtClose(KeyHandle);
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
@@ -0,0 +1,262 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* COPYRIGHT: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/ex/powerpc/fastinterlck.c
|
||||
* PURPOSE: Executive Atom Functions
|
||||
* PROGRAMMERS: Art Yerkes
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#include <internal/debug.h>
|
||||
|
||||
NTKERNELAPI
|
||||
PSINGLE_LIST_ENTRY
|
||||
FASTCALL
|
||||
ExInterlockedFlushSList(IN PSLIST_HEADER ListHead)
|
||||
{
|
||||
PSLIST_ENTRY NewHead = NULL;
|
||||
_InterlockedExchangePointer((PVOID *)&ListHead->Next.Next, &NewHead);
|
||||
return NewHead;
|
||||
}
|
||||
|
||||
#undef ExInterlockedPushEntrySList
|
||||
NTKERNELAPI
|
||||
PSLIST_ENTRY
|
||||
FASTCALL
|
||||
ExInterlockedPushEntrySList
|
||||
(IN PSLIST_HEADER ListHead,
|
||||
IN PSLIST_ENTRY ListEntry)
|
||||
{
|
||||
return InterlockedPushEntrySList(ListHead, ListEntry);
|
||||
}
|
||||
|
||||
#undef ExInterlockedPopEntrySList
|
||||
NTKERNELAPI
|
||||
PSINGLE_LIST_ENTRY
|
||||
NTAPI
|
||||
ExInterlockedPopEntrySList(
|
||||
IN PSLIST_HEADER ListHead,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return InterlockedPopEntrySList(ListHead);
|
||||
}
|
||||
|
||||
#undef ExInterlockedAddULong
|
||||
NTKERNELAPI
|
||||
ULONG
|
||||
NTAPI
|
||||
ExfInterlockedAddUlong(
|
||||
IN PULONG Addend,
|
||||
IN ULONG Increment,
|
||||
PKSPIN_LOCK Lock)
|
||||
{
|
||||
KIRQL OldIrql;
|
||||
KeAcquireSpinLock(Lock, &OldIrql);
|
||||
*Addend += Increment;
|
||||
KeReleaseSpinLock(Lock, OldIrql);
|
||||
return *Addend;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
LONGLONG
|
||||
FASTCALL
|
||||
ExfInterlockedCompareExchange64(
|
||||
IN OUT LONGLONG volatile *Destination,
|
||||
IN PLONGLONG Exchange,
|
||||
IN PLONGLONG Comperand)
|
||||
{
|
||||
return 0ll;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PLIST_ENTRY
|
||||
FASTCALL
|
||||
ExfInterlockedInsertHeadList(
|
||||
IN PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY ListEntry,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PLIST_ENTRY
|
||||
FASTCALL
|
||||
ExfInterlockedInsertTailList(
|
||||
IN PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY ListEntry,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PSINGLE_LIST_ENTRY
|
||||
FASTCALL
|
||||
ExfInterlockedPopEntryList(
|
||||
IN PSINGLE_LIST_ENTRY ListHead,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PSINGLE_LIST_ENTRY
|
||||
FASTCALL
|
||||
ExfInterlockedPushEntryList(
|
||||
IN PSINGLE_LIST_ENTRY ListHead,
|
||||
IN PSINGLE_LIST_ENTRY ListEntry,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PLIST_ENTRY
|
||||
FASTCALL
|
||||
ExfInterlockedRemoveHeadList(
|
||||
IN PLIST_ENTRY ListHead,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return ExInterlockedRemoveHeadList(ListHead, Lock);
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
INTERLOCKED_RESULT
|
||||
FASTCALL
|
||||
Exfi386InterlockedIncrementLong(
|
||||
IN PLONG Addend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
INTERLOCKED_RESULT
|
||||
FASTCALL
|
||||
Exfi386InterlockedDecrementLong(
|
||||
IN PLONG Addend)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
ULONG
|
||||
FASTCALL
|
||||
Exfi386InterlockedExchangeUlong(
|
||||
IN PULONG Target,
|
||||
IN ULONG Value)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
LARGE_INTEGER
|
||||
NTAPI
|
||||
ExInterlockedAddLargeInteger(
|
||||
IN PLARGE_INTEGER Addend,
|
||||
IN LARGE_INTEGER Increment,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
LARGE_INTEGER Result;
|
||||
Result.QuadPart = 0;
|
||||
return Result;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
ULONG
|
||||
NTAPI
|
||||
ExInterlockedAddUlong(
|
||||
IN PULONG Addend,
|
||||
IN ULONG Increment,
|
||||
PKSPIN_LOCK Lock)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef ExInterlockedIncrementLong
|
||||
NTKERNELAPI
|
||||
INTERLOCKED_RESULT
|
||||
NTAPI
|
||||
ExInterlockedIncrementLong(
|
||||
IN PLONG Addend,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
#undef ExInterlockedDecrementLong
|
||||
NTKERNELAPI
|
||||
INTERLOCKED_RESULT
|
||||
NTAPI
|
||||
ExInterlockedDecrementLong(
|
||||
IN PLONG Addend,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
ULONG
|
||||
NTAPI
|
||||
ExInterlockedExchangeUlong(
|
||||
IN PULONG Target,
|
||||
IN ULONG Value,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PLIST_ENTRY
|
||||
NTAPI
|
||||
ExInterlockedInsertHeadList(
|
||||
IN PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY ListEntry,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PLIST_ENTRY
|
||||
NTAPI
|
||||
ExInterlockedInsertTailList(
|
||||
IN PLIST_ENTRY ListHead,
|
||||
IN PLIST_ENTRY ListEntry,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PSINGLE_LIST_ENTRY
|
||||
NTAPI
|
||||
ExInterlockedPopEntryList(
|
||||
IN PSINGLE_LIST_ENTRY ListHead,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PSINGLE_LIST_ENTRY
|
||||
NTAPI
|
||||
ExInterlockedPushEntryList(
|
||||
IN PSINGLE_LIST_ENTRY ListHead,
|
||||
IN PSINGLE_LIST_ENTRY ListEntry,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
NTKERNELAPI
|
||||
PLIST_ENTRY
|
||||
NTAPI
|
||||
ExInterlockedRemoveHeadList(
|
||||
IN PLIST_ENTRY ListHead,
|
||||
IN PKSPIN_LOCK Lock)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
@@ -0,0 +1,171 @@
|
||||
/*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/ex/i386/ioport.S
|
||||
* PURPOSE: FASTCALL Interlocked Functions
|
||||
* PROGRAMMERS: Alex Ionescu (alex@relsoft.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ndk/asm.h>
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
.globl READ_REGISTER_UCHAR
|
||||
.globl READ_REGISTER_USHORT
|
||||
.globl READ_REGISTER_ULONG
|
||||
.globl READ_REGISTER_BUFFER_UCHAR
|
||||
.globl READ_REGISTER_BUFFER_USHORT
|
||||
.globl READ_REGISTER_BUFFER_ULONG
|
||||
.globl WRITE_REGISTER_UCHAR
|
||||
.globl WRITE_REGISTER_USHORT
|
||||
.globl WRITE_REGISTER_ULONG
|
||||
.globl WRITE_REGISTER_BUFFER_UCHAR
|
||||
.globl WRITE_REGISTER_BUFFER_USHORT
|
||||
.globl WRITE_REGISTER_BUFFER_ULONG
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
READ_REGISTER_UCHAR:
|
||||
/* Return the requested memory location */
|
||||
sync
|
||||
eieio
|
||||
lbz 3,0(3)
|
||||
blr
|
||||
|
||||
READ_REGISTER_USHORT:
|
||||
/* Return the requested memory location */
|
||||
sync
|
||||
eieio
|
||||
lhz 3,0(3)
|
||||
blr
|
||||
|
||||
READ_REGISTER_ULONG:
|
||||
/* Return the requested memory location */
|
||||
sync
|
||||
eieio
|
||||
lwz 3,0(3)
|
||||
blr
|
||||
|
||||
READ_REGISTER_BUFFER_UCHAR:
|
||||
1:
|
||||
cmpwi 0,5,0
|
||||
beq 2f
|
||||
|
||||
lbz 0,0(4)
|
||||
stb 0,0(3)
|
||||
|
||||
addi 3,3,1
|
||||
addi 4,4,1
|
||||
subi 5,5,1
|
||||
b 1b
|
||||
2:
|
||||
eieio
|
||||
sync
|
||||
blr
|
||||
|
||||
READ_REGISTER_BUFFER_USHORT:
|
||||
1:
|
||||
cmpwi 0,5,0
|
||||
beq 2f
|
||||
|
||||
lhz 0,0(4)
|
||||
sth 0,0(3)
|
||||
|
||||
addi 3,3,2
|
||||
addi 4,4,2
|
||||
subi 5,5,2
|
||||
b 1b
|
||||
2:
|
||||
eieio
|
||||
sync
|
||||
blr
|
||||
|
||||
READ_REGISTER_BUFFER_ULONG:
|
||||
1:
|
||||
cmpwi 0,5,0
|
||||
beq 2f
|
||||
|
||||
lwz 0,0(4)
|
||||
stw 0,0(3)
|
||||
|
||||
addi 3,3,4
|
||||
addi 4,4,4
|
||||
subi 5,5,4
|
||||
b 1b
|
||||
2:
|
||||
eieio
|
||||
sync
|
||||
blr
|
||||
|
||||
WRITE_REGISTER_UCHAR:
|
||||
stb 4,0(3)
|
||||
eieio
|
||||
sync
|
||||
blr
|
||||
|
||||
WRITE_REGISTER_USHORT:
|
||||
sth 4,0(3)
|
||||
eieio
|
||||
sync
|
||||
blr
|
||||
|
||||
WRITE_REGISTER_ULONG:
|
||||
stw 4,0(3)
|
||||
eieio
|
||||
sync
|
||||
blr
|
||||
|
||||
WRITE_REGISTER_BUFFER_UCHAR:
|
||||
sync
|
||||
eieio
|
||||
1:
|
||||
cmpwi 0,5,0
|
||||
beq 2f
|
||||
|
||||
lbz 0,0(4)
|
||||
stb 0,0(3)
|
||||
|
||||
addi 3,3,1
|
||||
addi 4,4,1
|
||||
subi 5,5,1
|
||||
b 1b
|
||||
2:
|
||||
blr
|
||||
|
||||
WRITE_REGISTER_BUFFER_USHORT:
|
||||
sync
|
||||
eieio
|
||||
1:
|
||||
cmpwi 0,5,0
|
||||
beq 2f
|
||||
|
||||
lhz 0,0(4)
|
||||
sth 0,0(3)
|
||||
|
||||
addi 3,3,2
|
||||
addi 4,4,2
|
||||
subi 5,5,2
|
||||
b 1b
|
||||
2:
|
||||
blr
|
||||
|
||||
WRITE_REGISTER_BUFFER_ULONG:
|
||||
sync
|
||||
eieio
|
||||
1:
|
||||
cmpwi 0,5,0
|
||||
beq 2f
|
||||
|
||||
lwz 0,0(4)
|
||||
stw 0,0(3)
|
||||
|
||||
addi 3,3,4
|
||||
addi 4,4,4
|
||||
subi 5,5,4
|
||||
b 1b
|
||||
2:
|
||||
blr
|
||||
|
||||
/* EOF */
|
||||
@@ -1923,7 +1923,7 @@ NtFlushInstructionCache (
|
||||
#if defined(_M_IX86)
|
||||
__wbinvd();
|
||||
#elif defined(_M_PPC)
|
||||
#error Needs to be implemented for PPC architecture!
|
||||
__asm__ __volatile__("tlbsync");
|
||||
#elif defined(_M_MIPS)
|
||||
DPRINT1("NtFlushInstructionCache() is not implemented\n");
|
||||
for (;;);
|
||||
|
||||
@@ -412,6 +412,9 @@ Ke386SetEs(IN USHORT Value)
|
||||
#error Unknown compiler for inline assembler
|
||||
#endif
|
||||
|
||||
#define KeArchFnInit() Ke386FnInit()
|
||||
#define KeArchHaltProcessor() Ke386HaltProcessor()
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
#ifndef __INCLUDE_INTERNAL_KERNEL_DEBUGGER_H
|
||||
#define __INCLUDE_INTERNAL_KERNEL_DEBUGGER_H
|
||||
|
||||
#ifdef _M_PPC
|
||||
#define KdDebuggerEnabled _KdDebuggerEnabled
|
||||
#define KdDebuggerNotPresent _KdDebuggerNotPresent
|
||||
#endif
|
||||
|
||||
//
|
||||
// Kernel Debugger Port Definition
|
||||
//
|
||||
|
||||
@@ -355,7 +355,7 @@ KiRundownThread(IN PKTHREAD Thread)
|
||||
{
|
||||
/* Clear it */
|
||||
KeGetCurrentPrcb()->NpxThread = NULL;
|
||||
Ke386FnInit();
|
||||
KeArchFnInit();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1529,7 +1529,11 @@ FORCEINLINE
|
||||
KeGetCurrentThread(VOID)
|
||||
{
|
||||
/* Return the current thread */
|
||||
#ifdef _M_PPC
|
||||
return ((PKIPCR)KeGetPcr())->PrcbData->CurrentThread;
|
||||
#else
|
||||
return ((PKIPCR)KeGetPcr())->PrcbData.CurrentThread;
|
||||
#endif
|
||||
}
|
||||
|
||||
UCHAR
|
||||
@@ -1545,6 +1549,10 @@ FORCEINLINE
|
||||
KeFlushProcessTb(VOID)
|
||||
{
|
||||
/* Flush the TLB by resetting CR3 */
|
||||
#ifdef _M_PPC
|
||||
__asm__("sync\n\tisync\n\t");
|
||||
#else
|
||||
__writecr3(__readcr3());
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
@@ -281,7 +281,7 @@ DefaultQueryInfoBufferCheck(ULONG Class,
|
||||
* Use IsPointerOffset to test whether a pointer should be interpreted as an offset
|
||||
* or as a pointer
|
||||
*/
|
||||
#if defined(_X86_) || defined(_M_AMD64) || defined(_MIPS_)
|
||||
#if defined(_X86_) || defined(_M_AMD64) || defined(_MIPS_) || defined(_PPC_)
|
||||
|
||||
/* for x86 and x86-64 the MSB is 1 so we can simply test on that */
|
||||
#define IsPointerOffset(Ptr) ((LONG_PTR)(Ptr) >= 0)
|
||||
@@ -314,6 +314,7 @@ C_ASSERT(FIELD_OFFSET(KPROCESS, DirectoryTableBase) == KPROCESS_DIRECTORY_TABLE_
|
||||
C_ASSERT(FIELD_OFFSET(KPCR, IRR) == KPCR_IRR);
|
||||
C_ASSERT(FIELD_OFFSET(KPCR, IDR) == KPCR_IDR);
|
||||
C_ASSERT(FIELD_OFFSET(KPCR, Irql) == KPCR_IRQL);
|
||||
#ifdef _M_IX86
|
||||
C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, CurrentThread) == KPCR_CURRENT_THREAD);
|
||||
C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, NextThread) == KPCR_PRCB_NEXT_THREAD);
|
||||
C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, NpxThread) == KPCR_NPX_THREAD);
|
||||
@@ -337,7 +338,6 @@ C_ASSERT(FIELD_OFFSET(KIPCR, PrcbData) + FIELD_OFFSET(KPRCB, DpcStack) == KPCR_P
|
||||
C_ASSERT(sizeof(FX_SAVE_AREA) == SIZEOF_FX_SAVE_AREA);
|
||||
|
||||
/* Platform specific checks */
|
||||
#ifdef _M_IX86
|
||||
C_ASSERT(FIELD_OFFSET(KPROCESS, IopmOffset) == KPROCESS_IOPM_OFFSET);
|
||||
C_ASSERT(FIELD_OFFSET(KPROCESS, LdtDescriptor) == KPROCESS_LDT_DESCRIPTOR0);
|
||||
C_ASSERT(FIELD_OFFSET(KV86M_TRAP_FRAME, SavedExceptionStack) == TF_SAVED_EXCEPTION_STACK);
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#ifndef _INTRIN_INTERNAL_
|
||||
#define _INTRIN_INTERNAL_
|
||||
|
||||
#define Ke386SaveFlags(x) __asm__ __volatile__("mfmsr %0" : "=r" (x) :)
|
||||
|
||||
#endif
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -19,11 +19,14 @@
|
||||
#ifndef __NTOSKRNL_INCLUDE_INTERNAL_POWERPC_KE_H
|
||||
#define __NTOSKRNL_INCLUDE_INTERNAL_POWERPC_KE_H
|
||||
|
||||
#include <ndk/powerpc/ketypes.h>
|
||||
|
||||
#if __GNUC__ >=3
|
||||
#pragma GCC system_header
|
||||
#endif
|
||||
|
||||
/* Possible values for KTHREAD's NpxState */
|
||||
#define KPCR_BASE 0xff000000
|
||||
#define NPX_STATE_INVALID 0x01
|
||||
#define NPX_STATE_VALID 0x02
|
||||
#define NPX_STATE_DIRTY 0x04
|
||||
@@ -107,7 +110,7 @@ static inline LONG KePPCTestAndSetBit(ULONG BitPos, volatile PULONG Addr)
|
||||
return NewValue & (1 << BitPos);
|
||||
}
|
||||
|
||||
#define KePPCRdmsr(msr,val1,val2) __asm__ __volatile__("mfmsr 2")
|
||||
#define KePPCRdmsr(msr,val1,val2) __asm__ __volatile__("mfmsr 3")
|
||||
|
||||
#define KePPCWrmsr(msr,val1,val2) __asm__ __volatile__("mtmsr 3")
|
||||
|
||||
@@ -120,17 +123,65 @@ __asm__ __volatile__("mfmsr 0\n\t" \
|
||||
|
||||
#define KePPCEnableInterrupts() \
|
||||
__asm__ __volatile__("mfmsr 0\n\t" \
|
||||
"li 8,0x8000\n\t" \
|
||||
"lis 8,0x8000@ha\n\t" \
|
||||
"or 0,8,0\n\t" \
|
||||
"mtmsr 0\n\t")
|
||||
|
||||
#define KePPCHaltProcessor() ;
|
||||
|
||||
#endif /* __ASM__ */
|
||||
#define KePPCHaltProcessor()
|
||||
|
||||
#define KeArchEraseFlags()
|
||||
#define KeArchDisableInterrupts() KePPCDisableInterrupts()
|
||||
|
||||
#define PPC_MIN_CACHE_LINE_SIZE 32
|
||||
|
||||
FORCEINLINE struct _KPCR * NTHALAPI KeGetCurrentKPCR(
|
||||
VOID)
|
||||
{
|
||||
return (struct _KPCR *)__readfsdword(0x1c);
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
KePPCInitThreadWithContext(
|
||||
PKTHREAD Thread,
|
||||
PKSYSTEM_ROUTINE SystemRoutine,
|
||||
PKSTART_ROUTINE StartRoutine,
|
||||
PVOID StartContext,
|
||||
PCONTEXT Context);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
KeApplicationProcessorInitDispatcher(
|
||||
VOID);
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
KeCreateApplicationProcessorIdleThread(
|
||||
ULONG Id);
|
||||
|
||||
static VOID KePPCFnInit()
|
||||
{
|
||||
__asm__("mfmsr 0\n\tori 0,0,0x2000\n\tmtmsr 0");
|
||||
}
|
||||
|
||||
#ifdef _NTOSKRNL_ /* FIXME: Move flags above to NDK instead of here */
|
||||
VOID
|
||||
STDCALL
|
||||
KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
|
||||
PKSTART_ROUTINE StartRoutine,
|
||||
PVOID StartContext,
|
||||
BOOLEAN UserThread,
|
||||
KTRAP_FRAME TrapFrame);
|
||||
#endif
|
||||
VOID
|
||||
NTAPI
|
||||
KiSaveProcessorControlState(OUT PKPROCESSOR_STATE ProcessorState);
|
||||
|
||||
#endif /* __ASM__ */
|
||||
|
||||
#define KeArchFnInit() KePPCFnInit()
|
||||
#define KeArchHaltProcessor() KePPCHaltProcessor()
|
||||
|
||||
#endif /* __NTOSKRNL_INCLUDE_INTERNAL_POWERPC_KE_H */
|
||||
|
||||
/* EOF */
|
||||
|
||||
@@ -108,7 +108,9 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
|
||||
{
|
||||
KD_CONTINUE_TYPE Return;
|
||||
ULONG ExceptionCommand = ExceptionRecord->ExceptionInformation[0];
|
||||
#ifdef _M_IX86
|
||||
ULONG EipOld;
|
||||
#endif
|
||||
|
||||
/* Check if this was a breakpoint due to DbgPrint or Load/UnloadSymbols */
|
||||
if ((ExceptionRecord->ExceptionCode == STATUS_BREAKPOINT) &&
|
||||
@@ -133,7 +135,9 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
|
||||
}
|
||||
|
||||
/* This we can handle: simply bump EIP */
|
||||
#ifdef _M_IX86
|
||||
Context->Eip++;
|
||||
#endif
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
@@ -141,7 +145,9 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
|
||||
if (KdDebuggerNotPresent) return FALSE;
|
||||
|
||||
/* Save old EIP value */
|
||||
#ifdef _M_IX86
|
||||
EipOld = Context->Eip;
|
||||
#endif
|
||||
|
||||
/* Call KDBG if available */
|
||||
Return = KdbEnterDebuggerException(ExceptionRecord,
|
||||
@@ -159,7 +165,9 @@ KdpEnterDebuggerException(IN PKTRAP_FRAME TrapFrame,
|
||||
#else
|
||||
/* We simulate the original behaviour when KDBG is turned off.
|
||||
Return var is set to kdHandleException, thus we always return FALSE */
|
||||
#ifdef _M_IX86
|
||||
Context->Eip = EipOld;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -311,12 +311,12 @@ VOID
|
||||
NTAPI
|
||||
KeRosDumpTriageForBugZillaReport(VOID)
|
||||
{
|
||||
#if 0
|
||||
extern BOOLEAN KiFastSystemCallDisable, KiSMTProcessorsPresent;
|
||||
extern ULONG KeI386MachineType, MxcsrFeatureMask;
|
||||
extern BOOLEAN Ke386Pae, Ke386NoExecute;
|
||||
|
||||
DbgPrint("ReactOS has crashed! Please go to http://www.reactos.org/bugzilla/enter_bug.cgi to file a bug!\n");
|
||||
#ifdef __i386__
|
||||
DbgPrint("\nHardware Information\n");
|
||||
DbgPrint("Processor Architecture: %d\n"
|
||||
"Feature Bits: %d\n"
|
||||
@@ -539,7 +539,7 @@ NTAPI
|
||||
KiBugCheckDebugBreak(IN ULONG StatusCode)
|
||||
{
|
||||
/* If KDBG isn't connected, freeze the CPU, otherwise, break */
|
||||
if (KdDebuggerNotPresent) for (;;) Ke386HaltProcessor();
|
||||
if (KdDebuggerNotPresent) for (;;) KeArchHaltProcessor();
|
||||
DbgBreakPointWithStatus(StatusCode);
|
||||
}
|
||||
|
||||
@@ -867,8 +867,12 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
|
||||
if ((TrapFrame) &&
|
||||
(BugCheckCode != KERNEL_MODE_EXCEPTION_NOT_HANDLED))
|
||||
{
|
||||
#ifdef _M_IX86
|
||||
/* Get EIP */
|
||||
Eip = (PVOID)TrapFrame->Eip;
|
||||
#elif defined(_M_PPC)
|
||||
Eip = (PVOID)TrapFrame->Dr0; /* srr0 */
|
||||
#endif
|
||||
}
|
||||
break;
|
||||
|
||||
@@ -963,9 +967,14 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
|
||||
/* Check if we have a frame now */
|
||||
if (TrapFrame)
|
||||
{
|
||||
#ifdef _M_IX86
|
||||
/* Get EIP */
|
||||
Eip = (PVOID)TrapFrame->Eip;
|
||||
KiBugCheckData[3] = (ULONG)Eip;
|
||||
#elif defined(_M_PPC)
|
||||
Eip = (PVOID)TrapFrame->Dr0; /* srr0 */
|
||||
KiBugCheckData[3] = (ULONG)Eip;
|
||||
#endif
|
||||
|
||||
/* Find out if was in the kernel or drivers */
|
||||
DriverBase = KiPcToFileHeader(Eip,
|
||||
@@ -1164,7 +1173,7 @@ KeBugCheckWithTf(IN ULONG BugCheckCode,
|
||||
else if (KeBugCheckOwnerRecursionCount > 2)
|
||||
{
|
||||
/* Halt the CPU */
|
||||
for (;;) Ke386HaltProcessor();
|
||||
for (;;) KeArchHaltProcessor();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,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@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(OUT 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);
|
||||
}
|
||||
@@ -0,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@reactos.org)
|
||||
* Gregor Anich
|
||||
* Skywing (skywing@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;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,322 @@
|
||||
/*
|
||||
* 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@reactos.org)
|
||||
* Art Yerkes (ayerkes@speakeasy.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#include <reactos/ppcboot.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#include <ppcdebug.h>
|
||||
#include "ppcmmu/mmu.h"
|
||||
|
||||
/* GLOBALS *******************************************************************/
|
||||
|
||||
/* Ku bit should be set, so that we get the best options for page protection */
|
||||
#define PPC_SEG_Ku 0x40000000
|
||||
#define PPC_SEG_Ks 0x20000000
|
||||
|
||||
extern LOADER_MODULE KeLoaderModules[64];
|
||||
extern ULONG KeLoaderModuleCount;
|
||||
extern ULONG_PTR MmFreeLdrLastKernelAddress;
|
||||
KPRCB PrcbData[MAXIMUM_PROCESSORS];
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
/*
|
||||
* Trap frame:
|
||||
* r0 .. r32
|
||||
* lr, ctr, srr0, srr1, dsisr
|
||||
*/
|
||||
__asm__(".text\n\t"
|
||||
".globl syscall_start\n\t"
|
||||
".globl syscall_end\n\t"
|
||||
".globl KiSystemService\n\t"
|
||||
"syscall_start:\n\t"
|
||||
"mr 2,1\n\t"
|
||||
"lis 1,KiSystemService1@ha\n\t"
|
||||
"addi 1,1,KiSystemService1@l\n\t"
|
||||
"mfsrr0 0\n\t"
|
||||
"mtsrr0 1\n\t"
|
||||
"lis 1,_kernel_trap_stack@ha\n\t"
|
||||
"addi 1,1,_kernel_trap_stack@l\n\t"
|
||||
"subi 1,1,0x100\n\t"
|
||||
"rfi\n\t"
|
||||
"syscall_end:\n\t"
|
||||
".space 4");
|
||||
|
||||
extern int syscall_start[], syscall_end;
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiSetupSyscallHandler()
|
||||
{
|
||||
paddr_t handler_target;
|
||||
int *source;
|
||||
for(source = syscall_start, handler_target = 0xc00;
|
||||
source < &syscall_end;
|
||||
source++, handler_target += sizeof(int))
|
||||
SetPhys(handler_target, *source);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializePcr(IN ULONG ProcessorNumber,
|
||||
IN PKIPCR Pcr,
|
||||
IN PKTHREAD IdleThread,
|
||||
IN PVOID DpcStack)
|
||||
{
|
||||
Pcr->MajorVersion = PCR_MAJOR_VERSION;
|
||||
Pcr->MinorVersion = PCR_MINOR_VERSION;
|
||||
Pcr->CurrentIrql = PASSIVE_LEVEL;
|
||||
Pcr->PrcbData = &PrcbData[ProcessorNumber];
|
||||
Pcr->PrcbData->MajorVersion = PRCB_MAJOR_VERSION;
|
||||
Pcr->PrcbData->MinorVersion = 0;
|
||||
Pcr->PrcbData->Number = 0; /* UP for now */
|
||||
Pcr->PrcbData->SetMember = 1;
|
||||
#if DBG
|
||||
Pcr->PrcbData->BuildType = PRCB_BUILD_DEBUG;
|
||||
#else
|
||||
Pcr->PrcbData->BuildType = 0;
|
||||
#endif
|
||||
Pcr->PrcbData->DpcStack = DpcStack;
|
||||
KiProcessorBlock[ProcessorNumber] = Pcr->PrcbData;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
/* Setup the Idle Thread */
|
||||
KeInitializeThread(InitProcess,
|
||||
InitThread,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
IdleStack);
|
||||
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, 0);
|
||||
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(;;);
|
||||
}
|
||||
|
||||
extern int KiPageFaultHandler(int inst, ppc_trap_frame_t *frame);
|
||||
|
||||
/* Use this for early boot additions to the page table */
|
||||
VOID
|
||||
NTAPI
|
||||
KiSystemStartup(IN PLOADER_PARAMETER_BLOCK LoaderBlock)
|
||||
{
|
||||
ULONG Cpu;
|
||||
ppc_map_info_t info[3];
|
||||
PKIPCR Pcr = (PKIPCR)KPCR_BASE;
|
||||
PKPRCB Prcb;
|
||||
|
||||
__asm__("mr 13,%0" : : "r" (KPCR_BASE));
|
||||
|
||||
/* Set the page fault handler to the kernel */
|
||||
MmuSetPageCallback(KiPageFaultHandler);
|
||||
|
||||
// Make 0xf... special
|
||||
MmuAllocVsid(2, 0x8000);
|
||||
MmuSetVsid(15,16,2);
|
||||
|
||||
/* Get the current CPU */
|
||||
Cpu = KeNumberProcessors;
|
||||
if (!Cpu)
|
||||
{
|
||||
/* We'll allocate a page from the end of the kernel area for KPCR. This code will probably
|
||||
* change when we get SMP support.
|
||||
*/
|
||||
info[0].phys = 0;
|
||||
info[0].proc = 2;
|
||||
info[0].addr = (vaddr_t)Pcr;
|
||||
info[0].flags = MMU_KRW_UR;
|
||||
info[1].phys = 0;
|
||||
info[1].proc = 2;
|
||||
info[1].addr = ((vaddr_t)Pcr) + (1 << PAGE_SHIFT);
|
||||
info[1].flags = MMU_KRW_UR;
|
||||
info[2].phys = 0;
|
||||
info[2].proc = 2;
|
||||
info[2].addr = (vaddr_t)KI_USER_SHARED_DATA;
|
||||
info[2].flags = MMU_KRW_UR;
|
||||
MmuMapPage(info, 3);
|
||||
}
|
||||
|
||||
/* 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);
|
||||
|
||||
/* Set us as the current process */
|
||||
KiInitialThread.Tcb.ApcState.Process = &KiInitialProcess.Pcb;
|
||||
|
||||
/* Setup CPU-related fields */
|
||||
AppCpuInit:
|
||||
Pcr->Number = Cpu;
|
||||
Pcr->SetMember = 1 << Cpu;
|
||||
Prcb = KeGetCurrentPrcb();
|
||||
Prcb->SetMember = 1 << Cpu;
|
||||
|
||||
/* Initialize the Processor with HAL */
|
||||
HalInitializeProcessor(Cpu, LoaderBlock);
|
||||
|
||||
/* Set active processors */
|
||||
KeActiveProcessors |= Pcr->SetMember;
|
||||
KeNumberProcessors++;
|
||||
|
||||
/* Initialize the Debugger for the Boot CPU */
|
||||
if (!Cpu) KdInitSystem (0, LoaderBlock);
|
||||
|
||||
/* Check for break-in */
|
||||
if (KdPollBreakIn())
|
||||
{
|
||||
DbgBreakPointWithStatus(1);
|
||||
}
|
||||
|
||||
/* Raise to HIGH_LEVEL */
|
||||
KfRaiseIrql(HIGH_LEVEL);
|
||||
|
||||
/* Call main kernel intialization */
|
||||
KiInitializeKernel(&KiInitialProcess.Pcb,
|
||||
&KiInitialThread.Tcb,
|
||||
P0BootStack,
|
||||
Prcb,
|
||||
Cpu,
|
||||
(PVOID)LoaderBlock);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitMachineDependent(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
void abort()
|
||||
{
|
||||
KeBugCheck(0);
|
||||
while(1);
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
#include <roscfg.h>
|
||||
#include <ndk/asm.h>
|
||||
|
||||
#define AP_MAGIC (0x12481020)
|
||||
|
||||
.global P0BootStack
|
||||
.global KiDoubleFaultStack
|
||||
.global _kernel_stack
|
||||
.global _kernel_stack_top
|
||||
.global _kernel_trap_stack
|
||||
.global _kernel_trap_stack_top
|
||||
|
||||
.section .bss
|
||||
.align 12
|
||||
|
||||
|
||||
/* guard page for the kernel stack */
|
||||
.fill 4096, 1, 0
|
||||
|
||||
_kernel_stack:
|
||||
.fill 3*4096, 1, 0
|
||||
P0BootStack:
|
||||
_kernel_stack_top:
|
||||
|
||||
/* guard page for the trap stack */
|
||||
.fill 4096, 1, 0
|
||||
|
||||
_kernel_trap_stack:
|
||||
.fill 3*4096, 1, 0
|
||||
_kernel_trap_stack_top:
|
||||
|
||||
.fill 3*4096, 1, 0
|
||||
KiDoubleFaultStack:
|
||||
|
||||
.text
|
||||
.globl NtProcessStartup
|
||||
.globl KiSystemStartup
|
||||
.globl KiRosPrepareForSystemStartup
|
||||
.globl DrawNumber
|
||||
|
||||
NtProcessStartup:
|
||||
lis 30,AP_MAGIC@ha
|
||||
ori 30,30,AP_MAGIC@l
|
||||
cmpw 0,30,3
|
||||
bne .m1
|
||||
|
||||
/*
|
||||
* Set a normal MSR value
|
||||
*/
|
||||
xor 0,0,0
|
||||
ori 30,0,0x3031
|
||||
mtmsr 30
|
||||
|
||||
/*
|
||||
* Reserve space for the floating point save area.
|
||||
*/
|
||||
addi 1,1,-SIZEOF_FX_SAVE_AREA
|
||||
|
||||
/* Bye bye asm land! */
|
||||
mr 4,3
|
||||
bl KiRosPrepareForSystemStartup
|
||||
|
||||
.m1:
|
||||
/* Load the initial kernel stack */
|
||||
lis 1,_kernel_stack_top@ha
|
||||
ori 1,1,_kernel_stack_top@l
|
||||
addi 1,1,-SIZEOF_FX_SAVE_AREA
|
||||
|
||||
/* Call the main kernel initialization */
|
||||
mr 4,3
|
||||
bl KiRosPrepareForSystemStartup
|
||||
|
||||
.global NtCurrentTeb
|
||||
NtCurrentTeb:
|
||||
mr 3,12
|
||||
blr
|
||||
|
||||
.globl KeSynchronizeExecution
|
||||
|
||||
KeSynchronizeExecution:
|
||||
blr
|
||||
@@ -0,0 +1,841 @@
|
||||
/* $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@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>
|
||||
#include <ppcmmu/mmu.h>
|
||||
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
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;
|
||||
|
||||
/* 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);
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KeDisableInterrupts(VOID)
|
||||
{
|
||||
ULONG Flags = 0;
|
||||
BOOLEAN Return;
|
||||
|
||||
Flags = __readmsr();
|
||||
Return = (Flags & 0x8000) ? TRUE: FALSE;
|
||||
|
||||
/* Disable interrupts */
|
||||
_disable();
|
||||
return Return;
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
KdpServiceDispatcher(ULONG Service, PCHAR Buffer, ULONG Length);
|
||||
|
||||
__asm__(".globl KiSystemService\n\t"
|
||||
".globl KiSystemService1\n\t"
|
||||
".globl kiss_proceed\n\t"
|
||||
".globl kiss_end\n"
|
||||
"KiSystemService1:\n\t"
|
||||
"stw 2,4(1)\n\t" // r1
|
||||
"stw 3,12(1)\n\t"
|
||||
"stw 4,16(1)\n\t"
|
||||
"stw 5,20(1)\n\t"
|
||||
"stw 6,24(1)\n\t"
|
||||
"stw 7,28(1)\n\t"
|
||||
"stw 8,32(1)\n\t"
|
||||
"stw 9,36(1)\n\t"
|
||||
"stw 10,40(1)\n\t"
|
||||
"stw 11,44(1)\n\t"
|
||||
"stw 12,48(1)\n\t"
|
||||
"stw 13,52(1)\n\t"
|
||||
"stw 14,56(1)\n\t"
|
||||
"stw 15,60(1)\n\t"
|
||||
"stw 16,64(1)\n\t"
|
||||
"stw 17,68(1)\n\t"
|
||||
"stw 18,72(1)\n\t"
|
||||
"stw 19,76(1)\n\t"
|
||||
"stw 20,80(1)\n\t"
|
||||
"stw 21,84(1)\n\t"
|
||||
"stw 22,88(1)\n\t"
|
||||
"stw 23,92(1)\n\t"
|
||||
"stw 24,96(1)\n\t"
|
||||
"stw 25,100(1)\n\t"
|
||||
"stw 26,104(1)\n\t"
|
||||
"stw 27,108(1)\n\t"
|
||||
"stw 28,112(1)\n\t"
|
||||
"stw 29,116(1)\n\t"
|
||||
"stw 30,120(1)\n\t"
|
||||
"stw 31,124(1)\n\t"
|
||||
/* This save is important */
|
||||
"stw 0,140(1)\n\t" // srr0
|
||||
"mflr 0\n\t"
|
||||
"stw 0,128(1)\n\t"
|
||||
"mfctr 0\n\t"
|
||||
"stw 0,136(1)\n\t"
|
||||
"mfsrr1 0\n\t"
|
||||
"stw 0,144(1)\n\t"
|
||||
"mfdsisr 0\n\t"
|
||||
"stw 0,148(1)\n\t"
|
||||
"mfdar 0\n\t"
|
||||
"stw 0,152(1)\n\t"
|
||||
"lis 3,KiSystemService@ha\n\t"
|
||||
"addi 3,3,KiSystemService@l\n\t"
|
||||
"mtctr 3\n\t"
|
||||
"mr 3,1\n\t"
|
||||
"subi 1,1,0x100\n\t"
|
||||
"bctrl\n\t"
|
||||
"addi 1,1,0x100\n\t"
|
||||
/* Return from kernel */
|
||||
"lwz 3,12(1)\n\t" /* Result */
|
||||
"lwz 0,128(1)\n\t"
|
||||
"mtlr 0\n\t"
|
||||
"lwz 0,140(1)\n\t"
|
||||
"mtsrr0 0\n\t"
|
||||
"lwz 0,144(1)\n\t"
|
||||
"mtsrr1 0\n\t"
|
||||
"lwz 1,4(1)\n" /* Stack */
|
||||
"rfi\n");
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiSystemService(ppc_trap_frame_t *trap_frame)
|
||||
{
|
||||
int i;
|
||||
switch(trap_frame->gpr[8])
|
||||
{
|
||||
case 0x10000: /* DebugService */
|
||||
for( i = 0; i < trap_frame->gpr[5]; i++ )
|
||||
SetPhysByte(0x800003f8, ((PCHAR)trap_frame->gpr[4])[i]);
|
||||
|
||||
trap_frame->gpr[3] = KdpServiceDispatcher
|
||||
(trap_frame->gpr[3],
|
||||
(PCHAR)trap_frame->gpr[4],
|
||||
trap_frame->gpr[5]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,234 @@
|
||||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/vdm/vdmmain.c
|
||||
* PURPOSE: VDM Support Services
|
||||
* PROGRAMMERS: Alex Ionescu (alex.ionescu@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ******************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtVdmControl(IN ULONG ControlCode,
|
||||
IN PVOID ControlData)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
Ke386CallBios(IN ULONG Int,
|
||||
OUT PCONTEXT Context)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiUnexpectedInterrupt()
|
||||
{
|
||||
}
|
||||
|
||||
LONG NTAPI Exi386InterlockedDecrementLong(PLONG Addend)
|
||||
{
|
||||
return _InterlockedIncrement(Addend);
|
||||
}
|
||||
|
||||
LONG NTAPI Exi386InterlockedIncrementLong(PLONG Addend)
|
||||
{
|
||||
return _InterlockedDecrement(Addend);
|
||||
}
|
||||
|
||||
LONG NTAPI Exi386InterlockedExchangeUlong(PLONG Target, LONG Exch, LONG Compare)
|
||||
{
|
||||
return _InterlockedCompareExchange(Target, Exch, Compare);
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KeI386FlatToGdtSelector(IN ULONG Base,
|
||||
IN USHORT Length,
|
||||
IN USHORT Selector)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KeI386ReleaseGdtSelectors(OUT PULONG SelArray,
|
||||
IN ULONG NumOfSelectors)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* @unimplemented
|
||||
*/
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KeI386AllocateGdtSelectors(OUT PULONG SelArray,
|
||||
IN ULONG NumOfSelectors)
|
||||
{
|
||||
UNIMPLEMENTED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KeDumpStackFrames(PULONG Frame)
|
||||
{
|
||||
}
|
||||
|
||||
LONG
|
||||
NTAPI
|
||||
Kei386EoiHelper() { return 0; }
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
KeUserModeCallback(IN ULONG RoutineIndex,
|
||||
IN PVOID Argument,
|
||||
IN ULONG ArgumentLength,
|
||||
OUT PVOID *Result,
|
||||
OUT PULONG ResultLength)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiCoprocessorError() { }
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiDispatchInterrupt() { }
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiInitializeUserApc(IN PKEXCEPTION_FRAME ExceptionFrame,
|
||||
IN PKTRAP_FRAME TrapFrame,
|
||||
IN PKNORMAL_ROUTINE NormalRoutine,
|
||||
IN PVOID NormalContext,
|
||||
IN PVOID SystemArgument1,
|
||||
IN PVOID SystemArgument2)
|
||||
{
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
KeSwitchKernelStack(PVOID StackBase, PVOID StackLimit)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KiSwapProcess(struct _KPROCESS *NewProcess, struct _KPROCESS *OldProcess)
|
||||
{
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
KiSwapContext(PKTHREAD CurrentThread, PKTHREAD NewThread)
|
||||
{
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
Mmi386ReleaseMmInfo(PEPROCESS Process)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
KeI386VdmInitialize(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtCallbackReturn
|
||||
( IN PVOID Result OPTIONAL, IN ULONG ResultLength, IN NTSTATUS Status )
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtContinue
|
||||
(IN PCONTEXT ThreadContext, IN BOOLEAN RaiseAlert)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
NTSYSAPI
|
||||
ULONG
|
||||
NTAPI
|
||||
NtGetTickCount() { return __rdtsc(); }
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
NtSetLdtEntries
|
||||
(ULONG Selector1, LDT_ENTRY LdtEntry1, ULONG Selector2, LDT_ENTRY LdtEntry2)
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
NTSYSAPI
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
NtRaiseException
|
||||
(IN PEXCEPTION_RECORD ExceptionRecord, IN PCONTEXT ThreadContext, IN BOOLEAN HandleException )
|
||||
{
|
||||
return STATUS_UNSUCCESSFUL;
|
||||
}
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
KiThreadStartup(PKSYSTEM_ROUTINE SystemRoutine,
|
||||
PKSTART_ROUTINE StartRoutine,
|
||||
PVOID StartContext,
|
||||
BOOLEAN UserThread,
|
||||
KTRAP_FRAME TrapFrame)
|
||||
{
|
||||
}
|
||||
|
||||
void _alldiv() { }
|
||||
|
||||
void _alldvrm() { }
|
||||
|
||||
void _allmul() { }
|
||||
|
||||
void _alloca_probe() { }
|
||||
|
||||
void _allrem() { }
|
||||
|
||||
void _allshl() { }
|
||||
|
||||
void _allshr() { }
|
||||
|
||||
void _aulldiv() { }
|
||||
|
||||
void _aulldvrm() { }
|
||||
|
||||
void _aullrem() { }
|
||||
|
||||
void _aullshr() { }
|
||||
|
||||
void _abnormal_termination() { }
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* 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: Art Yerkes (ayerkes@speakeasy.net)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
#include <ppcdebug.h>
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
KiComputeTimerTableIndex(LONGLONG Timer)
|
||||
{
|
||||
return 0; // XXX arty fixme
|
||||
}
|
||||
@@ -233,6 +233,7 @@ KiParseProfileList(IN PKTRAP_FRAME TrapFrame,
|
||||
LIST_FOR_EACH(Profile, ListHead, KPROFILE, ProfileListEntry)
|
||||
{
|
||||
/* Check if the source is good, and if it's within the range */
|
||||
#ifdef _M_IX86
|
||||
if ((Profile->Source != Source) ||
|
||||
(TrapFrame->Eip < (ULONG_PTR)Profile->RangeBase) ||
|
||||
(TrapFrame->Eip > (ULONG_PTR)Profile->RangeLimit)) {
|
||||
@@ -244,6 +245,9 @@ KiParseProfileList(IN PKTRAP_FRAME TrapFrame,
|
||||
BucketValue = (PULONG)((((ULONG_PTR)Profile->Buffer +
|
||||
(TrapFrame->Eip - (ULONG_PTR)Profile->RangeBase))
|
||||
>> Profile->BucketShift) &~ 0x3);
|
||||
#elif defined(_M_PPC)
|
||||
// XXX arty
|
||||
#endif
|
||||
|
||||
/* Increment the value */
|
||||
++BucketValue;
|
||||
|
||||
@@ -298,12 +298,14 @@ MmAccessFault(IN BOOLEAN StoreInstruction,
|
||||
/* Cute little hack for ROS */
|
||||
if ((ULONG_PTR)Address >= (ULONG_PTR)MmSystemRangeStart)
|
||||
{
|
||||
#ifdef _M_IX86
|
||||
/* Check for an invalid page directory in kernel mode */
|
||||
if (Mmi386MakeKernelPageTableGlobal(Address))
|
||||
{
|
||||
/* All is well with the world */
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/* Keep same old ReactOS Behaviour */
|
||||
|
||||
@@ -579,12 +579,14 @@ MmDumpToPagingFile(ULONG BugCode,
|
||||
Headers->Type = MmCoreDumpType;
|
||||
if (TrapFrame != NULL)
|
||||
{
|
||||
#ifdef _M_IX86
|
||||
if (!(TrapFrame->EFlags & (1 << 17)))
|
||||
{
|
||||
memcpy(&Headers->TrapFrame, TrapFrame,
|
||||
sizeof(KTRAP_FRAME) - (4 * sizeof(ULONG)));
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
memcpy(&Headers->TrapFrame, TrapFrame, sizeof(KTRAP_FRAME));
|
||||
}
|
||||
|
||||
@@ -0,0 +1,630 @@
|
||||
/* $Id: page.c 23907 2006-09-04 05:52:23Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/i386/page.c
|
||||
* PURPOSE: Low level memory managment manipulation
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@cwcom.net)
|
||||
* Revised for PowerPC by arty
|
||||
*/
|
||||
|
||||
/* INCLUDES ***************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#include <ppcmmu/mmu.h>
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
|
||||
#if defined (ALLOC_PRAGMA)
|
||||
#pragma alloc_text(INIT, MmInitGlobalKernelPageDirectory)
|
||||
#pragma alloc_text(INIT, MiInitPageDirectoryMap)
|
||||
#endif
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
#define HYPERSPACE_PAGEDIR_PTR ((PVOID)0xc0000000)
|
||||
|
||||
#define PA_PRESENT (1ll<<63)
|
||||
#define PA_USER (1ll<<62)
|
||||
#define PA_ACCESSED 0x200
|
||||
#define PA_DIRTY 0x100
|
||||
#define PA_WT 0x20
|
||||
#define PA_CD 0x10
|
||||
#define PA_READWRITE 3
|
||||
|
||||
#define HYPERSPACE (0xc0400000)
|
||||
#define IS_HYPERSPACE(v) (((ULONG)(v) >= HYPERSPACE && (ULONG)(v) < HYPERSPACE + 0x400000))
|
||||
|
||||
#define PTE_TO_PFN(X) ((X) >> PAGE_SHIFT)
|
||||
#define PFN_TO_PTE(X) ((X) << PAGE_SHIFT)
|
||||
|
||||
#if defined(__GNUC__)
|
||||
#define PTE_TO_PAGE(X) ((LARGE_INTEGER)(LONGLONG)(PAGE_MASK(X)))
|
||||
#else
|
||||
__inline LARGE_INTEGER PTE_TO_PAGE(ULONG npage)
|
||||
{
|
||||
LARGE_INTEGER dummy;
|
||||
dummy.QuadPart = (LONGLONG)(PAGE_MASK(npage));
|
||||
return dummy;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* FUNCTIONS ***************************************************************/
|
||||
|
||||
VOID
|
||||
STDCALL
|
||||
MiFlushTlbIpiRoutine(PVOID Address)
|
||||
{
|
||||
if (Address == (PVOID)0xffffffff)
|
||||
{
|
||||
__asm__("tlbsync");
|
||||
}
|
||||
else if (Address == (PVOID)0xfffffffe)
|
||||
{
|
||||
__asm__("tlbsync");
|
||||
}
|
||||
else
|
||||
{
|
||||
__asm__("tlbi %0" : "=r" (Address));
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
MiFlushTlb(PULONG Pt, PVOID Address)
|
||||
{
|
||||
__asm__("tlbi %0" : "=r" (Address));
|
||||
}
|
||||
|
||||
|
||||
|
||||
PULONG
|
||||
MmGetPageDirectory(VOID)
|
||||
{
|
||||
unsigned int page_dir=0;
|
||||
return((PULONG)page_dir);
|
||||
}
|
||||
|
||||
static ULONG
|
||||
ProtectToFlags(ULONG flProtect)
|
||||
{
|
||||
return MMU_ALL_RW; // XXX hack
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
STDCALL
|
||||
MmCopyMmInfo(PEPROCESS Src,
|
||||
PEPROCESS Dest,
|
||||
PPHYSICAL_ADDRESS DirectoryTableBase)
|
||||
{
|
||||
DPRINT("MmCopyMmInfo(Src %x, Dest %x)\n", Src, Dest);
|
||||
|
||||
KeBugCheck(0);
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmInitializeHandBuiltProcess(IN PEPROCESS Process,
|
||||
IN PLARGE_INTEGER DirectoryTableBase)
|
||||
{
|
||||
/* Share the directory base with the idle process */
|
||||
*DirectoryTableBase = PsGetCurrentProcess()->Pcb.DirectoryTableBase;
|
||||
|
||||
/* Initialize the Addresss Space */
|
||||
MmInitializeAddressSpace(Process, (PMADDRESS_SPACE)&Process->VadRoot);
|
||||
|
||||
/* The process now has an address space */
|
||||
Process->HasAddressSpace = TRUE;
|
||||
return STATUS_SUCCESS;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
STDCALL
|
||||
MmCreateProcessAddressSpace(IN ULONG MinWs,
|
||||
IN PEPROCESS Process,
|
||||
IN PLARGE_INTEGER DirectoryTableBase)
|
||||
{
|
||||
KeBugCheck(0);
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmDeletePageTable(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
PEPROCESS CurrentProcess = PsGetCurrentProcess();
|
||||
|
||||
if(!CurrentProcess) return;
|
||||
|
||||
MmuRevokeVsid((paddr_t)Process->UniqueProcessId, -1);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmFreePageTable(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
MmDeletePageTable(Process, Address);
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
MmGetPhysicalAddressProcess(PEPROCESS Process, PVOID Addr)
|
||||
{
|
||||
ppc_map_info_t info = { 0 };
|
||||
info.proc = Process ? (int)Process->UniqueProcessId : 0;
|
||||
info.addr = (vaddr_t)Addr;
|
||||
MmuInqPage(&info, 1);
|
||||
return (PVOID)info.phys;
|
||||
}
|
||||
|
||||
/*
|
||||
* @implemented
|
||||
*/
|
||||
PHYSICAL_ADDRESS STDCALL
|
||||
MmGetPhysicalAddress(PVOID vaddr)
|
||||
/*
|
||||
* FUNCTION: Returns the physical address corresponding to a virtual address
|
||||
*/
|
||||
{
|
||||
PHYSICAL_ADDRESS Addr;
|
||||
Addr.QuadPart = (ULONG)MmGetPhysicalAddressProcess(PsGetCurrentProcess()->UniqueProcessId, vaddr);
|
||||
return Addr;
|
||||
}
|
||||
|
||||
PFN_TYPE
|
||||
NTAPI
|
||||
MmGetPfnForProcess(PEPROCESS Process,
|
||||
PVOID Address)
|
||||
{
|
||||
return((PFN_TYPE)MmGetPhysicalAddressProcess(Process, Address) >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmDisableVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN* WasDirty, PPFN_TYPE Page)
|
||||
/*
|
||||
* FUNCTION: Delete a virtual mapping
|
||||
*/
|
||||
{
|
||||
ppc_map_info_t info = { 0 };
|
||||
info.proc = Process ? (int)Process->UniqueProcessId : 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
MmuUnmapPage(&info, 1);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmRawDeleteVirtualMapping(PVOID Address)
|
||||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmDeleteVirtualMapping(PEPROCESS Process, PVOID Address, BOOLEAN FreePage,
|
||||
BOOLEAN* WasDirty, PPFN_TYPE Page)
|
||||
/*
|
||||
* FUNCTION: Delete a virtual mapping
|
||||
*/
|
||||
{
|
||||
ppc_map_info_t info = { 0 };
|
||||
|
||||
DPRINT("MmDeleteVirtualMapping(%x, %x, %d, %x, %x)\n",
|
||||
Process, Address, FreePage, WasDirty, Page);
|
||||
|
||||
info.proc = Process ? (int)Process->UniqueProcessId : 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
MmuInqPage(&info, 1);
|
||||
|
||||
if (FreePage && info.phys)
|
||||
{
|
||||
MmReleasePageMemoryConsumer(MC_NPPOOL, info.phys >> PAGE_SHIFT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return some information to the caller
|
||||
*/
|
||||
if (WasDirty != NULL)
|
||||
{
|
||||
*WasDirty = !!(info.flags & MMU_PAGE_DIRTY);
|
||||
}
|
||||
if (Page != NULL)
|
||||
{
|
||||
*Page = info.phys >> PAGE_SHIFT;
|
||||
}
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmDeletePageFileMapping(PEPROCESS Process, PVOID Address,
|
||||
SWAPENTRY* SwapEntry)
|
||||
/*
|
||||
* FUNCTION: Delete a virtual mapping
|
||||
*/
|
||||
{
|
||||
ppc_map_info_t info = { 0 };
|
||||
/*
|
||||
* Decrement the reference count for this page table.
|
||||
*/
|
||||
if (Process != NULL &&
|
||||
((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
|
||||
Address < MmSystemRangeStart)
|
||||
{
|
||||
PUSHORT Ptrc;
|
||||
|
||||
Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
|
||||
MmFreePageTable(Process, Address);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return some information to the caller
|
||||
*/
|
||||
MmuInqPage(&info, 1);
|
||||
*SwapEntry = info.phys;
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmIsDirtyPage(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
ppc_map_info_t info = { 0 };
|
||||
info.proc = Process ? (int)Process->UniqueProcessId : 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
MmuInqPage(&info, 1);
|
||||
return !!(info.flags & MMU_PAGE_DIRTY);
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmIsAccessedAndResetAccessPage(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
ppc_map_info_t info = { 0 };
|
||||
|
||||
if (Address < MmSystemRangeStart && Process == NULL)
|
||||
{
|
||||
DPRINT1("MmIsAccessedAndResetAccessPage is called for user space without a process.\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
info.proc = Process ? (int)Process->UniqueProcessId : 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
MmuInqPage(&info, 1);
|
||||
return !!(info.flags /*& MMU_PAGE_ACCESS*/);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmSetCleanPage(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmSetDirtyPage(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmEnableVirtualMapping(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmIsPagePresent(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
ppc_map_info_t info = { 0 };
|
||||
info.proc = Process ? (int)Process->UniqueProcessId : 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
MmuInqPage(&info, 1);
|
||||
return !!info.phys;
|
||||
}
|
||||
|
||||
ULONGLONG MmGetPageEntryForProcess(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
return 0; // XXX arty
|
||||
}
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
MmIsPageSwapEntry(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
ULONG Entry;
|
||||
Entry = MmGetPageEntryForProcess(Process, Address);
|
||||
return !(Entry & PA_PRESENT) && Entry != 0 ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreateVirtualMappingForKernel(PVOID Address,
|
||||
ULONG flProtect,
|
||||
PPFN_TYPE Pages,
|
||||
ULONG PageCount)
|
||||
{
|
||||
ULONG i;
|
||||
PVOID Addr;
|
||||
|
||||
DPRINT("MmCreateVirtualMappingForKernel(%x, %x, %x, %d)\n",
|
||||
Address, flProtect, Pages, PageCount);
|
||||
|
||||
if (Address < MmSystemRangeStart)
|
||||
{
|
||||
DPRINT1("MmCreateVirtualMappingForKernel is called for user space\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
Addr = Address;
|
||||
|
||||
for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
|
||||
{
|
||||
#if 0
|
||||
if (!(Attributes & PA_PRESENT) && Pages[i] != 0)
|
||||
{
|
||||
DPRINT1("Setting physical address but not allowing access at address "
|
||||
"0x%.8X with attributes %x/%x.\n",
|
||||
Addr, Attributes, flProtect);
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
(void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
|
||||
#endif
|
||||
}
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreatePageFileMapping(PEPROCESS Process,
|
||||
PVOID Address,
|
||||
SWAPENTRY SwapEntry)
|
||||
{
|
||||
if (Process == NULL && Address < MmSystemRangeStart)
|
||||
{
|
||||
DPRINT1("No process\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
if (Process != NULL && Address >= MmSystemRangeStart)
|
||||
{
|
||||
DPRINT1("Setting kernel address with process context\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
if (SwapEntry & (1 << 31))
|
||||
{
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
|
||||
// XXX arty
|
||||
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreateVirtualMappingUnsafe(PEPROCESS Process,
|
||||
PVOID Address,
|
||||
ULONG flProtect,
|
||||
PPFN_TYPE Pages,
|
||||
ULONG PageCount)
|
||||
{
|
||||
ULONG Attributes;
|
||||
PVOID Addr;
|
||||
ULONG i;
|
||||
ppc_map_info_t info;
|
||||
|
||||
DPRINT("MmCreateVirtualMappingUnsafe(%x, %x, %x, %x (%x), %d)\n",
|
||||
Process, Address, flProtect, Pages, *Pages, PageCount);
|
||||
|
||||
if (Process == NULL)
|
||||
{
|
||||
if (Address < MmSystemRangeStart)
|
||||
{
|
||||
DPRINT1("No process\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
if (PageCount > 0x10000 ||
|
||||
(ULONG_PTR) Address / PAGE_SIZE + PageCount > 0x100000)
|
||||
{
|
||||
DPRINT1("Page count to large\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (Address >= MmSystemRangeStart)
|
||||
{
|
||||
DPRINT1("Setting kernel address with process context\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
if (PageCount > (ULONG_PTR)MmSystemRangeStart / PAGE_SIZE ||
|
||||
(ULONG_PTR) Address / PAGE_SIZE + PageCount >
|
||||
(ULONG_PTR)MmSystemRangeStart / PAGE_SIZE)
|
||||
{
|
||||
DPRINT1("Page Count to large\n");
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
}
|
||||
|
||||
Attributes = ProtectToFlags(flProtect);
|
||||
Addr = Address;
|
||||
|
||||
for (i = 0; i < PageCount; i++, Addr = (PVOID)((ULONG_PTR)Addr + PAGE_SIZE))
|
||||
{
|
||||
Process = PsGetCurrentProcess();
|
||||
info.proc = Process ? (int)Process->UniqueProcessId : 0;
|
||||
info.addr = (vaddr_t)Addr;
|
||||
info.flags = Attributes;
|
||||
MmuMapPage(&info, 1);
|
||||
//(void)InterlockedExchangeUL(Pt, PFN_TO_PTE(Pages[i]) | Attributes);
|
||||
if (Address < MmSystemRangeStart &&
|
||||
((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable != NULL &&
|
||||
Attributes & PA_PRESENT)
|
||||
{
|
||||
#if 0
|
||||
PUSHORT Ptrc;
|
||||
|
||||
Ptrc = ((PMADDRESS_SPACE)&Process->VadRoot)->PageTableRefCountTable;
|
||||
|
||||
Ptrc[ADDR_TO_PAGE_TABLE(Addr)]++;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return(STATUS_SUCCESS);
|
||||
}
|
||||
|
||||
NTSTATUS
|
||||
NTAPI
|
||||
MmCreateVirtualMapping(PEPROCESS Process,
|
||||
PVOID Address,
|
||||
ULONG flProtect,
|
||||
PPFN_TYPE Pages,
|
||||
ULONG PageCount)
|
||||
{
|
||||
ULONG i;
|
||||
|
||||
for (i = 0; i < PageCount; i++)
|
||||
{
|
||||
if (!MmIsUsablePage(Pages[i]))
|
||||
{
|
||||
DPRINT1("Page at address %x not usable\n", PFN_TO_PTE(Pages[i]));
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
}
|
||||
|
||||
return(MmCreateVirtualMappingUnsafe(Process,
|
||||
Address,
|
||||
flProtect,
|
||||
Pages,
|
||||
PageCount));
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
MmGetPageProtect(PEPROCESS Process, PVOID Address)
|
||||
{
|
||||
ULONG Protect = 0;
|
||||
ppc_map_info_t info = { 0 };
|
||||
|
||||
info.proc = Process ? (int)Process->UniqueProcessId : 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
MmuInqPage(&info, 1);
|
||||
|
||||
if (!info.phys) { return PAGE_NOACCESS; }
|
||||
if (!(info.flags & MMU_KMASK))
|
||||
{
|
||||
Protect |= PAGE_SYSTEM;
|
||||
if ((info.flags & MMU_KR) && (info.flags & MMU_KW))
|
||||
Protect = PAGE_READWRITE;
|
||||
else if (info.flags & MMU_KR)
|
||||
Protect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
else
|
||||
{
|
||||
if ((info.flags & MMU_UR) && (info.flags & MMU_UW))
|
||||
Protect = PAGE_READWRITE;
|
||||
else
|
||||
Protect = PAGE_EXECUTE_READ;
|
||||
}
|
||||
return(Protect);
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmSetPageProtect(PEPROCESS Process, PVOID Address, ULONG flProtect)
|
||||
{
|
||||
//ULONG Attributes = 0;
|
||||
|
||||
DPRINT("MmSetPageProtect(Process %x Address %x flProtect %x)\n",
|
||||
Process, Address, flProtect);
|
||||
|
||||
#if 0
|
||||
Attributes = ProtectToPTE(flProtect);
|
||||
|
||||
Pt = MmGetPageTableForProcess(Process, Address, FALSE);
|
||||
if (Pt == NULL)
|
||||
{
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
InterlockedExchange((PLONG)Pt, PAGE_MASK(*Pt) | Attributes | (*Pt & (PA_ACCESSED|PA_DIRTY)));
|
||||
MiFlushTlb(Pt, Address);
|
||||
#endif
|
||||
}
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
MmCreateHyperspaceMapping(PFN_TYPE Page)
|
||||
{
|
||||
PVOID Address;
|
||||
ppc_map_info_t info = { 0 };
|
||||
|
||||
Address = (PVOID)((ULONG_PTR)HYPERSPACE * PAGE_SIZE);
|
||||
info.proc = 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
info.flags = MMU_KRW;
|
||||
MmuMapPage(&info, 1);
|
||||
|
||||
return Address;
|
||||
}
|
||||
|
||||
PFN_TYPE
|
||||
NTAPI
|
||||
MmChangeHyperspaceMapping(PVOID Address, PFN_TYPE NewPage)
|
||||
{
|
||||
PFN_TYPE OldPage;
|
||||
ppc_map_info_t info = { 0 };
|
||||
|
||||
info.proc = 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
MmuUnmapPage(&info, 1);
|
||||
OldPage = info.phys;
|
||||
info.phys = (paddr_t)NewPage;
|
||||
MmuMapPage(&info, 1);
|
||||
|
||||
return NewPage;
|
||||
}
|
||||
|
||||
PFN_TYPE
|
||||
NTAPI
|
||||
MmDeleteHyperspaceMapping(PVOID Address)
|
||||
{
|
||||
ppc_map_info_t info = { 0 };
|
||||
ASSERT (IS_HYPERSPACE(Address));
|
||||
|
||||
info.proc = 0;
|
||||
info.addr = (vaddr_t)Address;
|
||||
|
||||
MmuUnmapPage(&info, 1);
|
||||
|
||||
return (PFN_TYPE)info.phys;
|
||||
}
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
NTAPI
|
||||
MmInitGlobalKernelPageDirectory(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
VOID
|
||||
INIT_FUNCTION
|
||||
NTAPI
|
||||
MiInitPageDirectoryMap(VOID)
|
||||
{
|
||||
}
|
||||
|
||||
ULONG
|
||||
NTAPI
|
||||
MiGetUserPageDirectoryCount(VOID)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmUpdatePageDir(PEPROCESS Process, PVOID Address, ULONG Size)
|
||||
{
|
||||
}
|
||||
|
||||
/* EOF */
|
||||
@@ -0,0 +1,96 @@
|
||||
/* $Id: pfault.c 24443 2006-10-08 10:01:27Z arty $
|
||||
*
|
||||
* COPYRIGHT: See COPYING in the top level directory
|
||||
* PROJECT: ReactOS kernel
|
||||
* FILE: ntoskrnl/mm/powerpc/pfault.c
|
||||
* PURPOSE: Paging file functions
|
||||
*
|
||||
* PROGRAMMERS: David Welch (welch@mcmail.com)
|
||||
*/
|
||||
|
||||
/* INCLUDES *****************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <internal/debug.h>
|
||||
#include <ppcmmu/mmu.h>
|
||||
|
||||
/* EXTERNS *******************************************************************/
|
||||
|
||||
extern ULONG KiKernelTrapHandler(PKTRAP_FRAME Tf, ULONG ExceptionNr, PVOID Cr2);
|
||||
|
||||
/* FUNCTIONS *****************************************************************/
|
||||
|
||||
VOID MmpPpcTrapFrameToTrapFrame(ppc_trap_frame_t *frame, PKTRAP_FRAME Tf)
|
||||
{
|
||||
RtlCopyMemory(&Tf->Gpr0, frame->gpr, 12 * sizeof(ULONG));
|
||||
Tf->Lr = frame->lr;
|
||||
Tf->Cr = frame->cr;
|
||||
Tf->Ctr = frame->ctr;
|
||||
Tf->Xer = frame->xer;
|
||||
Tf->Msr = frame->srr1 & 0xffff;
|
||||
Tf->Dr0 = frame->srr0;
|
||||
Tf->Dr1 = frame->srr1;
|
||||
Tf->Dr2 = frame->dar;
|
||||
Tf->Dr3 = frame->dsisr;
|
||||
}
|
||||
|
||||
int KiPageFaultHandler(int inst, ppc_trap_frame_t *frame)
|
||||
{
|
||||
NTSTATUS Status = STATUS_SUCCESS;
|
||||
KPROCESSOR_MODE Mode;
|
||||
EXCEPTION_RECORD Er;
|
||||
KTRAP_FRAME Tf;
|
||||
BOOLEAN AccessFault = !!(frame->dsisr & (1<<28));
|
||||
vaddr_t VirtualAddr;
|
||||
PVOID TrapInfo = NULL;
|
||||
|
||||
/* get the faulting address */
|
||||
if (inst)
|
||||
VirtualAddr = frame->srr0;
|
||||
else
|
||||
VirtualAddr = frame->dar;
|
||||
|
||||
/* MSR_PR */
|
||||
Mode = frame->srr1 & 0x4000 ? KernelMode : UserMode;
|
||||
|
||||
/* handle the fault */
|
||||
if (AccessFault)
|
||||
{
|
||||
Status = MmAccessFault(Mode, (PVOID)VirtualAddr, FALSE, TrapInfo);
|
||||
}
|
||||
else
|
||||
{
|
||||
KeBugCheck(0);
|
||||
//Status = MmNotPresentFault(Mode, (PVOID)VirtualAddr, FALSE, TrapInfo);
|
||||
}
|
||||
|
||||
if (NT_SUCCESS(Status))
|
||||
return 1;
|
||||
|
||||
if (KeGetCurrentThread()->ApcState.UserApcPending)
|
||||
{
|
||||
KIRQL oldIrql;
|
||||
|
||||
KeRaiseIrql(APC_LEVEL, &oldIrql);
|
||||
KiDeliverApc(UserMode, NULL, NULL);
|
||||
KeLowerIrql(oldIrql);
|
||||
}
|
||||
|
||||
MmpPpcTrapFrameToTrapFrame(frame, &Tf);
|
||||
|
||||
Er.ExceptionCode = STATUS_ACCESS_VIOLATION;
|
||||
Er.ExceptionFlags = 0;
|
||||
Er.ExceptionRecord = NULL;
|
||||
Er.ExceptionAddress = (PVOID)frame->srr0;
|
||||
Er.NumberParameters = 2;
|
||||
Er.ExceptionInformation[0] = AccessFault;
|
||||
Er.ExceptionInformation[1] = VirtualAddr;
|
||||
|
||||
/* FIXME: Which exceptions are noncontinuable? */
|
||||
Er.ExceptionFlags = 0;
|
||||
|
||||
KiDispatchException(&Er, 0, &Tf, Mode, TRUE);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
<include base="ntoskrnl">include</include>
|
||||
<include base="ntoskrnl" root="intermediate"></include>
|
||||
<include base="ntoskrnl" root="intermediate">include</include>
|
||||
<include base="ntoskrnl" root="intermediate">include/internal</include>
|
||||
<include base="ReactOS">include/reactos/drivers</include>
|
||||
<library>csq</library>
|
||||
<library>hal</library>
|
||||
@@ -29,6 +30,7 @@
|
||||
<library>kdcom</library>
|
||||
<library>bootvid</library>
|
||||
<library>wdmguid</library>
|
||||
<library>ppcmmu</library>
|
||||
<directory name="include">
|
||||
<pch>ntoskrnl.h</pch>
|
||||
</directory>
|
||||
@@ -54,6 +56,17 @@
|
||||
<file>v86m_sup.S</file>
|
||||
</directory>
|
||||
</if>
|
||||
<if property="ARCH" value="powerpc">
|
||||
<directory name="powerpc">
|
||||
<file first="true">main_asm.S</file>
|
||||
<file>cpu.c</file>
|
||||
<file>exp.c</file>
|
||||
<file>kiinit.c</file>
|
||||
<file>ppc_irq.c</file>
|
||||
<file>stubs.c</file>
|
||||
<file>systimer.c</file>
|
||||
</directory>
|
||||
</if>
|
||||
<file>apc.c</file>
|
||||
<file>balmgr.c</file>
|
||||
<file>bug.c</file>
|
||||
@@ -93,6 +106,11 @@
|
||||
<file>cmhardwr.c</file>
|
||||
</directory>
|
||||
</if>
|
||||
<if property="ARCH" value="powerpc">
|
||||
<directory name="powerpc">
|
||||
<file>cmhardwr.c</file>
|
||||
</directory>
|
||||
</if>
|
||||
<file>cmapi.c</file>
|
||||
<file>cmboot.c</file>
|
||||
<file>cmcheck.c</file>
|
||||
@@ -135,6 +153,12 @@
|
||||
<file>ioport.S</file>
|
||||
</directory>
|
||||
</if>
|
||||
<if property="ARCH" value="powerpc">
|
||||
<directory name="powerpc">
|
||||
<file>ioport.s</file>
|
||||
<file>fastinterlck.c</file>
|
||||
</directory>
|
||||
</if>
|
||||
<file>atom.c</file>
|
||||
<file>callback.c</file>
|
||||
<file>dbgctrl.c</file>
|
||||
@@ -257,7 +281,12 @@
|
||||
<directory name="kd">
|
||||
<directory name="wrappers">
|
||||
<file>bochs.c</file>
|
||||
<file>gdbstub.c</file>
|
||||
<if property="ARCH" value="i386">
|
||||
<file>gdbstub.c</file>
|
||||
</if>
|
||||
<if property="ARCH" value="powerpc">
|
||||
<file>gdbstub_powerpc.c</file>
|
||||
</if>
|
||||
<file>kdbg.c</file>
|
||||
</directory>
|
||||
<file>kdinit.c</file>
|
||||
@@ -292,6 +321,12 @@
|
||||
<file>page.c</file>
|
||||
</directory>
|
||||
</if>
|
||||
<if property="ARCH" value="powerpc">
|
||||
<directory name="powerpc">
|
||||
<file>pfault.c</file>
|
||||
<file>page.c</file>
|
||||
</directory>
|
||||
</if>
|
||||
<file>anonmem.c</file>
|
||||
<file>aspace.c</file>
|
||||
<file>balance.c</file>
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
/* Default linker script, for normal executables */
|
||||
OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc",
|
||||
"elf32-powerpc")
|
||||
OUTPUT_ARCH(powerpc:common)
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
__text_start__ = .;
|
||||
*(.text)
|
||||
*(init)
|
||||
*(INIT)
|
||||
__text_end__ = .;
|
||||
}
|
||||
.data :
|
||||
{
|
||||
*(.data)
|
||||
*(.data2)
|
||||
*(.rdata)
|
||||
*(.sdata)
|
||||
*(.pdata)
|
||||
}
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata)
|
||||
*(.got2)
|
||||
*(.eh_frame)
|
||||
}
|
||||
.idata :
|
||||
{
|
||||
*(.idata$2)
|
||||
SORT(*)(.idata$3)
|
||||
LONG(0); LONG(0); LONG(0); LONG(0); LONG(0);
|
||||
SORT(*)(.idata$4)
|
||||
SORT(*)(.idata$5)
|
||||
SORT(*)(.idata$6)
|
||||
SORT(*)(.idata$7)
|
||||
}
|
||||
.edata :
|
||||
{
|
||||
*(.edata)
|
||||
}
|
||||
.bss :
|
||||
{
|
||||
*(.sbss)
|
||||
*(.bss)
|
||||
*(COMMON)
|
||||
}
|
||||
.rsrc :
|
||||
{
|
||||
*(.rsrc)
|
||||
}
|
||||
.rela.text :
|
||||
{
|
||||
*(.rela.text)
|
||||
}
|
||||
.rela.data :
|
||||
{
|
||||
*(.rela.data)
|
||||
}
|
||||
.rela.rodata :
|
||||
{
|
||||
*(.rela.rodata)
|
||||
}
|
||||
.rela.got2 :
|
||||
{
|
||||
*(.rela.got2)
|
||||
}
|
||||
}
|
||||
@@ -181,6 +181,7 @@ PsGetContextThread(IN PETHREAD Thread,
|
||||
/* Read the flags */
|
||||
Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
|
||||
|
||||
#ifdef _M_IX86
|
||||
/* Check if the caller wanted extended registers */
|
||||
if ((Flags & CONTEXT_EXTENDED_REGISTERS) !=
|
||||
CONTEXT_EXTENDED_REGISTERS)
|
||||
@@ -188,6 +189,7 @@ PsGetContextThread(IN PETHREAD Thread,
|
||||
/* Cut them out of the size */
|
||||
Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if we came from user mode */
|
||||
if (PreviousMode != KernelMode)
|
||||
@@ -299,6 +301,7 @@ PsSetContextThread(IN PETHREAD Thread,
|
||||
/* Read the flags */
|
||||
Flags = ProbeForReadUlong(&ThreadContext->ContextFlags);
|
||||
|
||||
#ifdef _M_IX86
|
||||
/* Check if the caller wanted extended registers */
|
||||
if ((Flags & CONTEXT_EXTENDED_REGISTERS) !=
|
||||
CONTEXT_EXTENDED_REGISTERS)
|
||||
@@ -306,6 +309,7 @@ PsSetContextThread(IN PETHREAD Thread,
|
||||
/* Cut them out of the size */
|
||||
Size = FIELD_OFFSET(CONTEXT, ExtendedRegisters);
|
||||
}
|
||||
#endif
|
||||
|
||||
/* Check if we came from user mode */
|
||||
if (PreviousMode != KernelMode)
|
||||
|
||||
@@ -324,7 +324,8 @@ PspCreateThread(OUT PHANDLE ThreadHandle,
|
||||
Thread->StartAddress = (PVOID)ThreadContext->Eip;
|
||||
Thread->Win32StartAddress = (PVOID)ThreadContext->Eax;
|
||||
#elif defined(_M_PPC)
|
||||
#error Not implemented yet for PPC architecture!
|
||||
Thread->StartAddress = (PVOID)ThreadContext->Dr0;
|
||||
Thread->Win32StartAddress = (PVOID)ThreadContext->Gpr3;
|
||||
#elif defined(_M_MIPS)
|
||||
for (;;);
|
||||
#else
|
||||
|
||||
@@ -325,7 +325,11 @@ RtlWalkFrameChain(OUT PVOID *Callers,
|
||||
/* Get the stack limits */
|
||||
StackBegin = (ULONG_PTR)Teb->Tib.StackLimit;
|
||||
StackEnd = (ULONG_PTR)Teb->Tib.StackBase;
|
||||
#ifdef _M_IX86
|
||||
Stack = TrapFrame->Ebp;
|
||||
#elif defined(_M_PPC)
|
||||
Stack = TrapFrame->Gpr1;
|
||||
#endif
|
||||
|
||||
/* Validate them */
|
||||
if (StackEnd <= StackBegin) return 0;
|
||||
|
||||
@@ -2,8 +2,9 @@
|
||||
<!DOCTYPE group SYSTEM "../../../tools/rbuild/project.dtd">
|
||||
<group>
|
||||
<module name="win32k_base" type="objectlibrary">
|
||||
<include base="win32k">.</include>
|
||||
<include base="win32k">include</include>
|
||||
<include base="win32k_base">.</include>
|
||||
<include base="win32k_base">include</include>
|
||||
<include base="win32k_base" root="intermediate">.</include>
|
||||
<include base="ntoskrnl">include</include>
|
||||
<include base="freetype">include</include>
|
||||
<include base="ReactOS">include/reactos/subsys</include>
|
||||
|
||||
@@ -9,10 +9,8 @@ CD=output-ppc/ppcboot
|
||||
I=$CD/install
|
||||
TOOLS=tools/ppc.lost+found
|
||||
|
||||
$TOOLS/link-freeldr
|
||||
|
||||
mkdir -p $I
|
||||
cp freeldr.elf $I/yaboot
|
||||
cp output-ppc/boot/freeldr/freeldr/ofwldr $I/yaboot
|
||||
cp `dirname $0`/ofboot.b $I
|
||||
|
||||
mkisofs -chrp-boot -U -part -hfs -T -r -l -J -A "ReactOS" -sysid PPC \
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#!/bin/sh -v
|
||||
|
||||
export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin
|
||||
powerpc-unknown-linux-gnu-ld \
|
||||
-g -nostartfiles -nostdlib -N -Ttext=0xe00000 \
|
||||
-o freeldr.elf output-ppc/boot/freeldr/freeldr/ofwldr \
|
||||
-Lobj-ppc/lib/ppcmmu -lppcmmu_code -lppcmmu
|
||||
@@ -1,14 +0,0 @@
|
||||
#!/bin/sh
|
||||
|
||||
export PATH=$PATH:/usr/local/pkg/reactos-powerpc/bin
|
||||
make \
|
||||
ARCH=powerpc \
|
||||
HOST=mingw32-linux \
|
||||
PREFIX=reactos-powerpc \
|
||||
ROS_INTERMEDIATE=obj-ppc \
|
||||
ROS_OUTPUT=output-ppc \
|
||||
ROS_PREFIX=reactos-powerpc \
|
||||
ROS_INSTALL=rosppc \
|
||||
ROS_AUTOMAKE=makefile.ppc \
|
||||
ROS_RBUILDFLAGS=-rReactOS-ppc.rbuild \
|
||||
$*
|
||||
@@ -373,8 +373,9 @@ MingwBackend::GenerateHeader () const
|
||||
string
|
||||
MingwBackend::GenerateIncludesAndDefines ( IfableData& data ) const
|
||||
{
|
||||
set<string> used_defs;
|
||||
string includeParameters = MingwModuleHandler::GenerateGccIncludeParametersFromVector ( data.includes );
|
||||
string defineParameters = MingwModuleHandler::GenerateGccDefineParametersFromVector ( data.defines );
|
||||
string defineParameters = MingwModuleHandler::GenerateGccDefineParametersFromVector ( data.defines, used_defs );
|
||||
return includeParameters + " " + defineParameters;
|
||||
}
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
#include "mingw.h"
|
||||
#include "modulehandler.h"
|
||||
|
||||
using std::set;
|
||||
using std::string;
|
||||
using std::vector;
|
||||
|
||||
@@ -627,14 +628,20 @@ MingwModuleHandler::GetObjectFilenames ()
|
||||
|
||||
/* static */ string
|
||||
MingwModuleHandler::GenerateGccDefineParametersFromVector (
|
||||
const vector<Define*>& defines )
|
||||
const vector<Define*>& defines,
|
||||
set<string>& used_defs)
|
||||
{
|
||||
string parameters;
|
||||
|
||||
for ( size_t i = 0; i < defines.size (); i++ )
|
||||
{
|
||||
Define& define = *defines[i];
|
||||
if (used_defs.find(define.name) != used_defs.end())
|
||||
continue;
|
||||
if (parameters.length () > 0)
|
||||
parameters += " ";
|
||||
if (define.name.find('(') != string::npos)
|
||||
parameters += "$(QT)";
|
||||
parameters += "-D";
|
||||
parameters += define.name;
|
||||
if (define.value.length () > 0)
|
||||
@@ -642,6 +649,9 @@ MingwModuleHandler::GenerateGccDefineParametersFromVector (
|
||||
parameters += "=";
|
||||
parameters += define.value;
|
||||
}
|
||||
if (define.name.find('(') != string::npos)
|
||||
parameters += "$(QT)";
|
||||
used_defs.insert(used_defs.begin(),define.name);
|
||||
}
|
||||
return parameters;
|
||||
}
|
||||
@@ -649,8 +659,9 @@ MingwModuleHandler::GenerateGccDefineParametersFromVector (
|
||||
string
|
||||
MingwModuleHandler::GenerateGccDefineParameters () const
|
||||
{
|
||||
string parameters = GenerateGccDefineParametersFromVector ( module.project.non_if_data.defines );
|
||||
string s = GenerateGccDefineParametersFromVector ( module.non_if_data.defines );
|
||||
set<string> used_defs;
|
||||
string parameters = GenerateGccDefineParametersFromVector ( module.project.non_if_data.defines, used_defs );
|
||||
string s = GenerateGccDefineParametersFromVector ( module.non_if_data.defines, used_defs );
|
||||
if ( s.length () > 0 )
|
||||
{
|
||||
parameters += " ";
|
||||
@@ -2458,17 +2469,17 @@ MingwKernelModuleHandler::GenerateKernelModuleTarget ()
|
||||
|
||||
string dependencies = linkDepsMacro + " " + objectsMacro;
|
||||
|
||||
string linkerParameters = ssprintf ( "-Wl,-T,%s%cntoskrnl.lnk -Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s -Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared",
|
||||
string linkerParameters = ssprintf ( "-Wl,-T,%s%cntoskrnl_$(ARCH).lnk -Wl,--subsystem,native -Wl,--entry,%s -Wl,--image-base,%s",
|
||||
module.output->relative_path.c_str (),
|
||||
cSep,
|
||||
module.GetEntryPoint(true).c_str (),
|
||||
module.baseaddress.c_str () );
|
||||
GenerateLinkerCommand ( dependencies,
|
||||
"${gcc}",
|
||||
linkerParameters,
|
||||
objectsMacro,
|
||||
libsMacro,
|
||||
"-sections" );
|
||||
"${gcc}",
|
||||
linkerParameters + " $(NTOSKRNL_SHARED)",
|
||||
objectsMacro,
|
||||
libsMacro,
|
||||
"-sections" );
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -3708,7 +3719,7 @@ MingwElfExecutableModuleHandler::Process ()
|
||||
|
||||
fprintf ( fMakefile, "\t$(ECHO_BOOTPROG)\n" );
|
||||
|
||||
fprintf ( fMakefile, "\t${ld} $(%s_LINKFORMAT) %s %s -g -o %s\n",
|
||||
fprintf ( fMakefile, "\t${gcc} $(%s_LINKFORMAT) %s %s -g -o %s\n",
|
||||
module.buildtype.c_str(),
|
||||
objectsMacro.c_str(),
|
||||
libsMacro.c_str(),
|
||||
|
||||
@@ -51,7 +51,7 @@ public:
|
||||
const Module& module,
|
||||
string_list* pclean_files );
|
||||
|
||||
static std::string GenerateGccDefineParametersFromVector ( const std::vector<Define*>& defines );
|
||||
static std::string GenerateGccDefineParametersFromVector ( const std::vector<Define*>& defines, std::set<std::string> &used_defs );
|
||||
static std::string GenerateGccIncludeParametersFromVector ( const std::vector<Include*>& includes );
|
||||
|
||||
std::string GetModuleTargets ( const Module& module );
|
||||
|
||||
@@ -50,7 +50,9 @@ include tools/buildno/buildno.mak
|
||||
include tools/cabman/cabman.mak
|
||||
include tools/cdmake/cdmake.mak
|
||||
include tools/gendib/gendib.mak
|
||||
ifeq ($(ARCH),powerpc)
|
||||
include tools/ofw_interface/ofw_interface.mak
|
||||
endif
|
||||
include tools/mkhive/mkhive.mak
|
||||
include tools/nci/nci.mak
|
||||
include tools/pefixup.mak
|
||||
@@ -64,4 +66,4 @@ include tools/wpp/wpp.mak
|
||||
include tools/widl/widl.mak
|
||||
include tools/winebuild/winebuild.mak
|
||||
include tools/wmc/wmc.mak
|
||||
include tools/wrc/wrc.mak
|
||||
include tools/wrc/wrc.mak
|
||||
|
||||
Reference in New Issue
Block a user