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");