Untitled

 avatar
unknown
plain_text
a year ago
2.9 kB
8
Indexable
#include "VirtualMemory.h"
#include "PhysicalMemory.h"

void clearFrame(uint64_t baseAddress) {
    for (uint64_t i = 0; i < PAGE_SIZE; i++) {
        PMwrite(baseAddress * PAGE_SIZE + i, 0);
    }
}

void VMinitialize() {
    clearFrame(0);
}

bool isValidAddress(uint64_t virtualAddress) {
    return virtualAddress < VIRTUAL_MEMORY_SIZE;
}

int translateAddress(uint64_t virtualAddress, word_t* value, bool isWrite);

int VMread(uint64_t virtualAddress, word_t* value) {
    if (!isValidAddress(virtualAddress) || value == nullptr) {
        return 0;
    }
    return translateAddress(virtualAddress, value, false);
}

int VMwrite(uint64_t virtualAddress, word_t value) {
    if (!isValidAddress(virtualAddress)) {
        return 0;
    }
    return translateAddress(virtualAddress, &value, true);
}

int translateAddress(uint64_t virtualAddress, word_t* value, bool isWrite) {
    uint64_t address = virtualAddress;
    uint64_t offset = address & (PAGE_SIZE - 1);
    uint64_t currentFrame = 0;

    for (int depth = 0; depth < TABLES_DEPTH; depth++) {
        uint64_t index = (address >> (OFFSET_WIDTH + (TABLES_DEPTH - depth - 1) * OFFSET_WIDTH)) & (PAGE_SIZE - 1);
        word_t nextFrame;
        PMread(currentFrame * PAGE_SIZE + index, &nextFrame);

        if (nextFrame == 0) {
            if (!isWrite) {
                return 0; // Page fault or address not mapped
            }
            nextFrame = findFreeFrame(currentFrame, depth);
            if (nextFrame == 0) {
                return 0; // No free frames available
            }
            PMwrite(currentFrame * PAGE_SIZE + index, nextFrame);
            PMclear(nextFrame); // Clear the new frame
        }

        currentFrame = nextFrame;
    }

    uint64_t physicalAddress = currentFrame * PAGE_SIZE + offset;
    if (isWrite) {
        PMwrite(physicalAddress, *value);
    } else {
        PMread(physicalAddress, value);
    }
    return 1;
}

word_t findFreeFrame(uint64_t currentFrame, int depth) {
    bool framesUsed[NUM_FRAMES] = {false};
    markUsedFrames(0, framesUsed);

    for (uint64_t frame = 1; frame < NUM_FRAMES; frame++) {
        if (!framesUsed[frame]) {
            return frame;
        }
    }

    word_t frameToEvict = findFrameToEvict();
    evictFrame(frameToEvict);
    return frameToEvict;
}

void markUsedFrames(uint64_t frame, bool* framesUsed) {
    framesUsed[frame] = true;

    for (uint64_t i = 0; i < PAGE_SIZE; i++) {
        word_t value;
        PMread(frame * PAGE_SIZE + i, &value);
        if (value != 0) {
            markUsedFrames(value, framesUsed);
        }
    }
}

word_t findFrameToEvict() {
    return NUM_FRAMES - 1; // Placeholder: always evict the last frame
}

void evictFrame(word_t frame) {
    PMclear(frame); // Placeholder: clear the frame
}

void PMclear(uint64_t frame) {
    for (uint64_t i = 0; i < PAGE_SIZE; i++) {
        PMwrite(frame * PAGE_SIZE + i, 0);
    }
}
Editor is loading...
Leave a Comment