add bpmp-fw cmd interface

This commit is contained in:
souldbminersmwc committed 2026-08-28 13:43:50 -04:00
1 parent 39c612779b
commit 6b88b43cb9
7 files changed
+94 -17

No files matched your search

+27 -10
View File
@@ -39,11 +39,35 @@ namespace {
} // namespace
[[noreturn]] void HandleShutdown(HocClkBpmpSharedInfo &info) {
/* Deinit MMU otherwise sleep will fatal. */
bpmpMmu::Disable();
info.magic = 0x0;
printf("[hoc-bpmpfw]: Halting...\n");
for (;;)
;
}
void HandleCommand(HocClkBpmpSharedInfo &info) {
switch (info.cmd) {
case HocClkBpmpCmd_None:
break;
case HocClkBpmpCmd_RequestShutdown:
HandleShutdown(info);
break;
case HocClkBpmpCmd_SetUartEnabled:
g_uartLoggingEnabled = (info.cmdArg1 != 0);
info.cmd = HocClkBpmpCmd_None;
break;
default:
info.cmd = HocClkBpmpCmd_None;
break;
}
}
void MainLoop(HocClkBpmpSharedInfo &info) {
for (;;) {
if (info.exitRequested) {
break;
}
HandleCommand(info);
const u32 temp1 = MMIO32(SocthermBase + SocthermSensorTemp1);
const u32 temp2 = MMIO32(SocthermBase + SocthermSensorTemp2);
@@ -60,13 +84,6 @@ void MainLoop(HocClkBpmpSharedInfo &info) {
msleep(250);
}
/* Deinit MMU otherwise sleep will fatal. */
bpmpMmu::Disable();
info.magic = 0x0;
for (;;)
;
}
extern "C" void main() {
+8
View File
@@ -33,13 +33,21 @@
}
}
bool g_uartLoggingEnabled = true;
void UartPutc(char c) {
if (!g_uartLoggingEnabled) {
return;
}
while (!(MMIO32(UartBBase + UartLsr) & UartLsrThre))
;
MMIO32(UartBBase + UartThr) = static_cast<u32>(static_cast<u8>(c));
}
void UartFlush() {
if (!g_uartLoggingEnabled) {
return;
}
while (!(MMIO32(UartBBase + UartLsr) & UartLsrTmty))
;
}
+2
View File
@@ -45,6 +45,8 @@ constexpr u32 UartLsr = 0x14;
constexpr u32 UartLsrThre = (1u << 5);
constexpr u32 UartLsrTmty = (1u << 6);
extern bool g_uartLoggingEnabled;
void UartPutc(char c);
void UartFlush();
+12 -2
View File
@@ -22,6 +22,12 @@
#define HOCCLK_BPMP_MAGIC 0x42504D50 // 'BPMP'
typedef enum {
HocClkBpmpCmd_None = 0,
HocClkBpmpCmd_RequestShutdown = 1, // Request BPMP-FW to shut down for sleep mode.
HocClkBpmpCmd_SetUartEnabled = 2, // cmdArg1: 0/1.
} HocClkBpmpCmd;
/*
* Shared with BPMP-FW
* Any 64 bit data type is not permitted.
@@ -41,8 +47,12 @@ typedef struct {
u32 emcBwAll;
u32 emcBwCpu;
u32 emcBwGpu;
u32 exitRequested; // Request BPMP-FW to shutdown for sleep mode
u32 cmd; // HocClkBpmpCmd; 0 = no command pending
u32 cmdArg1;
u32 cmdArg2;
u32 cmdArg3;
u32 cmdArg4;
s32 tempAO;
} HocClkBpmpSharedInfo;
static_assert(sizeof(HocClkBpmpSharedInfo) == 0x40);
static_assert(sizeof(HocClkBpmpSharedInfo) == 0x50);
@@ -89,7 +89,7 @@ typedef struct {
HocClkBpmpSharedInfo bpmpInfo;
// Reserved for future use
u8 reserved[0x33C];
u8 reserved[0x32C];
} HocClkContext;
typedef struct
+6 -2
View File
@@ -105,7 +105,7 @@ export BUILD_EXEFS_SRC := $(TOPDIR)/$(EXEFS_SRC)
export APP_JSON := $(TOPDIR)/perms.json
.PHONY: $(BUILD) clean clean-libs clean-build all libs
.PHONY: $(BUILD) clean clean-libs clean-build all libs sync-bpmpfw
#---------------------------------------------------------------------------------
all: $(BUILD)
@@ -116,7 +116,11 @@ libs:
$(LIBNAMES):
@echo $@
$(BUILD): libs
sync-bpmpfw:
@$(MAKE) --no-print-directory -C $(TOPDIR)/../bpmpfw
@cp -f $(TOPDIR)/../bpmpfw/out/bpmpfw.bin $(TOPDIR)/data/bpmpfw.bin
$(BUILD): libs sync-bpmpfw
@[ -d $@ ] || mkdir -p $@
@[ -d $(OUTDIR) ] || mkdir -p $(OUTDIR)
@$(MAKE) --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile
+38 -2
View File
@@ -125,8 +125,8 @@ namespace bpmp {
return;
}
const u32 one = 1;
Result rc = SmcCopyToIram(WorkRamPhysBase + offsetof(HocClkBpmpSharedInfo, exitRequested), &one, sizeof(one));
const u32 cmd = HocClkBpmpCmd_RequestShutdown;
Result rc = SmcCopyToIram(WorkRamPhysBase + offsetof(HocClkBpmpSharedInfo, cmd), &cmd, sizeof(cmd));
if (R_FAILED(rc)) {
fileUtils::LogLine("[bpmp] RequestBpmpExitAndWait: SmcCopyToIram failed: 0x%x", rc);
return;
@@ -186,6 +186,40 @@ namespace bpmp {
SmcReadWriteRegister(McPhysBase + McSmmuTlbConfig, 0, 0);
}
bool WaitForBpmpReady(int maxAttempts = 50, u64 pollIntervalNs = 20'000'000) {
HocClkBpmpSharedInfo info = {};
for (int i = 0; i < maxAttempts; i++) {
Result rc = SmcCopyFromIram(&info, WorkRamPhysBase, sizeof(info));
if (R_SUCCEEDED(rc) && info.magic == HOCCLK_BPMP_MAGIC) {
return true;
}
svcSleepThread(pollIntervalNs);
}
return false;
}
void SendBpmpCommand(HocClkBpmpCmd cmd, u32 arg1 = 0, u32 arg2 = 0, u32 arg3 = 0, u32 arg4 = 0) {
if (!WaitForBpmpReady()) {
fileUtils::LogLine("[bpmp] SendBpmpCommand: BPMP never signaled ready (cmd=%u)", static_cast<u32>(cmd));
return;
}
struct {
u32 cmd;
u32 cmdArg1;
u32 cmdArg2;
u32 cmdArg3;
u32 cmdArg4;
} req = { static_cast<u32>(cmd), arg1, arg2, arg3, arg4 };
static_assert(offsetof(HocClkBpmpSharedInfo, cmdArg1) == offsetof(HocClkBpmpSharedInfo, cmd) + 1 * sizeof(u32));
static_assert(offsetof(HocClkBpmpSharedInfo, cmdArg4) == offsetof(HocClkBpmpSharedInfo, cmd) + 4 * sizeof(u32));
const Result rc = SmcCopyToIram(WorkRamPhysBase + offsetof(HocClkBpmpSharedInfo, cmd), &req, sizeof(req));
if (R_FAILED(rc)) {
fileUtils::LogLine("[bpmp] SendBpmpCommand: SmcCopyToIram failed: 0x%x (cmd=%u)", rc, static_cast<u32>(cmd));
}
}
void RestoreStockState() {
RequestBpmpExitAndWait();
@@ -306,6 +340,8 @@ namespace bpmp {
/* Clear the halt written by bootloader. */
SmcReadWriteRegister(FlowCtlrPhysBase + FlowCtlrHaltCopEvents, 0xFFFFFFFF, FlowModeNone);
SendBpmpCommand(HocClkBpmpCmd_SetUartEnabled, fileUtils::IsUartEnabled() ? 1u : 0u);
return 0;
}