commit
a7e9a858dd
@ -743,7 +743,7 @@ WARN_LOGFILE =
|
||||
# spaces.
|
||||
# Note: If this tag is empty the current directory is searched.
|
||||
|
||||
INPUT =
|
||||
INPUT = source include
|
||||
|
||||
# This tag can be used to specify the character encoding of the source files
|
||||
# that doxygen parses. Internally doxygen uses the UTF-8 encoding. Doxygen uses
|
||||
@ -763,7 +763,7 @@ INPUT_ENCODING = UTF-8
|
||||
# *.md, *.mm, *.dox, *.py, *.f90, *.f, *.for, *.tcl, *.vhd, *.vhdl, *.ucf,
|
||||
# *.qsf, *.as and *.js.
|
||||
|
||||
FILE_PATTERNS =
|
||||
FILE_PATTERNS = *.h *.c *.cpp *.s
|
||||
|
||||
# The RECURSIVE tag can be used to specify whether or not subdirectories should
|
||||
# be searched for input files as well.
|
||||
@ -811,7 +811,7 @@ EXCLUDE_SYMBOLS =
|
||||
# that contain example code fragments that are included (see the \include
|
||||
# command).
|
||||
|
||||
EXAMPLE_PATH =
|
||||
EXAMPLE_PATH = ../examples
|
||||
|
||||
# If the value of the EXAMPLE_PATH tag contains directories, you can use the
|
||||
# EXAMPLE_PATTERNS tag to specify one or more wildcard pattern (like *.cpp and
|
||||
|
@ -49,3 +49,24 @@ extern "C" {
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
/**
|
||||
* @example app_launch/source/main.c
|
||||
* @example audio/mic/source/main.c
|
||||
* @example get_system_language/source/main.c
|
||||
* @example gpu/source/main.c
|
||||
* @example graphics/bitmap/24bit-color/source/main.c
|
||||
* @example graphics/printing/hello-world/source/main.c
|
||||
* @example graphics/printing/both-screen-text/source/main.c
|
||||
* @example graphics/printing/colored-text/source/main.c
|
||||
* @example graphics/printing/multiple-windows-text/source/main.c
|
||||
* @example http/source/main.c
|
||||
* @example input/read-controls/source/main.c
|
||||
* @example input/touch-screen/source/main.c
|
||||
* @example libapplet_launch/source/main.c
|
||||
* @example mvd/source/main.c
|
||||
* @example qtm/source/main.c
|
||||
* @example sdmc/source/main.c
|
||||
* @example threads/event/source/main.c
|
||||
* @example time/rtc/source/main.c
|
||||
*/
|
||||
|
@ -1,3 +1,11 @@
|
||||
/**
|
||||
* @file gfx.h
|
||||
* @brief LCD Screens manipulation
|
||||
*
|
||||
* This header provides functions to configure and manipulate the two screens, including double buffering and 3D activation.
|
||||
* It is mainly an abstraction over the gsp service.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
#include <3ds/types.h>
|
||||
#include <3ds/services/gsp.h>
|
||||
@ -11,29 +19,129 @@ typedef enum
|
||||
GFX_BOTTOM = 1
|
||||
}gfxScreen_t;
|
||||
|
||||
/**
|
||||
* @brief Side of top screen framebuffer.
|
||||
*
|
||||
* This is to be used only when the 3D is enabled.
|
||||
* Use only GFX_LEFT if this concerns the bottom screen or if 3D is disabled.
|
||||
*/
|
||||
typedef enum
|
||||
{
|
||||
GFX_LEFT = 0,
|
||||
GFX_RIGHT = 1,
|
||||
GFX_LEFT = 0, ///< Left eye framebuffer
|
||||
GFX_RIGHT = 1,///< Right eye framebuffer
|
||||
// GFX_BOTTOM = 0
|
||||
}gfx3dSide_t;
|
||||
|
||||
//system stuff
|
||||
void gfxInitDefault();
|
||||
void gfxInit(GSP_FramebufferFormats topFormat, GSP_FramebufferFormats bottomFormat, bool vrambuffers);
|
||||
void gfxExit();
|
||||
|
||||
//control stuff
|
||||
///@name System related
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Initializes the LCD framebuffers with default parameters
|
||||
*
|
||||
* By default ctrulib will configure the LCD framebuffers with the @ref GSP_BGR8_OES format in linear memory.
|
||||
* This is the same as calling : @code gfxInit(GSP_BGR8_OES,GSP_BGR8_OES,false); @endcode
|
||||
*
|
||||
* @note You should always call @ref gfxExit once done to free the memory and services
|
||||
*/
|
||||
void gfxInitDefault();
|
||||
|
||||
/**
|
||||
* @brief Initializes the LCD framebuffers
|
||||
* @brief topFormat The format of the top screen framebuffers
|
||||
* @brief bottomFormat The format of the bottom screen framebuffers
|
||||
*
|
||||
* This function will allocate the memory for the framebuffers and open a gsp service session.
|
||||
* It will also bind the newly allocated framebuffers to the LCD screen and setup the VBlank event.
|
||||
*
|
||||
* The 3D stereoscopic display is will be disabled.
|
||||
*
|
||||
* @note Even if the double buffering is disabled, it will allocate two buffer per screen.
|
||||
* @note You should always call @ref gfxExit once done to free the memory and services
|
||||
*/
|
||||
void gfxInit(GSP_FramebufferFormats topFormat, GSP_FramebufferFormats bottomFormat, bool vrambuffers);
|
||||
|
||||
/**
|
||||
* @brief Closes the gsp service and frees the framebuffers.
|
||||
*
|
||||
* Just call it when you're done.
|
||||
*/
|
||||
void gfxExit();
|
||||
///@}
|
||||
|
||||
///@name Control
|
||||
///@{
|
||||
/**
|
||||
* @brief Enables the 3D stereoscopic effect.
|
||||
* @param enable Enables the 3D effect if true, disables it if false.
|
||||
*/
|
||||
void gfxSet3D(bool enable);
|
||||
|
||||
/**
|
||||
* @brief Changes the color format of a screen
|
||||
* @param screen The screen of which format should be changed
|
||||
* @param format One of the gsp pixel formats.
|
||||
*/
|
||||
void gfxSetScreenFormat(gfxScreen_t screen, GSP_FramebufferFormats format);
|
||||
|
||||
/**
|
||||
* @brief Gets a screen pixel format.
|
||||
* @return the pixel format of the chosen screen set by ctrulib.
|
||||
*/
|
||||
GSP_FramebufferFormats gfxGetScreenFormat(gfxScreen_t screen);
|
||||
|
||||
/**
|
||||
* @brief Enables the ctrulib double buffering
|
||||
*
|
||||
* ctrulib is by default using a double buffering scheme.
|
||||
* If you do not want to swap one of the screen framebuffers when @ref gfxSwapBuffers or @ref gfxSwapBuffers is called,
|
||||
* then you have to disable double buffering.
|
||||
*
|
||||
* It is however recommended to call @ref gfxSwapBuffers even if double buffering is disabled
|
||||
* for both screens if you want to keep the gsp configuration up to date.
|
||||
*/
|
||||
void gfxSetDoubleBuffering(gfxScreen_t screen, bool doubleBuffering);
|
||||
|
||||
/**
|
||||
* @brief Flushes the current framebuffers
|
||||
*
|
||||
* Use this if the data within your framebuffers changes a lot and that you want to make sure everything was updated correctly.
|
||||
* This shouldn't be needed and has a significant overhead.
|
||||
*/
|
||||
void gfxFlushBuffers();
|
||||
|
||||
/**
|
||||
* @brief Swaps the buffers and sets the gsp state
|
||||
*
|
||||
* This is to be called to update the gsp state and swap the framebuffers.
|
||||
* LCD rendering should start as soon as the gsp state is set.
|
||||
* When using the GPU, call @ref gfxSwapBuffers instead.
|
||||
*/
|
||||
void gfxSwapBuffers();
|
||||
|
||||
/**
|
||||
* @brief Swaps the framebuffers
|
||||
*
|
||||
* This is the version to be used with the GPU since the GPU will use the gsp shared memory,
|
||||
* so the gsp state mustn't be set directly by the user.
|
||||
*/
|
||||
void gfxSwapBuffersGpu();
|
||||
|
||||
//helper stuff
|
||||
///@}
|
||||
|
||||
|
||||
///@name Helper
|
||||
///@{
|
||||
/**
|
||||
* @brief Retrieves a framebuffer information
|
||||
* @param width Pointer that will hold the width of the framebuffer in pixels
|
||||
* @param height Pointer that will hold the height of the framebuffer in pixels
|
||||
* @return a pointer to the current framebuffer of the choosen screen
|
||||
*
|
||||
* Please remember that the returned pointer will change after each call to gfxSwapBuffers if double buffering is enabled.
|
||||
*/
|
||||
u8* gfxGetFramebuffer(gfxScreen_t screen, gfx3dSide_t side, u16* width, u16* height);
|
||||
///@}
|
||||
|
||||
//global variables
|
||||
extern u8* gfxTopLeftFramebuffers[2];
|
||||
|
@ -1,3 +1,8 @@
|
||||
/**
|
||||
* @file os.h
|
||||
*
|
||||
* OS related stuff.
|
||||
*/
|
||||
#pragma once
|
||||
|
||||
#define SYSTEM_VERSION(major, minor, revision) \
|
||||
@ -7,14 +12,52 @@
|
||||
#define GET_VERSION_MINOR(version) (((version)>>16)&0xFF)
|
||||
#define GET_VERSION_REVISION(version) (((version)>> 8)&0xFF)
|
||||
|
||||
/**
|
||||
* Converts an address from virtual (process) memory to physical memory.
|
||||
* It is sometimes required by services or when using the GPU command buffer.
|
||||
*/
|
||||
u32 osConvertVirtToPhys(u32 vaddr);
|
||||
u32 osConvertOldLINEARMemToNew(u32 addr);//Converts 0x14* vmem to 0x30*. Returns the input addr when it's already within the new vmem. Returns 0 when outside of either LINEAR mem areas.
|
||||
|
||||
/**
|
||||
* Converts 0x14* vmem to 0x30*.
|
||||
* @return The input address when it's already within the new vmem.
|
||||
* @return 0 when outside of either LINEAR mem areas.
|
||||
*/
|
||||
u32 osConvertOldLINEARMemToNew(u32 addr);
|
||||
|
||||
/**
|
||||
* @brief Basic information about a service error.
|
||||
* @return A string of the summary of an error.
|
||||
*
|
||||
* This can be used to get some details about an error returned by a service call.
|
||||
*/
|
||||
const char* osStrError(u32 error);
|
||||
|
||||
/**
|
||||
* @return the Firm version
|
||||
*
|
||||
* This can be used to compare system versions easily with @ref SYSTEM_VERSION.
|
||||
*/
|
||||
u32 osGetFirmVersion();
|
||||
|
||||
/**
|
||||
* @return the kernel version
|
||||
*
|
||||
* This can be used to compare system versions easily with @ref SYSTEM_VERSION.
|
||||
*
|
||||
* @code
|
||||
* if(osGetKernelVersion() > SYSTEM_VERSION(2,46,0)) printf("You are running 9.0 or higher\n");
|
||||
* @endcode
|
||||
*/
|
||||
u32 osGetKernelVersion();
|
||||
|
||||
/**
|
||||
* @return number of milliseconds since 1st Jan 1900 00:00.
|
||||
*/
|
||||
u64 osGetTime();
|
||||
|
||||
/* @brief Returns the Wifi signal strength.
|
||||
/**
|
||||
* @brief Returns the Wifi signal strength.
|
||||
*
|
||||
* Valid values are 0-3:
|
||||
* - 0 means the singal strength is terrible or the 3DS is disconnected from
|
||||
|
@ -1,5 +1,6 @@
|
||||
/**
|
||||
* @file y2r.h
|
||||
* @brief Y2R service for hardware YUV->RGB conversions
|
||||
*/
|
||||
#pragma once
|
||||
#include <3ds/types.h>
|
||||
|
@ -1,17 +1,39 @@
|
||||
/*
|
||||
svc.h _ Syscall wrappers.
|
||||
*/
|
||||
/**
|
||||
* @file svc.h
|
||||
* @brief Syscall wrappers.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
typedef enum {
|
||||
MEMOP_FREE =1, // Free heap
|
||||
MEMOP_ALLOC=3, // Allocate heap
|
||||
MEMOP_MAP =4, // Mirror mapping
|
||||
MEMOP_UNMAP=5, // Mirror unmapping
|
||||
MEMOP_PROT =6, // Change protection
|
||||
#include "types.h"
|
||||
|
||||
|
||||
///@name Memory management
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief @ref svcControlMemory operation flags
|
||||
*
|
||||
* The lowest 8 bits are the operation
|
||||
*/
|
||||
typedef enum {
|
||||
MEMOP_FREE = 1, ///< Memory un-mapping
|
||||
MEMOP_RESERVE = 2, ///< Reserve memory
|
||||
MEMOP_ALLOC = 3, ///< Memory mapping
|
||||
MEMOP_MAP = 4, ///< Mirror mapping
|
||||
MEMOP_UNMAP = 5, ///< Mirror unmapping
|
||||
MEMOP_PROT = 6, ///< Change protection
|
||||
|
||||
MEMOP_REGION_APP = 0x100,
|
||||
MEMOP_REGION_SYSTEM = 0x200,
|
||||
MEMOP_REGION_BASE = 0x300,
|
||||
|
||||
MEMOP_OP_MASK = 0xFF,
|
||||
MEMOP_REGION_MASK = 0xF00,
|
||||
MEMOP_LINEAR_FLAG = 0x10000, ///< Flag for linear memory operations
|
||||
|
||||
MEMOP_ALLOC_LINEAR = MEMOP_LINEAR_FLAG | MEMOP_ALLOC,
|
||||
|
||||
MEMOP_ALLOC_LINEAR=0x10003 // Allocate linear heap
|
||||
} MemOp;
|
||||
|
||||
typedef enum {
|
||||
@ -29,19 +51,21 @@ typedef enum {
|
||||
MEMSTATE_LOCKED = 11
|
||||
} MemState;
|
||||
|
||||
/**
|
||||
* @brief Memory permission flags
|
||||
*/
|
||||
typedef enum {
|
||||
MEMPERM_READ = 1,
|
||||
MEMPERM_WRITE = 2,
|
||||
MEMPERM_EXECUTE = 4,
|
||||
MEMPERM_DONTCARE = 0x10000000,
|
||||
MEMPERM_MAX = 0xFFFFFFFF //force 4-byte
|
||||
MEMPERM_DONTCARE = 0x10000000
|
||||
} MemPerm;
|
||||
|
||||
typedef struct {
|
||||
u32 base_addr;
|
||||
u32 size;
|
||||
u32 perm;
|
||||
u32 state;
|
||||
u32 perm; ///< See @ref MemPerm
|
||||
u32 state; ///< See @ref MemState
|
||||
} MemInfo;
|
||||
|
||||
typedef struct {
|
||||
@ -49,41 +73,49 @@ typedef struct {
|
||||
} PageInfo;
|
||||
|
||||
typedef enum {
|
||||
ARBITER_FREE =0,
|
||||
ARBITER_ACQUIRE =1,
|
||||
ARBITER_KERNEL2 =2,
|
||||
ARBITER_ACQUIRE_TIMEOUT=3,
|
||||
ARBITER_KERNEL4 =4,
|
||||
ARBITER_FREE = 0,
|
||||
ARBITER_ACQUIRE = 1,
|
||||
ARBITER_KERNEL2 = 2,
|
||||
ARBITER_ACQUIRE_TIMEOUT = 3,
|
||||
ARBITER_KERNEL4 = 4,
|
||||
} ArbitrationType;
|
||||
|
||||
typedef enum {
|
||||
DBG_EVENT_PROCESS = 0,
|
||||
DBG_EVENT_CREATE_THREAD = 1,
|
||||
DBG_EVENT_EXIT_THREAD = 2,
|
||||
DBG_EVENT_EXIT_PROCESS = 3,
|
||||
DBG_EVENT_EXCEPTION = 4,
|
||||
DBG_EVENT_DLL_LOAD = 5,
|
||||
DBG_EVENT_DLL_UNLOAD = 6,
|
||||
DBG_EVENT_SCHEDULE_IN = 7,
|
||||
DBG_EVENT_SCHEDULE_OUT = 8,
|
||||
DBG_EVENT_SYSCALL_IN = 9,
|
||||
DBG_EVENT_SYSCALL_OUT = 10,
|
||||
DBG_EVENT_OUTPUT_STRING = 11,
|
||||
DBG_EVENT_MAP = 12
|
||||
} DebugEventType;
|
||||
///@}
|
||||
|
||||
///@name Multithreading
|
||||
///@{
|
||||
|
||||
typedef enum {
|
||||
THREADINFO_TYPE_UNKNOWN
|
||||
} ThreadInfoType;
|
||||
|
||||
///@}
|
||||
|
||||
|
||||
///@name Debugging
|
||||
///@{
|
||||
typedef enum {
|
||||
REASON_CREATE = 1,
|
||||
REASON_ATTACH = 2
|
||||
} ProcessEventReason;
|
||||
|
||||
|
||||
typedef struct {
|
||||
u64 program_id;
|
||||
u8 process_name[8];
|
||||
u32 process_id;
|
||||
u32 reason;
|
||||
u32 reason; ///< See @ref ProcessEventReason
|
||||
} ProcessEvent;
|
||||
|
||||
typedef enum {
|
||||
EXITPROCESS_EVENT_NONE = 0,
|
||||
EXITPROCESS_EVENT_TERMINATE = 1,
|
||||
EXITPROCESS_EVENT_UNHANDLED_EXCEPTION = 2
|
||||
} ExitProcessEventReason;
|
||||
|
||||
typedef struct {
|
||||
u32 reason; ///< See @ref ExitProcessEventReason
|
||||
} ExitProcessEvent;
|
||||
|
||||
typedef struct {
|
||||
u32 creator_thread_id;
|
||||
u32 base_addr;
|
||||
@ -97,50 +129,33 @@ typedef enum {
|
||||
EXITTHREAD_EVENT_TERMINATE_PROCESS = 3
|
||||
} ExitThreadEventReason;
|
||||
|
||||
typedef enum {
|
||||
EXITPROCESS_EVENT_NONE = 0,
|
||||
EXITPROCESS_EVENT_TERMINATE = 1,
|
||||
EXITPROCESS_EVENT_UNHANDLED_EXCEPTION = 2
|
||||
} ExitProcessEventReason;
|
||||
|
||||
typedef struct {
|
||||
u32 reason;
|
||||
} ExitProcessEvent;
|
||||
|
||||
typedef struct {
|
||||
u32 reason;
|
||||
u32 reason; ///< See @ref ExitThreadEventReason
|
||||
} ExitThreadEvent;
|
||||
|
||||
typedef struct {
|
||||
u32 type;
|
||||
u32 address;
|
||||
u32 argument;
|
||||
} ExceptionEvent;
|
||||
|
||||
typedef enum {
|
||||
EXC_EVENT_UNDEFINED_INSTRUCTION = 0, // arg: (None)
|
||||
EXC_EVENT_UNKNOWN1 = 1, // arg: (None)
|
||||
EXC_EVENT_UNKNOWN2 = 2, // arg: address
|
||||
EXC_EVENT_UNKNOWN3 = 3, // arg: address
|
||||
EXC_EVENT_ATTACH_BREAK = 4, // arg: (None)
|
||||
EXC_EVENT_BREAKPOINT = 5, // arg: (None)
|
||||
EXC_EVENT_USER_BREAK = 6, // arg: user break type
|
||||
EXC_EVENT_DEBUGGER_BREAK = 7, // arg: (None)
|
||||
EXC_EVENT_UNDEFINED_SYSCALL = 8 // arg: attempted syscall
|
||||
} ExceptionEventType;
|
||||
|
||||
typedef enum {
|
||||
USERBREAK_PANIC = 0,
|
||||
USERBREAK_ASSERT = 1,
|
||||
USERBREAK_USER = 2
|
||||
} UserBreakType;
|
||||
|
||||
/**
|
||||
* Type of the query for svcGetThreadInfo
|
||||
*/
|
||||
typedef enum {
|
||||
THREADINFO_TYPE_UNKNOWN
|
||||
} ThreadInfoType;
|
||||
EXC_EVENT_UNDEFINED_INSTRUCTION = 0, ///< arg: (None)
|
||||
EXC_EVENT_UNKNOWN1 = 1, ///< arg: (None)
|
||||
EXC_EVENT_UNKNOWN2 = 2, ///< arg: address
|
||||
EXC_EVENT_UNKNOWN3 = 3, ///< arg: address
|
||||
EXC_EVENT_ATTACH_BREAK = 4, ///< arg: (None)
|
||||
EXC_EVENT_BREAKPOINT = 5, ///< arg: (None)
|
||||
EXC_EVENT_USER_BREAK = 6, ///< arg: @ref UserBreakType
|
||||
EXC_EVENT_DEBUGGER_BREAK = 7, ///< arg: (None)
|
||||
EXC_EVENT_UNDEFINED_SYSCALL = 8 ///< arg: attempted syscall
|
||||
} ExceptionEventType;
|
||||
|
||||
typedef struct {
|
||||
u32 type; ///< See @ref ExceptionEventType
|
||||
u32 address;
|
||||
u32 argument; ///< See @ref ExceptionEventType
|
||||
} ExceptionEvent;
|
||||
|
||||
typedef struct {
|
||||
u64 clock_tick;
|
||||
@ -163,8 +178,24 @@ typedef struct {
|
||||
u32 memstate;
|
||||
} MapEvent;
|
||||
|
||||
typedef enum {
|
||||
DBG_EVENT_PROCESS = 0,
|
||||
DBG_EVENT_CREATE_THREAD = 1,
|
||||
DBG_EVENT_EXIT_THREAD = 2,
|
||||
DBG_EVENT_EXIT_PROCESS = 3,
|
||||
DBG_EVENT_EXCEPTION = 4,
|
||||
DBG_EVENT_DLL_LOAD = 5,
|
||||
DBG_EVENT_DLL_UNLOAD = 6,
|
||||
DBG_EVENT_SCHEDULE_IN = 7,
|
||||
DBG_EVENT_SCHEDULE_OUT = 8,
|
||||
DBG_EVENT_SYSCALL_IN = 9,
|
||||
DBG_EVENT_SYSCALL_OUT = 10,
|
||||
DBG_EVENT_OUTPUT_STRING = 11,
|
||||
DBG_EVENT_MAP = 12
|
||||
} DebugEventType;
|
||||
|
||||
typedef struct {
|
||||
u32 type;
|
||||
u32 type; ///< See @ref DebugEventType
|
||||
u32 thread_id;
|
||||
u32 unknown[2];
|
||||
union {
|
||||
@ -178,10 +209,12 @@ typedef struct {
|
||||
SchedulerInOutEvent scheduler;
|
||||
SyscallInOutEvent syscall;
|
||||
OutputStringEvent output_string;
|
||||
MapEvent map;
|
||||
MapEvent map;
|
||||
};
|
||||
} DebugEventInfo;
|
||||
|
||||
///@}
|
||||
|
||||
static inline void* getThreadLocalStorage(void)
|
||||
{
|
||||
void* ret;
|
||||
@ -194,62 +227,212 @@ static inline u32* getThreadCommandBuffer(void)
|
||||
return (u32*)((u8*)getThreadLocalStorage() + 0x80);
|
||||
}
|
||||
|
||||
s32 svcControlMemory(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm);
|
||||
s32 svcQueryMemory(MemInfo* info, PageInfo* out, u32 addr);
|
||||
void __attribute__((noreturn)) svcExitProcess();
|
||||
s32 svcCreateThread(Handle* thread, ThreadFunc entrypoint, u32 arg, u32* stack_top, s32 thread_priority, s32 processor_id);
|
||||
void __attribute__((noreturn)) svcExitThread();
|
||||
void svcSleepThread(s64 ns);
|
||||
s32 svcGetThreadPriority(s32 *out, Handle handle);
|
||||
s32 svcSetThreadPriority(Handle thread, s32 prio);
|
||||
s32 svcGetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);
|
||||
s32 svcSetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);
|
||||
s32 svcGetThreadIdealProcessor(s32* processorid, Handle thread);
|
||||
s32 svcSetThreadIdealProcessor(Handle thread, s32 processorid);
|
||||
s32 svcGetProcessorID();
|
||||
s32 svcCreateMutex(Handle* mutex, bool initially_locked);
|
||||
s32 svcReleaseMutex(Handle handle);
|
||||
s32 svcCreateSemaphore(Handle* semaphore, s32 initial_count, s32 max_count);
|
||||
s32 svcReleaseSemaphore(s32* count, Handle semaphore, s32 release_count);
|
||||
s32 svcCreateEvent(Handle* event, u8 reset_type);
|
||||
s32 svcSignalEvent(Handle handle);
|
||||
s32 svcClearEvent(Handle handle);
|
||||
s32 svcCreateTimer(Handle* timer, u8 reset_type);
|
||||
s32 svcSetTimer(Handle timer, s64 initial, s64 interval);
|
||||
s32 svcCancelTimer(Handle timer);
|
||||
s32 svcClearTimer(Handle timer);
|
||||
s32 svcCreateMemoryBlock(Handle* memblock, u32 addr, u32 size, MemPerm my_perm, MemPerm other_perm);
|
||||
s32 svcMapMemoryBlock(Handle memblock, u32 addr, MemPerm my_perm, MemPerm other_perm);
|
||||
s32 svcUnmapMemoryBlock(Handle memblock, u32 addr);
|
||||
s32 svcCreateAddressArbiter(Handle *arbiter);
|
||||
s32 svcArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds);
|
||||
s32 svcWaitSynchronization(Handle handle, s64 nanoseconds);
|
||||
s32 svcWaitSynchronizationN(s32* out, Handle* handles, s32 handles_num, bool wait_all, s64 nanoseconds);
|
||||
s32 svcCloseHandle(Handle handle);
|
||||
s32 svcDuplicateHandle(Handle* out, Handle original);
|
||||
u64 svcGetSystemTick();
|
||||
s32 svcGetSystemInfo(s64* out, u32 type, s32 param);
|
||||
s32 svcGetProcessInfo(s64* out, Handle process, u32 type);
|
||||
s32 svcGetThreadInfo(s64* out, Handle thread, ThreadInfoType type);
|
||||
s32 svcConnectToPort(volatile Handle* out, const char* portName);
|
||||
s32 svcSendSyncRequest(Handle session);
|
||||
///@name Memory management
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Controls memory mapping
|
||||
* @param[out] addr_out The virtual address resulting from the operation. Usually the same as addr0.
|
||||
* @param addr0 The virtual address to be used for the operation.
|
||||
* @param addr1 The virtual address to be (un)mirrored by @p addr0 when using @ref MEMOP_MAP or @ref MEMOP_UNMAP.
|
||||
* It has to be pointing to a RW memory.
|
||||
* Use NULL if the operation is @ref MEMOP_FREE or @ref MEMOP_ALLOC.
|
||||
* @param size The requested size for @ref MEMOP_ALLOC and @ref MEMOP_ALLOC_LINEAR.
|
||||
* @param op Operation flags. See @ref MemOp.
|
||||
* @param perm A combination of @ref MEMPERM_READ and @ref MEMPERM_WRITE. Using MEMPERM_EXECUTE will return an error.
|
||||
* Value 0 is used when unmapping memory.
|
||||
*
|
||||
* If a memory is mapped for two or more addresses, you have to use MEMOP_UNMAP before being able to MEMOP_FREE it.
|
||||
* MEMOP_MAP will fail if @p addr1 was already mapped to another address.
|
||||
*
|
||||
* More information is available at http://3dbrew.org/wiki/SVC#Memory_Mapping.
|
||||
*
|
||||
* @sa svcControlProcessMemory
|
||||
*/
|
||||
Result svcControlMemory(u32* addr_out, u32 addr0, u32 addr1, u32 size, MemOp op, MemPerm perm);
|
||||
|
||||
/**
|
||||
* @brief Controls the memory mapping of a process
|
||||
* @param addr0 The virtual address to map
|
||||
* @param addr1 The virtual address to be mapped by @p addr0
|
||||
* @param type Only operations @ref MEMOP_MAP, @ref MEMOP_UNMAP and @ref MEMOP_PROT are allowed.
|
||||
*
|
||||
* This is the only SVC which allows mapping executable memory.
|
||||
* Using @ref MEMOP_PROT will change the memory permissions of an already mapped memory.
|
||||
*
|
||||
* @note The pseudo handle for the current process is not supported by this service call.
|
||||
* @sa svcControlProcess
|
||||
*/
|
||||
Result svcControlProcessMemory(Handle process, u32 addr0, u32 addr1, u32 size, u32 type, u32 perm);
|
||||
|
||||
Result svcCreateMemoryBlock(Handle* memblock, u32 addr, u32 size, MemPerm my_perm, MemPerm other_perm);
|
||||
Result svcMapMemoryBlock(Handle memblock, u32 addr, MemPerm my_perm, MemPerm other_perm);
|
||||
Result svcMapProcessMemory(Handle process, u32 startAddr, u32 endAddr);
|
||||
Result svcUnmapProcessMemory(Handle process, u32 startAddr, u32 endAddr);
|
||||
Result svcUnmapMemoryBlock(Handle memblock, u32 addr);
|
||||
/**
|
||||
* @brief Memory information query
|
||||
* @param addr Virtual memory address
|
||||
*/
|
||||
Result svcQueryMemory(MemInfo* info, PageInfo* out, u32 addr);
|
||||
Result svcQueryProcessMemory(MemInfo* info, PageInfo* out, Handle process, u32 addr);
|
||||
|
||||
Result svcCreateAddressArbiter(Handle *arbiter);
|
||||
Result svcArbitrateAddress(Handle arbiter, u32 addr, ArbitrationType type, s32 value, s64 nanoseconds);
|
||||
|
||||
Result svcReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size);
|
||||
Result svcWriteProcessMemory(Handle debug, const void* buffer, u32 addr, u32 size);
|
||||
///@}
|
||||
|
||||
|
||||
///@name Process management
|
||||
///@{
|
||||
|
||||
/**
|
||||
* @brief Gets the handle of a process.
|
||||
* @param[out] process The handle of the process
|
||||
* @param processId The ID of the process to open
|
||||
*/
|
||||
Result svcOpenProcess(Handle* process, u32 processId);
|
||||
Result svcOpenThread(Handle* thread,Handle process, u32 threadId);
|
||||
s32 svcGetProcessId(u32 *out, Handle handle);
|
||||
s32 svcGetProcessIdOfThread(u32 *out, Handle handle);
|
||||
s32 svcGetThreadId(u32 *out, Handle handle);
|
||||
s32 svcOutputDebugString(const char* str, int length);
|
||||
void svcExitProcess() __attribute__((noreturn));
|
||||
|
||||
Result svcGetProcessInfo(s64* out, Handle process, u32 type);
|
||||
Result svcGetProcessId(u32 *out, Handle handle);
|
||||
Result svcGetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount);
|
||||
Result svcCreatePort(Handle* portServer, Handle* portClient, const char* name, s32 maxSessions);
|
||||
Result svcConnectToPort(volatile Handle* out, const char* portName);
|
||||
///@}
|
||||
|
||||
///@name Multithreading
|
||||
///@{
|
||||
/**
|
||||
* @brief Creates a new thread.
|
||||
* @param[out] thread The thread handle
|
||||
* @param entrypoint The function that will be called first upon thread creation
|
||||
* @param arg The argument passed to @p entrypoint
|
||||
* @param stack_top The top of the thread's stack. Must be 0x8 bytes mem-aligned.
|
||||
* @param thread_priority Low values gives the thread higher priority.
|
||||
* For userland app, this has to be withing the range [0x18;0x3F]
|
||||
* @param processor_id The id of the processor the thread should be ran on. Those are labelled starting from 0.
|
||||
* For old 3ds it has to be <2, and for new 3DS <4.
|
||||
* Value -1 means all CPUs and -2 read from the Exheader.
|
||||
*
|
||||
* The processor with ID 1 is the system processor.
|
||||
* To enable multi-threading on this core you need to call APT_SetAppCpuTimeLimit at least once with a non-zero value.
|
||||
*
|
||||
* Since a thread is considered as a waitable object, you can use @ref svcWaitSynchronization
|
||||
* and @ref svcWaitSynchronizationN to join with it.
|
||||
*
|
||||
* @note The kernel will clear the @p stack_top's address low 3 bits to make sure it is 0x8-bytes aligned.
|
||||
*/
|
||||
Result svcCreateThread(Handle* thread, ThreadFunc entrypoint, u32 arg, u32* stack_top, s32 thread_priority, s32 processor_id);
|
||||
|
||||
/**
|
||||
* @brief Gets the handle of a thread.
|
||||
* @param[out] thread The handle of the thread
|
||||
* @param process The ID of the process linked to the thread
|
||||
*/
|
||||
Result svcOpenThread(Handle* thread,Handle process, u32 threadId);
|
||||
|
||||
/**
|
||||
* @brief Exits the current thread.
|
||||
*
|
||||
* This will trigger a state change and hence release all @ref svcWaitSynchronization operations.
|
||||
* It means that you can join a thread by calling @code svcWaitSynchronization(threadHandle,yourtimeout); @endcode
|
||||
*/
|
||||
void svcExitThread(void) __attribute__((noreturn));
|
||||
|
||||
/**
|
||||
* @brief Puts the current thread to sleep.
|
||||
* @param ns The minimum number of nanoseconds to sleep for.
|
||||
*/
|
||||
void svcSleepThread(s64 ns);
|
||||
|
||||
/**
|
||||
* @brief Retrieves the priority of a thread.
|
||||
*/
|
||||
Result svcGetThreadPriority(s32 *out, Handle handle);
|
||||
|
||||
/**
|
||||
* @brief Changes the priority of a thread
|
||||
* @param prio For userland apps, this has to be withing the range [0x18;0x3F]
|
||||
*
|
||||
* Low values gives the thread higher priority.
|
||||
*/
|
||||
Result svcSetThreadPriority(Handle thread, s32 prio);
|
||||
Result svcGetThreadAffinityMask(u8* affinitymask, Handle thread, s32 processorcount);
|
||||
Result svcSetThreadAffinityMask(Handle thread, u8* affinitymask, s32 processorcount);
|
||||
Result svcGetThreadIdealProcessor(s32* processorid, Handle thread);
|
||||
Result svcSetThreadIdealProcessor(Handle thread, s32 processorid);
|
||||
|
||||
/**
|
||||
* @brief Returns the ID of the processor the current thread is running on.
|
||||
* @sa svcCreateThread
|
||||
*/
|
||||
s32 svcGetProcessorID();
|
||||
|
||||
/**
|
||||
* @param out The thread ID of the thread @p handle.
|
||||
*/
|
||||
Result svcGetThreadId(u32 *out, Handle handle);
|
||||
|
||||
/**
|
||||
* @param out The process ID of the thread @p handle.
|
||||
* @sa svcOpenProcess
|
||||
*/
|
||||
Result svcGetProcessIdOfThread(u32 *out, Handle handle);
|
||||
|
||||
/**
|
||||
* @brief Checks if a thread handle is valid.
|
||||
* This requests always return an error when called, it only checks if the handle is a thread or not.
|
||||
* @return 0xD8E007ED (BAD_ENUM) if the Handle is a Thread Handle
|
||||
* @return 0xD8E007F7 (BAD_HANDLE) if it isn't.
|
||||
*/
|
||||
Result svcGetThreadInfo(s64* out, Handle thread, ThreadInfoType type);
|
||||
///@}
|
||||
|
||||
|
||||
///@name Synchronization
|
||||
///@{
|
||||
Result svcCreateMutex(Handle* mutex, bool initially_locked);
|
||||
Result svcReleaseMutex(Handle handle);
|
||||
Result svcCreateSemaphore(Handle* semaphore, s32 initial_count, s32 max_count);
|
||||
Result svcReleaseSemaphore(s32* count, Handle semaphore, s32 release_count);
|
||||
Result svcCreateEvent(Handle* event, u8 reset_type);
|
||||
Result svcSignalEvent(Handle handle);
|
||||
Result svcClearEvent(Handle handle);
|
||||
Result svcWaitSynchronization(Handle handle, s64 nanoseconds);
|
||||
Result svcWaitSynchronizationN(s32* out, Handle* handles, s32 handles_num, bool wait_all, s64 nanoseconds);
|
||||
Result svcSendSyncRequest(Handle session);
|
||||
///@}
|
||||
|
||||
///@name Time
|
||||
///@{
|
||||
Result svcCreateTimer(Handle* timer, u8 reset_type);
|
||||
Result svcSetTimer(Handle timer, s64 initial, s64 interval);
|
||||
Result svcCancelTimer(Handle timer);
|
||||
Result svcClearTimer(Handle timer);
|
||||
u64 svcGetSystemTick();
|
||||
///@}
|
||||
|
||||
///@name System
|
||||
///@{
|
||||
Result svcCloseHandle(Handle handle);
|
||||
Result svcDuplicateHandle(Handle* out, Handle original);
|
||||
Result svcGetSystemInfo(s64* out, u32 type, s32 param);
|
||||
///@}
|
||||
|
||||
|
||||
///@name Debugging
|
||||
///@{
|
||||
Result svcOutputDebugString(const char* str, int length);
|
||||
Result svcDebugActiveProcess(Handle* debug, u32 processId);
|
||||
Result svcBreakDebugProcess(Handle debug);
|
||||
Result svcTerminateDebugProcess(Handle debug);
|
||||
Result svcGetProcessDebugEvent(DebugEventInfo* info, Handle debug);
|
||||
Result svcContinueDebugEvent(Handle debug, u32 flags);
|
||||
Result svcGetProcessList(s32* processCount, u32* processIds, s32 processIdMaxCount);
|
||||
Result svcReadProcessMemory(void* buffer, Handle debug, u32 addr, u32 size);
|
||||
Result svcWriteProcessMemory(Handle debug, const void* buffer, u32 addr, u32 size);
|
||||
Result svcControlProcessMemory(Handle process, u32 addr0, u32 addr1, u32 size, u32 type, u32 perm);
|
||||
Result svcMapProcessMemory(Handle process, u32 startAddr, u32 endAddr);
|
||||
Result svcUnmapProcessMemory(Handle process, u32 startAddr, u32 endAddr);
|
||||
///@}
|
||||
|
||||
Result svcBackdoor(s32 (*callback)(void));
|
||||
Result svcQueryProcessMemory(MemInfo* info, PageInfo* out, Handle process, u32 addr);
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user