Add basic arm target support to the build system.

Reactos-arm.rbuild uses the same settings as the x86 version, but defines _ARM_ and __arm__ instead. _M_ARM is already defined by the compiler.
Add ARM system call stub support to ncitool. We are currently using a SWI 0x2E to achieve this.
Add ARM support to winnt.h.
Add a preliminary intrin_arm.h
Add ketypes.h and mmtypes.h for ARM in the NDK. For now these are mostly stubs to allow compiling to work.
Add ARM support to winddk.h.
Fix some broken x86-only assumptions in the NDK.
Add config-arm-template.rbuild. By defauilt we build for armv5te (armv4 and v5 are supported, not v6).
Set ROS_ARCH=arm to switch to ARM. Set ROS_PREFIX to an appropriate MinGW-32 ARM PE crosscompiler.


svn path=/trunk/; revision=32131
This commit is contained in:
ReactOS Portable Systems Group 2008-02-05 02:58:28 +00:00
parent 3be034d2ce
commit 57ad1f5f20
14 changed files with 672 additions and 12 deletions

View file

@ -0,0 +1,36 @@
<?xml version="1.0"?>
<!DOCTYPE project SYSTEM "tools/rbuild/project.dtd">
<project name="ReactOS" makefile="makefile.auto" xmlns:xi="http://www.w3.org/2001/XInclude">
<xi:include href="config-arm.rbuild">
<xi:fallback>
<xi:include href="config-arm.template.rbuild" />
</xi:fallback>
</xi:include>
<xi:include href="ReactOS-generic.rbuild" />
<define name="_ARM_" />
<define name="__arm__" />
<property name="NTOSKRNL_SHARED" value="-Wl,--file-alignment,0x1000 -Wl,--section-alignment,0x1000 -nostartfiles -shared"/>
<if property="OPTIMIZE" value="1">
<compilerflag>-Os</compilerflag>
<compilerflag>-ftracer</compilerflag>
</if>
<if property="OPTIMIZE" value="2">
<compilerflag>-Os</compilerflag>
</if>
<if property="OPTIMIZE" value="3">
<compilerflag>-O1</compilerflag>
</if>
<if property="OPTIMIZE" value="4">
<compilerflag>-O2</compilerflag>
</if>
<if property="OPTIMIZE" value="5">
<compilerflag>-O3</compilerflag>
</if>
<compilerflag>-Wno-attributes</compilerflag>
<compilerflag>-fno-strict-aliasing</compilerflag>
</project>

View file

@ -0,0 +1,81 @@
<?xml version="1.0"?>
<!DOCTYPE group SYSTEM "tools/rbuild/project.dtd">
<group>
<!--
This file is a template used as a starting point for compile-time
configuration of ReactOS. Make a copy of this file and name it config.rbuild.
Then change the options in config.rbuild. If you don't have a config.rbuild file,
then the defaults in this file, config.template.rbuild, will be used instead.
Boolean options can obtain the values 0 (disabled) or 1 (enabled). String
options can obtain any value specified in the comment before it.
-->
<!--
Sub-architecture to build for. Specify one of:
-->
<property name="SARCH" value="" />
<!--
Which CPU ReactOS should be optimized for. Specify one of:
armv4, armv4t, armv5, armv5te
See GCC manual for more CPU names and which CPUs GCC can optimize for.
-->
<property name="OARCH" value="armv5te" />
<!--
What level of optimisation to use.
0 = off (will not work)
1 = Default option, optimize for size (-Os) with some additional options
2 = -Os
3 = -O1
4 = -O2
5 = -O3
-->
<property name="OPTIMIZE" value="1" />
<!--
Whether to compile in the integrated kernel debugger.
-->
<property name="KDBG" value="0" />
<!--
Whether to compile for debugging. No compiler optimizations will be
performed.
-->
<property name="DBG" value="1" />
<!--
Whether to compile for debugging with GDB. If you don't use GDB, don't
enable this.
-->
<property name="GDB" value="0" />
<!--
Whether to compile apps/libs with features covered software patents or not.
If you live in a country where software patents are valid/apply, don't
enable this (except they/you purchased a license from the patent owner).
This settings is disabled (0) by default.
-->
<property name="NSWPAT" value="0" />
<!--
Whether to compile with the KD protocol. This will disable support for KDBG
as well as rossym and symbol lookups, and allow WinDBG to connect to ReactOS.
This is currently not fully working, and requires kdcom from Windows 2003 or
TinyKRNL. Booting into debug mode with this flag enabled will result in a
failure to enter GUI mode. Do not enable unless you know what you're doing.
-->
<property name="_WINKD_" value="0" />
</group>

View file

@ -228,7 +228,10 @@ typedef struct _ADAPTER_OBJECT *PADAPTER_OBJECT;
#define ZwCurrentProcess() NtCurrentProcess()
#define NtCurrentThread() ( (HANDLE)(LONG_PTR) -2 )
#define ZwCurrentThread() NtCurrentThread()
#if (_M_IX86)
#define KIP0PCRADDRESS 0xffdff000
#endif
#define KERNEL_STACK_SIZE 12288
#define KERNEL_LARGE_STACK_SIZE 61440
@ -5535,6 +5538,8 @@ KeGetCurrentProcessorNumber(VOID)
#elif defined(_MIPS_)
#error MIPS Headers are totally incorrect
typedef ULONG PFN_NUMBER, *PPFN_NUMBER;
#define PASSIVE_LEVEL 0
@ -5562,10 +5567,17 @@ KeGetCurrentProcessorNumber(VOID)
return 0;
}
#elif defined(_M_ARM)
//
// NT-ARM is not documented, need NDK
//
#include <arm/ketypes.h>
#else
#error Unknown architecture
#endif
#define PAGE_SIZE 0x1000
#define PAGE_SHIFT 12L

View file

@ -26,6 +26,8 @@ Author:
#include <i386/ketypes.h>
#elif defined(_M_PPC)
#include <powerpc/ketypes.h>
#elif defined(_M_ARM)
#include <arm/ketypes.h>
#else
#error "Unknown processor"
#endif

View file

@ -26,6 +26,8 @@ Author:
#include <i386/mmtypes.h>
#elif defined(_M_PPC)
#include <powerpc/mmtypes.h>
#elif defined(_M_ARM)
#include <arm/mmtypes.h>
#else
#error "Unknown processor"
#endif

View file

@ -0,0 +1,211 @@
/*++ NDK Version: 0098
Copyright (c) Alex Ionescu. All rights reserved.
Header Name:
ketypes.h (ARM)
Abstract:
ARM Type definitions for the Kernel services.
Author:
Alex Ionescu (alexi@tinykrnl.org) - Updated - 27-Feb-2006
--*/
#ifndef _ARM_KETYPES_H
#define _ARM_KETYPES_H
//
// Dependencies
//
//
// IRQLs
//
#define PASSIVE_LEVEL 0
#define LOW_LEVEL 0
#define APC_LEVEL 1
#define DISPATCH_LEVEL 2
#define IPI_LEVEL 7
#define POWER_LEVEL 7
#define PROFILE_LEVEL 8
#define HIGH_LEVEL 8
#define SYNCH_LEVEL (IPI_LEVEL - 1)
//
// IPI Types
//
#define IPI_APC 1
#define IPI_DPC 2
#define IPI_FREEZE 4
#define IPI_PACKET_READY 8
#define IPI_SYNCH_REQUEST 16
//
// PRCB Flags
//
#define PRCB_MAJOR_VERSION 1
#define PRCB_BUILD_DEBUG 1
#define PRCB_BUILD_UNIPROCESSOR 2
//
// HAL Variables
//
#define INITIAL_STALL_COUNT 0x64
//
// Static Kernel-Mode Address start (use MM_KSEG0_BASE for actual)
//
#define KSEG0_BASE 0x80000000
//
// FIXME: mmtypes.h?
//
#define KIPCR 0xFFFFF000
#define PCR ((volatile KPCR * const)KIPCR)
//
// Synchronization-level IRQL
//
#define SYNCH_LEVEL DISPATCH_LEVEL
//
// Trap Frame Definition
//
typedef struct _KTRAP_FRAME
{
ULONG R0;
ULONG R1;
ULONG R2;
ULONG R3;
ULONG R4;
ULONG R5;
ULONG R6;
ULONG R7;
ULONG R8;
ULONG R9;
ULONG R10;
ULONG R11;
ULONG R12;
ULONG Sp;
ULONG Lr;
ULONG Pc;
ULONG Psr;
UCHAR ExceptionRecord[(sizeof(EXCEPTION_RECORD) + 7) & (~7)];
UCHAR OldIrql;
UCHAR PreviousMode;
ULONG Fpscr;
ULONG FpExc;
ULONG S[33];
ULONG FpExtra[8];
} KTRAP_FRAME, *PKTRAP_FRAME;
#ifndef NTOS_MODE_USER
//
// Stub
//
typedef struct _KFLOATING_SAVE
{
ULONG Reserved;
} KFLOATING_SAVE, *PKFLOATING_SAVE;
//
// Processor Region Control Block
//
typedef struct _KPRCB
{
USHORT MinorVersion;
USHORT MajorVersion;
struct _KTHREAD *CurrentThread;
struct _KTHREAD *NextThread;
struct _KTHREAD *IdleThread;
UCHAR Number;
//
// TODO
//
} KPRCB, *PKPRCB;
//
// Processor Control Region
//
typedef struct _KPCR
{
ULONG MinorVersion;
ULONG MajorVersion;
PKINTERRUPT_ROUTINE InterruptRoutine[64];
PVOID XcodeDispatch;
ULONG FirstLevelDcacheSize;
ULONG FirstLevelDcacheFillSize;
ULONG FirstLevelIcacheSize;
ULONG FirstLevelIcacheFillSize;
ULONG SecondLevelDcacheSize;
ULONG SecondLevelDcacheFillSize;
ULONG SecondLevelIcacheSize;
ULONG SecondLevelIcacheFillSize;
struct _KPRCB *Prcb;
struct _TEB *Teb;
PVOID TlsArray;
ULONG DcacheFillSize;
ULONG IcacheAlignment;
ULONG IcacheFillSize;
ULONG ProcessorId;
ULONG ProfileInterval;
ULONG ProfileCount;
ULONG StallExecutionCount;
ULONG StallScaleFactor;
CCHAR Number;
PVOID DataBusError;
PVOID InstructionBusError;
ULONG CachePolicy;
UCHAR IrqlMask[64];
UCHAR IrqlTable[64];
UCHAR CurrentIrql;
KAFFINITY SetMember;
struct _KTHREAD *CurrentThread;
KAFFINITY NotMember;
ULONG SystemReserved[6];
ULONG DcacheAlignment;
ULONG HalReserved[64];
BOOLEAN FirstLevelActive;
BOOLEAN DpcRoutineActive;
ULONG CurrentPid;
BOOLEAN OnInterruptStack;
PVOID SavedInitialStack;
PVOID SavedStackLimit;
PVOID SystemServiceDispatchStart;
PVOID SystemServiceDispatchEnd;
PVOID InterruptStack;
PVOID PanicStack;
PVOID BadVaddr;
PVOID InitialStack;
PVOID StackLimit;
ULONG QuantumEnd;
} KPCR, *PKPCR;
//
// Macro to get current KPRCB
//
FORCEINLINE
struct _KPRCB *
KeGetCurrentPrcb(VOID)
{
return PCR->Prcb;
}
//
// Macro to get current CPU
//
FORCEINLINE
ULONG
DDKAPI
KeGetCurrentProcessorNumber(VOID)
{
return PCR->Number;
}
#endif
#endif

View file

@ -0,0 +1,141 @@
/*++ NDK Version: 0095
Copyright (c) Alex Ionescu. All rights reserved.
Header Name:
mmtypes.h (ARM)
Abstract:
ARM Type definitions for the Memory Manager
Author:
Alex Ionescu (alex.ionescu@reactos.com) 06-Oct-2004
--*/
#ifndef _ARM_MMTYPES_H
#define _ARM_MMTYPES_H
//
// Dependencies
//
//
// Page-related Macros
//
#define PAGE_SIZE 0x1000
#define PAGE_SHIFT 12L
#define MM_ALLOCATION_GRANULARITY 0x10000
#define MM_ALLOCATION_GRANULARITY_SHIFT 16L
//
// Sanity checks for Paging Macros
//
#ifdef C_ASSERT
C_ASSERT(PAGE_SIZE == (1 << PAGE_SHIFT));
C_ASSERT(MM_ALLOCATION_GRANULARITY == (1 << MM_ALLOCATION_GRANULARITY_SHIFT));
C_ASSERT(MM_ALLOCATION_GRANULARITY &&
!(MM_ALLOCATION_GRANULARITY & (MM_ALLOCATION_GRANULARITY - 1)));
C_ASSERT(MM_ALLOCATION_GRANULARITY >= PAGE_SIZE);
#endif
//
// Page Table Entry Definitions
//
typedef struct _HARDWARE_PTE_ARM
{
ULONG Valid:1;
ULONG Write:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype: 1;
ULONG reserved: 1;
ULONG PageFrameNumber:20;
} HARDWARE_PTE_ARM, *PHARDWARE_PTE_ARM;
typedef struct _MMPTE_SOFTWARE
{
ULONG Valid:1;
ULONG PageFileLow:4;
ULONG Protection:5;
ULONG Prototype:1;
ULONG Transition:1;
ULONG PageFileHigh:20;
} MMPTE_SOFTWARE;
typedef struct _MMPTE_TRANSITION
{
ULONG Valid:1;
ULONG Write:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Protection:5;
ULONG Prototype:1;
ULONG Transition:1;
ULONG PageFrameNumber:20;
} MMPTE_TRANSITION;
typedef struct _MMPTE_PROTOTYPE
{
ULONG Valid:1;
ULONG ProtoAddressLow:7;
ULONG ReadOnly:1;
ULONG WhichPool:1;
ULONG Prototype:1;
ULONG ProtoAddressHigh:21;
} MMPTE_PROTOTYPE;
typedef struct _MMPTE_SUBSECTION
{
ULONG Valid:1;
ULONG SubsectionAddressLow:4;
ULONG Protection:5;
ULONG Prototype:1;
ULONG SubsectionAddressHigh:20;
ULONG WhichPool:1;
} MMPTE_SUBSECTION;
typedef struct _MMPTE_LIST
{
ULONG Valid:1;
ULONG OneEntry:1;
ULONG filler0:8;
ULONG NextEntry:20;
ULONG Prototype:1;
ULONG filler1:1;
} MMPTE_LIST;
typedef struct _MMPTE_HARDWARE
{
ULONG Valid:1;
ULONG Write:1;
ULONG Owner:1;
ULONG WriteThrough:1;
ULONG CacheDisable:1;
ULONG Accessed:1;
ULONG Dirty:1;
ULONG LargePage:1;
ULONG Global:1;
ULONG CopyOnWrite:1;
ULONG Prototype:1;
ULONG reserved:1;
ULONG PageFrameNumber:20;
} MMPTE_HARDWARE, *PMMPTE_HARDWARE;
//
// Use the right PTE structure
//
#define HARDWARE_PTE HARDWARE_PTE_ARM
#define PHARDWARE_PTE PHARDWARE_PTE_ARM
#endif

View file

@ -23,6 +23,17 @@ Author:
// Dependencies
//
//
// KPCR Access for non-IA64 builds
//
#define K0IPCR ((ULONG_PTR)(KIP0PCRADDRESS))
#define PCR ((volatile KPCR * const)K0IPCR)
#if !defined(CONFIG_SMP) && !defined(NT_BUILD)
#define KeGetPcr() PCR
#else
#define KeGetPcr() ((volatile KPCR * const)__readfsdword(0x1C))
#endif
//
// Machine Types
//

View file

@ -103,17 +103,6 @@ Author:
#define KI_EXCEPTION_INTERNAL 0x10000000
#define KI_EXCEPTION_ACCESS_VIOLATION (KI_EXCEPTION_INTERNAL | 0x04)
//
// KPCR Access for non-IA64 builds
//
#define K0IPCR ((ULONG_PTR)(KIP0PCRADDRESS))
#define PCR ((volatile KPCR * const)K0IPCR)
#if !defined(CONFIG_SMP) && !defined(NT_BUILD)
#define KeGetPcr() PCR
#else
#define KeGetPcr() ((volatile KPCR * const)__readfsdword(0x1C))
#endif
//
// Number of dispatch codes supported by KINTERRUPT
//

View file

@ -535,12 +535,14 @@ typedef NTSTATUS
//
// Descriptor Table Entry Definition
//
#if (_M_IX86)
#define _DESCRIPTOR_TABLE_ENTRY_DEFINED
typedef struct _DESCRIPTOR_TABLE_ENTRY
{
ULONG Selector;
LDT_ENTRY Descriptor;
} DESCRIPTOR_TABLE_ENTRY, *PDESCRIPTOR_TABLE_ENTRY;
#endif
//
// PEB Lock Routine

View file

@ -75,6 +75,8 @@
#include "intrin_ppc.h"
#elif defined(_MIPS_)
#include "intrin_mips.h"
#elif defined(_M_ARM)
#include "intrin_arm.h"
#elif defined(__x86_64__)
/* TODO: the x64 architecture shares most of the i386 intrinsics. It should be easy to support */
#include "intrin_x86_64.h"

View file

@ -0,0 +1,152 @@
/*
Compatibility <intrin.h> header for GCC -- GCC equivalents of intrinsic
Microsoft Visual C++ functions. Originally developed for the ReactOS
(<http://www.reactos.org/>) and TinyKrnl (<http://www.tinykrnl.org/>)
projects.
Copyright (c) 2006 KJK::Hyperion <hackbunny@reactos.com>
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 do 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.
*/
#ifndef KJK_INTRIN_ARM_H_
#define KJK_INTRIN_ARM_H_
#ifndef __GNUC__
#error Unsupported compiler
#endif
#define _ReadWriteBarrier() __sync_synchronize()
FORCEINLINE char _InterlockedCompareExchange8(volatile char * const Destination, const char Exchange, const char Comperand)
{
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
}
FORCEINLINE short _InterlockedCompareExchange16(volatile short * const Destination, const short Exchange, const short Comperand)
{
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
}
FORCEINLINE long _InterlockedCompareExchange(volatile long * const Destination, const long Exchange, const long Comperand)
{
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
}
FORCEINLINE 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);
}
FORCEINLINE void * _InterlockedCompareExchangePointer(void * volatile * const Destination, void * const Exchange, void * const Comperand)
{
return __sync_val_compare_and_swap(Destination, Comperand, Exchange);
}
FORCEINLINE 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);
}
FORCEINLINE 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 _InterlockedExchangeAdd16(volatile short * const Addend, const short Value)
{
return __sync_fetch_and_add(Addend, Value);
}
FORCEINLINE long _InterlockedExchangeAdd(volatile long * const Addend, const long Value)
{
return __sync_fetch_and_add(Addend, Value);
}
FORCEINLINE char _InterlockedAnd8(volatile char * const value, const char mask)
{
return __sync_fetch_and_and(value, mask);
}
FORCEINLINE short _InterlockedAnd16(volatile short * const value, const short mask)
{
return __sync_fetch_and_and(value, mask);
}
FORCEINLINE long _InterlockedAnd(volatile long * const value, const long mask)
{
return __sync_fetch_and_and(value, mask);
}
FORCEINLINE char _InterlockedOr8(volatile char * const value, const char mask)
{
return __sync_fetch_and_or(value, mask);
}
FORCEINLINE short _InterlockedOr16(volatile short * const value, const short mask)
{
return __sync_fetch_and_or(value, mask);
}
FORCEINLINE long _InterlockedOr(volatile long * const value, const long mask)
{
return __sync_fetch_and_or(value, mask);
}
FORCEINLINE char _InterlockedXor8(volatile char * const value, const char mask)
{
return __sync_fetch_and_xor(value, mask);
}
FORCEINLINE short _InterlockedXor16(volatile short * const value, const short mask)
{
return __sync_fetch_and_xor(value, mask);
}
FORCEINLINE long _InterlockedXor(volatile long * const value, const long mask)
{
return __sync_fetch_and_xor(value, mask);
}
static __inline__ __attribute__((always_inline)) long _InterlockedDecrement(volatile long * const lpAddend)
{
return _InterlockedExchangeAdd(lpAddend, -1) - 1;
}
static __inline__ __attribute__((always_inline)) long _InterlockedIncrement(volatile long * const lpAddend)
{
return _InterlockedExchangeAdd(lpAddend, 1) + 1;
}
static __inline__ __attribute__((always_inline)) long _InterlockedDecrement16(volatile short * const lpAddend)
{
return _InterlockedExchangeAdd16(lpAddend, -1) - 1;
}
static __inline__ __attribute__((always_inline)) long _InterlockedIncrement16(volatile short * const lpAddend)
{
return _InterlockedExchangeAdd16(lpAddend, 1) + 1;
}
#endif
/* EOF */

View file

@ -4064,6 +4064,8 @@ static __inline__ PVOID GetCurrentFiber(void)
);
return ret;
}
#elif defined (_M_ARM)
PVOID WINAPI GetCurrentFiber(VOID);
#else
#if defined(_M_PPC)
static __inline__ __attribute__((always_inline)) unsigned long __readfsdword_winnt(const unsigned long Offset)
@ -4101,6 +4103,8 @@ static __inline__ struct _TEB * NtCurrentTeb(void)
return ret;
}
#elif _M_ARM
struct _TEB* WINAPI NtCurrentTeb(VOID);
#else
static __inline__ struct _TEB * NtCurrentTeb(void)
{
@ -4235,6 +4239,8 @@ BitScanReverse(OUT ULONG *Index,
#define YieldProcessor() __asm__ __volatile__("nop");
#elif defined(_M_MIPS)
#define YieldProcessor() __asm__ __volatile__("nop");
#elif defined(_M_ARM)
#define YieldProcessor()
#else
#error Unknown architecture
#endif

View file

@ -68,6 +68,13 @@
" j $8\n" \
" nop\n"
//
// For now, only supports 0-4 arguments
//
#define UserModeStub_arm " mov r12, #0x%x\n" \
" swi #0x2E\n" \
" bx lr\n\n"
#elif defined(_MSC_VER)
#define UserModeStub_x86 " asm { \n" \
" mov eax, %xh\n" \
@ -97,6 +104,10 @@
#define KernelModeStub_mips " j KiSystemService\n" \
" nop\n"
#define KernelModeStub_arm " mov r12, #0x%x\n" \
" swi #0x2E\n" \
" bx lr\n\n"
#elif defined(_MSC_VER)
#define KernelModeStub_x86 " asm { \n" \
" mov eax, %xh\n" \
@ -127,6 +138,8 @@ struct ncitool_data_t ncitool_data[] = {
"\t.globl %s\n", "%s:\n" },
{ "mips", 4, KernelModeStub_mips, UserModeStub_mips,
"\t.globl %s\n", "%s:\n" },
{ "arm", 4, KernelModeStub_arm, UserModeStub_arm,
"\t.globl %s\n", "%s:\n" },
{ 0, }
};
int arch_sel = 0;