diff --git a/Source/hoc-clk/bpmpfw/Makefile b/Source/hoc-clk/bpmpfw/Makefile
index 7af3a478..4cd0257a 100644
--- a/Source/hoc-clk/bpmpfw/Makefile
+++ b/Source/hoc-clk/bpmpfw/Makefile
@@ -19,7 +19,8 @@ OBJS := $(patsubst $(SOURCEDIR)/%.cpp,$(BUILDDIR)/%.o,$(CPP_SOURCES)) \
$(patsubst $(SOURCEDIR)/%.s,$(BUILDDIR)/%.o,$(S_SOURCES))
ARCH := -march=armv4t -mtune=arm7tdmi -mthumb-interwork
-INCLUDE := -I$(SOURCEDIR) -I$(LIBCDIR)/include -I$(LIBCDIR)/include/fslc
+COMMONDIR := ../common/include
+INCLUDE := -I$(SOURCEDIR) -I$(LIBCDIR)/include -I$(LIBCDIR)/include/fslc -I$(COMMONDIR)
CFLAGS := $(ARCH) -O2 -g -ffreestanding -nostdlib -ffunction-sections -fdata-sections \
-fomit-frame-pointer -std=gnu11 -Wall -Wextra $(CUSTOMDEFINES)
CXXFLAGS := $(ARCH) -O2 -g -ffreestanding -nostdlib -fno-exceptions -fno-rtti \
diff --git a/Source/hoc-clk/bpmpfw/out/bpmpfw.bin b/Source/hoc-clk/bpmpfw/out/bpmpfw.bin
index 04f7484e..64a8fc50 100644
Binary files a/Source/hoc-clk/bpmpfw/out/bpmpfw.bin and b/Source/hoc-clk/bpmpfw/out/bpmpfw.bin differ
diff --git a/Source/hoc-clk/bpmpfw/source/libc_platform.cpp b/Source/hoc-clk/bpmpfw/source/libc_platform.cpp
index 3f3efc4c..9ba02640 100644
--- a/Source/hoc-clk/bpmpfw/source/libc_platform.cpp
+++ b/Source/hoc-clk/bpmpfw/source/libc_platform.cpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
#include
#include "regs.hpp"
@@ -9,7 +26,11 @@ namespace {
return c;
}
- FILE g_uartStdout = { nullptr, UartStreamPutc, nullptr, nullptr, nullptr, -1 };
+ void UartStreamPostOutput(FILE *) {
+ UartFlush();
+ }
+
+ FILE g_uartStdout = { nullptr, UartStreamPutc, nullptr, nullptr, UartStreamPostOutput, -1 };
} // namespace
diff --git a/Source/hoc-clk/bpmpfw/source/libc_platform.hpp b/Source/hoc-clk/bpmpfw/source/libc_platform.hpp
index 4268a9c5..f29c8b03 100644
--- a/Source/hoc-clk/bpmpfw/source/libc_platform.hpp
+++ b/Source/hoc-clk/bpmpfw/source/libc_platform.hpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
#pragma once
void InitializeLibc();
diff --git a/Source/hoc-clk/bpmpfw/source/main.cpp b/Source/hoc-clk/bpmpfw/source/main.cpp
index 4e57d8db..d329e669 100644
--- a/Source/hoc-clk/bpmpfw/source/main.cpp
+++ b/Source/hoc-clk/bpmpfw/source/main.cpp
@@ -1,12 +1,47 @@
+/*
+ * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
#include
+#include
#include "libc_platform.hpp"
#include "regs.hpp"
+#include
+
+namespace {
+
+ HocClkBpmpSharedInfo &SharedInfo() {
+ return *reinterpret_cast(WorkRamStart);
+ }
+
+} // namespace
+
extern "C" void main() {
InitializeLibc();
printf("[hoc-bpmpfw] Starting bpmpfw\n");
- for (;;);
+ HocClkBpmpSharedInfo &info = SharedInfo();
+ memset(&info, 0, sizeof(info));
+ info.status = 0;
+ info.magic = HOCCLK_BPMP_MAGIC; // written last
+
+ for (;;) {
+
+ }
}
diff --git a/Source/hoc-clk/bpmpfw/source/regs.hpp b/Source/hoc-clk/bpmpfw/source/regs.hpp
index 4f8d5965..a39389b2 100644
--- a/Source/hoc-clk/bpmpfw/source/regs.hpp
+++ b/Source/hoc-clk/bpmpfw/source/regs.hpp
@@ -1,3 +1,20 @@
+/*
+ * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
#pragma once
#include
@@ -26,6 +43,7 @@ constexpr u32 UartBBase = 0x70006040;
constexpr u32 UartThr = 0x00;
constexpr u32 UartLsr = 0x14;
constexpr u32 UartLsrThre = (1u << 5);
+constexpr u32 UartLsrTmty = (1u << 6);
inline void UartPutc(char c) {
while (!(MMIO32(UartBBase + UartLsr) & UartLsrThre))
@@ -33,6 +51,12 @@ inline void UartPutc(char c) {
MMIO32(UartBBase + UartThr) = static_cast(static_cast(c));
}
+// Waits for the byte to be fully transmitted
+inline void UartFlush() {
+ while (!(MMIO32(UartBBase + UartLsr) & UartLsrTmty))
+ ;
+}
+
inline void UartPuts(const char *s) {
while (*s) {
UartPutc(*s++);
diff --git a/Source/hoc-clk/bpmpfw/source/start.s b/Source/hoc-clk/bpmpfw/source/start.s
index afabaa9c..83f2e136 100644
--- a/Source/hoc-clk/bpmpfw/source/start.s
+++ b/Source/hoc-clk/bpmpfw/source/start.s
@@ -1,3 +1,22 @@
+/*
+ * Copyright (c) Atmosphere-NX
+ *
+ * Copyright (c) Souldbminer, Lightos and Horizon OC Contributors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
.section .vectors, "ax", %progbits
.align 3
.global reset
diff --git a/Source/hoc-clk/common/include/hocclk/board.h b/Source/hoc-clk/common/include/hocclk/board.h
index 45b576d8..389ba513 100644
--- a/Source/hoc-clk/common/include/hocclk/board.h
+++ b/Source/hoc-clk/common/include/hocclk/board.h
@@ -30,7 +30,10 @@
#include
#include
#include
+#ifdef __SWITCH__ // Wont be defined in BPMP-FW
#include
+#endif
+
typedef enum
{
HocClkSocType_Erista = 0, // T210, found in Icosa and Copper
diff --git a/Source/hoc-clk/common/include/hocclk/bpmp.h b/Source/hoc-clk/common/include/hocclk/bpmp.h
new file mode 100644
index 00000000..b5cb8f4b
--- /dev/null
+++ b/Source/hoc-clk/common/include/hocclk/bpmp.h
@@ -0,0 +1,35 @@
+/*
+ * Copyright (c) Souldbminer, Lightos_ and Horizon OC Contributors
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see .
+ *
+ */
+
+#pragma once
+
+#include
+#include "board.h"
+
+#define HOCCLK_BPMP_MAGIC 0x42504D50 // 'BPMP'
+
+/*
+ * Shared with BPMP-FW
+ * Any 64 bit data type is not permitted.
+ */
+typedef struct {
+ u32 magic; // should be HOCCLK_BPMP_MAGIC once bpmpfw is running
+ u32 status; // Reserved for error codes and such
+ u32 reserved[6];
+} HocClkBpmpSharedInfo;
+
+static_assert(sizeof(HocClkBpmpSharedInfo) == 0x20);
diff --git a/Source/hoc-clk/common/include/hocclk/clock_manager.h b/Source/hoc-clk/common/include/hocclk/clock_manager.h
index 21e47646..f2338354 100644
--- a/Source/hoc-clk/common/include/hocclk/clock_manager.h
+++ b/Source/hoc-clk/common/include/hocclk/clock_manager.h
@@ -29,6 +29,7 @@
#include
#include "board.h"
+#include "bpmp.h"
typedef struct {
@@ -84,6 +85,9 @@ typedef struct {
bool rebootRequired;
bool isFirstLoad;
+ // Populated from bpmpfw's work-RAM via SmcCopyFromIram (see HocClkBpmpSharedInfo above).
+ HocClkBpmpSharedInfo bpmpInfo;
+
// Reserved for future use
u8 reserved[0x358];
} HocClkContext;
@@ -100,4 +104,4 @@ typedef struct
#define HOCCLK_GLOBAL_PROFILE_TID 0xA111111111111111
-static_assert(sizeof(HocClkContext) == 0x500);
\ No newline at end of file
+static_assert(sizeof(HocClkContext) == 0x520);
diff --git a/Source/hoc-clk/overlay/src/ui/gui/about_gui.cpp b/Source/hoc-clk/overlay/src/ui/gui/about_gui.cpp
index 2febf53f..f36b012b 100644
--- a/Source/hoc-clk/overlay/src/ui/gui/about_gui.cpp
+++ b/Source/hoc-clk/overlay/src/ui/gui/about_gui.cpp
@@ -43,6 +43,7 @@ tsl::elm::ListItem* bqtempitem = NULL;
tsl::elm::ListItem* aotagTempItem = NULL;
tsl::elm::ListItem* cTypeItem = NULL;
tsl::elm::ListItem* creditsItem = NULL;
+tsl::elm::ListItem* bpmpStatusItem = NULL;
#define R_ARROW "\u2192"
@@ -147,6 +148,9 @@ void AboutGui::listUI()
// custRevItem = new tsl::elm::ListItem("CUST revision:");
// this->listElement->addItem(custRevItem);
+ bpmpStatusItem = new tsl::elm::ListItem("BPMP Status:");
+ this->listElement->addItem(bpmpStatusItem);
+
kipVersionItem = new tsl::elm::ListItem("KIP version:");
this->listElement->addItem(kipVersionItem);
@@ -272,6 +276,7 @@ void AboutGui::refresh()
bqtempitem->setValue(strings[10]);
cTypeItem->setValue(hocClkFormatConsoleType(this->context->consoleType, true));
+ bpmpStatusItem->setValue(this->context->bpmpInfo.magic == HOCCLK_BPMP_MAGIC ? "Enabled" : "Disabled");
}
class CreditsSubMenu : public AboutGui {
diff --git a/Source/hoc-clk/sysmodule/src/bpmp/bpmp.cpp b/Source/hoc-clk/sysmodule/src/bpmp/bpmp.cpp
index 41c0792b..9485e559 100644
--- a/Source/hoc-clk/sysmodule/src/bpmp/bpmp.cpp
+++ b/Source/hoc-clk/sysmodule/src/bpmp/bpmp.cpp
@@ -20,6 +20,7 @@
#include
#include "../board/board.hpp"
+#include "../file/config.hpp"
#include "../file/file_utils.hpp"
#include "../mapping/mem_map.hpp"
#include "bpmp.hpp"
@@ -57,9 +58,12 @@ namespace bpmp {
constexpr u64 FwIramPhysBase = 0x40004000;
constexpr u32 FwStagingSize = 0x8000;
+ constexpr u64 WorkRamPhysBase = FwIramPhysBase + FwStagingSize; // matches bpmpfw's WorkRamStart
alignas(4096) u8 s_fwStageBuf[FwStagingSize];
+ HocClkBpmpSharedInfo s_sharedInfo = {};
+
inline volatile u32 &Mmio(u64 base_va, u32 offset) {
return *reinterpret_cast(base_va + offset);
}
@@ -213,4 +217,14 @@ namespace bpmp {
s_pscPrepared = false;
}
+ const HocClkBpmpSharedInfo *GetSharedInfo() {
+ if (!IsPatchedExosphere()) {
+ s_sharedInfo = {};
+ return &s_sharedInfo;
+ }
+
+ SmcCopyFromIram(&s_sharedInfo, WorkRamPhysBase, sizeof(s_sharedInfo));
+ return &s_sharedInfo;
+ }
+
} // namespace bpmp
diff --git a/Source/hoc-clk/sysmodule/src/bpmp/bpmp.hpp b/Source/hoc-clk/sysmodule/src/bpmp/bpmp.hpp
index 7a57069c..43d8bb32 100644
--- a/Source/hoc-clk/sysmodule/src/bpmp/bpmp.hpp
+++ b/Source/hoc-clk/sysmodule/src/bpmp/bpmp.hpp
@@ -18,9 +18,13 @@
#pragma once
#include
+#include
+
namespace bpmp {
Result StartBpmfwExecution();
void StartSleepMonitorThread();
void StopSleepMonitorThread();
+
+ const HocClkBpmpSharedInfo *GetSharedInfo();
}
diff --git a/Source/hoc-clk/sysmodule/src/mgr/clock_manager.cpp b/Source/hoc-clk/sysmodule/src/mgr/clock_manager.cpp
index c035c11e..770dc65a 100644
--- a/Source/hoc-clk/sysmodule/src/mgr/clock_manager.cpp
+++ b/Source/hoc-clk/sysmodule/src/mgr/clock_manager.cpp
@@ -30,6 +30,7 @@
#include
#include "../board/board.hpp"
+#include "../bpmp/bpmp.hpp"
#include "../display/aula.hpp"
#include "../display/display_refresh_rate.hpp"
#include "../file/config.hpp"
@@ -626,6 +627,8 @@ namespace clockManager {
bool RefreshContext() {
bool hasChanged = false;
+ gContext.bpmpInfo = *bpmp::GetSharedInfo();
+
std::uint32_t mode = 0;
Result rc = apmExtGetCurrentPerformanceConfiguration(&mode);
ASSERT_RESULT_OK(rc, "apmExtGetCurrentPerformanceConfiguration");