ARMv7: Added arch-specific platform info.
authorDavid Cock <david.cock@inf.ethz.ch>
Thu, 28 Jul 2016 17:21:35 +0000 (19:21 +0200)
committerDavid Cock <david.cock@inf.ethz.ch>
Tue, 2 Aug 2016 07:19:47 +0000 (09:19 +0200)
Certain things, such as the number of CPUs, can only be probed easily (or at
all), in the kernel.

Signed-off-by: David Cock <david.cock@inf.ethz.ch>

15 files changed:
hake/menu.lst.armv7_a9ve
if/monitor_blocking.if
include/barrelfish_kpi/platform.h
kernel/Hakefile
kernel/arch/armv7/plat_id.c [new file with mode: 0644]
kernel/arch/armv7/plat_omap44xx.c
kernel/arch/armv7/plat_vexpress.c
kernel/arch/armv7/plat_zynq7.c
kernel/include/arch/armv7/cp15.h
kernel/include/arch/armv7/platform.h
platforms/Hakefile
usr/kaluga/armv7.c
usr/listfacts/Hakefile
usr/listfacts/main.c
usr/monitor/monitor_rpc_server.c

index 1a3825c..6e9d2f8 100644 (file)
@@ -29,12 +29,13 @@ module /armv7/sbin/startd boot
 # Device drivers
 # module /armv7/sbin/serial_pl011 auto
 module /armv7/sbin/serial_kernel irq=37
+module /armv7/sbin/corectrl nospawn
 
 # General user domains
 module /armv7/sbin/angler serial0.terminal dumb
 module /armv7/sbin/fish nospawn
 
-module /armv7/sbin/memtest
+module /armv7/sbin/memtest nospawn
 
 # The FVP simulates 4GB of RAM, 2GB of which is in the 32-bit address space.
 #        start       size       id
index 4e3c802..ceec43e 100644 (file)
@@ -74,4 +74,7 @@ interface monitor_blocking "The monitor to client RPC interface" {
 
     /* get platform we're running on */
     rpc get_platform(out uint32 arch, out uint32 platform);
+
+    /* Get arch-specific platform data. Size must match PI_ARCH_INFO_SIZE+1. */
+    rpc get_platform_arch(out uint8 buf[length,256]);
 };
index 21784ca..3d23571 100644 (file)
@@ -16,6 +16,8 @@
 #ifndef BARRELFISH_KPI_PLATFORM_H
 #define BARRELFISH_KPI_PLATFORM_H
 
+#include <barrelfish/static_assert.h>
+
 enum pi_arch {
     PI_ARCH_X86,
     PI_ARCH_ARMV7A,
@@ -35,10 +37,34 @@ enum pi_platform {
     PI_PLATFORM_TMAS,
 };
 
+/* Must be at least as large as all architectures' structs. */
+#define PI_ARCH_INFO_SIZE 255
+
+struct arch_info_armv7 {
+    /* The number of cores in the system, as reported by the GIC.  The cores
+     * in the primary cluster will be numbered sequentially, those in other
+     * clusters (big.little) probably aren't. */
+    uint32_t ncores;
+
+    /* The various identification registers. */
+    uint32_t midr, ctr, id_pfr0, id_pfr1;
+    uint32_t id_dfr0, id_afr0;
+};
+STATIC_ASSERT_SIZEOF(struct arch_info_armv7, 28);
+
+STATIC_ASSERT(PI_ARCH_INFO_SIZE >= sizeof(struct arch_info_armv7), \
+              "Overflowed PI_ARCH_INFO_SIZE");
+
 /// Struct that can be used to request/parse platform information
 struct platform_info {
     enum pi_arch           arch;       // the architecture
     enum pi_platform       platform;   // the platfrom
+
+    /* Some platforms e.g. ARMv7 need the CPU driver to probe the hardware for
+     * them, e.g. for the number of CPUs. */
+    union {
+        struct arch_info_armv7 armv7;
+    } arch_info;
 };
 
 #endif
index 92fd139..3bff257 100644 (file)
@@ -258,6 +258,7 @@ let
                "arch/armv7/kludges.c",
                "arch/armv7/paging.c",
                "arch/armv7/plat_a15mpcore.c",
+               "arch/armv7/plat_id.c",
                "arch/armv7/plat_priv_cbar.c",
                "arch/armv7/plat_vexpress.c",
                "arch/armv7/plat_vexpress_consts.c",
@@ -316,6 +317,7 @@ let
                 "arch/armv7/kludges.c",
                 "arch/armv7/paging.c",
                 "arch/armv7/plat_a9mpcore.c",
+                "arch/armv7/plat_id.c",
                 "arch/armv7/plat_priv_cbar.c",
                 "arch/armv7/plat_vexpress.c",
                 "arch/armv7/plat_vexpress_consts.c",
@@ -411,6 +413,7 @@ let
                 "arch/armv7/init.c",
                 "arch/armv7/paging.c",
                 "arch/armv7/plat_a9mpcore.c",
+                "arch/armv7/plat_id.c",
                 "arch/armv7/plat_omap44xx.c",
                 "arch/armv7/plat_omap44xx_consts.c",
                 "arch/armv7/plat_priv_cbar.c",
@@ -485,6 +488,7 @@ let
                 "arch/armv7/init.c",
                 "arch/armv7/paging.c",
                 "arch/armv7/plat_a9mpcore.c",
+                "arch/armv7/plat_id.c",
                 "arch/armv7/plat_priv_cbar.c",
                 "arch/armv7/plat_zynq7.c",
                 "arch/armv7/plat_zynq7_consts.c",
diff --git a/kernel/arch/armv7/plat_id.c b/kernel/arch/armv7/plat_id.c
new file mode 100644 (file)
index 0000000..251575b
--- /dev/null
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2009-2015 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Haldeneggsteig 4, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+#include <kernel.h>
+
+#include <cp15.h>
+#include <platform.h>
+
+void
+armv7_get_info(struct arch_info_armv7 *ai) {
+    ai->ncores  = platform_get_core_count();
+    ai->midr    = cp15_read_midr();
+    ai->ctr     = cp15_read_ctr();
+    ai->id_pfr0 = cp15_read_id_pfr0();
+    ai->id_pfr1 = cp15_read_id_pfr1();
+    ai->id_dfr0 = cp15_read_id_dfr0();
+    ai->id_afr0 = cp15_read_id_afr0();
+}
index 3127069..c075b68 100644 (file)
@@ -77,6 +77,7 @@ void platform_get_info(struct platform_info *pi)
 {
     pi->arch     = PI_ARCH_ARMV7A;
     pi->platform = PI_PLATFORM_OMAP44XX;
+    armv7_get_info(&pi->arch_info.armv7);
 }
 
 /**
index c79e528..c246049 100644 (file)
@@ -68,9 +68,9 @@ void platform_get_info(struct platform_info *pi)
 {
     pi->arch     = PI_ARCH_ARMV7A;
     pi->platform = PI_PLATFORM_VEXPRESS;
+    armv7_get_info(&pi->arch_info.armv7);
 }
 
-
 /*
  * \brief Boot an arm app core
  *
index 2115ba5..a60998f 100644 (file)
@@ -99,6 +99,7 @@ void
 platform_get_info(struct platform_info *pi) {
     pi->arch     = PI_ARCH_ARMV7A;
     pi->platform = PI_PLATFORM_ZYNQ7;
+    armv7_get_info(&pi->arch_info.armv7);
 }
 
 /* The zc706 has 2GB of RAM beginning at address 0. */
index 788938b..ff7c061 100644 (file)
@@ -169,6 +169,27 @@ static inline uint32_t cp15_read_midr(void)
   return x;
 }
 
+static inline uint32_t cp15_read_ctr(void)
+{
+  uint32_t x;
+  __asm volatile ("mrc p15, 0, %[x], c0, c0, 1" : [x] "=r" (x));
+  return x;
+}
+
+static inline uint32_t cp15_read_id_dfr0(void)
+{
+  uint32_t x;
+  __asm volatile ("mrc p15, 0, %[x], c0, c1, 2" : [x] "=r" (x));
+  return x;
+}
+
+static inline uint32_t cp15_read_id_afr0(void)
+{
+  uint32_t x;
+  __asm volatile ("mrc p15, 0, %[x], c0, c1, 3" : [x] "=r" (x));
+  return x;
+}
+
 static inline uint32_t cp15_read_tpidruro(void)
 {
   uint32_t x;
index e502298..71af9f0 100644 (file)
@@ -54,6 +54,7 @@ void platform_print_id(void);
  * Fill out provided `struct platform_info`
  */
 void platform_get_info(struct platform_info *pi);
+void armv7_get_info(struct arch_info_armv7 *ai);
 
 /*
  * Figure out how much RAM we have
index 6540754..ef47c16 100644 (file)
@@ -320,7 +320,7 @@ let bin_rcce_lu = [ "/sbin/" ++ f | f <- [
                               "serial_kernel",
                               "spawnd",
                               "startd",
-                              -- "corectrl",
+                              "corectrl",
                               "skb",
                               "angler",
                               "fish",
index f675010..4272020 100644 (file)
@@ -118,6 +118,15 @@ errval_t arch_startup(char * add_device_db_file)
     assert(err_is_ok(err));
     assert(arch == PI_ARCH_ARMV7A);
 
+    uint8_t buf[PI_ARCH_INFO_SIZE];
+
+    struct arch_info_armv7 *arch_info= (struct arch_info_armv7 *)buf;
+    size_t buflen;
+    err = m->vtbl.get_platform_arch(m, buf, &buflen);
+    assert(buflen == sizeof(struct arch_info_armv7));
+
+    debug_printf("CPU driver reports %u core(s).\n", arch_info->ncores);
+
     switch(platform) {
         case PI_PLATFORM_OMAP44XX:
             debug_printf("Kaluga running on Pandaboard\n");
index 98fd636..4e68aa8 100644 (file)
@@ -14,5 +14,5 @@
                       cFiles = [ "main.c" ],
                       flounderBindings = [ "octopus" ],
                       addLibraries = libDeps [ "skb" ],
-                      architectures = [ "x86_64" ] }
+                      architectures = [ "x86_64", "armv7", "armv8" ] }
 ]
index 4538d73..94467db 100644 (file)
@@ -23,7 +23,7 @@
 #include <errors/errno.h>
 
 #include <barrelfish/barrelfish.h>
- #include <barrelfish/nameservice_client.h>
+#include <barrelfish/nameservice_client.h>
 #include <skb/skb.h>
 
 int main(int argc, char** argv)
@@ -31,8 +31,10 @@ int main(int argc, char** argv)
     errval_t err;
 
     printf("Starting listfacts\n");
+#ifndef __ARCH_ARM_7A__
     iref_t iref;
     nameservice_blocking_lookup("pci_discovery_done", &iref);
+#endif
 
     err = skb_client_connect();
     if (err_is_fail(err)) {
index 9e4c4cd..5019364 100644 (file)
@@ -553,6 +553,35 @@ static void get_platform(struct monitor_blocking_binding *b)
     }
 }
 
+static void get_platform_arch(struct monitor_blocking_binding *b)
+{
+    errval_t err;
+    size_t struct_size;
+
+    struct platform_info *pi= malloc(sizeof(struct platform_info));
+    if(!pi) USER_PANIC("Failed to allocate platform info struct.\n");
+
+    err = invoke_get_platform_info((uintptr_t)pi);
+    if (err_is_fail(err)) {
+        DEBUG_ERR(err, "get_platform_info invocation");
+    }
+
+    switch(pi->arch) {
+        case PI_ARCH_ARMV7A:
+            struct_size= sizeof(struct arch_info_armv7);
+            break;
+        default:
+            struct_size= 0;
+    }
+    assert(struct_size < PI_ARCH_INFO_SIZE);
+
+    err = b->tx_vtbl.get_platform_arch_response(b, MKCONT(free,pi),
+            (uint8_t *)&pi->arch_info, struct_size);
+    if (err_is_fail(err)) {
+        USER_PANIC_ERR(err, "sending platform info failed.");
+    }
+}
+
 /*------------------------- Initialization functions -------------------------*/
 
 static struct monitor_blocking_rx_vtbl rx_vtbl = {
@@ -585,6 +614,7 @@ static struct monitor_blocking_rx_vtbl rx_vtbl = {
     .get_global_paddr_call = get_global_paddr,
 
     .get_platform_call = get_platform,
+    .get_platform_arch_call = get_platform_arch,
 };
 
 static void export_callback(void *st, errval_t err, iref_t iref)