util: Allow overriding the magic address in the m5 utility.
authorGabe Black <gabeblack@google.com>
Fri, 27 Mar 2020 10:05:19 +0000 (03:05 -0700)
committerGabe Black <gabeblack@google.com>
Mon, 22 Jun 2020 08:33:04 +0000 (08:33 +0000)
This is useful in situations where the address is hard to know ahead of
time, for instance on ARM systems where the address map is hard to
predict.

The default address is now M5OP_ADDR, or 0 if that's not defined.

Change-Id: I3140e05b04365c1a76e52f8c3dc85f472c230ae4
Reviewed-on: https://gem5-review.googlesource.com/c/public/gem5/+/27244
Maintainer: Gabe Black <gabeblack@google.com>
Tested-by: kokoro <noreply+kokoro@google.com>
Reviewed-by: Giacomo Travaglini <giacomo.travaglini@arm.com>
util/m5/src/addr_call_type.c
util/m5/src/addr_call_type.h
util/m5/src/m5.c
util/m5/src/m5_mmap.c
util/m5/src/m5_mmap.h

index cb269dc5fa5133b3f32856d00aca83f32d77fd75..0b3d1fcf43b65ca1d035bdfc72f4a0d46945c82b 100644 (file)
@@ -28,6 +28,8 @@
 #include <string.h>
 
 #include "addr_call_type.h"
+#include "args.h"
+#include "m5_mmap.h"
 
 #define M5OP(name, func) __typeof__(name) M5OP_MERGE_TOKENS(name, _addr);
 M5OP_FOREACH
@@ -42,9 +44,40 @@ M5OP_FOREACH
 int
 addr_call_type_detect(int *argc, char **argv[])
 {
-    if (*argc > 0 && strcmp((*argv)[0], "--addr") == 0) {
+    static const char *prefix = "--addr";
+    const size_t prefix_len = strlen(prefix);
+    uint64_t addr_override;
+
+    // If the first argument starts with --addr...
+    if (*argc > 0 && memcmp((*argv)[0], prefix, prefix_len) == 0) {
+        char *argv0 = (*argv)[0];
         (*argc)--;
         (*argv)++;
+
+        // If there's more text in this argument...
+        if (strlen(argv0) != prefix_len) {
+            // If it doesn't start with '=', it's malformed.
+            if (argv0[prefix_len] != '=')
+                return -1;
+            // Attempt to extract an address after the '='.
+            char *temp_argv[] = { &argv0[prefix_len + 1] };
+            if (!parse_int_args(1, temp_argv, &addr_override, 1))
+                return -1;
+            // If we found an address, use it to override m5op_addr.
+            m5op_addr = addr_override;
+            return 1;
+        }
+        // If an address override wasn't part of the first argument, check if
+        // it's the second argument. If not, then there's no override.
+        if (*argc > 0 && parse_int_args(1, *argv, &addr_override, 1)) {
+            m5op_addr = addr_override;
+            (*argc)--;
+            (*argv)++;
+            return 1;
+        }
+        // If the default address was zero, an override is required.
+        if (!m5op_addr)
+            return -1;
         return 1;
     }
     return 0;
index d1fbfa6e878f76d4802c91ab2ce1ea4191efee38..6dcdb5bdbcad3ee863b6118093b46fed34edc878 100644 (file)
@@ -30,6 +30,7 @@
 
 #include "dispatch_table.h"
 
+// Returns 0 if not detected, 1 if detected successfully, and -1 on error.
 int addr_call_type_detect(int *argc, char **argv[]);
 DispatchTable *addr_call_type_init();
 
index 11e7d603d5ce173ea7e9de8cd731545876e5e91b..644acd03378ed6384da30f904268e6b0fb4870ef 100644 (file)
@@ -290,10 +290,16 @@ usage()
     fprintf(stderr, "\n");
     fprintf(stderr, "Call types:\n");
 #   if ENABLE_CT_addr
-    fprintf(stderr, "    --addr%s\n", DEFAULT_CT_addr ? " (default)" : "");
+    fprintf(stderr, "    --addr %s%s\n",
+#   if defined(M5OP_ADDR)
+            "[address override]",
+#   else
+            "<address override>",
+#   endif
+            DEFAULT_CT_addr ? " (default)" : "");
     fprintf(stderr, "        Use the address based invocation method.\n");
 #   if defined(M5OP_ADDR)
-    fprintf(stderr, "        The address is %#"PRIx64".\n",
+    fprintf(stderr, "        The default address is %#"PRIx64".\n",
             (uint64_t)M5OP_ADDR);
 #   endif
 #   endif
@@ -331,8 +337,12 @@ main(int argc, char *argv[])
     }
 #   endif
 #   if ENABLE_CT_addr
-    if (!dt && addr_call_type_detect(&argc, &argv)) {
-        dt = addr_call_type_init();
+    if (!dt) {
+        int detect = addr_call_type_detect(&argc, &argv);
+        if (detect < 0)
+            usage();
+        if (detect > 0)
+            dt = addr_call_type_init();
     }
 #   endif
 #   if ENABLE_CT_semi
index 79de59baabd54aeaf7a63b4414dec1f078029889..4a5aa0f559fa9fac6e3cc6a2cdcea9cffe7553cd 100644 (file)
 
 void *m5_mem = NULL;
 
+#ifndef M5OP_ADDR
+#define M5OP_ADDR 0
+#endif
+uint64_t m5op_addr = M5OP_ADDR;
+
 void
 map_m5_mem()
 {
-#ifdef M5OP_ADDR
     int fd;
 
     fd = open("/dev/mem", O_RDWR | O_SYNC);
@@ -62,10 +66,9 @@ map_m5_mem()
     }
 
     m5_mem = mmap(NULL, 0x10000, PROT_READ | PROT_WRITE, MAP_SHARED, fd,
-                  M5OP_ADDR);
+                  m5op_addr);
     if (!m5_mem) {
         perror("Can't mmap /dev/mem");
         exit(1);
     }
-#endif
 }
index d32857f0b1d3c2e6e94eb6f4b43117343c406e89..552b400d07572b1eed6a64f1001ef3ae768120c7 100644 (file)
 #define __UTIL_M5_MMAP_H__
 
 #include <fcntl.h>
+#include <stdint.h>
 #include <sys/mman.h>
 
 extern void *m5_mem;
+extern uint64_t m5op_addr;
 
 void map_m5_mem();