diff mbox series

[v2,21/29] switching between secure and non-secure memory added

Message ID 20231006090610.26171-22-nicolas.eder@lauterbach.com
State New
Headers show
Series first version of mcdstub | expand

Commit Message

nicolas.eder@lauterbach.com Oct. 6, 2023, 9:06 a.m. UTC
From: neder <nicolas.eder@lauterbach.com>

---
 mcdstub/mcdstub.c    | 131 +++++++++++++++++++++++++++----------------
 mcdstub/mcdstub.h    |   4 +-
 target/arm/mcdstub.c |  14 +++++
 target/arm/mcdstub.h |   1 +
 4 files changed, 100 insertions(+), 50 deletions(-)
diff mbox series

Patch

diff --git a/mcdstub/mcdstub.c b/mcdstub/mcdstub.c
index 3772bda0a1..7d8ce634c8 100644
--- a/mcdstub/mcdstub.c
+++ b/mcdstub/mcdstub.c
@@ -548,8 +548,8 @@  int mcd_handle_packet(const char *line_buf)
             };
             read_mem_cmd_desc.cmd = (char[2]) { TCP_CHAR_READ_MEMORY, '\0' };
             strcpy(read_mem_cmd_desc.schema,
-                (char[4]) { ARG_SCHEMA_CORENUM, ARG_SCHEMA_UINT64_T,
-                ARG_SCHEMA_INT, '\0' });
+                (char[5]) { ARG_SCHEMA_CORENUM, ARG_SCHEMA_INT,
+                ARG_SCHEMA_UINT64_T, ARG_SCHEMA_INT, '\0' });
             cmd_parser = &read_mem_cmd_desc;
         }
         break;
@@ -560,8 +560,9 @@  int mcd_handle_packet(const char *line_buf)
             };
             write_mem_cmd_desc.cmd = (char[2]) { TCP_CHAR_WRITE_MEMORY, '\0' };
             strcpy(write_mem_cmd_desc.schema,
-                (char[5]) { ARG_SCHEMA_CORENUM, ARG_SCHEMA_UINT64_T,
-                ARG_SCHEMA_INT, ARG_SCHEMA_HEXDATA, '\0' });
+                (char[6]) { ARG_SCHEMA_CORENUM, ARG_SCHEMA_INT,
+                ARG_SCHEMA_UINT64_T, ARG_SCHEMA_INT,
+                ARG_SCHEMA_HEXDATA, '\0' });
             cmd_parser = &write_mem_cmd_desc;
         }
         break;
@@ -1194,10 +1195,17 @@  int int_cmp(gconstpointer a, gconstpointer b)
 int mcd_arm_store_mem_spaces(CPUState *cpu, GArray *memspaces)
 {
     int nr_address_spaces = cpu->num_ases;
+    uint32_t mem_space_id = 0;
+
+    /*
+     * TODO: atm we can only access physical memory addresses,
+     * but trace32 needs fake locical spaces to work with
+    */
 
-    mcd_mem_space_st space1 = {
+    mem_space_id++;
+    mcd_mem_space_st non_secure = {
         .name = "Non Secure",
-        .id = 1,
+        .id = mem_space_id,
         .type = 34,
         .bits_per_mau = 8,
         .invariance = 1,
@@ -1205,38 +1213,13 @@  int mcd_arm_store_mem_spaces(CPUState *cpu, GArray *memspaces)
         .min_addr = 0,
         .max_addr = -1,
         .supported_access_options = 0,
+        .is_secure = false,
     };
-    g_array_append_vals(memspaces, (gconstpointer)&space1, 1);
-
-    mcd_mem_space_st space2 = {
+    g_array_append_vals(memspaces, (gconstpointer)&non_secure, 1);
+    mem_space_id++;
+    mcd_mem_space_st phys_non_secure = {
         .name = "Physical (Non Secure)",
-        .id = 2,
-        .type = 18,
-        .bits_per_mau = 8,
-        .invariance = 1,
-        .endian = 1,
-        .min_addr = 0,
-        .max_addr = -1,
-        .supported_access_options = 0,
-    };
-    g_array_append_vals(memspaces, (gconstpointer)&space2, 1);
-
-    if (nr_address_spaces == 2) {
-        mcd_mem_space_st space3 = {
-        .name = "Secure",
-        .id = 3,
-        .type = 34,
-        .bits_per_mau = 8,
-        .invariance = 1,
-        .endian = 1,
-        .min_addr = 0,
-        .max_addr = -1,
-        .supported_access_options = 0,
-    };
-    g_array_append_vals(memspaces, (gconstpointer)&space3, 1);
-    mcd_mem_space_st space4 = {
-        .name = "Physical (Secure)",
-        .id = 4,
+        .id = mem_space_id,
         .type = 18,
         .bits_per_mau = 8,
         .invariance = 1,
@@ -1244,14 +1227,44 @@  int mcd_arm_store_mem_spaces(CPUState *cpu, GArray *memspaces)
         .min_addr = 0,
         .max_addr = -1,
         .supported_access_options = 0,
+        .is_secure = false,
     };
-    g_array_append_vals(memspaces, (gconstpointer)&space4, 1);
+    g_array_append_vals(memspaces, (gconstpointer)&phys_non_secure, 1);
+    if(nr_address_spaces > 1) {
+        mem_space_id++;
+        mcd_mem_space_st secure = {
+            .name = "Secure",
+            .id = mem_space_id,
+            .type = 34,
+            .bits_per_mau = 8,
+            .invariance = 1,
+            .endian = 1,
+            .min_addr = 0,
+            .max_addr = -1,
+            .supported_access_options = 0,
+            .is_secure = true,
+        };
+        g_array_append_vals(memspaces, (gconstpointer)&secure, 1);
+        mem_space_id++;
+        mcd_mem_space_st phys_secure = {
+            .name = "Physical (Secure)",
+            .id = mem_space_id,
+            .type = 18,
+            .bits_per_mau = 8,
+            .invariance = 1,
+            .endian = 1,
+            .min_addr = 0,
+            .max_addr = -1,
+            .supported_access_options = 0,
+            .is_secure = true,
+        };
+        g_array_append_vals(memspaces, (gconstpointer)&phys_secure, 1);
     }
-
     /* TODO: get dynamically how the per (CP15) space is called */
-    mcd_mem_space_st space5 = {
+    mem_space_id++;
+    mcd_mem_space_st gpr = {
         .name = "GPR Registers",
-        .id = 5,
+        .id = mem_space_id,
         .type = 1,
         .bits_per_mau = 8,
         .invariance = 1,
@@ -1260,10 +1273,11 @@  int mcd_arm_store_mem_spaces(CPUState *cpu, GArray *memspaces)
         .max_addr = -1,
         .supported_access_options = 0,
     };
-    g_array_append_vals(memspaces, (gconstpointer)&space5, 1);
-    mcd_mem_space_st space6 = {
+    g_array_append_vals(memspaces, (gconstpointer)&gpr, 1);
+    mem_space_id++;
+    mcd_mem_space_st cpr = {
         .name = "CP15 Registers",
-        .id = 6,
+        .id = mem_space_id,
         .type = 1,
         .bits_per_mau = 8,
         .invariance = 1,
@@ -1272,7 +1286,7 @@  int mcd_arm_store_mem_spaces(CPUState *cpu, GArray *memspaces)
         .max_addr = -1,
         .supported_access_options = 0,
     };
-    g_array_append_vals(memspaces, (gconstpointer)&space6, 1);
+    g_array_append_vals(memspaces, (gconstpointer)&cpr, 1);
     return 0;
 }
 
@@ -2022,10 +2036,20 @@  int mcd_write_memory(CPUState *cpu, hwaddr addr, uint8_t *buf, int len)
 void handle_read_memory(GArray *params, void *user_ctx)
 {
     uint32_t cpu_id = get_param(params, 0)->cpu_id;
-    uint64_t mem_address = get_param(params, 1)->data_uint64_t;
-    uint32_t len = get_param(params, 2)->data_uint32_t;
+    uint32_t mem_space_id = get_param(params, 1)->data_uint32_t;
+    uint64_t mem_address = get_param(params, 2)->data_uint64_t;
+    uint32_t len = get_param(params, 3)->data_uint32_t;
 
     CPUState *cpu = mcd_get_cpu(cpu_id);
+    /* check if the mem space is secure */
+    GArray *memspaces = g_list_nth_data(mcdserver_state.all_memspaces, cpu_id);
+    mcd_mem_space_st space = g_array_index(memspaces, mcd_mem_space_st,
+        mem_space_id - 1);
+    if (arm_mcd_set_scr(cpu, space.is_secure)) {
+        mcd_put_packet(TCP_EXECUTION_ERROR);
+        return;
+    }
+    /* read memory */
     g_byte_array_set_size(mcdserver_state.mem_buf, len);
     if (mcd_read_memory(cpu, mem_address, mcdserver_state.mem_buf->data,
         mcdserver_state.mem_buf->len) != 0) {
@@ -2040,10 +2064,19 @@  void handle_read_memory(GArray *params, void *user_ctx)
 void handle_write_memory(GArray *params, void *user_ctx)
 {
     uint32_t cpu_id = get_param(params, 0)->cpu_id;
-    uint64_t mem_address = get_param(params, 1)->data_uint64_t;
-    uint32_t len = get_param(params, 2)->data_uint32_t;
-
+    uint32_t mem_space_id = get_param(params, 1)->data_uint32_t;
+    uint64_t mem_address = get_param(params, 2)->data_uint64_t;
+    uint32_t len = get_param(params, 3)->data_uint32_t;
     CPUState *cpu = mcd_get_cpu(cpu_id);
+    /* check if the mem space is secure */
+    GArray *memspaces = g_list_nth_data(mcdserver_state.all_memspaces, cpu_id);
+    mcd_mem_space_st space = g_array_index(memspaces, mcd_mem_space_st,
+        mem_space_id - 1);
+    if (arm_mcd_set_scr(cpu, space.is_secure)) {
+        mcd_put_packet(TCP_EXECUTION_ERROR);
+        return;
+    }
+    /* read memory */
     mcd_hextomem(mcdserver_state.mem_buf, mcdserver_state.str_buf->str, len);
     if (mcd_write_memory(cpu, mem_address,
         mcdserver_state.mem_buf->data, len) != 0) {
diff --git a/mcdstub/mcdstub.h b/mcdstub/mcdstub.h
index 25475acaf7..f8171cba71 100644
--- a/mcdstub/mcdstub.h
+++ b/mcdstub/mcdstub.h
@@ -58,7 +58,7 @@  enum {
 
 /* misc */
 #define QUERY_TOTAL_NUMBER 12
-#define CMD_SCHEMA_LENGTH 5
+#define CMD_SCHEMA_LENGTH 6
 #define MCD_SYSTEM_NAME "qemu-system"
 
 /* tcp query packet values templates */
@@ -185,6 +185,8 @@  typedef struct mcd_mem_space_st {
     uint64_t min_addr;
     uint64_t max_addr;
     uint32_t supported_access_options;
+    /* internal */
+    bool is_secure;
 } mcd_mem_space_st;
 
 typedef struct mcd_reg_group_st {
diff --git a/target/arm/mcdstub.c b/target/arm/mcdstub.c
index c0bd5bb545..8456352370 100644
--- a/target/arm/mcdstub.c
+++ b/target/arm/mcdstub.c
@@ -330,3 +330,17 @@  uint16_t arm_mcd_get_opcode(CPUState *cs, uint32_t n)
     }
     return 0;
 }
+
+int arm_mcd_set_scr(CPUState *cs, bool secure)
+{
+    /* swtiches between secure and non secure mode */
+    ARMCPU *cpu = ARM_CPU(cs);
+    CPUARMState *env = &cpu->env;
+    /* set bit 0 to 1 if non secure, to 0 if secure*/
+    if (secure) {
+        env->cp15.scr_el3 &= 0xFFFFFFFE;
+    } else {
+        env->cp15.scr_el3 |= 1;
+    }
+    return 0;
+}
diff --git a/target/arm/mcdstub.h b/target/arm/mcdstub.h
index 81d67246d8..c3b5c1ae8d 100644
--- a/target/arm/mcdstub.h
+++ b/target/arm/mcdstub.h
@@ -16,5 +16,6 @@  int arm_mcd_read_register(CPUState *cs, GByteArray *mem_buf, uint8_t reg_type,
 int arm_mcd_write_register(CPUState *cs, GByteArray *mem_buf, uint8_t reg_type,
     uint32_t n);
 uint16_t arm_mcd_get_opcode(CPUState *cs, uint32_t n);
+int arm_mcd_set_scr(CPUState *cs, bool secure);
 
 #endif /* ARM_MCDSTUB_H */