libctru  v2.3.1
os.h
Go to the documentation of this file.
1 /**
2  * @file os.h
3  * @brief OS related stuff.
4  */
5 #pragma once
6 #include "svc.h"
7 
8 ///< The external clock rate for the SoC.
9 #define SYSCLOCK_SOC (16756991u)
10 ///< The base system clock rate (for I2C, NDMA, etc.).
11 #define SYSCLOCK_SYS (SYSCLOCK_SOC * 2)
12 ///< The base clock rate for the SDMMC controller (and some other peripherals).
13 #define SYSCLOCK_SDMMC (SYSCLOCK_SYS * 2)
14 ///< The clock rate for the Arm9.
15 #define SYSCLOCK_ARM9 (SYSCLOCK_SYS * 4)
16 ///< The clock rate for the Arm11 in CTR mode and in \ref svcGetSystemTick.
17 #define SYSCLOCK_ARM11 (SYSCLOCK_ARM9 * 2)
18 ///< The clock rate for the Arm11 in LGR1 mode.
19 #define SYSCLOCK_ARM11_LGR1 (SYSCLOCK_ARM11 * 2)
20 ///< The clock rate for the Arm11 in LGR2 mode.
21 #define SYSCLOCK_ARM11_LGR2 (SYSCLOCK_ARM11 * 3)
22 ///< The highest possible clock rate for the Arm11 on known New 3DS units.
23 #define SYSCLOCK_ARM11_NEW SYSCLOCK_ARM11_LGR2
24 
25 #define CPU_TICKS_PER_MSEC (SYSCLOCK_ARM11 / 1000.0)
26 #define CPU_TICKS_PER_USEC (SYSCLOCK_ARM11 / 1000000.0)
27 
28 /// Packs a system version from its components.
29 #define SYSTEM_VERSION(major, minor, revision) \
30  (((major)<<24)|((minor)<<16)|((revision)<<8))
31 
32 /// Retrieves the major version from a packed system version.
33 #define GET_VERSION_MAJOR(version) ((version) >>24)
34 
35 /// Retrieves the minor version from a packed system version.
36 #define GET_VERSION_MINOR(version) (((version)>>16)&0xFF)
37 
38 /// Retrieves the revision version from a packed system version.
39 #define GET_VERSION_REVISION(version) (((version)>> 8)&0xFF)
40 
41 #define OS_HEAP_AREA_BEGIN 0x08000000 ///< Start of the heap area in the virtual address space
42 #define OS_HEAP_AREA_END 0x0E000000 ///< End of the heap area in the virtual address space
43 
44 #define OS_MAP_AREA_BEGIN 0x10000000 ///< Start of the mappable area in the virtual address space
45 #define OS_MAP_AREA_END 0x14000000 ///< End of the mappable area in the virtual address space
46 
47 #define OS_OLD_FCRAM_VADDR 0x14000000 ///< Old pre-8.x linear FCRAM mapping virtual address
48 #define OS_OLD_FCRAM_PADDR 0x20000000 ///< Old pre-8.x linear FCRAM mapping physical address
49 #define OS_OLD_FCRAM_SIZE 0x8000000 ///< Old pre-8.x linear FCRAM mapping size (128 MiB)
50 
51 #define OS_QTMRAM_VADDR 0x1E800000 ///< New3DS QTM memory virtual address
52 #define OS_QTMRAM_PADDR 0x1F000000 ///< New3DS QTM memory physical address
53 #define OS_QTMRAM_SIZE 0x400000 ///< New3DS QTM memory size (4 MiB; last 128 KiB reserved by kernel)
54 
55 #define OS_MMIO_VADDR 0x1EC00000 ///< Memory mapped IO range virtual address
56 #define OS_MMIO_PADDR 0x10100000 ///< Memory mapped IO range physical address
57 #define OS_MMIO_SIZE 0x400000 ///< Memory mapped IO range size (4 MiB)
58 
59 #define OS_VRAM_VADDR 0x1F000000 ///< VRAM virtual address
60 #define OS_VRAM_PADDR 0x18000000 ///< VRAM physical address
61 #define OS_VRAM_SIZE 0x600000 ///< VRAM size (6 MiB)
62 
63 #define OS_DSPRAM_VADDR 0x1FF00000 ///< DSP memory virtual address
64 #define OS_DSPRAM_PADDR 0x1FF00000 ///< DSP memory physical address
65 #define OS_DSPRAM_SIZE 0x80000 ///< DSP memory size (512 KiB)
66 
67 #define OS_KERNELCFG_VADDR 0x1FF80000 ///< Kernel configuration page virtual address
68 #define OS_SHAREDCFG_VADDR 0x1FF81000 ///< Shared system configuration page virtual address
69 
70 #define OS_FCRAM_VADDR 0x30000000 ///< Linear FCRAM mapping virtual address
71 #define OS_FCRAM_PADDR 0x20000000 ///< Linear FCRAM mapping physical address
72 #define OS_FCRAM_SIZE 0x10000000 ///< Linear FCRAM mapping size (256 MiB)
73 
74 #define OS_KernelConfig ((osKernelConfig_s const*)OS_KERNELCFG_VADDR) ///< Pointer to the kernel configuration page (see \ref osKernelConfig_s)
75 #define OS_SharedConfig ((osSharedConfig_s*)OS_SHAREDCFG_VADDR) ///< Pointer to the shared system configuration page (see \ref osSharedConfig_s)
76 
77 /// Kernel configuration page (read-only).
78 typedef struct
79 {
80  u32 kernel_ver;
81  u32 update_flag;
82  u64 ns_tid;
83  u32 kernel_syscore_ver;
84  u8 env_info;
85  u8 unit_info;
86  u8 boot_env;
87  u8 unk_0x17;
88  u32 kernel_ctrsdk_ver;
89  u32 unk_0x1c;
90  u32 firmlaunch_flags;
91  u8 unk_0x24[0xc];
92  u32 app_memtype;
93  u8 unk_0x34[0xc];
94  u32 memregion_sz[3];
95  u8 unk_0x4c[0x14];
96  u32 firm_ver;
97  u32 firm_syscore_ver;
98  u32 firm_ctrsdk_ver;
100 
101 /// Time reference information struct (filled in by PTM).
102 typedef struct
103 {
104  u64 value_ms; ///< Milliseconds elapsed since January 1900 when this structure was last updated
105  u64 value_tick; ///< System ticks elapsed since boot when this structure was last updated
106  s64 sysclock_hz;///< System clock frequency in Hz adjusted using RTC measurements (usually around \ref SYSCLOCK_ARM11)
107  s64 drift_ms; ///< Measured time drift of the system clock (according to the RTC) in milliseconds since the last update
108 } osTimeRef_s;
109 
110 /// Shared system configuration page structure (read-only or read-write depending on exheader).
111 typedef struct
112 {
113  vu32 timeref_cnt;
114  u8 running_hw;
115  u8 mcu_hwinfo;
116  u8 unk_0x06[0x1A];
117  volatile osTimeRef_s timeref[2];
118  u8 wifi_macaddr[6];
119  vu8 wifi_strength;
120  vu8 network_state;
121  u8 unk_0x68[0x18];
122  volatile float slider_3d;
123  vu8 led_3d;
124  vu8 led_battery;
125  vu8 unk_flag;
126  u8 unk_0x87;
127  u8 unk_0x88[0x18];
128  vu64 menu_tid;
129  vu64 cur_menu_tid;
130  u8 unk_0xB0[0x10];
131  vu8 headset_connected;
133 
134 /// Tick counter.
135 typedef struct
136 {
137  u64 elapsed; ///< Elapsed CPU ticks between measurements.
138  u64 reference; ///< Point in time used as reference.
139 } TickCounter;
140 
141 /// OS_VersionBin. Format of the system version: "<major>.<minor>.<build>-<nupver><region>"
142 typedef struct
143 {
144  u8 build;
145  u8 minor;
146  u8 mainver;//"major" in CVER, NUP version in NVer.
147  u8 reserved_x3;
148  char region;//"ASCII character for the system version region"
149  u8 reserved_x5[0x3];
150 } OS_VersionBin;
151 
152 /**
153  * @brief Converts an address from virtual (process) memory to physical memory.
154  * @param vaddr Input virtual address.
155  * @return The corresponding physical address.
156  * It is sometimes required by services or when using the GPU command buffer.
157  */
158 u32 osConvertVirtToPhys(const void* vaddr);
159 
160 /**
161  * @brief Converts 0x14* vmem to 0x30*.
162  * @param vaddr Input virtual address.
163  * @return The corresponding address in the 0x30* range, the input address if it's already within the new vmem, or 0 if it's outside of both ranges.
164  */
165 void* osConvertOldLINEARMemToNew(const void* vaddr);
166 
167 /**
168  * @brief Retrieves basic information about a service error.
169  * @param error Error to retrieve information about.
170  * @return A string containing a summary of an error.
171  *
172  * This can be used to get some details about an error returned by a service call.
173  */
174 const char* osStrError(Result error);
175 
176 /**
177  * @brief Gets the system's FIRM version.
178  * @return The system's FIRM version.
179  *
180  * This can be used to compare system versions easily with @ref SYSTEM_VERSION.
181  */
182 static inline u32 osGetFirmVersion(void)
183 {
184  return OS_KernelConfig->firm_ver &~ 0xFF;
185 }
186 
187 /**
188  * @brief Gets the system's kernel version.
189  * @return The system's kernel version.
190  *
191  * This can be used to compare system versions easily with @ref SYSTEM_VERSION.
192  *
193  * @code
194  * if(osGetKernelVersion() > SYSTEM_VERSION(2,46,0)) printf("You are running 9.0 or higher\n");
195  * @endcode
196  */
197 static inline u32 osGetKernelVersion(void)
198 {
199  return OS_KernelConfig->kernel_ver &~ 0xFF;
200 }
201 
202 /// Gets the system's "core version" (2 on NATIVE_FIRM, 3 on SAFE_FIRM, etc.)
203 static inline u32 osGetSystemCoreVersion(void)
204 {
205  return OS_KernelConfig->kernel_syscore_ver;
206 }
207 
208 /// Gets the system's memory layout ID (0-5 on Old 3DS, 6-8 on New 3DS)
209 static inline u32 osGetApplicationMemType(void)
210 {
211  return OS_KernelConfig->app_memtype;
212 }
213 
214 /**
215  * @brief Gets the size of the specified memory region.
216  * @param region Memory region to check.
217  * @return The size of the memory region, in bytes.
218  */
219 static inline u32 osGetMemRegionSize(MemRegion region)
220 {
221  if(region == MEMREGION_ALL) {
223  } else {
224  return OS_KernelConfig->memregion_sz[region-1];
225  }
226 }
227 
228 /**
229  * @brief Gets the number of used bytes within the specified memory region.
230  * @param region Memory region to check.
231  * @return The number of used bytes of memory.
232  */
233 static inline u32 osGetMemRegionUsed(MemRegion region)
234 {
235  s64 mem_used;
236  svcGetSystemInfo(&mem_used, 0, region);
237  return mem_used;
238 }
239 
240 /**
241  * @brief Gets the number of free bytes within the specified memory region.
242  * @param region Memory region to check.
243  * @return The number of free bytes of memory.
244  */
245 static inline u32 osGetMemRegionFree(MemRegion region)
246 {
247  return osGetMemRegionSize(region) - osGetMemRegionUsed(region);
248 }
249 
250 /**
251  * @brief Reads the latest reference timepoint published by PTM.
252  * @return Structure (see \ref osTimeRef_s).
253  */
255 
256 /**
257  * @brief Gets the current time.
258  * @return The number of milliseconds since 1st Jan 1900 00:00.
259  */
261 
262 /**
263  * @brief Starts a tick counter.
264  * @param cnt The tick counter.
265  */
266 static inline void osTickCounterStart(TickCounter* cnt)
267 {
268  cnt->reference = svcGetSystemTick();
269 }
270 
271 /**
272  * @brief Updates the elapsed time in a tick counter.
273  * @param cnt The tick counter.
274  */
275 static inline void osTickCounterUpdate(TickCounter* cnt)
276 {
277  u64 now = svcGetSystemTick();
278  cnt->elapsed = now - cnt->reference;
279  cnt->reference = now;
280 }
281 
282 /**
283  * @brief Reads the elapsed time in a tick counter.
284  * @param cnt The tick counter.
285  * @return The number of milliseconds elapsed.
286  */
287 double osTickCounterRead(const TickCounter* cnt);
288 
289 /**
290  * @brief Gets the current Wifi signal strength.
291  * @return The current Wifi signal strength.
292  *
293  * Valid values are 0-3:
294  * - 0 means the signal strength is terrible or the 3DS is disconnected from
295  * all networks.
296  * - 1 means the signal strength is bad.
297  * - 2 means the signal strength is decent.
298  * - 3 means the signal strength is good.
299  *
300  * Values outside the range of 0-3 should never be returned.
301  *
302  * These values correspond with the number of wifi bars displayed by Home Menu.
303  */
304 static inline u8 osGetWifiStrength(void)
305 {
306  return OS_SharedConfig->wifi_strength;
307 }
308 
309 /**
310  * @brief Gets the state of the 3D slider.
311  * @return The state of the 3D slider (0.0~1.0)
312  */
313 static inline float osGet3DSliderState(void)
314 {
315  return OS_SharedConfig->slider_3d;
316 }
317 
318 /**
319  * @brief Checks whether a headset is connected.
320  * @return true or false.
321  */
322 static inline bool osIsHeadsetConnected(void)
323 {
324  return OS_SharedConfig->headset_connected != 0;
325 }
326 
327 /**
328  * @brief Configures the New 3DS speedup.
329  * @param enable Specifies whether to enable or disable the speedup.
330  */
331 void osSetSpeedupEnable(bool enable);
332 
333 /**
334  * @brief Gets the NAND system-version stored in NVer/CVer.
335  * @param nver_versionbin Output OS_VersionBin structure for the data read from NVer.
336  * @param cver_versionbin Output OS_VersionBin structure for the data read from CVer.
337  * @return The result-code. This value can be positive if opening "romfs:/version.bin" fails with stdio, since errno would be returned in that case. In some cases the error can be special negative values as well.
338  */
339 Result osGetSystemVersionData(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin);
340 
341 /**
342  * @brief This is a wrapper for osGetSystemVersionData.
343  * @param nver_versionbin Optional output OS_VersionBin structure for the data read from NVer, can be NULL.
344  * @param cver_versionbin Optional output OS_VersionBin structure for the data read from CVer, can be NULL.
345  * @param sysverstr Output string where the printed system-version will be written, in the same format displayed by the System Settings title.
346  * @param sysverstr_maxsize Max size of the above string buffer, *including* NULL-terminator.
347  * @return See osGetSystemVersionData.
348  */
349 Result osGetSystemVersionDataString(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin, char *sysverstr, u32 sysverstr_maxsize);
u64 osGetTime(void)
Gets the current time.
const char * osStrError(Result error)
Retrieves basic information about a service error.
#define OS_KernelConfig
Pointer to the kernel configuration page (see osKernelConfig_s)
Definition: os.h:74
static u32 osGetKernelVersion(void)
Gets the system's kernel version.
Definition: os.h:197
static u32 osGetMemRegionFree(MemRegion region)
Gets the number of free bytes within the specified memory region.
Definition: os.h:245
static void osTickCounterUpdate(TickCounter *cnt)
Updates the elapsed time in a tick counter.
Definition: os.h:275
static u32 osGetApplicationMemType(void)
Gets the system's memory layout ID (0-5 on Old 3DS, 6-8 on New 3DS)
Definition: os.h:209
static u32 osGetFirmVersion(void)
Gets the system's FIRM version.
Definition: os.h:182
static float osGet3DSliderState(void)
Gets the state of the 3D slider.
Definition: os.h:313
void * osConvertOldLINEARMemToNew(const void *vaddr)
Converts 0x14* vmem to 0x30*.
osTimeRef_s osGetTimeRef(void)
Reads the latest reference timepoint published by PTM.
double osTickCounterRead(const TickCounter *cnt)
Reads the elapsed time in a tick counter.
void osSetSpeedupEnable(bool enable)
Configures the New 3DS speedup.
static u32 osGetMemRegionSize(MemRegion region)
Gets the size of the specified memory region.
Definition: os.h:219
static u32 osGetSystemCoreVersion(void)
Gets the system's "core version" (2 on NATIVE_FIRM, 3 on SAFE_FIRM, etc.)
Definition: os.h:203
static bool osIsHeadsetConnected(void)
Checks whether a headset is connected.
Definition: os.h:322
static u32 osGetMemRegionUsed(MemRegion region)
Gets the number of used bytes within the specified memory region.
Definition: os.h:233
static u8 osGetWifiStrength(void)
Gets the current Wifi signal strength.
Definition: os.h:304
Result osGetSystemVersionDataString(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin, char *sysverstr, u32 sysverstr_maxsize)
This is a wrapper for osGetSystemVersionData.
Result osGetSystemVersionData(OS_VersionBin *nver_versionbin, OS_VersionBin *cver_versionbin)
Gets the NAND system-version stored in NVer/CVer.
#define OS_SharedConfig
Pointer to the shared system configuration page (see osSharedConfig_s)
Definition: os.h:75
u32 osConvertVirtToPhys(const void *vaddr)
Converts an address from virtual (process) memory to physical memory.
static void osTickCounterStart(TickCounter *cnt)
Starts a tick counter.
Definition: os.h:266
OS_VersionBin. Format of the system version: "<major>.<minor>.<build>-<nupver><region>".
Definition: os.h:143
Tick counter.
Definition: os.h:136
u64 elapsed
Elapsed CPU ticks between measurements.
Definition: os.h:137
u64 reference
Point in time used as reference.
Definition: os.h:138
Kernel configuration page (read-only).
Definition: os.h:79
Shared system configuration page structure (read-only or read-write depending on exheader).
Definition: os.h:112
Time reference information struct (filled in by PTM).
Definition: os.h:103
s64 sysclock_hz
System clock frequency in Hz adjusted using RTC measurements (usually around SYSCLOCK_ARM11)
Definition: os.h:106
s64 drift_ms
Measured time drift of the system clock (according to the RTC) in milliseconds since the last update.
Definition: os.h:107
u64 value_ms
Milliseconds elapsed since January 1900 when this structure was last updated.
Definition: os.h:104
u64 value_tick
System ticks elapsed since boot when this structure was last updated.
Definition: os.h:105
Syscall wrappers.
u64 svcGetSystemTick(void)
Gets the current system tick.
Result svcGetSystemInfo(s64 *out, u32 type, s32 param)
Gets the system info.
MemRegion
Memory regions.
Definition: svc.h:67
@ MEMREGION_SYSTEM
SYSTEM memory.
Definition: svc.h:70
@ MEMREGION_BASE
BASE memory.
Definition: svc.h:71
@ MEMREGION_ALL
All regions.
Definition: svc.h:68
@ MEMREGION_APPLICATION
APPLICATION memory.
Definition: svc.h:69
volatile u8 vu8
8-bit volatile unsigned integer.
Definition: types.h:31
int64_t s64
64-bit signed integer
Definition: types.h:29
uint64_t u64
64-bit unsigned integer
Definition: types.h:24
uint8_t u8
would be nice if newlib had this already
Definition: types.h:21
volatile u32 vu32
32-bit volatile unsigned integer.
Definition: types.h:33
s32 Result
Function result.
Definition: types.h:42
volatile u64 vu64
64-bit volatile unsigned integer.
Definition: types.h:34
uint32_t u32
32-bit unsigned integer
Definition: types.h:23