diff --git a/Source/hoc-clk/bpmpfw/Makefile b/Source/hoc-clk/bpmpfw/Makefile
index ddfe3882..b855a056 100644
--- a/Source/hoc-clk/bpmpfw/Makefile
+++ b/Source/hoc-clk/bpmpfw/Makefile
@@ -39,18 +39,23 @@ all: $(BIN_TARGET)
$(BIN_TARGET): $(BUILDDIR)/$(TARGET).elf
@mkdir -p $(OUTPUTDIR)
- $(OBJCOPY) -S -O binary $< $@
+ @echo "bpmpfw.bin"
+ @$(OBJCOPY) -S -O binary $< $@
$(BUILDDIR)/$(TARGET).elf: $(OBJS)
+ @echo "linking $(TARGET).elf"
@$(CXX) $(LDFLAGS) $(OBJS) $(LDLIBS) -o $@
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.cpp | $(BUILDDIR)
+ @echo "$(notdir $<)"
@$(CXX) $(CXXFLAGS) $(INCLUDE) -c $< -o $@
$(BUILDDIR)/libc/%.o: $(LIBCDIR)/src/%.c | $(BUILDDIR)/libc
+ @echo "$(notdir $<)"
@$(CC) $(CFLAGS) $(INCLUDE) -c $< -o $@
$(BUILDDIR)/%.o: $(SOURCEDIR)/%.s | $(BUILDDIR)
+ @echo "$(notdir $<)"
@$(CXX) $(ASFLAGS) $(INCLUDE) -c $< -o $@
$(BUILDDIR):
diff --git a/Source/hoc-clk/bpmpfw/source/actmon.cpp b/Source/hoc-clk/bpmpfw/source/actmon.cpp
new file mode 100644
index 00000000..f6faa312
--- /dev/null
+++ b/Source/hoc-clk/bpmpfw/source/actmon.cpp
@@ -0,0 +1,65 @@
+/*
+ * 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 "actmon.hpp"
+
+namespace actmon {
+
+ u32 DevReg(ActmonDev dev, u32 off) {
+ return ActmonDevBase + (static_cast(dev) * ActmonDevSize) + off;
+ }
+
+ void EnableDev(ActmonDev dev, u32 freqKhz, u32 weight) {
+ MMIO32(DevReg(dev, DevInitAvg)) = freqKhz * ActmonPeriodMs / 2;
+ MMIO32(DevReg(dev, DevCountWeight)) = weight;
+ MMIO32(DevReg(dev, DevCtrl)) = ActmonDevCtrlEnb | ActmonDevCtrlEnbPeriodic | ActmonDevCtrlKVal3;
+ }
+
+ void Init() {
+ const u32 emcFreqKhz = static_cast(freq::MeasurePtoFreqHz(freq::ClkPtoEmc, 1) / 1000);
+
+ if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMcallMonAct)) {
+ MMIO32(ActmonBase + ActmonGlbPeriodCtrl) = (ActmonPeriodMs - 1) & 0xFF;
+ EnableDev(DevMcAll, emcFreqKhz, 256 * 4);
+ }
+
+ if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMccpuMonAct)) {
+ EnableDev(DevMcCpu, emcFreqKhz, 256 * 4);
+ }
+ }
+
+ void Update(HocClkBpmpSharedInfo &info) {
+ const u32 emcFreqKhz = info.freqMem;
+ if (emcFreqKhz == 0) {
+ return;
+ }
+
+ const u32 avgAll = MMIO32(DevReg(DevMcAll, DevAvgCount));
+ const u32 avgCpu = MMIO32(DevReg(DevMcCpu, DevAvgCount));
+
+ // Get 1000 -> 100.0.
+ info.emcLoadAll = static_cast((static_cast(avgAll) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs));
+ info.emcLoadCpu = static_cast((static_cast(avgCpu) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs));
+
+ info.emcBwAll = static_cast((static_cast(emcFreqKhz) * 16 * info.emcLoadAll) / 1000000);
+ info.emcBwCpu = static_cast((static_cast(emcFreqKhz) * 16 * info.emcLoadCpu) / 1000000);
+
+ // Not 100% accurate but should be enough.
+ info.emcBwGpu = (info.emcBwAll > info.emcBwCpu) ? (info.emcBwAll - info.emcBwCpu) : 0;
+ }
+
+} // namespace actmon
diff --git a/Source/hoc-clk/bpmpfw/source/actmon.hpp b/Source/hoc-clk/bpmpfw/source/actmon.hpp
index 9a607c4e..42e935f6 100644
--- a/Source/hoc-clk/bpmpfw/source/actmon.hpp
+++ b/Source/hoc-clk/bpmpfw/source/actmon.hpp
@@ -53,47 +53,12 @@ namespace actmon {
constexpr u32 DevCountWeight = 0x18;
constexpr u32 DevAvgCount = 0x20;
- inline u32 DevReg(ActmonDev dev, u32 off) {
- return ActmonDevBase + (static_cast(dev) * ActmonDevSize) + off;
- }
+ u32 DevReg(ActmonDev dev, u32 off);
- inline void EnableDev(ActmonDev dev, u32 freqKhz, u32 weight) {
- MMIO32(DevReg(dev, DevInitAvg)) = freqKhz * ActmonPeriodMs / 2;
- MMIO32(DevReg(dev, DevCountWeight)) = weight;
- MMIO32(DevReg(dev, DevCtrl)) = ActmonDevCtrlEnb | ActmonDevCtrlEnbPeriodic | ActmonDevCtrlKVal3;
- }
+ void EnableDev(ActmonDev dev, u32 freqKhz, u32 weight);
- inline void Init() {
- const u32 emcFreqKhz = static_cast(freq::MeasurePtoFreqHz(freq::ClkPtoEmc, 1) / 1000);
+ void Init();
- if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMcallMonAct)) {
- MMIO32(ActmonBase + ActmonGlbPeriodCtrl) = (ActmonPeriodMs - 1) & 0xFF;
- EnableDev(DevMcAll, emcFreqKhz, 256 * 4);
- }
-
- if (!(MMIO32(ActmonBase + ActmonGlbStatus) & ActmonMccpuMonAct)) {
- EnableDev(DevMcCpu, emcFreqKhz, 256 * 4);
- }
- }
-
- inline void Update(HocClkBpmpSharedInfo &info) {
- const u32 emcFreqKhz = info.freqMem;
- if (emcFreqKhz == 0) {
- return;
- }
-
- const u32 avgAll = MMIO32(DevReg(DevMcAll, DevAvgCount));
- const u32 avgCpu = MMIO32(DevReg(DevMcCpu, DevAvgCount));
-
- // Get 1000 -> 100.0.
- info.emcLoadAll = static_cast((static_cast(avgAll) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs));
- info.emcLoadCpu = static_cast((static_cast(avgCpu) * 10 * 100) / (emcFreqKhz * ActmonPeriodMs));
-
- info.emcBwAll = static_cast((static_cast(emcFreqKhz) * 16 * info.emcLoadAll) / 1000000);
- info.emcBwCpu = static_cast((static_cast(emcFreqKhz) * 16 * info.emcLoadCpu) / 1000000);
-
- // Not 100% accurate but should be enough.
- info.emcBwGpu = (info.emcBwAll > info.emcBwCpu) ? (info.emcBwAll - info.emcBwCpu) : 0;
- }
+ void Update(HocClkBpmpSharedInfo &info);
} // namespace actmon
diff --git a/Source/hoc-clk/bpmpfw/source/aotag.cpp b/Source/hoc-clk/bpmpfw/source/aotag.cpp
new file mode 100644
index 00000000..da71c08d
--- /dev/null
+++ b/Source/hoc-clk/bpmpfw/source/aotag.cpp
@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2014 - 2017, NVIDIA CORPORATION. All rights reserved.
+ * 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 "aotag.hpp"
+
+namespace aotag {
+
+ void Update(HocClkBpmpSharedInfo &info) {
+ const u32 regval = MMIO32(PmcBase + PmcTsensorStatus1);
+
+ if (!(regval & Status1ValidBit)) {
+ info.tempAO = InvalidSentinel;
+ return;
+ }
+
+ const u32 abs = (regval >> Status1AbsShift) & Status1AbsMask;
+ const bool frac = (regval & Status1FracBit) != 0;
+ const bool negative = (regval & Status1SignBit) != 0;
+
+ s32 temp = static_cast(abs) * 1000 + (frac ? 500 : 0);
+ if (negative) {
+ temp = -temp;
+ }
+
+ info.tempAO = temp;
+ }
+
+} // namespace aotag
diff --git a/Source/hoc-clk/bpmpfw/source/aotag.hpp b/Source/hoc-clk/bpmpfw/source/aotag.hpp
index 1e159139..25e18a0a 100644
--- a/Source/hoc-clk/bpmpfw/source/aotag.hpp
+++ b/Source/hoc-clk/bpmpfw/source/aotag.hpp
@@ -34,24 +34,6 @@ namespace aotag {
constexpr s32 InvalidSentinel = -125;
- inline void Update(HocClkBpmpSharedInfo &info) {
- const u32 regval = MMIO32(PmcBase + PmcTsensorStatus1);
-
- if (!(regval & Status1ValidBit)) {
- info.tempAO = InvalidSentinel;
- return;
- }
-
- const u32 abs = (regval >> Status1AbsShift) & Status1AbsMask;
- const bool frac = (regval & Status1FracBit) != 0;
- const bool negative = (regval & Status1SignBit) != 0;
-
- s32 temp = static_cast(abs) * 1000 + (frac ? 500 : 0);
- if (negative) {
- temp = -temp;
- }
-
- info.tempAO = temp;
- }
+ void Update(HocClkBpmpSharedInfo &info);
} // namespace aotag
diff --git a/Source/hoc-clk/bpmpfw/source/bpmp_mmu.cpp b/Source/hoc-clk/bpmpfw/source/bpmp_mmu.cpp
new file mode 100644
index 00000000..ad457560
--- /dev/null
+++ b/Source/hoc-clk/bpmpfw/source/bpmp_mmu.cpp
@@ -0,0 +1,96 @@
+/*
+ * Copyright (c) 2019-2025 CTCaer
+ * 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 "bpmp_mmu.hpp"
+
+namespace bpmpMmu {
+
+ u32 AlignUp(u32 x, u32 a) {
+ return (x + a - 1) & ~(a - 1);
+ }
+
+ u32 AlignDown(u32 x, u32 a) {
+ return x & ~(a - 1);
+ }
+
+ void Maintenance(u32 op, bool force) {
+ if (!force && !(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) {
+ return;
+ }
+
+ MMIO32(CacheBase + IntClear) = IntMaintDone;
+
+ // Blocking operation.
+ MMIO32(CacheBase + MaintReq) = MaintReqWayBitmapAll | op;
+
+ while (!(MMIO32(CacheBase + IntRawEvent) & IntMaintDone))
+ ;
+
+ MMIO32(CacheBase + IntClear) = MMIO32(CacheBase + IntRawEvent);
+ }
+
+ void SetEntry(u32 idx, const MmuEntry &entry) {
+ MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x0) = AlignUp(entry.startAddr, CacheLineSize);
+ MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x4) = AlignDown(entry.endAddr, CacheLineSize);
+ MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x8) = entry.attr;
+
+ MMIO32(CacheBase + MmuShadowCopyMask) |= (1u << idx);
+ }
+
+ void Enable() {
+ if (MMIO32(CacheBase + CacheConfig) & CfgEnableCache) {
+ return;
+ }
+
+ // Init BPMP MMU.
+ MMIO32(CacheBase + MmuCmd) = MmuCmdInit;
+ MMIO32(CacheBase + MmuFallbackEntry) = MmuEnRead | MmuEnWrite | MmuEnExec; // RWX for non-defined regions.
+ MMIO32(CacheBase + MmuCfg) = MmuCfgSeqEn | MmuCfgTlbEn | MmuCfgAbortStoreLast;
+
+ // Init BPMP MMU entries.
+ MMIO32(CacheBase + MmuShadowCopyMask) = 0;
+ for (u32 idx = 0; idx < sizeof(Entries) / sizeof(Entries[0]); idx++) {
+ SetEntry(idx, Entries[idx]);
+ }
+
+ MMIO32(CacheBase + MmuCmd) = MmuCmdCopyShadow;
+
+ // Invalidate cache.
+ Maintenance(MaintInvalidWay, true);
+
+ // Enable cache.
+ MMIO32(CacheBase + CacheConfig) = CfgEnableCache | CfgForceWriteThrough |
+ (TagModeParallel << CfgMmuTagModeShift) | CfgTagChkAbrtOnErr;
+
+ // HW bug. Invalidate cache again.
+ Maintenance(MaintInvalidWay, false);
+ }
+
+ void Disable() {
+ if (!(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) {
+ return;
+ }
+
+ // Clean and invalidate cache.
+ Maintenance(MaintCleanInvalidWay, false);
+
+ // Disable cache.
+ MMIO32(CacheBase + CacheConfig) = 0;
+ }
+
+} // namespace bpmpMmu
diff --git a/Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp b/Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp
index ca106eb8..9e4f2ea9 100644
--- a/Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp
+++ b/Source/hoc-clk/bpmpfw/source/bpmp_mmu.hpp
@@ -77,76 +77,15 @@ namespace bpmpMmu {
{ IramBase, IramEnd, MmuEnRead | MmuEnWrite | MmuEnExec | MmuEnCached },
};
- inline u32 AlignUp(u32 x, u32 a) {
- return (x + a - 1) & ~(a - 1);
- }
- inline u32 AlignDown(u32 x, u32 a) {
- return x & ~(a - 1);
- }
+ u32 AlignUp(u32 x, u32 a);
+ u32 AlignDown(u32 x, u32 a);
- inline void Maintenance(u32 op, bool force) {
- if (!force && !(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) {
- return;
- }
+ void Maintenance(u32 op, bool force);
- MMIO32(CacheBase + IntClear) = IntMaintDone;
+ void SetEntry(u32 idx, const MmuEntry &entry);
- // Blocking operation.
- MMIO32(CacheBase + MaintReq) = MaintReqWayBitmapAll | op;
+ void Enable();
- while (!(MMIO32(CacheBase + IntRawEvent) & IntMaintDone))
- ;
-
- MMIO32(CacheBase + IntClear) = MMIO32(CacheBase + IntRawEvent);
- }
-
- inline void SetEntry(u32 idx, const MmuEntry &entry) {
- MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x0) = AlignUp(entry.startAddr, CacheLineSize);
- MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x4) = AlignDown(entry.endAddr, CacheLineSize);
- MMIO32(ShadowEntryBase + sizeof(u32) * 4 * idx + 0x8) = entry.attr;
-
- MMIO32(CacheBase + MmuShadowCopyMask) |= (1u << idx);
- }
-
- inline void Enable() {
- if (MMIO32(CacheBase + CacheConfig) & CfgEnableCache) {
- return;
- }
-
- // Init BPMP MMU.
- MMIO32(CacheBase + MmuCmd) = MmuCmdInit;
- MMIO32(CacheBase + MmuFallbackEntry) = MmuEnRead | MmuEnWrite | MmuEnExec; // RWX for non-defined regions.
- MMIO32(CacheBase + MmuCfg) = MmuCfgSeqEn | MmuCfgTlbEn | MmuCfgAbortStoreLast;
-
- // Init BPMP MMU entries.
- MMIO32(CacheBase + MmuShadowCopyMask) = 0;
- for (u32 idx = 0; idx < sizeof(Entries) / sizeof(Entries[0]); idx++) {
- SetEntry(idx, Entries[idx]);
- }
-
- MMIO32(CacheBase + MmuCmd) = MmuCmdCopyShadow;
-
- // Invalidate cache.
- Maintenance(MaintInvalidWay, true);
-
- // Enable cache.
- MMIO32(CacheBase + CacheConfig) = CfgEnableCache | CfgForceWriteThrough |
- (TagModeParallel << CfgMmuTagModeShift) | CfgTagChkAbrtOnErr;
-
- // HW bug. Invalidate cache again.
- Maintenance(MaintInvalidWay, false);
- }
-
- inline void Disable() {
- if (!(MMIO32(CacheBase + CacheConfig) & CfgEnableCache)) {
- return;
- }
-
- // Clean and invalidate cache.
- Maintenance(MaintCleanInvalidWay, false);
-
- // Disable cache.
- MMIO32(CacheBase + CacheConfig) = 0;
- }
+ void Disable();
} // namespace bpmpMmu
diff --git a/Source/hoc-clk/bpmpfw/source/freq.cpp b/Source/hoc-clk/bpmpfw/source/freq.cpp
new file mode 100644
index 00000000..de97caaf
--- /dev/null
+++ b/Source/hoc-clk/bpmpfw/source/freq.cpp
@@ -0,0 +1,61 @@
+/*
+ * 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 "freq.hpp"
+
+namespace freq {
+
+ u64 MeasurePtoFreqHz(u32 srcId, u32 multiplier) {
+ constexpr u32 win = 16;
+ constexpr u32 osc = 32768;
+
+ const u32 val = (srcId << PtoSrcSelShift) | PtoDivSelDiv1 | PtoClkEnable | (win - 1);
+
+ MMIO32(CarBase + CarPtoClkCntCntl) = val;
+ (void)MMIO32(CarBase + CarPtoClkCntCntl);
+ usleep(2);
+
+ MMIO32(CarBase + CarPtoClkCntCntl) = val | PtoCntRst;
+ (void)MMIO32(CarBase + CarPtoClkCntCntl);
+ usleep(2);
+
+ MMIO32(CarBase + CarPtoClkCntCntl) = val;
+ (void)MMIO32(CarBase + CarPtoClkCntCntl);
+ usleep(2);
+
+ MMIO32(CarBase + CarPtoClkCntCntl) = val | PtoCntEn;
+ (void)MMIO32(CarBase + CarPtoClkCntCntl);
+ usleep((1000000u * win / osc) + 12 + 2); // 502us
+
+ while (MMIO32(CarBase + CarPtoClkCntStatus) & PtoClkCntBusy)
+ ;
+
+ const u32 cnt = MMIO32(CarBase + CarPtoClkCntStatus) & PtoClkCntMask;
+
+ MMIO32(CarBase + CarPtoClkCntCntl) = 0;
+ (void)MMIO32(CarBase + CarPtoClkCntCntl);
+ usleep(2);
+
+ return (static_cast(cnt) * multiplier * osc) / win;
+ }
+
+ void Update(HocClkBpmpSharedInfo &info) {
+ info.freqMem = static_cast(MeasurePtoFreqHz(ClkPtoEmc, 1) / 1000);
+ info.freqCpu = static_cast(MeasurePtoFreqHz(ClkPtoCclkGDiv2, 2) / 1000);
+ }
+
+} // namespace freq
diff --git a/Source/hoc-clk/bpmpfw/source/freq.hpp b/Source/hoc-clk/bpmpfw/source/freq.hpp
index eea8e9a4..95c24c65 100644
--- a/Source/hoc-clk/bpmpfw/source/freq.hpp
+++ b/Source/hoc-clk/bpmpfw/source/freq.hpp
@@ -37,43 +37,8 @@ namespace freq {
constexpr u32 ClkPtoCclkGDiv2 = 0x13;
constexpr u32 ClkPtoEmc = 0x24;
- inline u64 MeasurePtoFreqHz(u32 srcId, u32 multiplier) {
- constexpr u32 win = 16;
- constexpr u32 osc = 32768;
+ u64 MeasurePtoFreqHz(u32 srcId, u32 multiplier);
- const u32 val = (srcId << PtoSrcSelShift) | PtoDivSelDiv1 | PtoClkEnable | (win - 1);
-
- MMIO32(CarBase + CarPtoClkCntCntl) = val;
- (void)MMIO32(CarBase + CarPtoClkCntCntl);
- usleep(2);
-
- MMIO32(CarBase + CarPtoClkCntCntl) = val | PtoCntRst;
- (void)MMIO32(CarBase + CarPtoClkCntCntl);
- usleep(2);
-
- MMIO32(CarBase + CarPtoClkCntCntl) = val;
- (void)MMIO32(CarBase + CarPtoClkCntCntl);
- usleep(2);
-
- MMIO32(CarBase + CarPtoClkCntCntl) = val | PtoCntEn;
- (void)MMIO32(CarBase + CarPtoClkCntCntl);
- usleep((1000000u * win / osc) + 12 + 2); // 502us
-
- while (MMIO32(CarBase + CarPtoClkCntStatus) & PtoClkCntBusy)
- ;
-
- const u32 cnt = MMIO32(CarBase + CarPtoClkCntStatus) & PtoClkCntMask;
-
- MMIO32(CarBase + CarPtoClkCntCntl) = 0;
- (void)MMIO32(CarBase + CarPtoClkCntCntl);
- usleep(2);
-
- return (static_cast(cnt) * multiplier * osc) / win;
- }
-
- inline void Update(HocClkBpmpSharedInfo &info) {
- info.freqMem = static_cast(MeasurePtoFreqHz(ClkPtoEmc, 1) / 1000);
- info.freqCpu = static_cast(MeasurePtoFreqHz(ClkPtoCclkGDiv2, 2) / 1000);
- }
+ void Update(HocClkBpmpSharedInfo &info);
} // namespace freq
diff --git a/Source/hoc-clk/bpmpfw/source/pllmb.cpp b/Source/hoc-clk/bpmpfw/source/pllmb.cpp
new file mode 100644
index 00000000..559e149e
--- /dev/null
+++ b/Source/hoc-clk/bpmpfw/source/pllmb.cpp
@@ -0,0 +1,84 @@
+/*
+ * Copyright (c) Souldbminer
+ * Copyright (c) KazushiMe
+ * 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 "pllmb.hpp"
+
+namespace pllmb {
+
+ u64 MeasurePtoHz(u32 ptoId, u32 divider, u32 preselReg, u32 preselMask) {
+ u32 preselOrigBit = 0;
+
+ if (preselReg) {
+ u32 val = MMIO32(freq::CarBase + preselReg);
+ usleep(10);
+ preselOrigBit = val & preselMask;
+ val &= ~preselMask;
+ val |= preselMask;
+ MMIO32(freq::CarBase + preselReg) = val;
+ usleep(10);
+ }
+
+ constexpr u32 cycleCount = 16;
+ const u32 savedCntl = MMIO32(freq::CarBase + freq::CarPtoClkCntCntl);
+
+ u32 val = freq::PtoDivSelDiv1 | freq::PtoClkEnable | (cycleCount - 1);
+ val |= ptoId << freq::PtoSrcSelShift;
+
+ MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val;
+ usleep(10);
+ MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val | freq::PtoCntRst;
+ usleep(10);
+ MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val;
+ usleep(10);
+ MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val | freq::PtoCntEn;
+ usleep(500);
+
+ while (MMIO32(freq::CarBase + freq::CarPtoClkCntStatus) & PtoCyclePeriod)
+ ;
+
+ u32 cnt = MMIO32(freq::CarBase + freq::CarPtoClkCntStatus) & freq::PtoClkCntMask;
+ cnt *= divider;
+
+ const u64 rateHz = (static_cast(cnt) * 32768) / cycleCount;
+
+ usleep(10);
+ MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = savedCntl;
+ usleep(10);
+
+ if (preselReg) {
+ u32 val2 = MMIO32(freq::CarBase + preselReg);
+ usleep(10);
+ val2 &= ~preselMask;
+ val2 |= preselOrigBit;
+ MMIO32(freq::CarBase + preselReg) = val2;
+ usleep(10);
+ }
+
+ return rateHz;
+ }
+
+ u64 MeasureRamClockHz() {
+ const u64 pllmbHz = MeasurePtoHz(PtoPllmb, 2, PllmMisc2, PllmMisc2PllmbBit);
+ if (pllmbHz != 0) {
+ return pllmbHz;
+ }
+ return MeasurePtoHz(PtoPllm, 2, PllmMisc2, PllmMisc2PllmBit);
+ }
+
+} // namespace pllmb
diff --git a/Source/hoc-clk/bpmpfw/source/pllmb.hpp b/Source/hoc-clk/bpmpfw/source/pllmb.hpp
index 706b2993..5e296b76 100644
--- a/Source/hoc-clk/bpmpfw/source/pllmb.hpp
+++ b/Source/hoc-clk/bpmpfw/source/pllmb.hpp
@@ -32,64 +32,8 @@ namespace pllmb {
constexpr u32 PtoCyclePeriod = (1u << 31); // PTO_CLK_CNT_STATUS busy bit
- inline u64 MeasurePtoHz(u32 ptoId, u32 divider, u32 preselReg, u32 preselMask) {
- u32 preselOrigBit = 0;
+ u64 MeasurePtoHz(u32 ptoId, u32 divider, u32 preselReg, u32 preselMask);
- if (preselReg) {
- u32 val = MMIO32(freq::CarBase + preselReg);
- usleep(10);
- preselOrigBit = val & preselMask;
- val &= ~preselMask;
- val |= preselMask;
- MMIO32(freq::CarBase + preselReg) = val;
- usleep(10);
- }
-
- constexpr u32 cycleCount = 16;
- const u32 savedCntl = MMIO32(freq::CarBase + freq::CarPtoClkCntCntl);
-
- u32 val = freq::PtoDivSelDiv1 | freq::PtoClkEnable | (cycleCount - 1);
- val |= ptoId << freq::PtoSrcSelShift;
-
- MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val;
- usleep(10);
- MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val | freq::PtoCntRst;
- usleep(10);
- MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val;
- usleep(10);
- MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = val | freq::PtoCntEn;
- usleep(500);
-
- while (MMIO32(freq::CarBase + freq::CarPtoClkCntStatus) & PtoCyclePeriod)
- ;
-
- u32 cnt = MMIO32(freq::CarBase + freq::CarPtoClkCntStatus) & freq::PtoClkCntMask;
- cnt *= divider;
-
- const u64 rateHz = (static_cast(cnt) * 32768) / cycleCount;
-
- usleep(10);
- MMIO32(freq::CarBase + freq::CarPtoClkCntCntl) = savedCntl;
- usleep(10);
-
- if (preselReg) {
- u32 val2 = MMIO32(freq::CarBase + preselReg);
- usleep(10);
- val2 &= ~preselMask;
- val2 |= preselOrigBit;
- MMIO32(freq::CarBase + preselReg) = val2;
- usleep(10);
- }
-
- return rateHz;
- }
-
- inline u64 MeasureRamClockHz() {
- const u64 pllmbHz = MeasurePtoHz(PtoPllmb, 2, PllmMisc2, PllmMisc2PllmbBit);
- if (pllmbHz != 0) {
- return pllmbHz;
- }
- return MeasurePtoHz(PtoPllm, 2, PllmMisc2, PllmMisc2PllmBit);
- }
+ u64 MeasureRamClockHz();
} // namespace pllmb
diff --git a/Source/hoc-clk/bpmpfw/source/regs.cpp b/Source/hoc-clk/bpmpfw/source/regs.cpp
new file mode 100644
index 00000000..3b80f9af
--- /dev/null
+++ b/Source/hoc-clk/bpmpfw/source/regs.cpp
@@ -0,0 +1,58 @@
+/*
+ * 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 "regs.hpp"
+
+[[maybe_unused]] void usleep(u32 us) {
+ while (us) {
+ const u32 delay = (us > HaltMaxCnt) ? HaltMaxCnt : us;
+ us -= delay;
+ MMIO32(FlowCtlrBase + FlowCtlrHaltCopEvents) = HaltModeWaitEvent | HaltUsec | delay;
+ }
+}
+
+[[maybe_unused]] void msleep(u32 ms) {
+ while (ms) {
+ const u32 delay = (ms > HaltMaxCnt) ? HaltMaxCnt : ms;
+ ms -= delay;
+ MMIO32(FlowCtlrBase + FlowCtlrHaltCopEvents) = HaltModeWaitEvent | HaltMsec | delay;
+ }
+}
+
+void UartPutc(char c) {
+ while (!(MMIO32(UartBBase + UartLsr) & UartLsrThre))
+ ;
+ MMIO32(UartBBase + UartThr) = static_cast(static_cast(c));
+}
+
+void UartFlush() {
+ while (!(MMIO32(UartBBase + UartLsr) & UartLsrTmty))
+ ;
+}
+
+void UartPuts(const char *s) {
+ while (*s) {
+ UartPutc(*s++);
+ }
+}
+
+void UartPutHex32(u32 v) {
+ static const char digits[] = "0123456789ABCDEF";
+ for (int i = 28; i >= 0; i -= 4) {
+ UartPutc(digits[(v >> i) & 0xF]);
+ }
+}
diff --git a/Source/hoc-clk/bpmpfw/source/regs.hpp b/Source/hoc-clk/bpmpfw/source/regs.hpp
index b287c27b..9e0b1d9c 100644
--- a/Source/hoc-clk/bpmpfw/source/regs.hpp
+++ b/Source/hoc-clk/bpmpfw/source/regs.hpp
@@ -33,20 +33,8 @@ constexpr u32 HaltMsec = (1u << 24);
constexpr u32 HaltUsec = (1u << 25);
constexpr u32 HaltMaxCnt = 0xFF;
-[[maybe_unused]] inline void usleep(u32 us) {
- while (us) {
- const u32 delay = (us > HaltMaxCnt) ? HaltMaxCnt : us;
- us -= delay;
- MMIO32(FlowCtlrBase + FlowCtlrHaltCopEvents) = HaltModeWaitEvent | HaltUsec | delay;
- }
-}
-[[maybe_unused]] inline void msleep(u32 ms) {
- while (ms) {
- const u32 delay = (ms > HaltMaxCnt) ? HaltMaxCnt : ms;
- ms -= delay;
- MMIO32(FlowCtlrBase + FlowCtlrHaltCopEvents) = HaltModeWaitEvent | HaltMsec | delay;
- }
-}
+[[maybe_unused]] void usleep(u32 us);
+[[maybe_unused]] void msleep(u32 ms);
constexpr u32 TmrBase = 0x60005000;
constexpr u32 TimerUsCntr1Us = 0x10;
@@ -57,27 +45,10 @@ constexpr u32 UartLsr = 0x14;
constexpr u32 UartLsrThre = (1u << 5);
constexpr u32 UartLsrTmty = (1u << 6);
-inline void UartPutc(char c) {
- while (!(MMIO32(UartBBase + UartLsr) & UartLsrThre))
- ;
- MMIO32(UartBBase + UartThr) = static_cast(static_cast(c));
-}
+void UartPutc(char c);
-// Waits for the byte to be fully transmitted
-inline void UartFlush() {
- while (!(MMIO32(UartBBase + UartLsr) & UartLsrTmty))
- ;
-}
+void UartFlush();
-inline void UartPuts(const char *s) {
- while (*s) {
- UartPutc(*s++);
- }
-}
+void UartPuts(const char *s);
-inline void UartPutHex32(u32 v) {
- static const char digits[] = "0123456789ABCDEF";
- for (int i = 28; i >= 0; i -= 4) {
- UartPutc(digits[(v >> i) & 0xF]);
- }
-}
+void UartPutHex32(u32 v);
diff --git a/Source/hoc-clk/bpmpfw/source/sensors.cpp b/Source/hoc-clk/bpmpfw/source/sensors.cpp
new file mode 100644
index 00000000..bd2af778
--- /dev/null
+++ b/Source/hoc-clk/bpmpfw/source/sensors.cpp
@@ -0,0 +1,29 @@
+/*
+ * 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 "sensors.hpp"
+
+s32 TranslateSocthermTemp(u16 val) {
+ s32 t = ((val >> 8) & 0xFF) * 1000;
+ if (val & (1u << 7)) {
+ t += 500;
+ }
+ if (val & (1u << 0)) {
+ t = -t;
+ }
+ return t;
+}
diff --git a/Source/hoc-clk/bpmpfw/source/sensors.hpp b/Source/hoc-clk/bpmpfw/source/sensors.hpp
index 64aad219..1c101a5d 100644
--- a/Source/hoc-clk/bpmpfw/source/sensors.hpp
+++ b/Source/hoc-clk/bpmpfw/source/sensors.hpp
@@ -22,13 +22,4 @@ constexpr u32 SocthermBase = 0x700E2000;
constexpr u32 SocthermSensorTemp1 = 0x1C8;
constexpr u32 SocthermSensorTemp2 = 0x1CC;
-inline s32 TranslateSocthermTemp(u16 val) {
- s32 t = ((val >> 8) & 0xFF) * 1000;
- if (val & (1u << 7)) {
- t += 500;
- }
- if (val & (1u << 0)) {
- t = -t;
- }
- return t;
-}
+s32 TranslateSocthermTemp(u16 val);