Skip to content

Commit 00d3c8f

Browse files
authored
Merge pull request #46 from vidas/esrs-assorted
[sw-sysemu] Assorted fixes to ESRs in Erbium
2 parents 353f20e + 90d70d9 commit 00d3c8f

File tree

7 files changed

+55
-50
lines changed

7 files changed

+55
-50
lines changed

sw-sysemu/debugmodule.cpp

Lines changed: 2 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -126,20 +126,13 @@ void System::write_dmctrl(uint32_t value)
126126
return;
127127
}
128128

129-
// resumereq goes from 1 to 0: clear HASTATUS0.resumeack
130-
if (RESUMEREQ(oldvalue) == 1 && RESUMEREQ(newvalue) == 0) {
131-
LOG_AGENT(DEBUG, noagent, "%s", "dmctrl: clear HASTATUS0.resumeack");
132-
for (unsigned neigh = 0; neigh < num_minion_neighs; ++neigh) {
133-
const uint64_t mask = selected_neigh_harts(neigh);
134-
neigh_esrs[neigh].hastatus0 &= ~(mask << 32) | ~(0xFFFFull << 32);
135-
}
136-
}
137-
138129
// haltreq is set: halt selected harts
139130
if (HALTREQ(newvalue)) {
140131
LOG_AGENT(DEBUG, noagent, "%s", "dmctrl: halt harts");
141132
// NB: This will also update HASTATUS0
142133
for_each_selected([](Hart& hart) { hart.enter_debug_mode(Debug_entry::Cause::haltreq); });
134+
// NB: haltreq==0 (clear halt request) is not handled because halting is
135+
// atomic in the emulator - there is no pending request to cancel.
143136
return;
144137
}
145138

sw-sysemu/emu_defines.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ namespace bemu {
127127
// Main memory size (up to 32GiB)
128128
//
129129
#define EMU_DRAM_SIZE (32ULL*1024ULL*1024ULL*1024ULL)
130+
#define EMU_HAS_HIGH_MEMORY 1
130131

131132
#else
132133
#error "Architecture unspecified."

sw-sysemu/esrs.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ struct neigh_esrs_t {
7676
uint16_t texture_control;
7777
uint16_t texture_status;
7878
uint8_t icache_err_log_ctl;
79-
uint8_t mprot;
79+
uint16_t mprot;
8080
uint8_t neigh_chicken;
8181
uint8_t vmspagesize;
8282
bool dummy2;
@@ -156,6 +156,7 @@ struct shire_other_esrs_t {
156156
uint16_t shire_dll_auto_config;
157157
uint16_t shire_power_ctrl;
158158
uint16_t clk_gate_ctrl;
159+
uint8_t debug_clk_gate_ctrl;
159160
uint8_t minion_feature;
160161
uint8_t shire_ctrl_clockmux;
161162
uint8_t shire_channel_eco_ctl;

sw-sysemu/esrs_er.cpp

Lines changed: 11 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -199,12 +199,11 @@ void shire_other_esrs_t::cold_reset(unsigned shireid)
199199
{
200200
(void) shireid;
201201
minion_feature = 0x01;
202-
thread0_disable = 0xFE; // Can be overriden by OTP(?)
202+
thread0_disable = 0xFE; // Only start minion 0 hart 0.
203203
thread1_disable = 0xFF;
204204
mtime_local_target = 0;
205205
clk_gate_ctrl = 0;
206-
// TODO: no implemented yet
207-
// debug_clk_gate_ctrl = 0;
206+
debug_clk_gate_ctrl = 0;
208207
// time_config = 0x28;
209208
// sm_config = 0;
210209
}
@@ -386,22 +385,22 @@ uint64_t System::esr_read(const Agent& agent, uint64_t addr)
386385
case ESR_CLK_GATE_CTRL:
387386
return shire_other_esrs[shire].clk_gate_ctrl;
388387
case ESR_DEBUG_CLK_GATE_CTRL:
389-
// TODO: new, no spec
390-
return 0;
388+
return shire_other_esrs[shire].debug_clk_gate_ctrl;
391389
case ESR_DMCTRL:
392390
return agent.chip->read_dmctrl();
393391
case ESR_SM_CONFIG:
394-
// TODO: implement Status Monitor in debug module
392+
// Status Monitor not implemented.
395393
return 0;
396394
case ESR_SM_TRIGGER:
395+
// Status Monitor not implemented.
397396
return 0; // WARL
398397
case ESR_SM_MATCH:
399398
case ESR_SM_FILTER0:
400399
case ESR_SM_FILTER1:
401400
case ESR_SM_FILTER2:
402401
case ESR_SM_DATA0:
403402
case ESR_SM_DATA1:
404-
// TODO: implement Status Monitor in debug module
403+
// Status Monitor not implemented.
405404
return 0;
406405
}
407406
WARN_AGENT(esrs, agent, "Read unknown shire_other ESR S%u:0x%" PRIx64, shireid(shire), esr);
@@ -683,27 +682,18 @@ void System::esr_write(const Agent& agent, uint64_t addr, uint64_t value)
683682
shireid(shire), shire_other_esrs[shire].clk_gate_ctrl);
684683
return;
685684
case ESR_DEBUG_CLK_GATE_CTRL:
686-
// TODO: implement
687-
// shire_other_esrs[shire].debug_clk_gate_ctrl = uint8_t(value & 0x2);
688-
// LOG_AGENT(DEBUG, agent, "S%u:debug_clk_gate_ctrl = 0x%" PRIx8,
689-
// shireid(shire), shire_other_esrs[shire].debug_clk_gate_ctrl);
685+
shire_other_esrs[shire].debug_clk_gate_ctrl = uint8_t(value & 0x1);
686+
LOG_AGENT(DEBUG, agent, "S%u:debug_clk_gate_ctrl = 0x%" PRIx8,
687+
shireid(shire), shire_other_esrs[shire].debug_clk_gate_ctrl);
690688
return;
691689
case ESR_DMCTRL:
692690
agent.chip->write_dmctrl(uint32_t(value & 0xF400'000F));
693691
LOG_AGENT(DEBUG, agent, "S%u:dmctrl = 0x%" PRIx32,
694692
shireid(shire), uint32_t(value & 0xF400'000F));
695693
return;
696694
case ESR_SM_CONFIG:
697-
// TODO: implement Status Monitor in debug module
698-
// shire_other_esrs[shire].sm_config = uint16_t(value & 0xFFF);
699-
// LOG_AGENT(DEBUG, agent, "S%u:sm_config = 0x%" PRIx16,
700-
// shireid(shire), shire_other_esrs[shire].sm_config);
701-
return;
702695
case ESR_SM_TRIGGER:
703-
// TODO: implement Status Monitor in debug module
704-
// shire_other_esrs[shire].sm_trigger = uint8_t(value & 0x1);
705-
// LOG_AGENT(DEBUG, agent, "S%u:sm_trigger = 0x%" PRIx8,
706-
// shireid(shire), shire_other_esrs[shire].sm_trigger);
696+
// No-op - emulator has no low level state information.
707697
return;
708698
}
709699
WARN_AGENT(esrs, agent, "Write unknown shire_other ESR S%u:0x%" PRIx64, shireid(shire), esr);
@@ -754,7 +744,7 @@ void System::write_icache_prefetch(Privilege /*privilege*/, unsigned shire, uint
754744
(void)(value);
755745
#else
756746
if (!shire_other_esrs[shire].icache_prefetch_active) {
757-
bool active = ((value >> 48) & 0xF) && shire_other_esrs[shire].shire_coop_mode;
747+
bool active = shire_other_esrs[shire].shire_coop_mode;
758748
shire_other_esrs[shire].icache_prefetch_active = active;
759749
}
760750
#endif

sw-sysemu/memory/erbium/main_memory.cpp

Lines changed: 6 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,19 +13,16 @@ namespace bemu {
1313

1414
void MainMemory::reset()
1515
{
16-
size_t pos = 0;
17-
18-
regions[pos++].reset(new SysregsEr<erbreg_base>());
19-
regions[pos++].reset(new DenseRegion<bootrom_base, 8_KiB, false>());
20-
regions[pos++].reset(new DenseRegion<sram_base, 2_KiB>());
21-
regions[pos++].reset(new DenseRegion<dram_base, 16_MiB>());
22-
// TODO:
23-
// regions[pos++].reset(new SysregRegion<sysreg_base, 16_MiB>());
16+
regions[erbreg_idx].reset(new SysregsEr<region_bases[erbreg_idx]>());
17+
regions[bootrom_idx].reset(new DenseRegion<region_bases[bootrom_idx], region_sizes[bootrom_idx], false>());
18+
regions[sram_idx].reset(new DenseRegion<region_bases[sram_idx], region_sizes[sram_idx]>());
19+
regions[dram_idx].reset(new DenseRegion<region_bases[dram_idx], region_sizes[dram_idx]>());
20+
regions[sysreg_idx].reset(new SysregRegion<region_bases[sysreg_idx], region_sizes[sysreg_idx]>());
2421
}
2522

2623
void MainMemory::wdt_clock_tick(const Agent& agent, uint64_t cycle)
2724
{
28-
auto ptr = dynamic_cast<SysregsEr<erbreg_base>*>(regions[0].get());
25+
auto ptr = dynamic_cast<SysregsEr<region_bases[erbreg_idx]>*>(regions[erbreg_idx].get());
2926
ptr->wdt_clock_tick(agent, cycle);
3027
}
3128

sw-sysemu/memory/erbium/main_memory.h

Lines changed: 27 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -41,17 +41,34 @@ struct MainMemory {
4141
using pointer = typename MemoryRegion::pointer;
4242
using const_pointer = typename MemoryRegion::const_pointer;
4343

44-
// ----- Types -----
45-
46-
enum : unsigned long long {
47-
// base addresses for the various regions of the address space
48-
erbreg_base = 0x0002000000ULL,
49-
bootrom_base = 0x000200A000ULL,
50-
sram_base = 0x000200E000ULL,
51-
dram_base = 0x0040000000ULL, /* Actually MRAM */
52-
sysreg_base = 0x0080000000ULL,
44+
private:
45+
enum : unsigned {
46+
erbreg_idx,
47+
bootrom_idx,
48+
sram_idx,
49+
dram_idx,
50+
sysreg_idx,
51+
52+
REGION_COUNT
5353
};
5454

55+
constexpr static uint64_t region_bases[REGION_COUNT] = {
56+
/* erbreg */ 0x00'0200'0000ull,
57+
/* bootrom */ 0x00'0200'A000ull,
58+
/* sram */ 0x00'0200'E000ull,
59+
/* dram */ 0x00'4000'0000ull, /* Actually MRAM */
60+
/* sysreg */ 0x00'8000'0000ull,
61+
};
62+
63+
constexpr static size_t region_sizes[REGION_COUNT] = {
64+
/* erbreg */ 4_KiB,
65+
/* bootrom */ 8_KiB,
66+
/* sram */ 2_KiB,
67+
/* dram */ 16_MiB,
68+
/* sysreg */ 16_MiB,
69+
};
70+
71+
public:
5572
// ----- Public methods -----
5673

5774
void reset();
@@ -107,7 +124,7 @@ struct MainMemory {
107124
}
108125

109126
// This array must be sorted by region base address
110-
std::array<std::unique_ptr<MemoryRegion>, 4> regions{};
127+
std::array<std::unique_ptr<MemoryRegion>, REGION_COUNT> regions{};
111128
};
112129

113130

sw-sysemu/system.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -592,8 +592,11 @@ void System::load_elf(std::istream& stream)
592592
idx, sec->get_name().c_str(), vma, lma, sec->get_size(),
593593
sec->get_type(), sec->get_flags());
594594

595+
#if EMU_HAS_HIGH_MEMORY
596+
// TODO: remove magic constant
595597
if (lma >= MainMemory::dram_base)
596598
lma &= ~0x4000000000ULL;
599+
#endif
597600

598601
memory.init(noagent, lma, sec->get_size(), sec->get_data());
599602
}
@@ -624,8 +627,11 @@ void System::load_raw(const char* filename, unsigned long long addr)
624627
std::streamsize count = file.gcount();
625628
if (count <= 0)
626629
break;
630+
#if EMU_HAS_HIGH_MEMORY
631+
// TODO: remove magic constant
627632
if (addr >= MainMemory::dram_base)
628633
addr &= ~0x4000000000ULL;
634+
#endif
629635
memory.init(noagent, addr, count, reinterpret_cast<MainMemory::const_pointer>(fbuf));
630636
addr += count;
631637
}

0 commit comments

Comments
 (0)