Skip to content

Commit 56c2f2a

Browse files
author
Jacob Michael Fustos
committed
First attempt at implementing gdb for Vanadis. Testing has been limited, only interger regiseter supported
1 parent a6587a0 commit 56c2f2a

File tree

10 files changed

+2264
-56
lines changed

10 files changed

+2264
-56
lines changed

src/sst/elements/vanadis/decoder/vdecoder.h

+16-2
Original file line numberDiff line numberDiff line change
@@ -214,8 +214,18 @@ class VanadisDecoder : public SST::SubComponent
214214

215215
void setThreadLocalStoragePointer(uint64_t new_tls) { tls_ptr = new_tls; }
216216

217-
uint64_t getThreadLocalStoragePointer() const { return tls_ptr; }
218-
uint64_t getCycleCount() const { return cycle_count; }
217+
static void * getThreadLocalStoragePointer_stub( void * arg_input ) {
218+
VanadisDecoder * me = (VanadisDecoder *)arg_input;
219+
return me->getThreadLocalStoragePointer( );
220+
}
221+
222+
void * getThreadLocalStoragePointer() { return (void *)&tls_ptr; }
223+
static void * getCycleCount_stub( void * arg_input ) {
224+
VanadisDecoder * me = (VanadisDecoder *)arg_input;
225+
return me->getCycleCount( );
226+
}
227+
228+
void * getCycleCount() { return (void *)&cycle_count; }
219229

220230
// VanadisCircularQueue<VanadisInstruction*>* getDecodedQueue() { return
221231
// decoded_q; }
@@ -232,6 +242,10 @@ class VanadisDecoder : public SST::SubComponent
232242
VanadisBranchUnit* getBranchPredictor() { return branch_predictor; }
233243

234244
virtual VanadisCPUOSHandler* getOSHandler() { return os_handler; }
245+
virtual void gdb_tick() {}
246+
virtual void register_pipeline( SST::Output* ) {}
247+
virtual bool is_rob_empty( ) { return false; }
248+
virtual void instruction_to_rob( SST::Output*, VanadisInstruction*, bool *, VanadisInstructionBundle* ) {}
235249

236250
protected:
237251
virtual void clearDecoderAfterMisspeculate(SST::Output* output) {};

src/sst/elements/vanadis/decoder/vmipsdecoder.h

+2-3
Original file line numberDiff line numberDiff line change
@@ -2068,11 +2068,10 @@ class VanadisMIPSDecoder : public VanadisDecoder
20682068

20692069
switch ( rd ) {
20702070
case 29:
2071-
auto thread_call = std::bind(&VanadisMIPSDecoder::getThreadLocalStoragePointer, this);
2072-
20732071
bundle->addInstruction(
20742072
new VanadisSetRegisterByCallInstruction<int32_t>(
2075-
ins_addr, hw_thr, options, target_reg, thread_call));
2073+
ins_addr, hw_thr, options, target_reg,
2074+
&VanadisMIPSDecoder::getThreadLocalStoragePointer_stub, (void *)this));
20762075
insertDecodeFault = false;
20772076
break;
20782077
}

src/sst/elements/vanadis/decoder/vriscv64decoder.cc

+1
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@
1616

1717
#include <sst_config.h>
1818

19+
#include "decoder/vriscv64gdb.h"
1920
#include "decoder/vriscv64decoder.h"
2021

src/sst/elements/vanadis/decoder/vriscv64decoder.h

+74-43
Original file line numberDiff line numberDiff line change
@@ -49,7 +49,7 @@ class VanadisRISCV64Decoder : public VanadisDecoder
4949
SST_ELI_ELEMENT_VERSION(1, 0, 0),
5050
"Implements a RISCV64-compatible decoder for Vanadis CPU processing.",
5151
SST::Vanadis::VanadisDecoder)
52-
52+
SST_ELI_DOCUMENT_SUBCOMPONENT_SLOTS({ "gdb_unit", "GDB Server for Vanadis", "SST::Vanadis::VanadisRISCV64GDB" })
5353
SST_ELI_DOCUMENT_PARAMS(
5454
{"decode_max_ins_per_cycle", "Maximum number of instructions that can be "
5555
"decoded and issued per cycle", "2"},
@@ -71,6 +71,7 @@ class VanadisRISCV64Decoder : public VanadisDecoder
7171

7272
fatal_decode_fault = params.find<bool>("halt_on_decode_fault", false);
7373

74+
gdb = loadUserSubComponent<SST::Vanadis::VanadisRISCV64GDB>("gdb_unit");
7475
}
7576

7677
~VanadisRISCV64Decoder() {}
@@ -127,6 +128,66 @@ class VanadisRISCV64Decoder : public VanadisDecoder
127128
regFile->setIntReg(sp_phys_reg, value);
128129
}
129130

131+
void gdb_tick() {
132+
if ( gdb != nullptr ) {
133+
gdb->tick();
134+
}
135+
}
136+
137+
void register_pipeline( SST::Output* output_p ) {
138+
if ( gdb != nullptr ) {
139+
gdb->register_pipeline( output_p, this );
140+
}
141+
}
142+
143+
bool is_rob_empty() {
144+
return thread_rob->size() == 0;
145+
}
146+
147+
void instruction_to_rob( SST::Output* output, VanadisInstruction* next_ins, bool * bundle_has_branch, VanadisInstructionBundle* bundle ) {
148+
// Note: Caller must confirm there is space in the rob before calling
149+
// Note: last 2 arguments not used if instruction is not a branch
150+
if ( next_ins->getInstFuncType() == INST_BRANCH ) {
151+
VanadisSpeculatedInstruction* next_spec_ins =
152+
dynamic_cast<VanadisSpeculatedInstruction*>(next_ins);
153+
154+
if ( branch_predictor->contains(ip) ) {
155+
// We have an address predicton from the branching unit
156+
const uint64_t predicted_address = branch_predictor->predictAddress(ip);
157+
next_spec_ins->setSpeculatedAddress(predicted_address);
158+
159+
if(output->getVerboseLevel() >= 16) {
160+
output->verbose(
161+
CALL_INFO, 16, 0,
162+
"----> contains a branch: 0x%" PRI_ADDR " / predicted "
163+
"(found in predictor): 0x%" PRI_ADDR "\n",
164+
ip, predicted_address);
165+
}
166+
167+
ip = predicted_address;
168+
*bundle_has_branch = true;
169+
}
170+
else {
171+
// We don't have an address prediction
172+
// so just speculate that we are going to drop through to the
173+
// next instruction as we aren't sure where this will go yet
174+
175+
if(output->getVerboseLevel() >= 16) {
176+
output->verbose(
177+
CALL_INFO, 16, 0,
178+
"----> contains a branch: 0x%" PRI_ADDR " / predicted "
179+
"(not-found in predictor): 0x%" PRI_ADDR ", pc-increment: %" PRIu64 "\n",
180+
ip, ip + 4, bundle->pcIncrement());
181+
}
182+
183+
ip += bundle->pcIncrement();
184+
next_spec_ins->setSpeculatedAddress(ip);
185+
*bundle_has_branch = true;
186+
}
187+
}
188+
189+
thread_rob->push(next_ins->clone());
190+
}
130191

131192
void tick(SST::Output* output, uint64_t cycle) override
132193
{
@@ -145,6 +206,12 @@ class VanadisRISCV64Decoder : public VanadisDecoder
145206
output->verbose(
146207
CALL_INFO, 16, 0, "---> Found uop bundle for ip=0x%" PRI_ADDR ", loading from cache...\n", ip);
147208
}
209+
210+
if ( gdb != nullptr && gdb->should_stall(ip) ) {
211+
// We are stopped at a breakpoint, so stall this cycle
212+
break;
213+
}
214+
148215
stat_uop_hit->addData(1);
149216

150217
VanadisInstructionBundle* bundle = ins_loader->getBundleAt(ip);
@@ -163,46 +230,7 @@ class VanadisRISCV64Decoder : public VanadisDecoder
163230
for ( uint32_t i = 0; i < bundle->getInstructionCount(); ++i ) {
164231
VanadisInstruction* next_ins = bundle->getInstructionByIndex(i);
165232

166-
if ( next_ins->getInstFuncType() == INST_BRANCH ) {
167-
VanadisSpeculatedInstruction* next_spec_ins =
168-
dynamic_cast<VanadisSpeculatedInstruction*>(next_ins);
169-
170-
if ( branch_predictor->contains(ip) ) {
171-
// We have an address predicton from the branching unit
172-
const uint64_t predicted_address = branch_predictor->predictAddress(ip);
173-
next_spec_ins->setSpeculatedAddress(predicted_address);
174-
175-
if(output->getVerboseLevel() >= 16) {
176-
output->verbose(
177-
CALL_INFO, 16, 0,
178-
"----> contains a branch: 0x%" PRI_ADDR " / predicted "
179-
"(found in predictor): 0x%" PRI_ADDR "\n",
180-
ip, predicted_address);
181-
}
182-
183-
ip = predicted_address;
184-
bundle_has_branch = true;
185-
}
186-
else {
187-
// We don't have an address prediction
188-
// so just speculate that we are going to drop through to the
189-
// next instruction as we aren't sure where this will go yet
190-
191-
if(output->getVerboseLevel() >= 16) {
192-
output->verbose(
193-
CALL_INFO, 16, 0,
194-
"----> contains a branch: 0x%" PRI_ADDR " / predicted "
195-
"(not-found in predictor): 0x%" PRI_ADDR ", pc-increment: %" PRIu64 "\n",
196-
ip, ip + 4, bundle->pcIncrement());
197-
}
198-
199-
ip += bundle->pcIncrement();
200-
next_spec_ins->setSpeculatedAddress(ip);
201-
bundle_has_branch = true;
202-
}
203-
}
204-
205-
thread_rob->push(next_ins->clone());
233+
instruction_to_rob( output, next_ins, &bundle_has_branch, bundle );
206234
}
207235

208236
// Move to the next address, if we had a branch we should have
@@ -304,6 +332,7 @@ class VanadisRISCV64Decoder : public VanadisDecoder
304332
uint16_t icache_max_bytes_per_cycle;
305333
uint16_t max_decodes_per_cycle;
306334
uint16_t decode_buffer_max_entries;
335+
VanadisRISCV64GDB* gdb;
307336

308337
void decode(SST::Output* output, const uint64_t ins_address, const uint32_t ins, VanadisInstructionBundle* bundle)
309338
{
@@ -1112,8 +1141,10 @@ class VanadisRISCV64Decoder : public VanadisDecoder
11121141
case 0xc00:
11131142
{
11141143
if ( 0 == rs1 ) {
1115-
auto thread_call = std::bind(&VanadisRISCV64Decoder::getCycleCount, this);
1116-
bundle->addInstruction( new VanadisSetRegisterByCallInstruction<int64_t>( ins_address, hw_thr, options, rd, thread_call));
1144+
bundle->addInstruction(
1145+
new VanadisSetRegisterByCallInstruction<int64_t>(
1146+
ins_address, hw_thr, options, rd,
1147+
&VanadisRISCV64Decoder::getCycleCount_stub, (void *)this));
11171148
decode_fault = false;
11181149
}
11191150
} break;

0 commit comments

Comments
 (0)