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:
Art Yerkes
2007-10-06 07:53:20 +00:00
parent 9a2d4a0858
commit 0abf169695
60 changed files with 6403 additions and 180 deletions
+1 -1
View File
@@ -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
+2
View File
@@ -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
View File
@@ -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>
+1 -1
View File
@@ -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:
+4
View File
@@ -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.
+29
View File
@@ -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
+117 -97
View File
@@ -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__
+12 -2
View File
@@ -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__)
+3
View File
@@ -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>
+82
View File
@@ -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
+5
View File
@@ -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>
+105
View File
@@ -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
+41
View File
@@ -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
+2
View File
@@ -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
+6 -1
View File
@@ -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">
+834
View File
@@ -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;
}
+262
View File
@@ -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;
}
+171
View File
@@ -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 */
+1 -1
View File
@@ -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 */
+5
View File
@@ -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
//
+9 -1
View File
@@ -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
}
+2 -2
View File
@@ -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 */
+56 -5
View File
@@ -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 */
+8
View File
@@ -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
+12 -3
View File
@@ -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();
}
}
+277
View File
@@ -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);
}
+114
View File
@@ -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;
}
+322
View File
@@ -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);
}
+81
View File
@@ -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
+841
View File
@@ -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 */
+234
View File
@@ -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() { }
+21
View File
@@ -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
}
+4
View File
@@ -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;
+2
View File
@@ -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 */
+2
View File
@@ -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));
}
+630
View File
@@ -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 */
+96
View File
@@ -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;
}
+36 -1
View File
@@ -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>
+69
View 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)
}
}
+4
View File
@@ -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)
+2 -1
View File
@@ -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
+4
View File
@@ -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>
+1 -3
View File
@@ -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
-14
View File
@@ -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 \
$*
+2 -1
View File
@@ -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 );
+3 -1
View File
@@ -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