Browse Source

[fesvr,xcc,sim] fixed multicore sim for akaros

cs250
Andrew Waterman 15 years ago
parent
commit
605d638068
  1. 4
      riscv/applink.cc
  2. 1
      riscv/decode.h
  3. 8
      riscv/insns/mfpcr.h
  4. 4
      riscv/insns/mtpcr.h
  5. 35
      riscv/mmu.h
  6. 78
      riscv/processor.cc
  7. 4
      riscv/processor.h
  8. 43
      riscv/sim.cc
  9. 3
      riscv/sim.h
  10. 2
      riscv/trap.h

4
riscv/applink.cc

@ -112,7 +112,7 @@ int appserver_link_t::wait_for_packet()
demand(p.addr % APP_DATA_ALIGN == 0, "misaligned address");
demand(p.data_size % APP_DATA_ALIGN == 0, "misaligned data");
demand(p.data_size <= APP_MAX_DATA_SIZE, "long read data");
demand(p.addr <= sim->memsz && p.addr+p.data_size <= sim->memsz, "out of bounds");
demand(p.addr <= sim->memsz && p.addr+p.data_size <= sim->memsz, "out of bounds: 0x%llx",(unsigned long long)p.addr);
memcpy(ackpacket.data,sim->mem+p.addr,p.data_size);
ackpacket.data_size = p.data_size;
break;
@ -120,7 +120,7 @@ int appserver_link_t::wait_for_packet()
demand(p.addr % APP_DATA_ALIGN == 0, "misaligned address");
demand(p.data_size % APP_DATA_ALIGN == 0, "misaligned data");
demand(p.data_size <= bytes - offsetof(packet,data), "short packet");
demand(p.addr <= sim->memsz && p.addr+p.data_size <= sim->memsz, "out of bounds");
demand(p.addr <= sim->memsz && p.addr+p.data_size <= sim->memsz, "out of bounds: 0x%llx",(unsigned long long)p.addr);
memcpy(sim->mem+p.addr,p.data,p.data_size);
break;
case APP_CMD_READ_CONTROL_REG:

1
riscv/decode.h

@ -45,6 +45,7 @@ const int JUMP_ALIGN_BITS = 1;
#define SR_VM 0x0000000000010000ULL
#define SR_ZERO ~(SR_ET|SR_EF|SR_EV|SR_EC|SR_PS|SR_S|SR_UX|SR_SX|SR_IM|SR_VM)
#define SR_IM_SHIFT 8
#define IPI_IRQ 5
#define TIMER_IRQ 7
#define CAUSE_EXCCODE 0x000000FF

8
riscv/insns/mfpcr.h

@ -34,10 +34,18 @@ switch(insn.rtype.rs2)
val = mmu.get_ptbr();
break;
case 10:
val = id;
break;
case 11:
val = vecbanks;
break;
case 12:
val = sim->num_cores();
break;
case 17:
fromhost = val = sim->get_fromhost();
break;

4
riscv/insns/mtpcr.h

@ -19,6 +19,10 @@ switch(insn.rtype.rs2)
compare = RS1;
break;
case 7:
sim->send_ipi(RS1);
break;
case 9:
mmu.set_ptbr(RS1);
break;

35
riscv/mmu.h

@ -12,16 +12,16 @@ const reg_t PPN_BITS = 8*sizeof(reg_t) - PGSHIFT;
struct pte_t
{
reg_t v : 1;
reg_t t : 1;
reg_t e : 1;
reg_t r : 1;
reg_t d : 1;
reg_t ux : 1;
reg_t ur : 1;
reg_t uw : 1;
reg_t ur : 1;
reg_t sx : 1;
reg_t sr : 1;
reg_t sw : 1;
reg_t sr : 1;
reg_t unused1 : 2;
reg_t ppn : PPN_BITS;
};
@ -176,10 +176,10 @@ private:
: fetch ? trap_instruction_access_fault
: trap_load_access_fault;
if(!pte.v || tag != (addr >> PGSHIFT))
if(!pte.e || tag != (addr >> PGSHIFT))
{
pte = walk(addr);
if(!pte.v)
if(!pte.e)
throw trap;
tlb_data[idx] = pte;
@ -200,15 +200,15 @@ private:
if(!vm_enabled)
{
pte.v = addr < memsz;
pte.e = 1;
pte.t = 0;
pte.e = addr < memsz;
pte.r = pte.d = 0;
pte.ur = pte.uw = pte.ux = pte.sr = pte.sw = pte.sx = 1;
pte.ppn = addr >> PGSHIFT;
}
else
{
pte.v = 0;
pte.t = pte.e = 0;
int lg_ptesz = sizeof(pte_t) == 4 ? 2
: sizeof(pte_t) == 8 ? 3
@ -217,22 +217,31 @@ private:
reg_t base = ptbr;
for(int i = LEVELS-1; i >= 0; i++)
for(int i = LEVELS-1; i >= 0; i--)
{
reg_t idx = addr >> (PGSHIFT + i*(PGSHIFT - lg_ptesz));
idx &= (1<<(PGSHIFT - lg_ptesz)) - 1;
int idxbits = PGSHIFT - lg_ptesz;
int shift = PGSHIFT + i*idxbits;
reg_t idx = addr >> shift;
idx &= (1 << idxbits) - 1;
reg_t pte_addr = base + idx*sizeof(pte_t);
if(pte_addr >= memsz)
break;
pte = *(pte_t*)(mem+pte_addr);
if(!pte.v || pte.e)
if(pte.e)
{
// if this PTE is from a larger PT, fake a leaf
// PTE so the TLB will work right
reg_t vpn = addr >> PGSHIFT;
pte.ppn += vpn & ((1<<(i*idxbits))-1);
break;
}
if(!pte.t)
break;
base = pte.ppn << PGSHIFT;
}
pte.v &= pte.e;
}
return pte;

78
riscv/processor.cc

@ -15,35 +15,6 @@
processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
: sim(_sim), mmu(_mem,_memsz)
{
memset(XPR,0,sizeof(XPR));
memset(FPR,0,sizeof(FPR));
pc = 0;
evec = 0;
epc = 0;
badvaddr = 0;
cause = 0;
pcr_k0 = 0;
pcr_k1 = 0;
tohost = 0;
fromhost = 0;
count = 0;
compare = 0;
cycle = 0;
set_sr(SR_S | SR_SX); // SX ignored if 64b mode not supported
set_fsr(0);
// vector stuff
vecbanks = 0xff;
vecbanks_count = 8;
utidx = -1;
vlmax = 32;
vl = 0;
nxfpr_bank = 256;
nxpr_use = 32;
nfpr_use = 32;
for (int i=0; i<MAX_UTS; i++)
uts[i] = NULL;
// a few assumptions about endianness, including freg_t union
static_assert(BYTE_ORDER == LITTLE_ENDIAN);
static_assert(sizeof(freg_t) == 8);
@ -56,6 +27,8 @@ processor_t::processor_t(sim_t* _sim, char* _mem, size_t _memsz)
dcsim = NULL;
itlbsim = NULL;
dtlbsim = NULL;
reset();
}
processor_t::~processor_t()
@ -105,6 +78,41 @@ void processor_t::init(uint32_t _id, icsim_t* default_icache,
#endif
}
void processor_t::reset()
{
run = false;
memset(XPR,0,sizeof(XPR));
memset(FPR,0,sizeof(FPR));
pc = 0;
evec = 0;
epc = 0;
badvaddr = 0;
cause = 0;
pcr_k0 = 0;
pcr_k1 = 0;
tohost = 0;
fromhost = 0;
count = 0;
compare = 0;
cycle = 0;
set_sr(SR_S | SR_SX); // SX ignored if 64b mode not supported
set_fsr(0);
// vector stuff
vecbanks = 0xff;
vecbanks_count = 8;
utidx = -1;
vlmax = 32;
vl = 0;
nxfpr_bank = 256;
nxpr_use = 32;
nfpr_use = 32;
for (int i=0; i<MAX_UTS; i++)
uts[i] = NULL;
}
void processor_t::set_sr(uint32_t val)
{
sr = val & ~SR_ZERO;
@ -151,7 +159,7 @@ void processor_t::setvl(int vlapp)
void processor_t::step(size_t n, bool noisy)
{
size_t i = 0;
while(1) try
while(run) try
{
for( ; i < n; i++)
{
@ -188,6 +196,10 @@ void processor_t::step(size_t n, bool noisy)
if (cmd == vt_command_stop)
return;
}
catch(halt_t t)
{
reset();
}
}
void processor_t::take_trap(trap_t t, bool noisy)
@ -206,6 +218,12 @@ void processor_t::take_trap(trap_t t, bool noisy)
badvaddr = mmu.get_badvaddr();
}
void processor_t::deliver_ipi()
{
cause |= 1 << (IPI_IRQ+CAUSE_IP_SHIFT);
run = true;
}
void processor_t::disasm(insn_t insn, reg_t pc)
{
printf("core %3d: 0x%016llx (0x%08x) ",id,(unsigned long long)pc,insn.bits);

4
riscv/processor.h

@ -18,6 +18,7 @@ public:
~processor_t();
void init(uint32_t _id, icsim_t* defualt_icache, icsim_t* default_dcache);
void step(size_t n, bool noisy);
void deliver_ipi();
private:
sim_t* sim;
@ -41,6 +42,8 @@ private:
uint32_t count;
uint32_t compare;
bool run;
// unprivileged control registers
uint32_t fsr;
@ -54,6 +57,7 @@ private:
reg_t cycle;
// functions
void reset();
void set_sr(uint32_t val);
void set_fsr(uint32_t val);
void take_trap(trap_t t, bool noisy);

43
riscv/sim.cc

@ -14,7 +14,7 @@ sim_t::sim_t(int _nprocs, size_t _memsz, appserver_link_t* _applink, icsim_t* de
{
demand(mem != MAP_FAILED, "couldn't allocate target machine's memory");
for(int i = 0; i < (int)procs.size(); i++)
for(int i = 0; i < (int)num_cores(); i++)
procs[i].init(i, default_icache, default_dcache);
applink->init(this);
@ -37,10 +37,19 @@ reg_t sim_t::get_fromhost()
return fromhost;
}
void sim_t::send_ipi(reg_t who)
{
if(who < num_cores())
procs[who].deliver_ipi();
}
void sim_t::run(bool debug)
{
applink->wait_for_start();
// start core 0
send_ipi(0);
while(1)
{
if(!debug)
@ -93,7 +102,7 @@ void sim_t::run(bool debug)
void sim_t::step_all(size_t n, size_t interleave, bool noisy)
{
for(size_t j = 0; j < n; j+=interleave)
for(int i = 0; i < (int)procs.size(); i++)
for(int i = 0; i < (int)num_cores(); i++)
procs[i].step(interleave,noisy);
}
@ -131,7 +140,7 @@ void sim_t::interactive_run_proc(const std::string& cmd, const std::vector<std::
return;
int p = atoi(a[0].c_str());
if(p >= (int)procs.size())
if(p >= (int)num_cores())
return;
if(a.size() == 2)
@ -151,7 +160,7 @@ reg_t sim_t::get_pc(const std::vector<std::string>& args)
throw trap_illegal_instruction;
int p = atoi(args[0].c_str());
if(p >= (int)procs.size())
if(p >= (int)num_cores())
throw trap_illegal_instruction;
return procs[p].pc;
@ -164,7 +173,7 @@ reg_t sim_t::get_reg(const std::vector<std::string>& args)
int p = atoi(args[0].c_str());
int r = atoi(args[1].c_str());
if(p >= (int)procs.size() || r >= NXPR)
if(p >= (int)num_cores() || r >= NXPR)
throw trap_illegal_instruction;
return procs[p].XPR[r];
@ -177,7 +186,7 @@ reg_t sim_t::get_freg(const std::vector<std::string>& args)
int p = atoi(args[0].c_str());
int r = atoi(args[1].c_str());
if(p >= (int)procs.size() || r >= NFPR)
if(p >= (int)num_cores() || r >= NFPR)
throw trap_illegal_instruction;
return procs[p].FPR[r];
@ -189,7 +198,7 @@ reg_t sim_t::get_tohost(const std::vector<std::string>& args)
throw trap_illegal_instruction;
int p = atoi(args[0].c_str());
if(p >= (int)procs.size())
if(p >= (int)num_cores())
throw trap_illegal_instruction;
return procs[p].tohost;
@ -223,14 +232,26 @@ void sim_t::interactive_fregd(const std::string& cmd, const std::vector<std::str
reg_t sim_t::get_mem(const std::vector<std::string>& args)
{
if(args.size() != 1)
if(args.size() != 1 && args.size() != 2)
throw trap_illegal_instruction;
std::string addr_str = args[0];
mmu_t mmu(mem, memsz);
mmu.set_supervisor(true);
if(args.size() == 2)
{
int p = atoi(args[0].c_str());
if(p >= (int)num_cores())
throw trap_illegal_instruction;
mmu.set_vm_enabled(!!(procs[p].sr & SR_VM));
mmu.set_ptbr(procs[p].mmu.get_ptbr());
addr_str = args[1];
}
reg_t addr = strtol(args[0].c_str(),NULL,16), val;
reg_t addr = strtol(addr_str.c_str(),NULL,16), val;
if(addr == LONG_MAX)
addr = strtoul(args[0].c_str(),NULL,16);
addr = strtoul(addr_str.c_str(),NULL,16);
mmu_t mmu(mem,memsz);
switch(addr % 8)
{
case 0:

3
riscv/sim.h

@ -18,6 +18,9 @@ public:
void set_tohost(reg_t val);
reg_t get_fromhost();
void send_ipi(reg_t who);
size_t num_cores() { return procs.size(); }
private:
// global architected state

2
riscv/trap.h

@ -36,6 +36,8 @@ enum trap_t
NUM_TRAPS
};
struct halt_t {}; // thrown to stop the processor from running
extern "C" const char* trap_name(trap_t t);
#endif

Loading…
Cancel
Save