mirror of
https://github.com/shadergz/cosmic-station.git
synced 2024-11-23 06:09:40 +00:00
Mio
: Change the allocation strategy for the auxiliary pointers
This commit is contained in:
parent
bddd6872c6
commit
9df76e3003
@ -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) {
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user