-
Notifications
You must be signed in to change notification settings - Fork 10
WIP: Function overlay #87
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: upmem_release_120
Are you sure you want to change the base?
Changes from all commits
c096826
610e8ec
04bdbd6
0bcf4a9
f49c551
eef7f9a
718c233
f7ebeb6
a79efcb
5fa2775
4e9862b
e8ab96f
5f4bdd1
1ccffb0
3f21115
efbc616
e5ca72c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,6 +50,10 @@ | |
#include "Plugins/Process/POSIX/ProcessPOSIXLog.h" | ||
#include "ThreadDpu.h" | ||
|
||
extern "C" { | ||
#include <dpu_program.h> | ||
} | ||
|
||
#include <linux/unistd.h> | ||
#include <sys/timerfd.h> /* TODO only exists on Linux */ | ||
#include <sys/types.h> | ||
|
@@ -351,7 +355,7 @@ ProcessDpu::ProcessDpu(::pid_t pid, int terminal_fd, NativeDelegate &delegate, | |
SetState(StateType::eStateStopped, false); | ||
|
||
m_iram_region.GetRange().SetRangeBase(k_dpu_iram_base); | ||
m_iram_region.GetRange().SetRangeEnd(k_dpu_iram_base + m_iram_size); | ||
m_iram_region.GetRange().SetRangeEnd(k_dpu_iram_base + k_dpu_viram_offset*6 + m_iram_size); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. operand space operand |
||
m_iram_region.SetReadable(MemoryRegionInfo::eYes); | ||
m_iram_region.SetWritable(MemoryRegionInfo::eYes); | ||
m_iram_region.SetExecutable(MemoryRegionInfo::eYes); | ||
|
@@ -374,6 +378,8 @@ ProcessDpu::ProcessDpu(::pid_t pid, int terminal_fd, NativeDelegate &delegate, | |
|
||
void ProcessDpu::InterfaceTimerCallback() { | ||
unsigned int exit_status; | ||
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_PROCESS)); | ||
LLDB_LOG(log, "========= this is a log test ==========="); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please cleanup when you're done with your experiment. |
||
StateType current_state = m_dpu->PollStatus(&exit_status); | ||
if (current_state != StateType::eStateInvalid) { | ||
if (current_state == StateType::eStateExited) { | ||
|
@@ -546,6 +552,7 @@ Status ProcessDpu::GetMemoryRegionInfo(lldb::addr_t load_addr, | |
range_info = m_mram_region; | ||
} else if (m_iram_region.GetRange().Contains(load_addr)) { | ||
range_info = m_iram_region; | ||
// FIXME : add viram ranges | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. please do if necessary |
||
} else { | ||
range_info.GetRange().SetRangeBase(load_addr); | ||
range_info.GetRange().SetRangeEnd(LLDB_INVALID_ADDRESS); | ||
|
@@ -578,8 +585,10 @@ size_t ProcessDpu::UpdateThreads() { return m_threads.size(); } | |
|
||
Status ProcessDpu::SetBreakpoint(lldb::addr_t addr, uint32_t size, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Does function_group feature works with breakpoint now? same apply to unwinding. |
||
bool hardware) { | ||
size_t bytes_read; | ||
Log *log(GetLogIfAnyCategoriesSet(POSIX_LOG_BREAKPOINTS)); | ||
if (hardware) | ||
return SetHardwareBreakpoint(addr, size); | ||
return SetHardwareBreakpoint(addr, size); | ||
else | ||
return SetSoftwareBreakpoint(addr, size); | ||
} | ||
|
@@ -593,7 +602,9 @@ Status ProcessDpu::RemoveBreakpoint(lldb::addr_t addr, bool hardware) { | |
|
||
ProcessDpu::eMemoryAddressSpace | ||
ProcessDpu::ComputeMemoryAddressSpace(lldb::addr_t addr, size_t size) { | ||
if (addr >= k_dpu_iram_base && | ||
if (addr >= k_dpu_iram_base + k_dpu_viram_offset && ((addr & (~k_dpu_viram_msb_mask)) + size) <= (k_dpu_iram_base + m_iram_size)) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't hesitate to \n to be more readable. |
||
return eMemoryAddressSpaceVIRAM; | ||
} else if (addr >= k_dpu_iram_base && | ||
(addr + size) <= (k_dpu_iram_base + m_iram_size)) { | ||
return eMemoryAddressSpaceIRAM; | ||
} else if (addr >= k_dpu_mram_base && | ||
|
@@ -610,10 +621,20 @@ ProcessDpu::ComputeMemoryAddressSpace(lldb::addr_t addr, size_t size) { | |
Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, | ||
size_t &bytes_read) { | ||
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); | ||
Status error; | ||
LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); | ||
|
||
bytes_read = 0; | ||
switch (ComputeMemoryAddressSpace(addr, size)) { | ||
case eMemoryAddressSpaceVIRAM: | ||
// expected behaviour : if can fetch symbols, read correct mram location. Otherwise, read iram | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I don't understand your logic here. |
||
lldb::addr_t mram_addr; | ||
error = ViramAddressToMramPhysicalAddress(addr, &mram_addr); | ||
if (error.Fail()) | ||
return Status("ReadMemory: cannot convert viram to mram physical address"); | ||
if (!m_dpu->ReadMRAM(mram_addr - k_dpu_mram_base, buf, size)) | ||
return Status("ReadMemory: Cannot copy from MRAM"); | ||
break; | ||
case eMemoryAddressSpaceIRAM: | ||
if (!m_dpu->ReadIRAM(addr - k_dpu_iram_base, buf, size)) | ||
return Status("ReadMemory: Cannot copy from IRAM"); | ||
|
@@ -640,10 +661,26 @@ Status ProcessDpu::ReadMemory(lldb::addr_t addr, void *buf, size_t size, | |
Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, | ||
size_t &bytes_written) { | ||
Log *log(ProcessPOSIXLog::GetLogIfAllCategoriesSet(POSIX_LOG_MEMORY)); | ||
Status error; | ||
LLDB_LOG(log, "addr = {0:X}, buf = {1}, size = {2}", addr, buf, size); | ||
|
||
bytes_written = 0; | ||
switch (ComputeMemoryAddressSpace(addr, size)) { | ||
case eMemoryAddressSpaceVIRAM: | ||
// expected behaviour : if can fetch symbols, write to correct mram location and if fg is loaded, write to iram. Otherwise, only write to iram | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. same as above |
||
lldb::addr_t mram_addr; | ||
lldb::addr_t iram_addr; | ||
error = ViramAddressToMramPhysicalAddress(addr, &mram_addr); | ||
if (error.Fail()) | ||
return Status("WriteMemory: cannot convert viram to mram physical address"); | ||
if (!m_dpu->WriteMRAM(mram_addr - k_dpu_mram_base, buf, size)) | ||
return Status("WriteMemory: Cannot copy to MRAM"); | ||
error = ViramAddressToLoadedIramAddress(addr, &iram_addr); | ||
if (error.Fail()) { | ||
LLDB_LOG(log, "WriteMemory: Could not write viram to iram as this function group is not currently loaded"); | ||
} else if (!m_dpu->WriteIRAM(iram_addr - k_dpu_iram_base, buf, size)) | ||
return Status("WriteMemory: Cannot copy to IRAM"); | ||
break; | ||
case eMemoryAddressSpaceIRAM: | ||
if (!m_dpu->WriteIRAM(addr - k_dpu_iram_base, buf, size)) | ||
return Status("WriteMemory: Cannot copy to IRAM"); | ||
|
@@ -667,6 +704,57 @@ Status ProcessDpu::WriteMemory(lldb::addr_t addr, const void *buf, size_t size, | |
return Status(); | ||
} | ||
|
||
Status ProcessDpu::ViramAddressToMramPhysicalAddress(lldb::addr_t viram_addr, lldb::addr_t *mram_addr) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. don't hesitate to use \n in the two functions below :) |
||
Status error; | ||
size_t bytes_read; | ||
lldb::addr_t overlay_start_address = 0; | ||
lldb::addr_t load_starts_table_address = 0; | ||
lldb::addr_t load_start_address = 0; | ||
size_t fg_id = ((viram_addr & k_dpu_viram_msb_mask)/k_dpu_viram_offset) - 1; | ||
const char *using_function_groups = std::getenv("USING_FUNCTION_GROUPS"); | ||
if (using_function_groups == NULL || using_function_groups[0] == '\0') | ||
return Status("Could not find USING_FUNCTION_GROUPS env variable\n"); | ||
error = ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); | ||
if(error.Fail() || bytes_read != 4) | ||
return Status("could not read load start address\n"); | ||
overlay_start_address <<= 3; | ||
lldbassert(viram_addr >= overlay_start_address); | ||
error = ReadMemory(ADDR_FG_LOAD_STARTS_ADDR, &load_starts_table_address, 4, bytes_read); | ||
if(error.Fail() || bytes_read != 4) | ||
return Status("could not read load starts table address\n"); | ||
if (load_starts_table_address == 0) | ||
return Status("function groups not properly initialized"); | ||
error = ReadMemory(load_starts_table_address+4*fg_id, &load_start_address, 4, bytes_read); | ||
if(error.Fail() || bytes_read != 4) | ||
return Status("could not read load start address\n"); | ||
*mram_addr = (viram_addr & ~k_dpu_viram_msb_mask) + load_start_address - overlay_start_address - k_dpu_iram_base + k_dpu_mram_base; | ||
return Status(); | ||
} | ||
|
||
Status ProcessDpu::ViramAddressToLoadedIramAddress(lldb::addr_t viram_addr, lldb::addr_t *iram_addr) { | ||
Status error; | ||
size_t bytes_read; | ||
lldb::addr_t overlay_start_address; | ||
// FIXME : try and fetch symbol instead of trusting overlay_start_address will always be stored at the same address in the elf | ||
error = ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); | ||
if(!error.Fail() && bytes_read == 4) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
reduce the indentation |
||
overlay_start_address <<= 3; | ||
overlay_start_address += 0x80000000; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. k_dpu_iram_base |
||
if (viram_addr >= overlay_start_address && overlay_start_address != 0x80000000) { | ||
uint32_t loaded_group_value; | ||
// FIXME : try and fetch symbol instead of trusting the loaded_group will always be stored at the same address in the elf | ||
error = ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &loaded_group_value, 4, bytes_read); | ||
if(!error.Fail() && bytes_read == 4) { | ||
if ((viram_addr & k_dpu_viram_msb_mask) == k_dpu_viram_offset*(loaded_group_value+1)) { | ||
*iram_addr = viram_addr & ~k_dpu_viram_msb_mask; | ||
return Status(); | ||
} | ||
} | ||
} | ||
} | ||
return Status("This function group is not currently loaded in iram\n"); | ||
} | ||
|
||
Status ProcessDpu::GetLoadedModuleFileSpec(const char *module_path, | ||
FileSpec &file_spec) { | ||
return DpuErrorStatus("GetLoadedModuleFileSpec: Not Implemented"); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -25,6 +25,11 @@ | |
#include "ThreadDpu.h" | ||
#include "lldb/Host/common/NativeProcessProtocol.h" | ||
|
||
#define ADDR_FG_IRAM_OVERLAY_START 0x8 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. constexpr maybe ? |
||
#define ADDR_FG_CURRENTLY_LOADED_GROUP 0x10 | ||
#define ADDR_FG_LOAD_STARTS_ADDR 0x18 | ||
#define ADDR_FG_INITIALIZED 0x20 | ||
|
||
namespace lldb_private { | ||
class Status; | ||
class Scalar; | ||
|
@@ -39,6 +44,8 @@ const ArchSpec k_dpu_arch("dpu-upmem-dpurte"); | |
constexpr lldb::addr_t k_dpu_wram_base = 0x00000000; | ||
constexpr lldb::addr_t k_dpu_mram_base = 0x08000000; | ||
constexpr lldb::addr_t k_dpu_iram_base = 0x80000000; | ||
constexpr lldb::addr_t k_dpu_viram_offset = 0x00100000; | ||
constexpr lldb::addr_t k_dpu_viram_msb_mask = k_dpu_viram_offset*0xf; | ||
} // namespace dpu | ||
|
||
namespace process_dpu { | ||
|
@@ -96,6 +103,10 @@ class ProcessDpu : public NativeProcessProtocol { | |
Status WriteMemory(lldb::addr_t addr, const void *buf, size_t size, | ||
size_t &bytes_written) override; | ||
|
||
Status ViramAddressToMramPhysicalAddress(lldb::addr_t viram_addr, lldb::addr_t *mram_addr); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. private function |
||
|
||
Status ViramAddressToLoadedIramAddress(lldb::addr_t viram_addr, lldb::addr_t *iram_addr); | ||
|
||
virtual llvm::Expected<lldb::addr_t> | ||
AllocateMemory(size_t size, uint32_t permissions) override; | ||
|
||
|
@@ -167,6 +178,7 @@ class ProcessDpu : public NativeProcessProtocol { | |
Status DpuErrorStatus(const char *message); | ||
|
||
enum eMemoryAddressSpace { | ||
eMemoryAddressSpaceVIRAM, | ||
eMemoryAddressSpaceIRAM, | ||
eMemoryAddressSpaceMRAM, | ||
eMemoryAddressSpaceWRAM, | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -28,6 +28,7 @@ using namespace lldb_private::process_dpu; | |
namespace { | ||
|
||
constexpr lldb::addr_t k_dpu_iram_base = 0x80000000; | ||
constexpr lldb::addr_t k_dpu_viram_offset = 0x00100000; | ||
|
||
} // end of anonymous namespace | ||
|
||
|
@@ -78,6 +79,7 @@ RegisterContextDpu::RegisterContextDpu(ThreadDpu &thread, ProcessDpu &process) | |
process.GetThreadContext(thread.GetIndex(), m_context_reg, m_context_pc, | ||
m_context_zf, m_context_cf, | ||
m_registers_has_been_modified); | ||
m_process = &process; | ||
} | ||
|
||
uint32_t RegisterContextDpu::GetRegisterSetCount() const { return 1; } | ||
|
@@ -94,6 +96,38 @@ RegisterContextDpu::GetRegisterSet(uint32_t set_index) const { | |
return &g_reg_sets_dpu; | ||
} | ||
|
||
Status FixPc(ProcessDpu *process, uint32_t *pc) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. abuse \n :) |
||
Status error; | ||
size_t bytes_read; | ||
// uint64_t magic_value; | ||
uint32_t initialized = 0; | ||
lldb::addr_t overlay_start_address = 0; | ||
uint32_t fg_id; | ||
|
||
const char *using_function_groups = std::getenv("USING_FUNCTION_GROUPS"); | ||
if (using_function_groups == NULL || using_function_groups[0] == '\0') | ||
return Status("Could not find USING_FUNCTION_GROUPS env variable\n"); | ||
|
||
error = process->ReadMemory(ADDR_FG_INITIALIZED, &initialized, 4, bytes_read); | ||
if(error.Fail() || bytes_read != 4 || initialized == 0) | ||
return Status("fg groups not initialized\n"); | ||
|
||
error = process->ReadMemory(ADDR_FG_IRAM_OVERLAY_START, &overlay_start_address, 4, bytes_read); | ||
if(error.Fail() || bytes_read != 4) | ||
return Status("could not read load start address\n"); | ||
|
||
overlay_start_address <<= 3; | ||
if((*pc) < k_dpu_iram_base + overlay_start_address) | ||
return Status("pc below overlay_start_address\n"); | ||
|
||
error = process->ReadMemory(ADDR_FG_CURRENTLY_LOADED_GROUP, &fg_id, 4, bytes_read); | ||
if(error.Fail() || bytes_read != 4) | ||
return Status("could not read load start address\n"); | ||
|
||
*pc |= k_dpu_viram_offset * (1 + fg_id); | ||
return Status(); | ||
} | ||
|
||
Status RegisterContextDpu::ReadRegister(const RegisterInfo *info, | ||
RegisterValue &value) { | ||
if (!info) | ||
|
@@ -106,6 +140,7 @@ Status RegisterContextDpu::ReadRegister(const RegisterInfo *info, | |
*m_context_pc * 8 /*sizeof(iram_instruction_t)*/ + k_dpu_iram_base; | ||
if (m_thread.GetState() == eStateSuspended) | ||
pc++; | ||
FixPc(m_process, &pc); | ||
value.SetUInt32(pc); | ||
} else if (reg == zf_dpu) | ||
value.SetUInt32(*m_context_zf ? 1 : 0); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
readjust header includes.
have together the backends includes, (dpu_types.h above)