riscv: misc code cleanup (now I can actually focus on stuff!)

This commit is contained in:
Lily Tsuru 2023-07-24 00:20:40 -04:00
parent 878990a921
commit 7af85f5601
4 changed files with 24 additions and 47 deletions

View File

@ -23,7 +23,7 @@ namespace riscv {
constexpr void Reset() { constexpr void Reset() {
// Initalize some state. We're cool like that :) // Initalize some state. We're cool like that :)
pc = 0x80000000; pc = 0x80000000;
gpr[10] = 0x0; // HART id gpr[Gpr::A0] = 0x0; // HART id
extraflags |= 3; // Start in Machine mode extraflags |= 3; // Start in Machine mode
} }
@ -57,9 +57,7 @@ namespace riscv {
/// Set by [CPU::Trap] for the trap code. /// Set by [CPU::Trap] for the trap code.
u32 trapCode { 0 }; u32 trapCode { 0 };
u32 Step(u32 instCount); void Step(u32 instCount);
// todo: counters for chrono/inst count.
}; };
} // namespace riscv } // namespace riscv

View File

@ -1,17 +1,12 @@
//! Portions of this code are copyright 2022 Charles Lohr (CNLohr). //! Portions of this code are copyright 2022 Charles Lohr (CNLohr),
//! from [mini-rv32ima](https://github.com/cnlohr/mini-rv32ima).
#include <riscv/Bus.hpp> #include <riscv/Bus.hpp>
#include <riscv/CPU.hpp> #include <riscv/CPU.hpp>
#include <lucore/Logger.hpp>
namespace riscv { namespace riscv {
// Not needed
//constexpr static Address RamImageOffset = 0x80000000;
void CPU::Clock() { void CPU::Clock() {
// do the thing
Step(1024); Step(1024);
} }
@ -37,14 +32,14 @@ namespace riscv {
// trapCode = 0x80000007; // trapCode = 0x80000007;
} }
u32 CPU::Step(u32 instCount) { void CPU::Step(u32 instCount) {
auto interruptsInFlight = [&]() { auto interruptsInFlight = [&]() {
return (mip & (1 << 7) /*|| mip & (1 << 11)*/) && (mie & (1 << 7) /*|| mie & (1 << 11)*/) && (mstatus & 0x8 /*mie*/); return (mip & (1 << 7) /*|| mip & (1 << 11)*/) && (mie & (1 << 7) /*|| mie & (1 << 11)*/) && (mstatus & 0x8 /*mie*/);
}; };
// Don't run if waiting for an interrupt // Don't run if waiting for an interrupt
if(extraflags & 4) if(extraflags & 4)
return 1; return;
u32 rdid = 0; u32 rdid = 0;
u32 rval = 0; u32 rval = 0;
@ -57,10 +52,7 @@ namespace riscv {
rdid = 0; // force it to gpr 0 (zero), which is not writable rdid = 0; // force it to gpr 0 (zero), which is not writable
cycle++; cycle++;
//lucore::LogInfo("[CPU] pc @ 0x{:08x}", pc);
if((pc & 3)) { if((pc & 3)) {
lucore::LogWarning("[CPU] misaligned jump target.. 0x{:08x}", pc);
Trap(TrapCode::InstructionAddressMisaligned); Trap(TrapCode::InstructionAddressMisaligned);
break; break;
} else { } else {
@ -75,8 +67,6 @@ namespace riscv {
break; break;
} }
//lucore::LogInfo("[CPU] fetch 0x{:08x} 0x{:08x}", pc, ir);
rdid = (ir >> 7) & 0x1f; rdid = (ir >> 7) & 0x1f;
// Do the thing! // Do the thing!
@ -96,7 +86,6 @@ namespace riscv {
if(reladdy & 0x00100000) if(reladdy & 0x00100000)
reladdy |= 0xffe00000; reladdy |= 0xffe00000;
rval = pc + 4; rval = pc + 4;
//lucore::LogInfo("j/al 0x{:08x}", pc + reladdy);
pc = pc + reladdy - 4; pc = pc + reladdy - 4;
break; break;
} }
@ -106,7 +95,6 @@ namespace riscv {
i32 imm_se = imm | ((imm & 0x800) ? 0xfffff000 : 0); i32 imm_se = imm | ((imm & 0x800) ? 0xfffff000 : 0);
rval = pc + 4; rval = pc + 4;
pc = ((gpr[((ir >> 15) & 0x1f)] + imm_se) & ~1) - 4; pc = ((gpr[((ir >> 15) & 0x1f)] + imm_se) & ~1) - 4;
//lucore::LogInfo("jalr {}, 0x{:08x}", RegName(static_cast<Gpr>(((ir >> 15) & 0x1f))), ((gpr[((ir >> 15) & 0x1f)] + imm_se) & ~1) - 4);
break; break;
} }
@ -140,12 +128,12 @@ namespace riscv {
break; break;
case 6: // BLTU case 6: // BLTU
if((uint32_t)rs1 < (uint32_t)rs2) if((u32)rs1 < (u32)rs2)
pc = immm4; pc = immm4;
break; break;
case 7: // BGEU case 7: // BGEU
if((uint32_t)rs1 >= (uint32_t)rs2) if((u32)rs1 >= (u32)rs2)
pc = immm4; pc = immm4;
break; break;
default: default:
@ -423,7 +411,7 @@ namespace riscv {
mstatus |= 8; // Enable interrupts mstatus |= 8; // Enable interrupts
extraflags |= 4; // Set inernal WFI bit extraflags |= 4; // Set inernal WFI bit
this->pc = pc + 4; this->pc = pc + 4;
return 1; return;
} else if(((csrno & 0xff) == 0x02)) { // MRET } else if(((csrno & 0xff) == 0x02)) { // MRET
// https://raw.githubusercontent.com/riscv/virtual-memory/main/specs/663-Svpbmt.pdf // https://raw.githubusercontent.com/riscv/virtual-memory/main/specs/663-Svpbmt.pdf
// Table 7.6. MRET then in mstatus/mstatush sets MPV=0, MPP=0, // Table 7.6. MRET then in mstatus/mstatush sets MPV=0, MPP=0,
@ -461,12 +449,6 @@ namespace riscv {
u32 rs2 = gpr[(ir >> 20) & 0x1f]; u32 rs2 = gpr[(ir >> 20) & 0x1f];
u32 irmid = (ir >> 27) & 0x1f; u32 irmid = (ir >> 27) & 0x1f;
// rs1 -= MINIRV32_RAM_IMAGE_OFFSET;
//rs1 -= RamImageOffset;
// We don't implement load/store from UART or CLNT with RV32A here.
rval = bus->PeekWord(rs1); rval = bus->PeekWord(rs1);
if(trapped) { if(trapped) {
rval = rs1; // + RamImageOffset; rval = rs1; // + RamImageOffset;
@ -528,11 +510,8 @@ namespace riscv {
if(trapped) if(trapped)
break; break;
if(rdid) { if(rdid)
//lucore::LogInfo("writing register {} -> 0x{:08x}", RegName(static_cast<Gpr>(rdid)), rval);
gpr[rdid] = rval; gpr[rdid] = rval;
}
pc += 4; pc += 4;
} }
} }
@ -550,13 +529,11 @@ namespace riscv {
else else
mtval = pc; mtval = pc;
} }
mepc = pc; // TRICKY: The kernel advances mepc automatically. mepc = pc; // Interrupt handler will advance mepc
// CSR( mstatus ) & 8 = MIE, & 0x80 = MPIE
// On an interrupt, the system moves current MIE into MPIE
mstatus = (mstatus & 0x08) << 4 | ((extraflags)&3) << 11; mstatus = (mstatus & 0x08) << 4 | ((extraflags)&3) << 11;
pc = (mtvec - 4); pc = (mtvec - 4);
// If trapping, always enter machine mode. // Always enter machine mode when trapping.
extraflags |= 3; extraflags |= 3;
// Reset trap flags // Reset trap flags
@ -568,8 +545,6 @@ namespace riscv {
if(cyclel > cycle) if(cyclel > cycle)
cycleh++; cycleh++;
cyclel = cycle; cyclel = cycle;
pc = pc;
return 0;
} }
} // namespace riscv } // namespace riscv

View File

@ -5,18 +5,21 @@ namespace riscv {
System* System::Create(Address ramSize) { System* System::Create(Address ramSize) {
auto* system = new System; auto* system = new System;
// create all the devices we require.
system->bus = new Bus(); system->bus = new Bus();
system->cpu = new CPU(); system->cpu = new CPU();
system->ram = new devices::RamDevice(0x80000000, ramSize); system->ram = new devices::RamDevice(0x80000000, ramSize);
system->clnt = new devices::ClntDevice(); system->clnt = new devices::ClntDevice();
system->syscon = new devices::SysconDevice(system); system->syscon = new devices::SysconDevice(system);
// techinically this is done on construction but lets be hard about it
system->cpu->Reset(); system->cpu->Reset();
system->bus->AttachDevice(system->cpu); // attach everything into the bus
system->bus->AttachDevice(system->clnt); if(!system->bus->AttachDevice(system->cpu)) return nullptr;
system->bus->AttachDevice(system->syscon); if(!system->bus->AttachDevice(system->clnt)) return nullptr;
system->bus->AttachDevice(system->ram); if(!system->bus->AttachDevice(system->syscon)) return nullptr;
if(!system->bus->AttachDevice(system->ram)) return nullptr;
return system; return system;
} }

View File

@ -42,6 +42,7 @@ int main(int argc, char** argv) {
// 128 KB of ram. Won't be enough to boot linux but should be good enough to test most baremetal apps // 128 KB of ram. Won't be enough to boot linux but should be good enough to test most baremetal apps
auto system = riscv::System::Create(128 * 1024); auto system = riscv::System::Create(128 * 1024);
LUCORE_CHECK(system, "could not create system for some reason.");
// Attach our UART device // Attach our UART device
system->bus->AttachDevice(new SimpleUartDevice); system->bus->AttachDevice(new SimpleUartDevice);