Tlspl partitions: 1-6 in both privilege levels, and document kernel-mode tests

threads/tls/kernel/partition now records the sweep from a kernel module, which settles the range
question the user-mode recording couldn't: privilege changes the permission check, not the range.
Partitions 1, 3 and 4 are ILLEGAL_PERM from user mode and fine from kernel mode, while 7 and up
are ILLEGAL_ARGUMENT either way. So the check goes back to a plain 1-6 for both, and the
kernel-mode carve-out from the last commit - which would have let 8 and 9 through - is gone.

The hardware doc gains a section on kernel-mode tests: what COMMON_KERNEL does, why the stock
crt0 makes a kernel PRX unloadable, which libraries can't be imported, and how much room there
actually is in the kernel partition.
This commit is contained in:
Henrik Rydgård committed 2026-09-08 15:18:02 -06:00
1 parent 705ea7eb02
commit a676eecba7
3 files changed
+54 -12

No files matched your search

+47
View File
@@ -174,6 +174,53 @@ python3 test.py --graphics=software io/shortname/shortname
- **The module must be named `TESTMODULE`** (`common.c` does this) or `gentest.py` prints the load
line as an unexpected result.
## Kernel-mode tests
Some behaviour differs by privilege - `sceKernelCreateTlspl` accepts partitions 1, 3 and 4 from a
kernel module and rejects them with `ILLEGAL_PERM` from user mode - so occasionally a test has to
run as a kernel module. `tests/threads/tls/kernel` is the working example. Set `COMMON_KERNEL = 1`
in the Makefile before including `common.mk` and you get a kernel build:
```make
TARGETS = partition
EXTRA_OBJS = tlspl-imports.o
COMMON_KERNEL = 1
COMMON_DIR = ../../../../common
include $(COMMON_DIR)/common.mk
```
Three things make this work, and all three took a while to find, so don't undo them casually:
- **`USE_KERNEL_LIBS`, set automatically by `common.mk`.** The stock `crt0_prx.o` references
`__libcglue_init`, which pulls in the whole of libcglue, which imports `sceNetInet`,
`sceUtility` and the `ForUser` IO libraries. A kernel module that imports any of those fails to
load with `8002013C` (library not found), and no amount of trimming `LIBS` helps because the
reference comes from the startup object itself. `USE_KERNEL_LIBS` selects a different startup -
and brings `-nostdlib`, so `common/kernelglue.c` supplies the newlib support hooks that go
missing: `_sbrk` over a fixed heap, the `_read`/`_write`/`_close` stubs, no-op retargetable
locks, and `module_start`.
- **Nothing may import a `ForUser` library.** `ThreadManForUser` is fine, but `SysMemUserForUser`
is not, which is why `common.c` compiles the `sceKernelSetCompiledSdkVersion` helpers out of
kernel builds - a function pointer table referencing them is enough to pull the stubs in.
Watch for this: `psp-strings yourtest.prx | grep For` lists what you're importing. Beware also
that `ThreadManForKernel` does not export the Tlspl calls - importing them from there links
cleanly and then returns `8002013A`, library not yet linked, from every call.
- **Size.** The kernel partition has about 285 KB free with PSPLink resident, 242 KB of it
contiguous, and loading over the cable needs room for the file *and* the loaded image at once.
A kernel build therefore gets a 4 KB `schedfBuffer` and a 4 KB heap instead of the user build's
64 KB and 21 MB. `psp-size yourtest.elf` plus the `.prx` file size against `meminfo`'s MAXFREE
tells you whether it will fit; `800200D9` (memblock alloc failed) means it didn't.
Output works normally - `printf`, `checkpoint` and `schedf` all behave - but a kernel build writes
to `host0:` with `sceIo` directly rather than through newlib's `FILE`, since that's what dragged
libcglue in. Formatting still goes through newlib's `vsnprintf`, so the usual format specifiers
are all available.
**PPSSPP can't run these yet.** `PPSSPPHeadless` times out on a kernel PRX built this way, so a
kernel-mode test can't go in `test.py` - keep it as a hardware reference and diff it by hand
against its user-mode twin.
## Worked example: FAT short names
`tests/io/shortname` was written this way and is a decent template. It creates a scratch directory