(vita) build fix (cont).
[pcsx_rearmed.git] / frontend / 3ds / libkhax / khaxinternal.h
1 #pragma once\r
2 \r
3 #define KHAX_DEBUG\r
4 //#define KHAX_DEBUG_DUMP_DATA\r
5 \r
6 #ifdef KHAX_DEBUG\r
7         #define KHAX_printf(...) printf(__VA_ARGS__), gspWaitForVBlank(), gfxFlushBuffers(), gfxSwapBuffers()\r
8 #else\r
9         #define KHAX_printf static_cast<void>\r
10 #endif\r
11 \r
12 // Shut up IntelliSense warnings when using MSVC as an IDE, even though MSVC will obviously never\r
13 // actually compile this program.\r
14 #ifdef _MSC_VER\r
15         #undef ALIGN\r
16         #define ALIGN(x) __declspec(align(x))\r
17         #if _MSC_VER < 1900\r
18                 #define alignof __alignof\r
19         #endif\r
20         #define KHAX_ATTRIBUTE(...)\r
21 #else\r
22         #define KHAX_ATTRIBUTE(...) __VA_ARGS__\r
23 #endif\r
24 \r
25 #define KHAX_lengthof(...) (sizeof(__VA_ARGS__) / sizeof((__VA_ARGS__)[0]))\r
26 \r
27 //------------------------------------------------------------------------------------------------\r
28 namespace KHAX\r
29 {\r
30         //------------------------------------------------------------------------------------------------\r
31         // This code uses offsetof illegally (i.e. on polymorphic classes).\r
32         #pragma GCC diagnostic push\r
33         #pragma GCC diagnostic ignored "-Winvalid-offsetof"\r
34 \r
35         //------------------------------------------------------------------------------------------------\r
36         // General linked list node kernel object.\r
37         struct KLinkedListNode\r
38         {\r
39                 KLinkedListNode *next;\r
40                 KLinkedListNode *prev;\r
41                 void *data;\r
42         };\r
43         static_assert(sizeof(KLinkedListNode) == 0x00C, "KLinkedListNode isn't the expected size.");\r
44 \r
45         //------------------------------------------------------------------------------------------------\r
46         // Base class of reference-counted kernel objects.\r
47         class KAutoObject\r
48         {\r
49         public:\r
50                 u32 m_refCount;                                 // +004\r
51 \r
52         protected:\r
53                 virtual ~KAutoObject() {}\r
54         };\r
55         static_assert(sizeof(KAutoObject) == 0x008, "KAutoObject isn't the expected size.");\r
56         static_assert(offsetof(KAutoObject, m_refCount) == 0x004, "KAutoObject isn't the expected layout.");\r
57 \r
58         //------------------------------------------------------------------------------------------------\r
59         // Base class of synchronizable objects.\r
60         class KSynchronizationObject : public KAutoObject\r
61         {\r
62         public:\r
63                 u32 m_threadSyncCount;                          // +008\r
64                 KLinkedListNode *m_threadSyncFirst;             // +00C\r
65                 KLinkedListNode *m_threadSyncLast;              // +010\r
66         };\r
67         static_assert(sizeof(KSynchronizationObject) == 0x014, "KSynchronizationObject isn't the expected size.");\r
68         static_assert(offsetof(KSynchronizationObject, m_threadSyncCount) == 0x008,\r
69                 "KSynchronizationObject isn't the expected layout.");\r
70 \r
71         //------------------------------------------------------------------------------------------------\r
72         struct KDebugThread;\r
73         struct KThreadLocalPage;\r
74         class KCodeSet;\r
75 \r
76         //------------------------------------------------------------------------------------------------\r
77         // Unofficial name\r
78         typedef u8 KSVCACL[0x80 / 8];\r
79 \r
80         //------------------------------------------------------------------------------------------------\r
81         // ARM VFP register\r
82         union KHAX_ATTRIBUTE(__attribute__((__aligned__(4))) __attribute__((__packed__))) VFPRegister\r
83         {\r
84                 float m_single[2];\r
85                 double m_double;\r
86         };\r
87         static_assert(alignof(VFPRegister) == 0x004,\r
88                 "VFPRegister isn't the expected alignment.");\r
89         static_assert(sizeof(VFPRegister) == 0x008,\r
90                 "VFPRegister isn't the expected size.");\r
91 \r
92         //------------------------------------------------------------------------------------------------\r
93         // SVC-mode register save area.\r
94         // http://3dbrew.org/wiki/Memory_layout#0xFF4XX000\r
95         struct SVCRegisterState\r
96         {\r
97                 u32 m_r4;                                       // +000\r
98                 u32 m_r5;                                       // +004\r
99                 u32 m_r6;                                       // +008\r
100                 u32 m_r7;                                       // +00C\r
101                 u32 m_r8;                                       // +010\r
102                 u32 m_r9;                                       // +014\r
103                 u32 m_sl;                                       // +018\r
104                 u32 m_fp;                                       // +01C\r
105                 u32 m_sp;                                       // +020\r
106                 u32 m_lr;                                       // +024\r
107         };\r
108         static_assert(sizeof(SVCRegisterState) == 0x028,\r
109                 "SVCRegisterState isn't the expected size.");\r
110 \r
111         //------------------------------------------------------------------------------------------------\r
112         // SVC-mode thread state structure.  This is the last part of the per-\r
113         // thread page allocated in 0xFF4XX000.\r
114         // http://3dbrew.org/wiki/Memory_layout#0xFF4XX000\r
115         struct SVCThreadArea\r
116         {\r
117                 KSVCACL m_svcAccessControl;                     // +000\r
118                 u32 m_unknown010;                               // +010\r
119                 u32 m_unknown014;                               // +014\r
120                 SVCRegisterState m_svcRegisterState;            // +018\r
121                 VFPRegister m_vfpRegisters[16];                 // +040\r
122                 u32 m_unknown0C4;                               // +0C0\r
123                 u32 m_fpexc;                                    // +0C4\r
124         };\r
125         static_assert(offsetof(SVCThreadArea, m_svcRegisterState) == 0x018,\r
126                 "ThreadSVCArea isn't the expected layout.");\r
127         static_assert(sizeof(SVCThreadArea) == 0x0C8,\r
128                 "ThreadSVCArea isn't the expected size.");\r
129 \r
130         //------------------------------------------------------------------------------------------------\r
131         // Kernel's internal structure of a thread object.\r
132         class KThread : public KSynchronizationObject\r
133         {\r
134         public:\r
135                 u32 m_unknown014;                               // +014\r
136                 u32 m_unknown018;                               // +018\r
137                 u32 m_unknown01C;                               // +01C\r
138                 u32 m_unknown020;                               // +020\r
139                 u32 m_unknown024;                               // +024\r
140                 u32 m_unknown028;                               // +028\r
141                 u32 m_unknown02C;                               // +02C\r
142                 u32 m_unknown030;                               // +030\r
143                 u32 m_unknown034;                               // +034\r
144                 KDebugThread *m_debugThread;                    // +038\r
145                 s32 m_threadPriority;                           // +03C\r
146                 void *m_waitingOnObject;                        // +040\r
147                 u32 m_unknown044;                               // +044\r
148                 KThread **m_schedulerUnknown048;                // +048\r
149                 void *m_arbitrationAddress;                     // +04C\r
150                 u32 m_unknown050;                               // +050\r
151                 u32 m_unknown054;                               // +054\r
152                 u32 m_unknown058;                               // +058\r
153                 KLinkedListNode *m_waitingOnList;               // +05C\r
154                 u32 m_unknownListCount;                         // +060\r
155                 KLinkedListNode *m_unknownListHead;             // +064\r
156                 KLinkedListNode *m_unknownListTail;             // +068\r
157                 s32 m_threadPriority2;                          // +06C\r
158                 s32 m_creatingProcessor;                        // +070\r
159                 u32 m_unknown074;                               // +074\r
160                 u32 m_unknown078;                               // +078\r
161                 u16 m_unknown07C;                               // +07C\r
162                 u8 m_threadType;                                // +07E\r
163                 u8 m_padding07F;                                // +07F\r
164                 void *m_process;                                // +080\r
165                 u32 m_threadID;                                 // +084\r
166                 SVCRegisterState *m_svcRegisterState;           // +088\r
167                 void *m_svcPageEnd;                             // +08C\r
168                 s32 m_idealProcessor;                           // +090\r
169                 void *m_tlsUserMode;                            // +094\r
170                 void *m_tlsKernelMode;                          // +098\r
171                 u32 m_unknown09C;                               // +09C\r
172                 KThread *m_prev;                                // +0A0\r
173                 KThread *m_next;                                // +0A4\r
174                 KThread **m_temporaryLinkedList;                // +0A8\r
175                 u32 m_unknown0AC;                               // +0B0\r
176         };\r
177         static_assert(sizeof(KThread) == 0x0B0,\r
178                 "KThread isn't the expected size.");\r
179         static_assert(offsetof(KThread, m_svcRegisterState) == 0x088,\r
180                 "KThread isn't the expected layout.");\r
181 \r
182         //------------------------------------------------------------------------------------------------\r
183         // Kernel's internal structure of a process object.\r
184         // Version 1.0.0(?) - 7.2.0\r
185         class KProcess_1_0_0_Old : public KSynchronizationObject\r
186         {\r
187         public:\r
188                 u32 m_unknown014;                               // +014\r
189                 u32 m_unknown018;                               // +018\r
190                 KThread *volatile m_interactingThread;          // +01C\r
191                 u16 m_unknown020;                               // +020\r
192                 u16 m_unknown022;                               // +022\r
193                 u32 m_unknown024;                               // +024\r
194                 u32 m_unknown028;                               // +028\r
195                 u32 m_memoryBlockCount;                         // +02C\r
196                 KLinkedListNode *m_memoryBlockFirst;            // +030\r
197                 KLinkedListNode *m_memoryBlockLast;             // +034\r
198                 u32 m_unknown038;                               // +038\r
199                 u32 m_unknown03C;                               // +03C\r
200                 void *m_translationTableBase;                   // +040\r
201                 u8 m_contextID;                                 // +044\r
202                 u32 m_unknown048;                               // +048\r
203                 u32 m_unknown04C;                               // +04C\r
204                 u32 m_mmuTableSize;                             // +050\r
205                 void *m_mmuTableAddress;                        // +054\r
206                 u32 m_threadContextPagesSize;                   // +058\r
207                 u32 m_threadLocalPageCount;                     // +05C\r
208                 KLinkedListNode *m_threadLocalPageFirst;        // +060\r
209                 KLinkedListNode *m_threadLocalPageLast;         // +064\r
210                 u32 m_unknown068;                               // +068\r
211                 s32 m_idealProcessor;                           // +06C\r
212                 u32 m_unknown070;                               // +070\r
213                 void *m_resourceLimits;                         // +074\r
214                 u8 m_unknown078;                                // +078\r
215                 u8 m_affinityMask;                              // +079\r
216                 u32 m_threadCount;                              // +07C\r
217                 KSVCACL m_svcAccessControl;                     // +080\r
218                 u32 m_interruptFlags[0x80 / 32];                // +090\r
219                 u32 m_kernelFlags;                              // +0A0\r
220                 u16 m_handleTableSize;                          // +0A4\r
221                 u16 m_kernelReleaseVersion;                     // +0A6\r
222                 KCodeSet *m_codeSet;                            // +0A8\r
223                 u32 m_processID;                                // +0AC\r
224                 u32 m_kernelFlags2;                             // +0B0\r
225                 u32 m_unknown0B4;                               // +0B4\r
226                 KThread *m_mainThread;                          // +0B8\r
227                 //...more...\r
228         };\r
229         static_assert(offsetof(KProcess_1_0_0_Old, m_svcAccessControl) == 0x080,\r
230                 "KProcess_1_0_0_Old isn't the expected layout.");\r
231 \r
232         //------------------------------------------------------------------------------------------------\r
233         // Kernel's internal structure of a process object.\r
234         // Old 3DS Version 8.0.0 - 9.5.0...\r
235         class KProcess_8_0_0_Old : public KSynchronizationObject\r
236         {\r
237         public:\r
238                 u32 m_unknown014;                               // +014\r
239                 u32 m_unknown018;                               // +018\r
240                 KThread *volatile m_interactingThread;          // +01C\r
241                 u16 m_unknown020;                               // +020\r
242                 u16 m_unknown022;                               // +022\r
243                 u32 m_unknown024;                               // +024\r
244                 u32 m_unknown028;                               // +028\r
245                 u32 m_memoryBlockCount;                         // +02C\r
246                 KLinkedListNode *m_memoryBlockFirst;            // +030\r
247                 KLinkedListNode *m_memoryBlockLast;             // +034\r
248                 u32 m_unknown038;                               // +038\r
249                 u32 m_unknown03C;                               // +03C\r
250                 void *m_translationTableBase;                   // +040\r
251                 u8 m_contextID;                                 // +044\r
252                 u32 m_unknown048;                               // +048\r
253                 void *m_userVirtualMemoryEnd;                   // +04C\r
254                 void *m_userLinearVirtualBase;                  // +050\r
255                 u32 m_unknown054;                               // +054\r
256                 u32 m_mmuTableSize;                             // +058\r
257                 void *m_mmuTableAddress;                        // +05C\r
258                 u32 m_threadContextPagesSize;                   // +060\r
259                 u32 m_threadLocalPageCount;                     // +064\r
260                 KLinkedListNode *m_threadLocalPageFirst;        // +068\r
261                 KLinkedListNode *m_threadLocalPageLast;         // +06C\r
262                 u32 m_unknown070;                               // +070\r
263                 s32 m_idealProcessor;                           // +074\r
264                 u32 m_unknown078;                               // +078\r
265                 void *m_resourceLimits;                         // +07C\r
266                 u32 m_unknown080;                               // +080\r
267                 u32 m_threadCount;                              // +084\r
268                 u8 m_svcAccessControl[0x80 / 8];                // +088\r
269                 u32 m_interruptFlags[0x80 / 32];                // +098\r
270                 u32 m_kernelFlags;                              // +0A8\r
271                 u16 m_handleTableSize;                          // +0AC\r
272                 u16 m_kernelReleaseVersion;                     // +0AE\r
273                 KCodeSet *m_codeSet;                            // +0B0\r
274                 u32 m_processID;                                // +0B4\r
275                 u32 m_unknown0B8;                               // +0B8\r
276                 u32 m_unknown0BC;                               // +0BC\r
277                 KThread *m_mainThread;                          // +0C0\r
278                 //...more...\r
279         };\r
280         static_assert(offsetof(KProcess_8_0_0_Old, m_svcAccessControl) == 0x088,\r
281                 "KProcess_8_0_0_Old isn't the expected layout.");\r
282 \r
283         //------------------------------------------------------------------------------------------------\r
284         // Kernel's internal structure of a process object.\r
285         // New 3DS Version 8.0.0 - 9.5.0...\r
286         class KProcess_8_0_0_New : public KSynchronizationObject\r
287         {\r
288         public:\r
289                 u32 m_unknown014;                               // +014\r
290                 u32 m_unknown018;                               // +018\r
291                 KThread *volatile m_interactingThread;          // +01C\r
292                 u16 m_unknown020;                               // +020\r
293                 u16 m_unknown022;                               // +022\r
294                 u32 m_unknown024;                               // +024\r
295                 u32 m_unknown028;                               // +028\r
296                 u32 m_unknown02C;                               // +02C new to New 3DS\r
297                 u32 m_unknown030;                               // +030 new to New 3DS\r
298                 u32 m_memoryBlockCount;                         // +034\r
299                 KLinkedListNode *m_memoryBlockFirst;            // +038\r
300                 KLinkedListNode *m_memoryBlockLast;             // +03C\r
301                 u32 m_unknown040;                               // +040\r
302                 u32 m_unknown044;                               // +044\r
303                 void *m_translationTableBase;                   // +048\r
304                 u8 m_contextID;                                 // +04C\r
305                 u32 m_unknown050;                               // +050\r
306                 void *m_userVirtualMemoryEnd;                   // +054\r
307                 void *m_userLinearVirtualBase;                  // +058\r
308                 u32 m_unknown05C;                               // +05C\r
309                 u32 m_mmuTableSize;                             // +060\r
310                 void *m_mmuTableAddress;                        // +064\r
311                 u32 m_threadContextPagesSize;                   // +068\r
312                 u32 m_threadLocalPageCount;                     // +06C\r
313                 KLinkedListNode *m_threadLocalPageFirst;        // +070\r
314                 KLinkedListNode *m_threadLocalPageLast;         // +074\r
315                 u32 m_unknown078;                               // +078\r
316                 s32 m_idealProcessor;                           // +07C\r
317                 u32 m_unknown080;                               // +080\r
318                 void *m_resourceLimits;                         // +084\r
319                 u32 m_unknown088;                               // +088\r
320                 u32 m_threadCount;                              // +08C\r
321                 u8 m_svcAccessControl[0x80 / 8];                // +090\r
322                 u32 m_interruptFlags[0x80 / 32];                // +0A0\r
323                 u32 m_kernelFlags;                              // +0B0\r
324                 u16 m_handleTableSize;                          // +0B4\r
325                 u16 m_kernelReleaseVersion;                     // +0B6\r
326                 KCodeSet *m_codeSet;                            // +0B8\r
327                 u32 m_processID;                                // +0BC\r
328                 u32 m_unknown0C0;                               // +0C0\r
329                 u32 m_unknown0C4;                               // +0C4\r
330                 KThread *m_mainThread;                          // +0C8\r
331                 //...more...\r
332         };\r
333         static_assert(offsetof(KProcess_8_0_0_New, m_svcAccessControl) == 0x090,\r
334                 "KProcess_8_0_0_New isn't the expected layout.");\r
335 \r
336         //------------------------------------------------------------------------------------------------\r
337         // Done using illegal offsetof\r
338         #pragma GCC diagnostic pop\r
339 }\r