ARM platforms: Add support for MT bit in MPIDR
authorSummer Qin <summer.qin@arm.com>
Tue, 28 Feb 2017 16:46:17 +0000 (16:46 +0000)
committerSummer Qin <summer.qin@arm.com>
Mon, 27 Mar 2017 13:53:43 +0000 (14:53 +0100)
This patch modifies some of the functions in ARM platform layer to cater
for the case when multi-threading `MT` is set in MPIDR. A new build flag
`ARM_PLAT_MT` is added, and when enabled, the functions accessing MPIDR
now assume that the `MT` bit is set for the platform and access the bit
fields accordingly.

Also, a new API plat_arm_get_cpu_pe_count is added when `ARM_PLAT_MT` is
enabled, returning the PE count within the physical cpu corresponding to
`mpidr`.

Change-Id: I04ccf212ac3054a60882761f4087bae299af13cb
Signed-off-by: Summer Qin <summer.qin@arm.com>
docs/user-guide.md
include/lib/aarch32/arch.h
include/lib/aarch64/arch.h
include/plat/arm/common/plat_arm.h
plat/arm/common/arm_common.mk
plat/arm/common/arm_topology.c
plat/arm/css/common/css_topology.c
plat/arm/css/drivers/scpi/css_scpi.c

index 091aeba04f60f8f14a7fe7faf9f099605d8bdb2b..9a2562cac1f52f60e0bb4afc04c5547f1820d2cf 100644 (file)
@@ -197,6 +197,12 @@ performed.
     by the interrupt management framework. Default is 2 (that is, version 2.0).
     This build option is deprecated.
 
+*   `ARM_PLAT_MT`: This flag determines whether the ARM platform layer has to
+    cater for the multi-threading `MT` bit when accessing MPIDR. When this
+    flag is set, the functions which deal with MPIDR assume that the `MT` bit
+    in MPIDR is set and access the bit-fields in MPIDR accordingly. Default
+    value of this flag is 0.
+
 *   `ASM_ASSERTION`: This flag determines whether the assertion checks within
     assembly source files are enabled or not. This option defaults to the
     value of `DEBUG` - that is, by default this is only enabled for a debug
index 8525c7babd7c8b497dcdc9a2af4a9b8b6d8cdfd7..14212d5d25dd2dc501000a0a57e15e4d354e4cc4 100644 (file)
@@ -46,6 +46,7 @@
 /*******************************************************************************
  * MPIDR macros
  ******************************************************************************/
+#define MPIDR_MT_MASK          (1 << 24)
 #define MPIDR_CPU_MASK         MPIDR_AFFLVL_MASK
 #define MPIDR_CLUSTER_MASK     (MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS)
 #define MPIDR_AFFINITY_BITS    8
index 5876ce817d4f85e779a3a7b3bef1df0ed3bc49d0..a854e9611e2f7f9d1e79e6098c8e60a0b9004666 100644 (file)
@@ -49,6 +49,7 @@
 /*******************************************************************************
  * MPIDR macros
  ******************************************************************************/
+#define MPIDR_MT_MASK          (1 << 24)
 #define MPIDR_CPU_MASK         MPIDR_AFFLVL_MASK
 #define MPIDR_CLUSTER_MASK     MPIDR_AFFLVL_MASK << MPIDR_AFFINITY_BITS
 #define MPIDR_AFFINITY_BITS    8
index e878f9ebf7ea789450a86e646e8a2192076c64d3..ccdfd41a06af4e9272f07b191a13c3308bb1d7de 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
@@ -203,6 +203,10 @@ void plat_arm_interconnect_init(void);
 void plat_arm_interconnect_enter_coherency(void);
 void plat_arm_interconnect_exit_coherency(void);
 
+#if ARM_PLAT_MT
+unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr);
+#endif
+
 #if LOAD_IMAGE_V2
 /*
  * This function is called after loading SCP_BL2 image and it is used to perform
index 4628a43d07042f11bcdec24415b23d2f6661a20b..204ae4c9c9956b45fc9a549166eda1856ad6b474 100644 (file)
@@ -90,6 +90,11 @@ ARM_BL31_IN_DRAM             :=      0
 $(eval $(call assert_boolean,ARM_BL31_IN_DRAM))
 $(eval $(call add_define,ARM_BL31_IN_DRAM))
 
+# Process ARM_PLAT_MT flag
+ARM_PLAT_MT                    :=      0
+$(eval $(call assert_boolean,ARM_PLAT_MT))
+$(eval $(call add_define,ARM_PLAT_MT))
+
 # Enable PSCI_STAT_COUNT/RESIDENCY APIs on ARM platforms
 ENABLE_PSCI_STAT               :=      1
 ENABLE_PMF                     :=      1
index 4430b139991cdbe1bbf20d540ca1705a5c32cf2c..3c952636a47f76bb22b541ce5eedb85e07d9131e 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
 int arm_check_mpidr(u_register_t mpidr)
 {
        unsigned int cluster_id, cpu_id;
+       uint64_t valid_mask;
 
-       mpidr &= MPIDR_AFFINITY_MASK;
-
-       if (mpidr & ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK))
-               return -1;
+#if ARM_PLAT_MT
+       unsigned int pe_id;
 
+       valid_mask = ~(MPIDR_AFFLVL_MASK |
+                       (MPIDR_AFFLVL_MASK << MPIDR_AFF1_SHIFT) |
+                       (MPIDR_AFFLVL_MASK << MPIDR_AFF2_SHIFT));
+       cluster_id = (mpidr >> MPIDR_AFF2_SHIFT) & MPIDR_AFFLVL_MASK;
+       cpu_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
+       pe_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+#else
+       valid_mask = ~(MPIDR_CLUSTER_MASK | MPIDR_CPU_MASK);
        cluster_id = (mpidr >> MPIDR_AFF1_SHIFT) & MPIDR_AFFLVL_MASK;
        cpu_id = (mpidr >> MPIDR_AFF0_SHIFT) & MPIDR_AFFLVL_MASK;
+#endif /* ARM_PLAT_MT */
+
+       mpidr &= MPIDR_AFFINITY_MASK;
+       if (mpidr & valid_mask)
+               return -1;
 
        if (cluster_id >= PLAT_ARM_CLUSTER_COUNT)
                return -1;
@@ -57,5 +69,10 @@ int arm_check_mpidr(u_register_t mpidr)
        if (cpu_id >= plat_arm_get_cluster_core_count(mpidr))
                return -1;
 
+#if ARM_PLAT_MT
+       if (pe_id >= plat_arm_get_cpu_pe_count(mpidr))
+               return -1;
+#endif /* ARM_PLAT_MT */
+
        return 0;
 }
index d5f0275a8e04389f802ea8f6698ec15cd3ea3eee..9c86f8939f60e181157bce4bc3fbea3b003105bd 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2015-2016, ARM Limited and Contributors. All rights reserved.
+ * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are met:
 
 #include <plat_arm.h>
 
+#if ARM_PLAT_MT
+#pragma weak plat_arm_get_cpu_pe_count
+#endif
+
 /******************************************************************************
  * This function implements a part of the critical interface between the psci
  * generic layer and the platform that allows the former to query the platform
@@ -43,3 +47,14 @@ int plat_core_pos_by_mpidr(u_register_t mpidr)
 
        return -1;
 }
+
+#if ARM_PLAT_MT
+/******************************************************************************
+ * This function returns the PE count within the physical cpu corresponding to
+ * `mpidr`. Now one cpu only have one thread, so just return 1.
+ *****************************************************************************/
+unsigned int plat_arm_get_cpu_pe_count(u_register_t mpidr)
+{
+       return 1;
+}
+#endif /* ARM_PLAT_MT */
index 65ae978f867781208d0f40edeac3aba0eea5838d..7c5c5789a53dfaafdfe785b8fd2af9d0fac37a78 100644 (file)
@@ -150,8 +150,18 @@ void scpi_set_css_power_state(unsigned int mpidr,
        uint32_t state = 0;
        uint32_t *payload_addr;
 
+#if ARM_PLAT_MT
+       /*
+        * The current SCPI driver only caters for single-threaded platforms.
+        * Hence we ignore the thread ID (which is always 0) for such platforms.
+        */
+       state |= (mpidr >> MPIDR_AFF1_SHIFT) & 0x0f;    /* CPU ID */
+       state |= ((mpidr >> MPIDR_AFF2_SHIFT) & 0x0f) << 4;     /* Cluster ID */
+#else
        state |= mpidr & 0x0f;  /* CPU ID */
        state |= (mpidr & 0xf00) >> 4;  /* Cluster ID */
+#endif /* ARM_PLAT_MT */
+
        state |= cpu_state << 8;
        state |= cluster_state << 12;
        state |= css_state << 16;