psx.wiki

BIOS Threads: Difference between revisions

Revision as of 02:44, 23 October 2026
RemmyLee
(CPU and system bus at register depth: instruction set, COP0, I/O map, memory control, interrupts, DMA, timers)
Revision as of 02:45, 23 October 2026
RemmyLee
(BIOS and kernel: A, B, C functions, syscalls, events, threads, file I/O, boot, PS-X EXE)
Line 1:Line 1:
+---
+title: BIOS Threads
+type: component
+summary: Thread management service that switches execution between saved register contexts.
+category: System software
+info: Control block = TCB, 0xC0 bytes
+info: Default count = 4 (TCB = 4)
+info: Descriptor = 0xFF000000 and up
+---
+
+## Overview
+
+Threads allow an application to have multiple flows of control. They provide a form of multi-tasking in which contexts are switched by calling a switching function, and the same mechanism may be used to change context at the time of an interrupt.[^lo212] A thread is composed of register states, a stack area and CPU states, and multiple threads, multi-tasking and multiple interrupts can be implemented with the thread management service.[^os33]
+
+The kernel never switches threads by itself. All other threads stay paused until the current thread passes control with ChangeTh().[^spxth] The [PS-X OS](/system/ps-x-os/) starts in single task mode, and a program that opens no further threads remains in that mode.[^os43]
+
+## Context and TCB
+
+The thread context consists of the complete contents of the registers. It is stored in a data structure called a task control block (TCB), and switching threads means storing the current context in one TCB and loading the registers from another.[^lo212] The context is stored in the execution TCB whenever an interrupt occurs or a switching function is called. The execution TCB is pointed to by the task status queue (TCBH), which is reached through ToT entry 1.[^lo212][^lo204]
+
+```
+struct TCB { /* task control block */
+ long status; /* status */
+ long mode; /* mode */
+ unsigned long reg[NREGS]; /* register save area */
+ /* specify with register-specified macro */
+ long system[6]; /* system reserved */
+};
+
+struct TCBH { /* task status queue */
+ struct TCB *entry; /* pointer to execution TCB */
+ long flag; /* system reserved */
+};
+```
+
+The structures are defined in kernel.h.[^lo204][^lr106][^lr107] The byte offsets of the TCB are shown below.[^spxcb]
+
+Table: TCB layout
+
+| Offset | Size | Contents |
+| --- | --- | --- |
+| 0x00 | 4 | Status (0x1000 free, 0x4000 used) |
+| 0x04 | 4 | Mode (set to 0x1000 by OpenTh) |
+| 0x08 | 0x80 | R0 to R31 (R0 and R26 entries unused) |
+| 0x88 | 4 | EPC (COP0 r14), the PC on return from the exception |
+| 0x8C | 8 | HI and LO |
+| 0x94 | 4 | SR (COP0 r12), saved and restored by the exception handler |
+| 0x98 | 4 | CAUSE (COP0 r13), saved on exception entry only |
+| 0x9C | 0x24 | Not used |
+
+The reg[] entries are indexed by the register specification macros in asm.h. These include R_ZERO to R_RA for the general-purpose registers and the following macros for the other saved registers.[^lo214]
+
+Table: Register specification macros beyond R31
+
+| Macro | Contents |
+| --- | --- |
+| R_EPC | Interrupt return address |
+| R_MDHI | Multiplication/division register (high) |
+| R_MDLO | Multiplication/division register (low) |
+| R_SR | Status register |
+| R_CAUSE | Cause register |
+
+The [CPU](/hardware/cpu/) page lists the assignments of the general-purpose registers.
+
+## TCB Status
+
+A TCB is either TcbStUNUSED or TcbStACTIVE. OpenTh() makes it TcbStACTIVE, after which ChangeTh() may execute it.[^lo213]
+
+Table: TCB status
+
+| Macro | Status | Value |
+| --- | --- | --- |
+| TcbStUNUSED | Not used | 0x1000 |
+| TcbStACTIVE | Execution possible | 0x4000 |
+
+The values are from psx-spx, which calls them free and used.[^spxcb]
+
+## Status After the Kernel Starts
+
+When the kernel starts, it allocates the TCB array, opens element 0 with OpenTh() and links it in the task status queue as the execution TCB. The descriptor of this default thread is DescTH|0x0000 = 0xFF000000.[^lo212] With the default TCB = 4 in SYSTEM.CNF, the boot executable runs in thread 0 and three threads are free. Their descriptors are 0xFF000001 to 0xFF000003.[^spxth]
+
+## Opening and Switching Threads
+
+OpenTh() secures a free TCB and initializes it with the start function, the stack pointer, and the global pointer. The same value is stored for SP and FP. OpenTh() must be executed in a critical section, and it returns to the current thread; the new thread starts only when ChangeTh() is called.[^lr155][^spxth]
+
+```
+unsigned long new_th;
+new_th = OpenTh(0x80020000, 0x1ffff0, 0x00);
+ChangeTh(new_th);
+```
+
+The example is from the Run-Time Library Overview.[^lo212] When ChangeTh() is called, a software interrupt jumps into the kernel interrupt dispatcher with other interrupts inhibited. The context of the calling thread is saved in its TCB, the specified TCB is linked to the task status queue, and the context of the new TCB is loaded when the dispatcher finishes.[^lo212]
+
+ChangeTh() returns 1 when the original thread is restored and 0 on failure.[^lr113] The return value is stored in the V0 entry of the saved TCB. Another thread may therefore change it before switching back, which is a way to pass information between threads.[^lo212][^lr113]
+
+CloseTh() closes a thread and releases its TCB. It must be executed in a critical section.[^lr116] psx-spx finds that CloseTh() always returns 1, and that closing the current thread does not stop it. A safe sequence is to disable interrupts, close the current thread, and then change to another thread.[^spxth]
+
+Each thread has its own R1 to R31, HI, LO, SR and PC. The GTE registers and the I/O ports are not saved, so a program must save them itself when threads share them.[^spxth]
+
+## Status Register
+
+Before ChangeTh() is executed, the reg[R_SR] entry of the new TCB must be initialized to 0x404 for an interrupt context or 0x401 for the main flow.[^lr113] psx-spx finds that OpenTh() does not set the SR entry at all. A TCB that is closed and opened again therefore keeps the SR of the old thread, and the new thread may start with interrupts enabled or in user mode.[^spxth]
+
+## Interrupts and the TCB
+
+The context at the time of an interrupt is stored in the TCB that is being executed. It stays there during the return from the handler to the main flow and remains until the next interrupt.[^lo212] Functions that generate internal exceptions destroy the main flow context in this way, and ExitCriticalSection() is one of them. The thread management service can prevent this by changing the execution TCB.[^lo206]
+
+## Thread Functions
+
+Table: Thread functions
+
+| Function | BIOS | Explanation |
+| --- | --- | --- |
+| OpenTh(func, sp, gp) | B(0Eh) | Secures a TCB and returns the thread descriptor, or -1[^lr155] |
+| CloseTh(thread) | B(0Fh) | Closes a thread and releases its TCB[^lr116] |
+| ChangeTh(thread) | B(10h) | Transfers execution to a thread[^lr113] |
+| get_free_TCB_slot() | C(05h) | Returns the first free TCB number, or -1[^spxth] |
+| ChangeThreadSubFunction(addr) | SYS(03h) | Makes the TCB at R5 current inside the syscall exception[^spxth] |
+| Exception() | | Causes an interrupt and stores the context in the execution TCB[^lr124] |
+| GetSp(), SetSp(new_sp) | | Reads or sets the stack pointer[^lr136][^lr165] |
+| GetGp() | | Reads the global pointer[^lr134] |
+| GetSr(), GetCr() | | Read the status and cause registers[^lr137][^lr133] |
+
+## References
+
+[^os33]: Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 3-3.
+[^os43]: Sony Computer Entertainment Inc. PlayStation Operating System. August 1998. Page 4-3.
+[^lo204]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-4, Table 2-2.
+[^lo206]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-6.
+[^lo212]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-12.
+[^lo213]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-13, Table 2-15.
+[^lo214]: Sony Computer Entertainment Inc. Run-Time Library Overview. January 1999. Page 2-14, Table 2-16.
+[^lr106]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-6, TCB.
+[^lr107]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-7, TCBH.
+[^lr113]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-13, ChangeTh.
+[^lr116]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-16, CloseTh.
+[^lr124]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-24, Exception.
+[^lr133]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-33, GetCr.
+[^lr134]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-34, GetGp.
+[^lr136]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-36, GetSp.
+[^lr137]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-37, GetSr.
+[^lr155]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-55, OpenTh.
+[^lr165]: Sony Computer Entertainment Inc. Run-Time Library Reference. January 1999. Page 1-65, SetSp.
+[^spxth]: psx-spx. Kernel (BIOS), BIOS Thread Functions. https://psx-spx.consoledev.net/kernelbios/
+[^spxcb]: psx-spx. Kernel (BIOS), BIOS Control Blocks, Thread Control Blocks. https://psx-spx.consoledev.net/kernelbios/