Will be used for semihosting.
Signed-off-by: Brian Cain <[email protected]>
Reviewed-by: Pierrick Bouvier <[email protected]>
Signed-off-by: Matheus Tavares Bernardino <[email protected]>
---
target/hexagon/cpu_helper.c | 100 ++++++++++++++++++++++++++++++++++++
target/hexagon/cpu_helper.h | 6 +++
2 files changed, 106 insertions(+)
diff --git a/target/hexagon/cpu_helper.c b/target/hexagon/cpu_helper.c
index 64c5746c6d..fab9a9d7b1 100644
--- a/target/hexagon/cpu_helper.c
+++ b/target/hexagon/cpu_helper.c
@@ -25,6 +25,106 @@
#include "sys_macros.h"
#include "arch.h"
+#ifndef CONFIG_USER_ONLY
+
+static bool hexagon_read_memory_small(CPUHexagonState *env, target_ulong addr,
+ int byte_count, uint64_t *data,
+ int mmu_idx, uintptr_t retaddr)
+ {
+ /* handle small sizes */
+ switch (byte_count) {
+ case 1:
+ *data = cpu_ldub_mmuidx_ra(env, addr, mmu_idx, retaddr);
+ return true;
+
+ case 2:
+ *data = cpu_lduw_le_mmuidx_ra(env, addr, mmu_idx, retaddr);
+ return true;
+
+ case 4:
+ *data = cpu_ldl_le_mmuidx_ra(env, addr, mmu_idx, retaddr);
+ return true;
+
+ case 8:
+ *data = cpu_ldq_le_mmuidx_ra(env, addr, mmu_idx, retaddr);
+ return true;
+
+ default:
+ /* larger request, handle elsewhere */
+ return false;
+ }
+}
+
+void hexagon_read_memory(CPUHexagonState *env, target_ulong vaddr, int size,
+ void *retptr, uintptr_t retaddr)
+{
+ BQL_LOCK_GUARD();
+ CPUState *cs = env_cpu(env);
+ unsigned mmu_idx = cpu_mmu_index(cs, false);
+ uint64_t data;
+ if (hexagon_read_memory_small(env, vaddr, size, &data, mmu_idx, retaddr)) {
+ stn_he_p(retptr, size, data);
+ } else {
+ cpu_abort(cs, "%s: ERROR: bad size = %d!\n", __func__, size);
+ }
+}
+
+static bool hexagon_write_memory_small(CPUHexagonState *env, target_ulong addr,
+ int byte_count, uint64_t data,
+ int mmu_idx, uintptr_t retaddr)
+{
+ /* handle small sizes */
+ switch (byte_count) {
+ case 1:
+ cpu_stb_mmuidx_ra(env, addr, (uint8_t)data, mmu_idx, retaddr);
+ return true;
+
+ case 2:
+ cpu_stw_le_mmuidx_ra(env, addr, (uint16_t)data, mmu_idx, retaddr);
+ return true;
+
+ case 4:
+ cpu_stl_le_mmuidx_ra(env, addr, (uint32_t)data, mmu_idx, retaddr);
+ return true;
+
+ case 8:
+ cpu_stq_le_mmuidx_ra(env, addr, (uint64_t)data, mmu_idx, retaddr);
+ return true;
+
+ default:
+ /* larger request, handle elsewhere */
+ return false;
+ }
+}
+
+void hexagon_write_memory(CPUHexagonState *env, target_ulong vaddr,
+ int size, uint64_t data, uintptr_t retaddr)
+{
+ CPUState *cs = env_cpu(env);
+ unsigned mmu_idx = cpu_mmu_index(cs, false);
+ if (!hexagon_write_memory_small(env, vaddr, size, data, mmu_idx, retaddr))
{
+ cpu_abort(cs, "%s: ERROR: bad size = %d!\n", __func__, size);
+ }
+}
+
+static inline uint32_t page_start(uint32_t addr)
+{
+ uint32_t page_align = ~(TARGET_PAGE_SIZE - 1);
+ return addr & page_align;
+}
+
+void hexagon_peek_memory_range(CPUHexagonState *env, uint32_t start_addr,
+ uint32_t length, uintptr_t retaddr)
+{
+ unsigned int warm;
+ uint32_t first = page_start(start_addr);
+ uint32_t last = page_start(start_addr + length - 1);
+ for (uint32_t page = first; page <= last; page += TARGET_PAGE_SIZE) {
+ hexagon_read_memory(env, page, 1, &warm, retaddr);
+ }
+}
+
+#endif
uint32_t hexagon_get_pmu_counter(CPUHexagonState *cur_env, int index)
{
diff --git a/target/hexagon/cpu_helper.h b/target/hexagon/cpu_helper.h
index d176750315..ca2e13ab1d 100644
--- a/target/hexagon/cpu_helper.h
+++ b/target/hexagon/cpu_helper.h
@@ -7,6 +7,12 @@
#ifndef HEXAGON_CPU_HELPER_H
#define HEXAGON_CPU_HELPER_H
+void hexagon_read_memory(CPUHexagonState *env, target_ulong vaddr, int size,
+ void *retptr, uintptr_t retaddr);
+void hexagon_write_memory(CPUHexagonState *env, target_ulong vaddr,
+ int size, uint64_t data, uintptr_t retaddr);
+void hexagon_peek_memory_range(CPUHexagonState *env, uint32_t start_addr,
+ uint32_t length, uintptr_t retaddr);
uint32_t hexagon_get_pmu_counter(CPUHexagonState *cur_env, int index);
void hexagon_modify_ssr(CPUHexagonState *env, uint32_t new, uint32_t old);
int get_cpu_mode(CPUHexagonState *env);
--
2.37.2