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