Skip to content

Commit ba5c011

Browse files
Add changes to support scratchpad buffer patching for new ELFs (Xilinx#9741)
* Add changes to support scratchpad buffer patching for new ELFs Signed-off-by: Rahul Bramandlapalli <rbramand@amd.com> Signed-off-by: rahul <rbramand@amd.com> * Address comments on PR Signed-off-by: Rahul Bramandlapalli <rbramand@amd.com> * Remove code duplicacy Signed-off-by: rahul <rbramand@amd.com> --------- Signed-off-by: Rahul Bramandlapalli <rbramand@amd.com> Signed-off-by: rahul <rbramand@amd.com>
1 parent 3100735 commit ba5c011

5 files changed

Lines changed: 133 additions & 68 deletions

File tree

src/runtime_src/core/common/api/elf_int.h

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ struct module_config_aie_gen2
175175
const buf& preempt_save_data;
176176
const buf& preempt_restore_data;
177177

178-
// Size of scratch pad memory
178+
// Size of scratch pad memory per column
179179
size_t scratch_pad_mem_size;
180180

181181
// Control scratch pad memory size (0 if not present)
@@ -214,6 +214,9 @@ struct module_config_aie_gen2_plus
214214

215215
// Reference to dump buffer for debug/trace
216216
const buf& dump_buf;
217+
218+
// Size of scratch pad memory per column
219+
size_t scratch_pad_mem_size;
217220
// NOLINTEND
218221

219222
// Parent elf_impl pointer for any mutable operations

src/runtime_src/core/common/api/elf_patcher.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ patch_ctrl57_aie4(uint32_t* bd_data_ptr, uint64_t patch)
157157

158158
void
159159
symbol_patcher::
160-
patch_symbol(xrt::bo bo, uint64_t value, bool first)
160+
patch_symbol(xrt::bo bo, uint64_t value, bool first, bool is_arg)
161161
{
162162
if (!m_config)
163163
throw std::runtime_error("symbol_patcher: config not set");
@@ -176,14 +176,20 @@ patch_symbol(xrt::bo bo, uint64_t value, bool first)
176176
auto offset = config.offset_to_patch_buffer;
177177
auto bd_data_ptr = reinterpret_cast<uint32_t*>(base + offset);
178178

179-
if (!state.dirty) {
180-
// first time patching cache bd ptr values using bd ptrs array in patch state
181-
std::copy(bd_data_ptr, bd_data_ptr + max_bd_words, state.bd_data_ptrs.begin());
182-
state.dirty = true;
183-
}
184-
else {
185-
// not the first time patching, restore bd ptr values from patch state bd ptrs array
186-
std::copy(state.bd_data_ptrs.begin(), state.bd_data_ptrs.end(), bd_data_ptr);
179+
// If the symbol patched is an argument to kernel we have to cache
180+
// original bd data ptrs as args can be changed in subsequent runs.
181+
// For non-arg symbols we only patch and sync without caching
182+
// as they are patched once and never changed.
183+
if (is_arg) {
184+
if (!state.dirty) {
185+
// first time patching cache bd ptr values using bd ptrs array in patch state
186+
std::copy(bd_data_ptr, bd_data_ptr + max_bd_words, state.bd_data_ptrs.begin());
187+
state.dirty = true;
188+
}
189+
else {
190+
// not the first time patching, restore bd ptr values from patch state bd ptrs array
191+
std::copy(state.bd_data_ptrs.begin(), state.bd_data_ptrs.end(), bd_data_ptr);
192+
}
187193
}
188194

189195
// lambda for calling sync bo

src/runtime_src/core/common/api/elf_patcher.h

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,18 @@ generate_key_string(const std::string& argument_name, buf_type type)
5959
return argument_name + std::to_string(static_cast<int>(type));
6060
}
6161

62+
// Get symbol name from section name
63+
inline std::string
64+
get_symbol_name_from_section_name(const std::string& section_name)
65+
{
66+
// Symbol name is section name without the grp idx
67+
// if sec name is .ctrlpkt-57.grp_idx then sym name is .ctrlpkt-57
68+
auto dot_pos = section_name.rfind('.');
69+
return (dot_pos != std::string::npos && dot_pos > 0)
70+
? section_name.substr(0, dot_pos)
71+
: section_name;
72+
}
73+
6274
// Symbol type enum for patching schemes
6375
enum class symbol_type {
6476
uc_dma_remote_ptr_symbol_kind = 1,
@@ -132,7 +144,7 @@ struct symbol_patcher
132144

133145
// Function to patch a symbol in the buffer.
134146
void
135-
patch_symbol(xrt::bo bo, uint64_t value, bool first);
147+
patch_symbol(xrt::bo bo, uint64_t value, bool first, bool is_arg = true);
136148

137149
// static method for patching raw buffers passed by shim tests
138150
// where the caller handles sync themselves

src/runtime_src/core/common/api/xrt_elf.cpp

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,9 @@ using xrt_core::elf_int::no_ctrl_code_id;
3535
static constexpr size_t
3636
operator"" _kb(unsigned long long v) { return 1024u * v; } // NOLINT
3737

38+
static constexpr size_t
39+
operator"" _mb(unsigned long long v) { return 1024u * 1024u * v; } // NOLINT
40+
3841
///////////////////////////////////////////////////////////////
3942
// Helper functions for kernel signature demangling and parsing
4043
///////////////////////////////////////////////////////////////
@@ -1269,6 +1272,11 @@ class elf_aie_gen2_plus : public elf_impl
12691272
// section to patch is ctrlpkt
12701273
abs_offset += rela->r_offset;
12711274
buf_type = patcher_buf_type::ctrlpkt;
1275+
// we have multiple ctrlpkt sections and to uniquely identify symbol
1276+
// for patching we add ctrlpkt section symbol name to key string
1277+
auto sym_name =
1278+
xrt_core::elf_patcher::get_symbol_name_from_section_name(patch_sec_name);
1279+
argnm += sym_name;
12721280
}
12731281
else {
12741282
// section to patch is ctrlcode
@@ -1362,10 +1370,17 @@ class elf_aie_gen2_plus : public elf_impl
13621370

13631371
static const std::map<std::string, buf> empty_ctrlpkt_map;
13641372

1373+
auto scratch_pad_size = (m_platform == elf::platform::aie4 ||
1374+
m_platform == elf::platform::aie4a ||
1375+
m_platform == elf::platform::aie4z)
1376+
? 3_mb // NOLINT
1377+
: 0;
1378+
13651379
return module_config_aie_gen2_plus{
13661380
ctrlcode_it->second, // ctrlcodes
13671381
ctrlpkt_it != m_ctrlpkt_buf_map.end() ? ctrlpkt_it->second : empty_ctrlpkt_map, // ctrlpkt_bufs
13681382
dump_it != m_dump_buf_map.end() ? dump_it->second : buf::get_empty_buf(), // dump_buf
1383+
scratch_pad_size, // scratch_pad_mem_size
13691384
this // elf_parent
13701385
};
13711386
}

src/runtime_src/core/common/api/xrt_module.cpp

Lines changed: 86 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,9 @@ class module_run : public module_impl
200200
using patcher_config = xrt_core::elf_patcher::patcher_config;
201201
using symbol_patcher = xrt_core::elf_patcher::symbol_patcher;
202202

203+
// scratchpad memory symbol name
204+
static constexpr const char* Scratch_Pad_Mem_Symbol = "scratch-pad-mem";
205+
203206
// Pointer to shared patcher configs
204207
// This is created during ELF parsing and shared across module_run instances
205208
const std::map<std::string, patcher_config>* m_patcher_configs = nullptr;
@@ -262,22 +265,22 @@ class module_run : public module_impl
262265

263266
// Helper function for patching buffer with argument name or index
264267
bool
265-
patch_helper(xrt::bo& bo, const std::string& argnm, size_t index, uint64_t patch,
266-
xrt_core::elf_patcher::buf_type type)
268+
patch_helper(xrt::bo& bo, uint64_t patch, xrt_core::elf_patcher::buf_type type,
269+
const std::string& arg_string, const std::string& index_string,
270+
bool is_arg = true)
267271
{
268272
// Check if patcher configs exist
269273
if (!m_patcher_configs || m_patcher_configs->empty())
270274
return false;
271275

272-
const auto key_string = xrt_core::elf_patcher::generate_key_string(argnm, type);
276+
const auto key_string = xrt_core::elf_patcher::generate_key_string(arg_string, type);
273277

274278
auto config_it = m_patcher_configs->find(key_string);
275279
auto not_found_use_argument_name = (config_it == m_patcher_configs->end());
276280
std::string used_key = key_string;
277281

278282
if (not_found_use_argument_name) {
279283
// Search using index
280-
auto index_string = std::to_string(index);
281284
const auto key_index_string = xrt_core::elf_patcher::generate_key_string(index_string, type);
282285
config_it = m_patcher_configs->find(key_index_string);
283286
if (config_it == m_patcher_configs->end())
@@ -293,20 +296,20 @@ class module_run : public module_impl
293296
}
294297

295298
// Call patch - symbol_patcher owns its state internally
296-
patcher_it->second.patch_symbol(bo, patch, m_first_patch);
299+
patcher_it->second.patch_symbol(bo, patch, m_first_patch, is_arg);
297300

298301
if (xrt_core::config::get_xrt_debug()) {
299302
if (not_found_use_argument_name) {
300303
std::stringstream ss;
301304
ss << "Patched " << xrt_core::elf_patcher::get_section_name(type)
302-
<< " using argument index " << index
305+
<< " using argument index " << index_string
303306
<< " with value " << std::hex << patch;
304307
xrt_core::message::send( xrt_core::message::severity_level::debug, "xrt_module", ss.str());
305308
}
306309
else {
307310
std::stringstream ss;
308311
ss << "Patched " << xrt_core::elf_patcher::get_section_name(type)
309-
<< " using argument name " << argnm
312+
<< " using argument name " << arg_string
310313
<< " with value " << std::hex << patch;
311314
xrt_core::message::send( xrt_core::message::severity_level::debug, "xrt_module", ss.str());
312315
}
@@ -363,8 +366,7 @@ class module_run_aie_gen2 : public module_run
363366
// map storing xrt::bo that stores pdi data corresponding to each pdi symbol
364367
std::map<std::string, xrt::bo> m_pdi_bo_map;
365368

366-
// Symbol names for patching
367-
static constexpr const char* Scratch_Pad_Mem_Symbol = "scratch-pad-mem";
369+
// Symbol names for patching specific to aie_gen2 platform
368370
static constexpr const char* Control_Packet_Symbol = "control-packet";
369371
static constexpr const char* Control_ScratchPad_Symbol = "scratch-pad-ctrl";
370372

@@ -457,10 +459,10 @@ class module_run_aie_gen2 : public module_run
457459
if (!scratchpad_mem)
458460
throw std::runtime_error("Failed to get scratchpad buffer from context\n");
459461

460-
patch_helper(m_preempt_save_bo, Scratch_Pad_Mem_Symbol, 0, scratchpad_mem.address(),
461-
xrt_core::elf_patcher::buf_type::preempt_save);
462-
patch_helper(m_preempt_restore_bo, Scratch_Pad_Mem_Symbol, 0, scratchpad_mem.address(),
463-
xrt_core::elf_patcher::buf_type::preempt_restore);
462+
patch_helper(m_preempt_save_bo, scratchpad_mem.address(),
463+
xrt_core::elf_patcher::buf_type::preempt_save, Scratch_Pad_Mem_Symbol, {}, false);
464+
patch_helper(m_preempt_restore_bo, scratchpad_mem.address(),
465+
xrt_core::elf_patcher::buf_type::preempt_restore, Scratch_Pad_Mem_Symbol, {}, false);
464466

465467
if (is_dump_preemption_codes()) {
466468
std::stringstream ss;
@@ -475,8 +477,8 @@ class module_run_aie_gen2 : public module_run
475477
// Create control scratchpad buffer and patch if symbol is present
476478
if (m_config.ctrl_scratch_pad_mem_size > 0) {
477479
m_ctrl_scratch_pad_mem = xbi::create_bo(m_hwctx, m_config.ctrl_scratch_pad_mem_size, xbi::use_type::ctrl_scratch_pad);
478-
patch_helper(m_instr_bo, Control_ScratchPad_Symbol, 0, m_ctrl_scratch_pad_mem.address(),
479-
xrt_core::elf_patcher::buf_type::ctrltext);
480+
patch_helper(m_instr_bo, m_ctrl_scratch_pad_mem.address(),
481+
xrt_core::elf_patcher::buf_type::ctrltext, Control_ScratchPad_Symbol, {}, false);
480482
}
481483

482484
// Patch all PDI addresses using config's pdi symbols
@@ -488,13 +490,13 @@ class module_run_aie_gen2 : public module_run
488490
auto [it, inserted] = m_pdi_bo_map.emplace(symbol, std::move(pdi_bo));
489491

490492
// Patch instr buffer with PDI address
491-
patch_helper(m_instr_bo, symbol, 0, it->second.address(), xrt_core::elf_patcher::buf_type::ctrltext);
493+
patch_helper(m_instr_bo, it->second.address(), xrt_core::elf_patcher::buf_type::ctrltext, symbol, {}, false);
492494
}
493495

494496
// Patch control packet address if present
495497
if (m_ctrlpkt_bo) {
496-
patch_helper(m_instr_bo, Control_Packet_Symbol, 0, m_ctrlpkt_bo.address(),
497-
xrt_core::elf_patcher::buf_type::ctrltext);
498+
patch_helper(m_instr_bo, m_ctrlpkt_bo.address(),
499+
xrt_core::elf_patcher::buf_type::ctrltext, Control_Packet_Symbol, {}, false);
498500
}
499501

500502
// Patch ctrlpkt preemption buffers using config's dynsyms
@@ -507,8 +509,8 @@ class module_run_aie_gen2 : public module_run
507509
if (bo_itr == m_ctrlpkt_pm_bos.end())
508510
throw std::runtime_error("Unable to find ctrlpkt pm buffer for symbol " + dynsym);
509511

510-
patch_helper(m_instr_bo, dynsym, 0, bo_itr->second.address(),
511-
xrt_core::elf_patcher::buf_type::ctrltext);
512+
patch_helper(m_instr_bo, bo_itr->second.address(),
513+
xrt_core::elf_patcher::buf_type::ctrltext, dynsym, {}, false);
512514
}
513515

514516
XRT_DEBUGF("<- module_run_aie_gen2::create_instruction_buf()\n");
@@ -573,22 +575,21 @@ class module_run_aie_gen2 : public module_run
573575
void
574576
patch(const std::string& argnm, size_t index, uint64_t value) override
575577
{
576-
bool patched = false;
577-
578578
// patch control-packet buffer
579579
if (m_ctrlpkt_bo) {
580-
if (patch_helper(m_ctrlpkt_bo, argnm, index, value, xrt_core::elf_patcher::buf_type::ctrldata))
581-
patched = true;
580+
auto type = xrt_core::elf_patcher::buf_type::ctrldata;
581+
if (patch_helper(m_ctrlpkt_bo, value, type, argnm, std::to_string(index)))
582+
m_patched_args.insert(
583+
xrt_core::elf_patcher::generate_key_string(argnm, type));
582584
}
583585

584586
// patch instruction buffer
585587
if (m_instr_bo) {
586-
if (patch_helper(m_instr_bo, argnm, index, value, xrt_core::elf_patcher::buf_type::ctrltext))
587-
patched = true;
588+
auto type = xrt_core::elf_patcher::buf_type::ctrltext;
589+
if (patch_helper(m_instr_bo, value, type, argnm, std::to_string(index)))
590+
m_patched_args.insert(
591+
xrt_core::elf_patcher::generate_key_string(argnm, type));
588592
}
589-
590-
if (patched) // if patched, add to patched args set
591-
m_patched_args.insert(argnm);
592593
}
593594

594595
// Sync buffers to device if patching was done
@@ -881,26 +882,49 @@ class module_run_aie_gen2_plus : public module_run
881882
for (size_t i = 0; i < col_data.size(); ++i) {
882883
// Find the control-code-* sym-name and patch it in instruction buffer
883884
auto sym_name = std::string(Control_Code_Symbol) + "-" + std::to_string(i);
884-
if (patch_helper(m_buffer, sym_name, std::numeric_limits<size_t>::max(),
885-
m_buffer.address() + offset,
886-
xrt_core::elf_patcher::buf_type::ctrltext))
887-
m_patched_args.insert(sym_name);
885+
auto type = xrt_core::elf_patcher::buf_type::ctrltext;
886+
if (patch_helper(m_buffer, m_buffer.address() + offset, type, sym_name, {}, false))
887+
m_patched_args.insert(
888+
xrt_core::elf_patcher::generate_key_string(sym_name, type));
888889
offset += col_data[i].size();
889890
}
890891

892+
// create scratchpad memory buffer and patch it in ctrlpkt buffers and
893+
// instruction buffer if symbol is present in ELF
894+
xrt::bo scratchpad_mem;
895+
if (m_config.scratch_pad_mem_size > 0) {
896+
scratchpad_mem = xrt_core::hw_context_int::get_scratchpad_mem_buf(m_hwctx, m_config.scratch_pad_mem_size);
897+
if (!scratchpad_mem)
898+
throw std::runtime_error("Failed to get scratchpad buffer from context\n");
899+
}
900+
891901
// Patch control packet addresses in instruction buffer
892-
for (const auto& [name, ctrlpktbo] : m_ctrlpkt_bos) {
893-
// Symbol name is section name without the grp idx
894-
// if sec name is .ctrlpkt-57.grp_idx then sym name is .ctrlpkt-57
895-
auto dot_pos = name.rfind('.');
896-
auto sym_name = (dot_pos != std::string::npos && dot_pos > 0)
897-
? name.substr(0, dot_pos)
898-
: name;
899-
900-
if (patch_helper(m_buffer, sym_name, std::numeric_limits<size_t>::max(),
901-
ctrlpktbo.address(),
902-
xrt_core::elf_patcher::buf_type::ctrltext))
903-
m_patched_args.insert(sym_name);
902+
auto type = xrt_core::elf_patcher::buf_type::buf_type_count;
903+
for (auto& [name, ctrlpktbo] : m_ctrlpkt_bos) {
904+
auto sym_name =
905+
xrt_core::elf_patcher::get_symbol_name_from_section_name(name);
906+
907+
// Patch scratchpad memory address in ctrlpkt buffer if present
908+
if (scratchpad_mem) {
909+
type = xrt_core::elf_patcher::buf_type::ctrlpkt;
910+
auto symbol = std::string{Scratch_Pad_Mem_Symbol} + sym_name;
911+
if (patch_helper(ctrlpktbo, scratchpad_mem.address(), type, symbol, {}, false))
912+
m_patched_args.insert(
913+
xrt_core::elf_patcher::generate_key_string(symbol, type));
914+
}
915+
916+
type = xrt_core::elf_patcher::buf_type::ctrltext;
917+
if (patch_helper(m_buffer, ctrlpktbo.address(), type, sym_name, {}, false))
918+
m_patched_args.insert(
919+
xrt_core::elf_patcher::generate_key_string(sym_name, type));
920+
}
921+
922+
// Patch scratchpad memory address in instruction buffer if present
923+
if (scratchpad_mem) {
924+
type = xrt_core::elf_patcher::buf_type::ctrltext;
925+
if (patch_helper(m_buffer, scratchpad_mem.address(), type, Scratch_Pad_Mem_Symbol, {}, false))
926+
m_patched_args.insert(
927+
xrt_core::elf_patcher::generate_key_string(Scratch_Pad_Mem_Symbol, type));
904928
}
905929
}
906930

@@ -1015,25 +1039,30 @@ class module_run_aie_gen2_plus : public module_run
10151039
void
10161040
patch(const std::string& argnm, size_t index, uint64_t value) override
10171041
{
1018-
bool patched = false;
1019-
1042+
auto type = xrt_core::elf_patcher::buf_type::ctrltext;
10201043
// patch instruction buffer
1021-
if (patch_helper(m_buffer, argnm, index, value, xrt_core::elf_patcher::buf_type::ctrltext))
1022-
patched = true;
1044+
if (patch_helper(m_buffer, value, type, argnm, std::to_string(index)))
1045+
m_patched_args.insert(
1046+
xrt_core::elf_patcher::generate_key_string(argnm, type));
10231047

10241048
// patch argument in pad section
1025-
if (patch_helper(m_buffer, argnm, index, value, xrt_core::elf_patcher::buf_type::pad))
1026-
patched = true;
1049+
type = xrt_core::elf_patcher::buf_type::pad;
1050+
if (patch_helper(m_buffer, value, type, argnm, std::to_string(index)))
1051+
m_patched_args.insert(
1052+
xrt_core::elf_patcher::generate_key_string(argnm, type));
10271053

10281054
// New Elfs have multiple ctrlpkt sections
10291055
// Iterate over all ctrlpkt buffers and patch them
1030-
for (auto& ctrlpkt : m_ctrlpkt_bos) {
1031-
if (patch_helper(ctrlpkt.second, argnm, index, value, xrt_core::elf_patcher::buf_type::ctrlpkt))
1032-
patched = true;
1056+
type = xrt_core::elf_patcher::buf_type::ctrlpkt;
1057+
for (auto& [name, ctrlpktbo] : m_ctrlpkt_bos) {
1058+
auto sym_name =
1059+
xrt_core::elf_patcher::get_symbol_name_from_section_name(name);
1060+
1061+
if (patch_helper(ctrlpktbo, value, type, argnm + sym_name,
1062+
std::to_string(index) + sym_name))
1063+
m_patched_args.insert(
1064+
xrt_core::elf_patcher::generate_key_string(argnm, type));
10331065
}
1034-
1035-
if (patched) // if patched, add to patched args set
1036-
m_patched_args.insert(argnm);
10371066
}
10381067

10391068
// Sync buffers to device if patching was done

0 commit comments

Comments
 (0)