Skip to content

Conversation

nemecad
Copy link

@nemecad nemecad commented Sep 4, 2025

This PR addresses some previous feedback, most notably:

  • Set-associative TLB (machine::TLB): Implements a set-associative Translation Lookaside Buffer (TLB) frontend over physical memory, handling virtual to physical translation, flush, and replacement policy.
  • Pluggable Replacement Policies (machine::TLBPolicy): Abstract TLB replacement policy interface & implementations (RAND, LRU, LFU, PLRU) for set-associative tables.
  • SV32 Page-Table Walker (machine::PageTableWalker): Performs multi-level page-table walks (SV32) in memory to resolve a virtual address to a physical one.
  • Sv32Pte Bitfield Helpers (sv32.h): SV32-specific definitions: page-table entry (PTE) bitfields, shifts/masks, and PTE to physical address helpers.
  • VirtualAddress (virtual_address.h): Lightweight VirtualAddress wrapper offering raw access, alignment checks, arithmetic, and comparisons.
  • Add supervisor CSRs and sstatus handling: supervisor CSRs (sstatus, stvec, sscratch, sepc, scause, stval, satp) and a write handler that presents sstatus as a masked view of mstatus so supervisor-visible bits stay in sync.
  • Store current privilege level in CoreState: tracking of the hart's current privilege level in CoreState so exception/return handling and visualization can read/update it from the central CoreState structure.

Tests:

  • Add SV32 page-table + TLB integration tests: a set of small assembly tests that exercise the SV32 page-table walker, SATP enablement and the new TLB code. The tests create a root page table and map a virtual page at 0xC4000000, then exercise several scenarios. The tests verify page-table walker behaviour, SATP switching and TLB caching/flush logic. Tests were written based on the consultation.

UI Components:

  • Show current privilege level in core state view:
Snímek obrazovky 2025-09-04 115127
  • Virtual memory configuration to NewDialog:
Snímek obrazovky 2025-09-04 115904
  • TLB visualization and statistics dock:
Snímek obrazovky 2025-09-04 115521
  • VM toggle and "As CPU" memory access view:
Snímek obrazovky 2025-09-04 120034

Add tracking of the hart's current privilege level to the core state so code
handling exceptions/returns and visualization can read/update it from the
central CoreState structure.
Add supervisor CSRs (sstatus, stvec, sscratch, sepc, scause, stval, satp)
and a write handler that presents sstatus as a masked view of mstatus so
supervisor-visible bits stay in sync.
Add a configurable TLB and a full SV32 page-table walker.
The walker implements two-level SV32 walks
and raises page-fault exceptions for invalid mappings.
The TLB supports I/D caches, SATP awareness (SATP
writes flush the TLB), and caching of resolved mappings.
Add a set of small assembly tests that exercise the SV32 page-table walker,
SATP enablement and the new TLB code. The tests create a root page
table and map a virtual page at 0xC4000000, then exercise several scenarios.
The tests verify page-table walker behaviour, SATP switching and TLB caching/flush logic.
Tests were written based on the consultation.
@jdupak jdupak self-requested a review September 28, 2025 17:17
windows/tlb/tlbview.h
windows/tlb/tlbview.cpp
windows/tlb/tlbdock.cpp
windows/tlb/tlbdock.h)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does no seem right - source files in icon path.

void NewDialog::vm_enabled_change(bool v) {
if (config->get_vm_enabled() != v) {
config->set_vm_enabled(v);
switch2custom();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nit: please prefer a consistent naming convention switch_to_custom. Also try to think of a more descriptive name or add a comment.

}

TLBViewScene::~TLBViewScene() {
delete[] block;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we make this RAII?

unsigned way_index;
unsigned rows;
QGraphicsSimpleTextItem **validity;
QGraphicsSimpleTextItem **asid;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@nemecad This is an important comment with a more generic theme:
Please avoid using pointer type for arrays at all cost. That is extremely confusing and dangerous. Just use std::vector or std::array. As a rule of thumb, new keyword should be avoided unless it is required by Qt (method that take ownership of the pointer). Such pointers should be marked by the QT_OWNED macro to make it clear.
For owned types that need to be allocated (because of Qt requirements), use Box<T>.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For any class members, please:

  1. prefer value types, if not possible use Box (shorthand for QtScopedPointer), std::vector or std::array.
  2. Prefer references over pointers, of not possible mark them with macro BORROWED (another custom class) or QT_OWNED. And consider adding a comment explaining the lifetime if it is not obvious.

memory/cache/cache_policy.cpp
memory/frontend_memory.cpp
memory/memory_bus.cpp
memory/tlb/tlb.cpp
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Formatting

}

const TLB *Machine::get_tlb_program() const {
return tlb_program ? &*tlb_program : nullptr;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a method for this (get iirc). I am not sure if this is correct.

#include <QObject>
#include <QTimer>
#include <cstdint>
#include <iostream>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?


#include <QMap>
#include <utility>
#include <iostream>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is this needed?

// See example in read_generic for byteswap explanation.
const T swapped_value
= byteswap_if(value, this->simulated_machine_endian != NATIVE_ENDIAN);
if (auto tlb = dynamic_cast<TLB *>(this)) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This makes me worried. This object model does not make much sense. See my comments on the previous PR.

static constexpr uint64_t PHYS_PPN_START = 0x200; // I have noticed that programs are loaded into memory starting at 0x200.

// Sv32Pte wraps the raw 32-bit PTE value and provides helpers to read flags and fields.
// Layout (bit indices):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks :)

@jdupak
Copy link
Collaborator

jdupak commented Sep 28, 2025

I am getting this weird zoom.
image

@jdupak
Copy link
Collaborator

jdupak commented Sep 28, 2025

Notice that address sanitizer is failing in CI.

void tlb_update(unsigned way, unsigned set, bool valid, unsigned asid, quint64 vpn, quint64 phys, bool write);

private:
const machine::TLB *tlb;
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Who owns this pointer?

#include <cstdint>

namespace machine {
enum TLBType { PROGRAM, DATA };
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why does LTB need to know this?

@ppisa
Copy link
Member

ppisa commented Sep 29, 2025

@jdupak thanks for review of interfacing to the memory model architecture.

@ppisa
Copy link
Member

ppisa commented Sep 29, 2025

From my side, the changes to the processor pipeline diagram has been applied directly to the SVG files (src/gui/windows/coreview/schemas), but current design uses DRAW.IO source (extras/core_graphics) as the authoritative source of the pipeline visualization and SVGs are generated from this file. So the commit with SVG change should include extras/core_graphics/diagram.drawio change as well or extras/core_graphics/diagram.drawio change should be commit before SVG files regeneration commit. In long term, I would lean to single SVG file with tags for conditional rendering, but we have not got to that state yet and current solution implemented by @jdupak is based on DRAW.IO and exports controlled by tagging (some documentation there docs/developer/coreview-graphics/using-drawio-diagram.md).

@ppisa
Copy link
Member

ppisa commented Sep 29, 2025

For memory view, I would not complicate it with Show virtual checkbox. I would use only switching between As CPU (VMA), Cached and Raw.

Add privilege level mapping to the GUI so the current hart privilege
(UNPRIV, SUPERV, HYPERV, MACHINE) is displayed in core state visualization.
@nemecad nemecad force-pushed the feature/sv32-vm-tlb-ptw-cleanup branch 4 times, most recently from aa7df79 to 7b06705 Compare October 5, 2025 18:34
Extend NewDialog with controls for virtual memory setup, including TLB
number of sets, associativity, and replacement policy.
Introduce new components for displaying and
tracking TLB state similar to cache. TLBViewBlock and TLBAddressBlock render per-set
and per-way TLB contents, updated on tlb_update signals. TLBViewScene
assembles these views based on associativity. TLBDock integrates into
the GUI, showing hit/miss counts, memory accesses, stall cycles, hit rate,
and speed improvement, with live updates from the TLB.
Introduce an "As CPU (VMA)" access option in the cached access selector to
render memory contents as observed by the CPU through the
frontend interface.
This resolves the incorrect zoom behavior.
Store only `current_privilege_u` in CoreState and use accessor methods
to convert to CSR::PrivilegeLevel. Resolves previous issues with
duplicated privilege representation.
Removes the previous approach; instead, TLBs are now created every time. If virtual memory is disabled, the TLB logic is skipped.
Include new supervisor registers in the expected output to fix CI failures.
@nemecad nemecad force-pushed the feature/sv32-vm-tlb-ptw-cleanup branch from 0bb04d1 to ca4300b Compare October 5, 2025 19:16
@nemecad
Copy link
Author

nemecad commented Oct 5, 2025

@ppisa @jdupak Thank you for your detailed feedback. I appreciate it and have made some changes based on your review. I would be grateful for any further feedback.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants