simx 64-bit addressing fixes

This commit is contained in:
Blaise Tine 2023-05-18 01:58:23 -04:00
parent 39ef09be1d
commit 5bd6561514
15 changed files with 84 additions and 54 deletions

View file

@ -37,6 +37,7 @@ endif
CFLAGS += -O3 -mcmodel=medany -fno-rtti -fno-exceptions -nostartfiles -fdata-sections -ffunction-sections
CFLAGS += -I./include -I../hw
CFLAGS += -DXLEN_$(XLEN)
PROJECT = libvortexrt

View file

@ -1,15 +1,25 @@
#include <VX_config.h>
#include <VX_types.h>
.type vx_serial, @function
.global vx_serial
vx_serial:
addi sp, sp, -24
#if (XLEN == 64)
sd ra, 40(sp)
sd s4, 32(sp)
sd s3, 24(sp)
sd s2, 16(sp)
sd s1, 8(sp)
sd s0, 0(sp)
#else
sw ra, 20(sp)
sw s4, 16(sp)
sw s3, 12(sp)
sw s2, 8(sp)
sw s1, 4(sp)
sw s0, 0(sp)
#endif
mv s4, a0 # s4 <- callback
mv s3, a1 # s3 <- arg
csrr s2, CSR_NT # s2 <- NT
@ -26,12 +36,21 @@ label_join:
.insn r 0x0b, 3, 0, x0, x0, x0 # join
addi s0, s0, 1 # index++
blt s0, s2, label_loop # loop back
#if (XLEN == 64)
ld ra, 40(sp)
ld s4, 32(sp)
ld s3, 24(sp)
ld s2, 16(sp)
ld s1, 8(sp)
ld s0, 0(sp)
#else
lw ra, 20(sp)
lw s4, 16(sp)
lw s3, 12(sp)
lw s2, 8(sp)
lw s1, 4(sp)
lw s0, 0(sp)
#endif
addi sp, sp, 24
ret

View file

@ -74,7 +74,14 @@ init_regs:
.option pop
# set stack pointer register
#if (XLEN == 64)
li a0, (STACK_BASE_ADDR >> 32) # load upper 32 bits stack base address
slli a0, a0, 32 # shift left 32 bits
li sp, (STACK_BASE_ADDR & 0xffffffff) # load lower 32 bits stack base address
or sp, sp, a0 # combine upper and lower bits
#else
li sp, STACK_BASE_ADDR # load stack base address
#endif
csrr a0, CSR_GTID # get global thread id
sll a1, a0, STACK_LOG2_SIZE
sub sp, sp, a1

View file

@ -20,8 +20,9 @@ RamMemDevice::RamMemDevice(const char *filename, uint32_t wordSize)
contents_.push_back(input.get());
} while (input);
while (contents_.size() & (wordSize-1))
while (contents_.size() & (wordSize-1)) {
contents_.push_back(0x00);
}
}
RamMemDevice::RamMemDevice(uint64_t size, uint32_t wordSize)
@ -29,7 +30,7 @@ RamMemDevice::RamMemDevice(uint64_t size, uint32_t wordSize)
, wordSize_(wordSize)
{}
void RamMemDevice::read(void *data, uint64_t addr, uint64_t size) {
void RamMemDevice::read(void* data, uint64_t addr, uint64_t size) {
auto addr_end = addr + size;
if ((addr & (wordSize_-1))
|| (addr_end & (wordSize_-1))
@ -44,7 +45,7 @@ void RamMemDevice::read(void *data, uint64_t addr, uint64_t size) {
}
}
void RamMemDevice::write(const void *data, uint64_t addr, uint64_t size) {
void RamMemDevice::write(const void* data, uint64_t addr, uint64_t size) {
auto addr_end = addr + size;
if ((addr & (wordSize_-1))
|| (addr_end & (wordSize_-1))
@ -68,26 +69,26 @@ void RomMemDevice::write(const void* /*data*/, uint64_t /*addr*/, uint64_t /*siz
///////////////////////////////////////////////////////////////////////////////
bool MemoryUnit::ADecoder::lookup(uint64_t a, uint32_t wordSize, mem_accessor_t* ma) {
uint64_t e = a + (wordSize - 1);
assert(e >= a);
bool MemoryUnit::ADecoder::lookup(uint64_t addr, uint32_t wordSize, mem_accessor_t* ma) {
uint64_t end = addr + (wordSize - 1);
assert(end >= addr);
for (auto iter = entries_.rbegin(), iterE = entries_.rend(); iter != iterE; ++iter) {
if (a >= iter->start && e <= iter->end) {
if (addr >= iter->start && end <= iter->end) {
ma->md = iter->md;
ma->addr = a - iter->start;
ma->addr = addr - iter->start;
return true;
}
}
return false;
}
void MemoryUnit::ADecoder::map(uint64_t a, uint64_t e, MemDevice &m) {
assert(e >= a);
entry_t entry{&m, a, e};
void MemoryUnit::ADecoder::map(uint64_t start, uint64_t end, MemDevice &md) {
assert(end >= start);
entry_t entry{&md, start, end};
entries_.emplace_back(entry);
}
void MemoryUnit::ADecoder::read(void *data, uint64_t addr, uint64_t size) {
void MemoryUnit::ADecoder::read(void* data, uint64_t addr, uint64_t size) {
mem_accessor_t ma;
if (!this->lookup(addr, size, &ma)) {
std::cout << "lookup of 0x" << std::hex << addr << " failed.\n";
@ -96,7 +97,7 @@ void MemoryUnit::ADecoder::read(void *data, uint64_t addr, uint64_t size) {
ma.md->read(data, ma.addr, size);
}
void MemoryUnit::ADecoder::write(const void *data, uint64_t addr, uint64_t size) {
void MemoryUnit::ADecoder::write(const void* data, uint64_t addr, uint64_t size) {
mem_accessor_t ma;
if (!this->lookup(addr, size, &ma)) {
std::cout << "lookup of 0x" << std::hex << addr << " failed.\n";
@ -132,7 +133,7 @@ MemoryUnit::TLBEntry MemoryUnit::tlbLookup(uint64_t vAddr, uint32_t flagMask) {
}
}
void MemoryUnit::read(void *data, uint64_t addr, uint64_t size, bool sup) {
void MemoryUnit::read(void* data, uint64_t addr, uint64_t size, bool sup) {
uint64_t pAddr;
if (enableVM_) {
uint32_t flagMask = sup ? 8 : 1;
@ -144,7 +145,7 @@ void MemoryUnit::read(void *data, uint64_t addr, uint64_t size, bool sup) {
return decoder_.read(data, pAddr, size);
}
void MemoryUnit::write(const void *data, uint64_t addr, uint64_t size, bool sup) {
void MemoryUnit::write(const void* data, uint64_t addr, uint64_t size, bool sup) {
uint64_t pAddr;
if (enableVM_) {
uint32_t flagMask = sup ? 16 : 2;
@ -169,7 +170,6 @@ void MemoryUnit::tlbRm(uint64_t va) {
RAM::RAM(uint32_t page_size, uint64_t capacity)
: capacity_(capacity)
, size_(0)
, page_bits_(log2ceil(page_size))
, last_page_(nullptr)
, last_page_index_(0) {
@ -223,14 +223,14 @@ uint8_t *RAM::get(uint64_t address) const {
return page + page_offset;
}
void RAM::read(void *data, uint64_t addr, uint64_t size) {
void RAM::read(void* data, uint64_t addr, uint64_t size) {
uint8_t* d = (uint8_t*)data;
for (uint64_t i = 0; i < size; i++) {
d[i] = *this->get(addr + i);
}
}
void RAM::write(const void *data, uint64_t addr, uint64_t size) {
void RAM::write(const void* data, uint64_t addr, uint64_t size) {
const uint8_t* d = (const uint8_t*)data;
for (uint64_t i = 0; i < size; i++) {
*this->get(addr + i) = d[i];

View file

@ -13,8 +13,8 @@ class MemDevice {
public:
virtual ~MemDevice() {}
virtual uint64_t size() const = 0;
virtual void read(void *data, uint64_t addr, uint64_t size) = 0;
virtual void write(const void *data, uint64_t addr, uint64_t size) = 0;
virtual void read(void* data, uint64_t addr, uint64_t size) = 0;
virtual void write(const void* data, uint64_t addr, uint64_t size) = 0;
};
///////////////////////////////////////////////////////////////////////////////
@ -22,11 +22,11 @@ public:
class RamMemDevice : public MemDevice {
public:
RamMemDevice(uint64_t size, uint32_t wordSize);
RamMemDevice(const char *filename, uint32_t wordSize);
RamMemDevice(const char* filename, uint32_t wordSize);
~RamMemDevice() {}
void read(void *data, uint64_t addr, uint64_t size) override;
void write(const void *data, uint64_t addr, uint64_t size) override;
void read(void* data, uint64_t addr, uint64_t size) override;
void write(const void* data, uint64_t addr, uint64_t size) override;
virtual uint64_t size() const {
return contents_.size();
@ -51,7 +51,7 @@ public:
~RomMemDevice();
void write(const void *data, uint64_t addr, uint64_t size) override;
void write(const void* data, uint64_t addr, uint64_t size) override;
};
///////////////////////////////////////////////////////////////////////////////
@ -64,19 +64,19 @@ public:
: faultAddr(a)
, notFound(nf)
{}
uint64_t faultAddr;
bool notFound;
uint64_t faultAddr;
bool notFound;
};
MemoryUnit(uint64_t pageSize = 0);
void attach(MemDevice &m, uint64_t start, uint64_t end);
void read(void *data, uint64_t addr, uint64_t size, bool sup);
void write(const void *data, uint64_t addr, uint64_t size, bool sup);
void read(void* data, uint64_t addr, uint64_t size, bool sup);
void write(const void* data, uint64_t addr, uint64_t size, bool sup);
void tlbAdd(uint64_t virt, uint64_t phys, uint32_t flags);
void tlbRm(uint64_t va);
void tlbRm(uint64_t vaddr);
void tlbFlush() {
tlb_.clear();
}
@ -86,25 +86,25 @@ private:
public:
ADecoder() {}
void read(void *data, uint64_t addr, uint64_t size);
void write(const void *data, uint64_t addr, uint64_t size);
void read(void* data, uint64_t addr, uint64_t size);
void write(const void* data, uint64_t addr, uint64_t size);
void map(uint64_t start, uint64_t end, MemDevice &md);
private:
struct mem_accessor_t {
MemDevice* md;
uint64_t addr;
MemDevice* md;
uint64_t addr;
};
struct entry_t {
MemDevice *md;
uint64_t start;
uint64_t end;
MemDevice* md;
uint64_t start;
uint64_t end;
};
bool lookup(uint64_t a, uint32_t wordSize, mem_accessor_t*);
bool lookup(uint64_t addr, uint32_t wordSize, mem_accessor_t*);
std::vector<entry_t> entries_;
};
@ -122,9 +122,9 @@ private:
TLBEntry tlbLookup(uint64_t vAddr, uint32_t flagMask);
std::unordered_map<uint64_t, TLBEntry> tlb_;
uint64_t pageSize_;
ADecoder decoder_;
bool enableVM_;
uint64_t pageSize_;
ADecoder decoder_;
bool enableVM_;
};
///////////////////////////////////////////////////////////////////////////////
@ -139,8 +139,8 @@ public:
uint64_t size() const override;
void read(void *data, uint64_t addr, uint64_t size) override;
void write(const void *data, uint64_t addr, uint64_t size) override;
void read(void* data, uint64_t addr, uint64_t size) override;
void write(const void* data, uint64_t addr, uint64_t size) override;
void loadBinImage(const char* filename, uint64_t destination);
void loadHexImage(const char* filename);
@ -158,7 +158,6 @@ private:
uint8_t *get(uint64_t address) const;
uint64_t capacity_;
uint64_t size_;
uint32_t page_bits_;
mutable std::unordered_map<uint64_t, uint8_t*> pages_;
mutable uint8_t* last_page_;

View file

@ -61,7 +61,7 @@ int main(int argc, char **argv) {
// setup base DCRs
processor.write_dcr(DCR_BASE_STARTUP_ADDR0, STARTUP_ADDR & 0xffffffff);
#if XLEN == 64
#if (XLEN == 64)
processor.write_dcr(DCR_BASE_STARTUP_ADDR1, STARTUP_ADDR >> 32);
#endif
processor.write_dcr(DCR_BASE_MPM_CLASS, 0);

View file

@ -273,7 +273,7 @@ bool Cluster::running() const {
return false;
}
bool Cluster::getIRegValue(int* value, int reg) const {
bool Cluster::getIRegValue(Word* value, int reg) const {
for (auto& core : cores_) {
if (core->check_exit()) {
*value = core->getIRegValue(reg);

View file

@ -52,7 +52,7 @@ public:
bool running() const;
bool getIRegValue(int* value, int reg) const;
bool getIRegValue(Word* value, int reg) const;
void bind(SimPort<MemReq>* mem_req_port, SimPort<MemRsp>* mem_rsp_port);

View file

@ -123,7 +123,11 @@ void Core::reset() {
void Core::attach_ram(RAM* ram) {
// bind RAM to memory unit
mmu_.attach(*ram, 0, 0xFFFFFFFF);
#if (XLEN == 64)
mmu_.attach(*ram, 0, 0xFFFFFFFFFFFFFFFF);
#else
mmu_.attach(*ram, 0, 0xFFFFFFFF);
#endif
}
void Core::cout_flush() {

View file

@ -108,7 +108,7 @@ public:
return dcrs_;
}
uint32_t getIRegValue(int reg) const {
Word getIRegValue(int reg) const {
return warps_.at(0)->getIRegValue(reg);
}

View file

@ -78,7 +78,7 @@ int main(int argc, char **argv) {
// setup base DCRs
processor.write_dcr(DCR_BASE_STARTUP_ADDR0, STARTUP_ADDR & 0xffffffff);
#if XLEN == 64
#if (XLEN == 64)
processor.write_dcr(DCR_BASE_STARTUP_ADDR1, STARTUP_ADDR >> 32);
#endif
processor.write_dcr(DCR_BASE_MPM_CLASS, 0);

View file

@ -73,7 +73,7 @@ int ProcessorImpl::run() {
SimPlatform::instance().reset();
this->clear_perf_counters();
bool running;
int exitcode = 0;
Word exitcode = 0;
do {
SimPlatform::instance().tick();
running = false;

View file

@ -13,13 +13,13 @@
namespace vortex {
typedef uint8_t Byte;
#if XLEN == 32
#if (XLEN == 32)
typedef uint32_t Word;
typedef int32_t WordI;
typedef uint64_t DWord;
typedef int64_t DWordI;
typedef uint32_t FWord;
#elif XLEN == 64
#elif (XLEN == 64)
typedef uint64_t Word;
typedef int64_t WordI;
typedef __uint128_t DWord;

View file

@ -24,7 +24,7 @@ Warp::Warp(Core *core, uint32_t warp_id)
void Warp::clear() {
active_ = false;
PC_ = core_->dcrs().base_dcrs.read(DCR_BASE_STARTUP_ADDR0);
#if XLEN == 64
#if (XLEN == 64)
PC_ = (uint64_t(core_->dcrs().base_dcrs.read(DCR_BASE_STARTUP_ADDR1)) << 32) | PC_;
#endif
tmask_.reset();

View file

@ -87,7 +87,7 @@ public:
return 0;
}
uint32_t getIRegValue(uint32_t reg) const {
Word getIRegValue(uint32_t reg) const {
return ireg_file_.at(0).at(reg);
}