Repository navigation
feat(libkernel): report the host SoC and CPU temperature - #4588
Conversation
|
Thanks bot. A note on the overlaps this PR has, so you can pick whichever you prefer: This PR implements the host CPU/thermal surface for PPSA99058 and PPSA99420, which import all three and stop at start-up on
Sensor 0 = host CPU/package, 1 = first other, 2 = NVMe; values come from Overlaps:
The two titles need all three, so as long as each function lands in some PR they are unblocked either way. Happy to rebase or split on request. AI-assisted: yes |
|
Heads-up on the overlap the bot flagged: #4466 also exports |
|
Thanks @babyhuey — agreed, and that's a clean plan.
Same arrangement stands for #4592 and For reference, this PR's AI-assisted: yes |
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for the PR. Two things to fix before this can merge:
sceKernelGetCpuFrequencyis already onmainsince #4466 (core/libs/prx/libkernel/Time/Time.cpp, returns the TSC ratesceKernelGetTscFrequencyreports, pinned byGuestCurrentCpu.cpp). Keeping this copy exports the symbol twice. As agreed with @babyhuey, please drop it fromThermalSensors.cpp, the test and TechnicalDebt (includingHostCpuFrequencyHzand the cpufreq/registry code), and keep the two sensors.- The branch conflicts with
main: TechnicalDebt entries now live indocs/dev/debt/libkernel.md(thesceKernelGetCpuTemperatureline is there, at the "imported by PPSA99902" entry). Rebase and move your line there, in the section where the old one was, not at the end.
Also: #4592 (open) adds a throwing sceKernelGetSocSensorTemperature stub in Unimplemented.cpp. Whichever lands second must drop its copy; if #4592 lands first, remove the stub there when you rebase.
Windows-only paths (WMI, IOCTL_STORAGE_QUERY_PROPERTY) and the title start-ups remain untested on our side; the Windows CI job isn't run automatically, so please re-run your local Windows test after the rebase.
5af2223 to
89eccbe
Compare
|
Runtime update, 2026-10-13: Before #4588, fresh PPSA99902 conversion on integration f1a3/main068 stops at unresolved Adapted integration native validation: full build/checks, 18 selected groups x5 under both requested NVIDIA GPL modes (including CPU thermal tests), full NVIDIA 1092 passed / 0 failed / 8 skipped of 1100, max 24.3817 s. This confirms the title's import-binding prerequisite is resolved; it does not demonstrate sensor-call execution, host/console temperatures or units. No duplicate sensor PR. Earlier static caller evidence below retains its original scope. Exact-main unit refresh (2026-10-16): the original Earlier static caller evidenceAdditional static caller evidence from Sonic Unleashed Recompiled PPSA99902 01.003.000 for
I rechecked the argument/loop instruction bytes against the original ELF today (SHA256 AI-assisted investigation/reporting: Codex. No game assets attached. |
|
Linux test (Arch, GCC 16.2.1, Release, Dell XPS 16 with an Intel Core Ultra), this PR merged onto
The SoC value is the problem. It is the first and
A suggestion: skip |
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for dropping sceKernelGetCpuFrequency. Remaining points:
core/libs/prx/libkernel/System/src/ThermalSensors.cpp:62-73: the "other" sensor (id 1) is the firsthwmonentry that is not CPU or NVMe, indirectory_iteratororder, which is unsorted. @nicolasfalesy measured on Linux that it ends up being the battery, the Wi-Fi card or the embedded controller depending on order and loaded drivers. Please sort the entries so the pick is stable, skip power supplies (BAT*,AC*,ucsi_source_psy_*) and network adapters (iwlwifi*), and prefer a SoC-like sensor (GPUedge, or the CPU package) as the fallback.core/libs/tests/GuestThermalSensors.cpp: add a case where the layout has several non-CPU/NVMe entries (a battery plus another one) in a non-alphabetical directory order and pin which one is picked, and check that*outkeeps a sentinel for unsupported ids (3 and 15), as @Amoenus noted the title checks the output rather than the return code.- The branch conflicts with
maininUnimplemented.cpp(thesceKernelGetCpuTemperaturestub sits next to new lines); please rebase and rerunguest_thermal_sensors.
Build and guest_thermal_sensors pass here on the PR head. The Windows paths (WMI, storage IOCTL) were not run.
89eccbe to
968b2a2
Compare
|
Thanks — you were right: the board channel was whichever entry
|
|
Thanks — I read the title's usage the same way: the output is set to
|
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for the update; the sorted, role-based pick on Linux looks good. Remaining points:
core/libs/prx/libkernel/System/src/ThermalSensors.cpp:200-201:ReadStorageTemperaturereads the wrong offsets ofSTORAGE_TEMPERATURE_DATA_DESCRIPTOR(docs).Version/Sizeare 4 bytes each, thenCriticalTemperature(+8),WarningTemperature(+10),InfoCount(+12),Reserved0[2](+14),Reserved1[2](+16), andTemperatureInfo[0]starts at +24 (IndexWORD,TemperatureSHORT at +26). The code checks +10 (the warning threshold) as if it were the count and reads +14 (reserved, zero) as the temperature, so a drive that answers would report 0 °C as sensor 2. Please checkInfoCountat +12 and readTemperatureat +26 (astructmirroring the descriptor would also makereturnedbounds checks clearer), and requirereturned >= 28.- Since your machine takes the unsupported path, this code has never run. Please test it on a host that exposes the storage property (any NVMe drive normally does) and paste the value next to the drive's own reading.
- No code comments are allowed:
ThermalSensors.hpp:4-6and the inline// StorageDeviceTemperatureProperty,// PropertyStandardQuery,// IOCTL_STORAGE_QUERY_PROPERTY,// some drivers report tenths of KelvininThermalSensors.cpp(use named constants instead). - The branch conflicts with
maininUnimplemented.cpp; please rebase.
968b2a2 to
5510cf2
Compare
|
Rebased onto current |
adriadam10
left a comment
There was a problem hiding this comment.
Thanks for the rebase. The head still has the points from the previous review (only the conflict was addressed):
core/libs/prx/libkernel/System/src/ThermalSensors.cpp:200-201:ReadStorageTemperaturereads the wrong offsets ofSTORAGE_TEMPERATURE_DATA_DESCRIPTOR.InfoCountis at +12 andTemperatureInfo[0].Temperatureat +26 (Version/Sizeare 4 bytes, thenCriticalTemperature+8,WarningTemperature+10,InfoCount+12,Reserved0[2]+14,Reserved1[2]+16,TemperatureInfo[0]+24). The code checks +10 (the warning threshold) and reads +14 (reserved), so a drive that answers would report 0 °C. Check +12, read +26, requirereturned >= 28; a struct mirroring the descriptor would make the bounds clearer.- This path has never run on the author's machine. Please test it on a host with an NVMe drive and paste the value next to the drive's own reading.
- No code comments:
ThermalSensors.hpp:4-6and the four inline comments inThermalSensors.cpp(StorageDeviceTemperatureProperty,PropertyStandardQuery,IOCTL_STORAGE_QUERY_PROPERTY, tenths of Kelvin). Use named constants instead.
The Linux side (sorted entries, power/network skipped, unsupported id leaves the output untouched) looks good.
|
Other open pull requests touch the same code. Merging one will break the other, or both implement the same thing. If this one builds on them, list them in Depends on.
|
PPSA99058 and PPSA99420 import sceKernelGetCpuTemperature and sceKernelGetSocSensorTemperature and stop at start-up on main. Read the host CPU/package, board and NVMe sensors (hwmon/thermal on Linux, the ACPI thermal zones and the storage temperature property on Windows) and report an unsupported sensor with EINVAL.
5510cf2 to
0f73f5f
Compare
|
Fixed all three — and the offset review led me to the real reason the path never ran. Descriptor offsets. It now actually runs. The old code also queried Hardware result. On this machine (WD_BLACK SN7100, NVMe) the built Independently, the drive's own SMART / Health Information log (GET LOG PAGE Comments. Removed the |
adriadam10
left a comment
There was a problem hiding this comment.
Checked on this PR merged onto main: build and the libkernel/libs tests pass on Linux, including guest_thermal_sensors; the descriptor offsets (+12 InfoCount, +24 TemperatureInfo[0], +26 Temperature) and property ids 52/22 match the SDK; sensor selection is sorted and skips power/network devices; unsupported ids leave the output untouched. The Windows path is covered by the full Build. Merging.
Conflicts: Unimplemented.cpp drops both stubs (__tls_get_addr is ours in Rtld.cpp); CMakeLists keeps both sources.
What
Report the SoC and CPU temperature from the host, for the libkernel exports Overdrive (PPSA99058) and LZ4-Compression (PPSA99420) import:
sceKernelGetCpuTemperature(previously theUnimplemented.cppstub)sceKernelGetSocSensorTemperatureBoth titles import the sensors and stop at start-up on
main:With this change they get past both sensors.
Behaviour:
sceKernelGetCpuTemperaturereports sensor 0.hwmonandthermalentries are read in sorted order and battery/power-supply (BAT*,AC,ucsi*) and network-adapter (iwl*,mt79*,ath*,rtw*,wlan*,wifi*) devices are skipped, so the board channel does not depend on directory order. On Linux the values come from/sys/class/hwmonand/sys/class/thermal; on Windows from the ACPI thermal zones (MSAcpi_ThermalZoneTemperatureover WMI) and the storage temperature of the first physical drive that answers (StorageDeviceTemperatureProperty, read with a struct mirroringSTORAGE_TEMPERATURE_DATA_DESCRIPTOR). A sensor the host does not expose (including any id above 2) returnsEINVALand leaves the output untouched; a null output returnsEFAULT.docs/dev/debt/libkernel.md.sceKernelGetCpuFrequencyis no longer part of this PR — it landed separately in #4466, so it was dropped after the rebase.Tested
Windows 11, MinGW-w64 GCC 15.2.0 (WinLibs r7), Release. Linux reviewer run on Arch (Intel Core Ultra).
guest_thermal_sensorspasses: it reads a synthetichwmon/thermallayout and checks the sensor mapping, that a battery and a Wi-Fi sensor are skipped and that the GPU die becomes the SoC channel when no CPU package sensor is present, a missing directory and a null root, and theEFAULT/EINVALpaths (including that an unsupported id leaves the output untouched).sceKernelGetSocSensorTemperature(2, …)returns 36 °C, matching the drive's own SMART/Health log (GET LOG PAGE0x02, read overStorageDeviceSpecificProperty): composite temperature 309 K = 36 °C. The descriptor offsets were confirmed against the Windows SDK'sntddstor.h(InfoCountat +12,TemperatureInfo[0].Temperatureat +26, the value in Celsius) and astatic_assertpins them; the earlier code checked the warning threshold (+10), read a reserved field (+14), used the pre-2004StorageDeviceTemperaturePropertyvalue and applied a Kelvin adjustment, all now removed.half144/overdrive-releasesv0.1.4, assetOverdrive-PPSA99058.zip) and LZ4-Compression (PPSA99420,theghostonline/PS5-LZ4-Compressionv1.4.2, assetLZ4-Compression-PPSA99420.zip),eboot.binunwrapped from their SELF and relinked with the built relinker--windows: onmainthey stop atzzKyvoELf4I(sceKernelGetSocSensorTemperature). With this change they pass both sensors; afterposix_spawnlanded onmainboth run to the 12-second harness timeout with no unresolved import.python tools/check_conventions.py --base origin/mainpasses.Checklist
main; no other open PR implements the same functionsNotImplemented_nid_no_patch); silent stubs are listed in TechnicalDebt.mdfiles or images added to the repository (attach them to this PR)