mirror of
https://github.com/vortexgpgpu/vortex.git
synced 2025-04-23 05:17:45 -04:00
simx 64-bit addressing fixes
This commit is contained in:
parent
39ef09be1d
commit
5bd6561514
15 changed files with 84 additions and 54 deletions
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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];
|
||||
|
|
|
@ -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_;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -108,7 +108,7 @@ public:
|
|||
return dcrs_;
|
||||
}
|
||||
|
||||
uint32_t getIRegValue(int reg) const {
|
||||
Word getIRegValue(int reg) const {
|
||||
return warps_.at(0)->getIRegValue(reg);
|
||||
}
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue