Mio: Change the allocation strategy for the auxiliary pointers

This commit is contained in:
Correia 2024-05-17 13:35:44 -03:00
parent bddd6872c6
commit 9df76e3003
3 changed files with 46 additions and 46 deletions

View File

@ -3,50 +3,44 @@
#include <mio/mmu_tlb.h>
namespace cosmic::mio {
TlbCache::TlbCache(std::shared_ptr<GlobalMemory>& global) :
blocks(global) {
blocks(global) {
std::memset(entries.data(), 0, sizeof(entries));
if (!userVtlb) {
userVtlb = new u8*[1024 * 1024];
}
std::memset(userVtlb, 0, sizeof(u8*) * 1024 * 1024);
if (!supervisorVtlb) {
supervisorVtlb = new u8*[1024 * 1024];
}
std::memset(supervisorVtlb, 0, sizeof(u8*) * 1024 * 1024);
if (!kernelVtlb) {
kernelVtlb = new u8*[1024 * 1024];
}
if (!tlbInfo) {
tlbInfo = new TlbInfo[1024 * 1024];
}
std::memset(kernelVtlb, 0, sizeof(u8*) * 1024 * 1024);
std::memset(tlbInfo, 0, sizeof(TlbInfo) * 1024 * 1024);
virtArea.resize(1024 * 1024 * 3);
tlbInfo.resize(1024 * 1024);
userVirt = &virtArea[0];
supervisorVirt = &virtArea[1024 * 1024];
kernelVirt = &virtArea[1024 * 1024 * 2];
virtArea.clear();
tlbInfo.clear();
constexpr u32 unmapStart{0x80000000};
constexpr u32 unmapEnd{0xc0000000};
constexpr u32 kUnmapStart{0x80000000};
constexpr u32 kUnmapEnd{0xc0000000};
// Kernel page segments are not mapped in the TLB; we need to pass physical addresses
// directly to the table entries
for (auto segmentPage{kUnmapStart}; segmentPage != kUnmapEnd; segmentPage += 4096) {
auto kVTable{segmentPage / 4096};
if (kVTable >= 1024 * 1024) {
throw MioErr("Kernel TLB table {} is outside the specified range", kVTable);
for (auto segmentPage{unmapStart}; segmentPage != unmapEnd; segmentPage += 4096) {
auto table{segmentPage / 4096};
if (table >= 1024 * 1024) {
throw MioErr("Kernel TLB table {} is outside the specified range", table);
}
kernelVirt[table] = choiceMemSrc(segmentPage & (0x20000000 - 1));
tlbInfo[table].cacheMode = TlbCacheMode::Uncached;
kernelVtlb[kVTable] = choiceMemSrc(segmentPage & (0x20000000 - 1));
if (segmentPage < 0xa0000000)
tlbInfo[kVTable].cacheMode = TlbCacheMode::Cached;
else
tlbInfo[kVTable].cacheMode = TlbCacheMode::Uncached;
if (segmentPage < 0xa0000000) {
tlbInfo[table].cacheMode = TlbCacheMode::Cached;
}
}
}
TlbCache::~TlbCache() {
delete[] userVtlb;
delete[] supervisorVtlb;
delete[] kernelVtlb;
// delete[] userVirt;
// delete[] supervisorVirt;
// delete[] kernelVirt;
delete[] tlbInfo;
std::vector<TlbInfo> infoEmpty;
tlbInfo.swap(infoEmpty);
}
u8* TlbCache::choiceMemSrc(u32 logicalA) {
u8* mapAddress{};
[[likely]] if (logicalA < 0x10000000) {
@ -59,8 +53,9 @@ namespace cosmic::mio {
}
void TlbCache::tlbChangeModified(u32 page, bool value) {
if (page >= 1024 * 1024)
if (page >= 1024 * 1024) {
throw MioErr("Page {} is outside the range, TLB is missing for this page", page);
}
tlbInfo[page].isModified = value;
}
bool TlbCache::isCached(u32 address) {

View File

@ -5,8 +5,11 @@
#include <mio/blocks.h>
// kuseg | 00000000h-7fffffffh | User, TLB-mapped
// kseg0 | 80000000h-9fffffffh | Kernel, directly-mapped, cached
// kseg1 | a0000000h-bfffffffh | Kernel, directly-mapped, uncached
namespace cosmic::mio {
enum TlbCacheMode : u32 {
Invalid = 0b00,
@ -14,9 +17,10 @@ namespace cosmic::mio {
Cached = 0b11,
UncachedAccelerated = 0b111
};
struct TlbPageEntry {
std::array<TlbCacheMode, 2> cacheMode;
// Scratchpad. When set, the virtual mapping goes to scratchpad instead of main memory
// Scratchpad: When set, the virtual mapping goes to scratchpad instead of main memory
bool isSPad;
std::array<u32, 2> pfn;
std::array<u32, 2> dirty;
@ -39,12 +43,13 @@ namespace cosmic::mio {
public:
TlbCache(std::shared_ptr<GlobalMemory>& global);
~TlbCache();
u8** userVtlb{};
u8** supervisorVtlb{};
u8** kernelVtlb{};
u8** userVirt{};
u8** supervisorVirt{};
u8** kernelVirt{};
TlbInfo* tlbInfo{};
std::array<TlbPageEntry, 48> entries;
std::vector<u8*> virtArea;
std::vector<TlbInfo> tlbInfo;
u8* choiceMemSrc(u32 logicalA);

View File

@ -31,12 +31,12 @@ namespace cosmic::mio {
// We need to use a physical address to map into
u8* phyPtr{choiceMemSrc(physicalAddr + phyInd)};
kernelVtlb[mapFromPage + phyInd] = phyPtr;
kernelVirt[mapFromPage + phyInd] = phyPtr;
if (mapFromAddr < 0x80000000) {
supervisorVtlb[mapFromPage + phyInd] = phyPtr;
userVtlb[mapFromPage + phyInd] = phyPtr;
supervisorVirt[mapFromPage + phyInd] = phyPtr;
userVirt[mapFromPage + phyInd] = phyPtr;
} else if (mapFromAddr >= 0xc0000000 && mapFromAddr < 0xe0000000) {
supervisorVtlb[mapFromPage + phyInd] = phyPtr;
supervisorVirt[mapFromPage + phyInd] = phyPtr;
}
tlbInfo[mapFromPage + phyInd].cacheMode = entry.cacheMode[1];
}
@ -54,9 +54,9 @@ namespace cosmic::mio {
u32 pageIndex{pageRange / 4096};
for (u32 ini{}; ini < pageIndex; ini++) {
kernelVtlb[invAroundHere + ini] = 0;
supervisorVtlb[invAroundHere + ini] = 0;
userVtlb[invAroundHere + ini] = 0;
kernelVirt[invAroundHere + ini] = 0;
supervisorVirt[invAroundHere + ini] = 0;
userVirt[invAroundHere + ini] = 0;
}
}
}