sdk-core v2026.11.05
PS2 SDK - core tier (build-critical EE/IOP modules)
Loading...
Searching...
No Matches
thcommon.h
Go to the documentation of this file.
1
5#ifndef THCOMMON_H_
6#define THCOMMON_H_
7
8#include "thbase.h"
9
10#include "list.h"
11#include "sysmem.h"
12#include "thmsgbx.h"
13
14#include <tamtypes.h>
15
16#define DEBUG_FLAGS (8)
17
18#define TAG_THREAD 0x7f01
19#define TAG_SEMA 0x7f02
20#define TAG_EVF 0x7f03
21#define TAG_MBX 0x7f04
22#define TAG_VPL 0x7f05
23#define TAG_FPL 0x7f06
24
25#define MAKE_HANDLE(ptr) (((u32)(ptr) << 5) | ((((struct heaptag *)(ptr))->id & 0x3f) << 1) | 1)
26#define HANDLE_PTR(handle) ((void *)((((u32)handle) >> 7) << 2))
27#define HANDLE_ID(handle) (((handle) >> 1) & 0x3f)
28#define HANDLE_VERIFY(handle, t) (((struct heaptag *)(HANDLE_PTR(handle)))->tag == (t) && \
29 HANDLE_ID(handle) == ((struct heaptag *)(HANDLE_PTR(handle)))->id)
30
31#ifdef ALIGN
32#undef ALIGN
33#endif
34#define ALIGN(i) (((i) + 3) & (~3))
35#define ALIGN_256(i) (((i) + 0xff) & (~0xff))
36
37#define UNIMPLEMENTED() \
38 do { \
39 Kprintf("UNIMPLEMENTED FUNCTION %s\n", __PRETTY_FUNCTION__); \
40 while (1) \
41 ; \
42 } while (0)
43
44#define TRACE() \
45 do { \
46 Kprintf("TRACE %s\n", __PRETTY_FUNCTION__); \
47 } while (0)
48
49#define TRACE_ERROR() \
50 do { \
51 Kprintf("TRACE %s %s:%d\n", __PRETTY_FUNCTION__, __FILE__, __LINE__); \
52 } while (0)
53
54#define RESERVED_REGCTX_SIZE 0xb8
55
56// context state, saved and restored by intrman
57struct regctx
58{
59 u32 unk, at, v0, v1, a0,
60 a1, a2, a3, t0, t1,
61 t2, t3, t4, t5, t6,
62 t7, s0, s1, s2, s3,
63 s4, s5, s6, s7, t8,
64 t9, unk68, unk6c, gp,
65 sp, fp, ra, hi, lo, sr,
66 pc, I_CTRL, unk2;
67};
68
69struct heaptag
70{
71 u16 tag;
72 u16 id;
73};
74
75struct event
76{
77 u32 attr;
78 u32 waiter_count;
79 struct list_head waiters;
80 u32 option;
81};
82
84{
85 struct heaptag tag;
86 struct list_head evf_list;
87 struct event event;
88 u32 bits;
89 u32 init_bits;
90};
91
93{
94 struct heaptag tag;
95 struct list_head sema_list;
96 struct event event;
97 u32 count;
98 u32 max_count;
99 u32 initial_count;
100};
101
102struct mbox
103{
104 struct heaptag tag;
105 struct list_head mbox_list;
106 struct event event;
107 u32 msg_count;
108 iop_message_t *newest_msg;
109};
110
112{
113 struct fpl_block *next;
114};
115
116struct fpool
117{
118 struct heaptag tag;
119 struct list_head fpl_list;
120 struct event event;
121 void *memory;
122 struct fpl_block *free;
123 u32 free_blocks;
124 u32 block_size;
125 u32 blocks;
126 u32 mem_size;
127};
128
129struct vpool
130{
131 struct heaptag tag;
132 struct list_head vpl_list;
133 struct event event;
134 void *heap;
135 u32 free_size;
136};
137
138struct alarm
139{
140 struct heaptag tag;
141 struct list_head alarm_list;
142 u64 target;
143 unsigned int (*cb)(void *userdata);
144 void *userptr;
145};
146
147struct thread
148{
149 struct heaptag tag;
150 struct list_head queue;
151 u8 status;
152 u16 priority;
153 struct regctx *saved_regs;
154 u32 unk14;
155 u32 unk18;
156 u16 wait_type;
157 u16 wakeup_count;
158 union
159 {
160 struct event *wait_event;
161 u32 wait_usecs;
162 };
163 // originally singly linked list of all threads
164 // struct thread *thread_list;
165 struct list_head thread_list;
166 u32 event_bits;
167 u16 event_mode;
168 u16 init_priority;
169 u32 run_clocks_hi;
170 u32 run_clocks_lo;
171 void *entry;
172 void *stack_top;
173 u32 stack_size;
174 void *gp;
175 u32 attr;
176 u32 option;
177 // nothing seems to use wait_return, would be $ra
178 // at the point of calling the wait function
179 // leftover debugging feature?
180 // u32 wait_return;
181 u32 *reason_counter;
182 u32 irq_preemption_count;
183 u32 thread_preemption_count;
184 u32 release_count;
185};
186
188{
189 struct thread *current_thread;
190 struct thread *run_next;
191 u32 queue_map[4]; // bitset of active priorities
192 u32 debug_flags;
193 struct list_head ready_queue[128];
194 s32 timer_id;
195 u32 (*timer_func)();
196 u32 time_hi;
197 u32 time_lo;
198 u32 last_timer;
199 // struct thread *thread_list;
200 // switched to a doubly linked thread list
201 struct list_head thread_list;
202 struct thread *idle_thread;
203 struct list_head semaphore;
204 struct list_head event_flag;
205 struct list_head mbox;
206 struct list_head vpool;
207 struct list_head fpool;
208 struct list_head alarm;
209 struct list_head alarm_pool;
210 u16 thread_id;
211 u16 sema_id;
212 u16 evflag_id;
213 u16 mbox_id;
214 u32 unused_or_padding;
215 u32 alarm_id;
216 u32 alarm_count;
217 struct list_head sleep_queue;
218 struct list_head delay_queue;
219 struct list_head dormant_queue;
220 // struct list_head unused_list1;
221 // struct list_head unused_list2;
222 struct list_head delete_queue;
223 void *heap;
224 s32 sytem_status_flag;
225 u32 thread_switch_count;
226 u32 thread_resume_count;
227 u32 min_wait;
228 u32 unk4c8;
229 u32 unk_clock_mult;
230 u32 unk_clock_div;
231};
232
233extern struct thread_context thctx;
234
235static inline u64 add64(u32 hi1, u32 lo1, u32 hi2, u32 lo2)
236{
237
238 u32 lo = lo1 + lo2;
239 u32 hi = hi1 + hi2 + (lo1 > (lo1 + lo2));
240 return lo | ((u64)hi << 32);
241}
242
243static inline u64 as_u64(u32 a1, u32 a2)
244{
245 return (u64)a1 << 32 | a2;
246}
247
248// Maybe uninline these to reduce code size if needed
249
250/*
251** Schedule at at the end of queeu
252*/
253static inline void readyq_insert_back(struct thread *thread)
254{
255 u32 prio = thread->priority;
256 thctx.queue_map[prio >> 5] |= 1 << (prio & 0x1f);
257 list_insert(&thctx.ready_queue[prio], &thread->queue);
258}
259
260/*
261** Schedule at at the front of queue
262*/
263static inline void readyq_insert_front(struct thread *thread)
264{
265 u32 prio = thread->priority;
266 thctx.queue_map[prio >> 5] |= 1 << (prio & 0x1f);
267 list_insert(thctx.ready_queue[prio].next, &thread->queue);
268}
269
270/*
271** Remove from the queue
272*/
273static inline void readyq_remove(struct thread *thread, u32 prio)
274{
275 if (list_node_is_last(&thread->queue)) {
276 thctx.queue_map[prio >> 5] &= ~(1 << (prio & 0x1f));
277 }
278
279 list_remove(&thread->queue);
280}
281
282extern u32 readyq_highest();
283
284extern struct alarm *alarm_alloc();
285extern void alarm_free(struct alarm *alarm);
286extern void alarm_insert(struct list_head *list, struct alarm *alarm);
287
288extern void update_timer_compare(int timid, u64 time, struct list_head *alarm_list);
289
290extern void *heap_alloc(u16 tag, u32 bytes);
291extern int heap_free(struct heaptag *tag);
292
293extern int thread_start(struct thread *thread, int intr_state);
294extern int thread_init_and_start(struct thread *thread, int intr_state);
295extern int thread_leave(int unk, int unk2, int intr_state, int release);
296
297extern unsigned int thread_delay_cb(void *user);
298
299extern int read_sys_time(iop_sys_clock_t *clock);
300
301extern void waitlist_insert(struct thread *thread, struct event *event, s32 priority);
302
303extern int check_thread_stack();
304
305#endif // THCOMMON_H_
int thread_leave(int unk, int unk2, int intr_state, int release)
Definition thcommon.c:159