Bug fix: Rectify logic to enter or exit from DVM domain
authorVikram Kanigiri <vikram.kanigiri@arm.com>
Mon, 4 Jan 2016 16:23:22 +0000 (16:23 +0000)
committerVikram Kanigiri <vikram.kanigiri@arm.com>
Mon, 8 Feb 2016 10:42:56 +0000 (10:42 +0000)
Currently, `ccn_snoop_dvm_domain_common()` is responsible for providing
a bitmap of HN-F and HN-I nodes in the interconnect. There is a request
node (RN) corresponding to the master interface (e.g. cluster) that needs
to be added or removed from the snoop/DVM domain. This request node is
removed from or added to each HN-F or HN-I node present in the bitmap
depending upon the type of domain.

The above logic is incorrect when participation of a master interface in
the DVM domain has to be managed. The request node should be removed
from or added to the single Miscellaneous Node (MN) in the system
instead of each HN-I node.

This patch fixes this by removing the intermediate
`ccn_snoop_dvm_domain_common()` and instead reads the MN registers to
get the needed node Id bitmap for snoop(HN-F bitmap) and DVM(MN bitmap)
domains.

Additionally, it renames `MN_DDC_SET_OFF` to `MN_DDC_SET_OFFSET` to
be inline with other macros.

Change-Id: Id896046dd0ccc5092419e74f8ac85e31b104f7a4

drivers/arm/ccn/ccn.c
drivers/arm/ccn/ccn_private.h

index aef891b207adfd50d2b0bd33ccc6b3e1489813a3..28d270984a0c35e3c3820c25cbf11c87d377c604 100644 (file)
@@ -268,7 +268,7 @@ static unsigned long long ccn_master_to_rn_id_map(unsigned long long master_map)
 /*******************************************************************************
  * This function executes the necessary operations to add or remove Request node
  * IDs specified in the 'rn_id_map' bitmap from the snoop/DVM domains specified
- * in the 'hn_id_map'. The 'region_id' specifies the ID of the first HN-F/HN-I
+ * in the 'hn_id_map'. The 'region_id' specifies the ID of the first HN-F/MN
  * on which the operation should be performed. 'op_reg_offset' specifies the
  * type of operation (add/remove). 'stat_reg_offset' specifies the register
  * which should be polled to determine if the operation has completed or not.
@@ -309,35 +309,6 @@ static void ccn_snoop_dvm_do_op(unsigned long long rn_id_map,
 #endif
 }
 
-/*******************************************************************************
- * This function reads the bitmap of Home nodes on the basis of the
- * 'mn_hn_id_reg_offset' parameter from the Miscellaneous node's (MN)
- * programmer's view. The MN has a register which carries the bitmap of present
- * Home nodes of each type i.e. HN-Fs, HN-Is & HN-Ds. It calls
- * 'ccn_snoop_dvm_do_op()' with this information to perform the actual
- * operation.
- ******************************************************************************/
-static void ccn_snoop_dvm_domain_common(unsigned long long rn_id_map,
-                                       unsigned int hn_op_reg_offset,
-                                       unsigned int hn_stat_reg_offset,
-                                       unsigned int mn_hn_id_reg_offset,
-                                       unsigned int hn_region_id)
-{
-       unsigned long long mn_hn_id_map;
-
-       assert(ccn_plat_desc);
-       assert(ccn_plat_desc->periphbase);
-
-       mn_hn_id_map = ccn_reg_read(ccn_plat_desc->periphbase,
-                                   MN_REGION_ID,
-                                   mn_hn_id_reg_offset);
-       ccn_snoop_dvm_do_op(rn_id_map,
-                           mn_hn_id_map,
-                           hn_region_id,
-                           hn_op_reg_offset,
-                           hn_stat_reg_offset);
-}
-
 /*******************************************************************************
  * The following functions provide the boot and runtime API to the platform for
  * adding and removing master interfaces from the snoop/DVM domains. A bitmap of
@@ -357,17 +328,18 @@ void ccn_enter_snoop_dvm_domain(unsigned long long master_iface_map)
        unsigned long long rn_id_map;
 
        rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
-       ccn_snoop_dvm_domain_common(rn_id_map,
-                                   HNF_SDC_SET_OFFSET,
-                                   HNF_SDC_STAT_OFFSET,
-                                   MN_HNF_NODEID_OFFSET,
-                                   HNF_REGION_ID_START);
-
-       ccn_snoop_dvm_domain_common(rn_id_map,
-                                   MN_DDC_SET_OFF,
-                                   MN_DDC_STAT_OFFSET,
-                                   MN_HNI_NODEID_OFFSET,
-                                   MN_REGION_ID);
+       ccn_snoop_dvm_do_op(rn_id_map,
+                           CCN_GET_HN_NODEID_MAP(ccn_plat_desc->periphbase,
+                                                 MN_HNF_NODEID_OFFSET),
+                           HNF_REGION_ID_START,
+                           HNF_SDC_SET_OFFSET,
+                           HNF_SDC_STAT_OFFSET);
+
+       ccn_snoop_dvm_do_op(rn_id_map,
+                           CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
+                           MN_REGION_ID,
+                           MN_DDC_SET_OFFSET,
+                           MN_DDC_STAT_OFFSET);
 }
 
 void ccn_exit_snoop_dvm_domain(unsigned long long master_iface_map)
@@ -375,17 +347,18 @@ void ccn_exit_snoop_dvm_domain(unsigned long long master_iface_map)
        unsigned long long rn_id_map;
 
        rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
-       ccn_snoop_dvm_domain_common(rn_id_map,
-                                   HNF_SDC_CLR_OFFSET,
-                                   HNF_SDC_STAT_OFFSET,
-                                   MN_HNF_NODEID_OFFSET,
-                                   HNF_REGION_ID_START);
-
-       ccn_snoop_dvm_domain_common(rn_id_map,
-                                   MN_DDC_CLR_OFFSET,
-                                   MN_DDC_STAT_OFFSET,
-                                   MN_HNI_NODEID_OFFSET,
-                                   MN_REGION_ID);
+       ccn_snoop_dvm_do_op(rn_id_map,
+                           CCN_GET_HN_NODEID_MAP(ccn_plat_desc->periphbase,
+                                                 MN_HNF_NODEID_OFFSET),
+                           HNF_REGION_ID_START,
+                           HNF_SDC_CLR_OFFSET,
+                           HNF_SDC_STAT_OFFSET);
+
+       ccn_snoop_dvm_do_op(rn_id_map,
+                           CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
+                           MN_REGION_ID,
+                           MN_DDC_CLR_OFFSET,
+                           MN_DDC_STAT_OFFSET);
 }
 
 void ccn_enter_dvm_domain(unsigned long long master_iface_map)
@@ -393,11 +366,11 @@ void ccn_enter_dvm_domain(unsigned long long master_iface_map)
        unsigned long long rn_id_map;
 
        rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
-       ccn_snoop_dvm_domain_common(rn_id_map,
-                                   MN_DDC_SET_OFF,
-                                   MN_DDC_STAT_OFFSET,
-                                   MN_HNI_NODEID_OFFSET,
-                                   MN_REGION_ID);
+       ccn_snoop_dvm_do_op(rn_id_map,
+                           CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
+                           MN_REGION_ID,
+                           MN_DDC_SET_OFFSET,
+                           MN_DDC_STAT_OFFSET);
 }
 
 void ccn_exit_dvm_domain(unsigned long long master_iface_map)
@@ -405,11 +378,11 @@ void ccn_exit_dvm_domain(unsigned long long master_iface_map)
        unsigned long long rn_id_map;
 
        rn_id_map = ccn_master_to_rn_id_map(master_iface_map);
-       ccn_snoop_dvm_domain_common(rn_id_map,
-                                   MN_DDC_CLR_OFFSET,
-                                   MN_DDC_STAT_OFFSET,
-                                   MN_HNI_NODEID_OFFSET,
-                                   MN_REGION_ID);
+       ccn_snoop_dvm_do_op(rn_id_map,
+                           CCN_GET_MN_NODEID_MAP(ccn_plat_desc->periphbase),
+                           MN_REGION_ID,
+                           MN_DDC_CLR_OFFSET,
+                           MN_DDC_STAT_OFFSET);
 }
 
 /*******************************************************************************
index e92e870266322762af03feb2ae151c85f15b1c85..8b15472565e48e30179ea8e1a37251a7f17526d9 100644 (file)
@@ -147,7 +147,7 @@ typedef enum rn_types {
 #define MN_HNI_NODEID_OFFSET   0x01C0
 #define MN_SN_NODEID_OFFSET    0x01D0
 #define MN_DDC_STAT_OFFSET     DOMAIN_CTRL_STAT_OFFSET
-#define MN_DDC_SET_OFF         DOMAIN_CTRL_SET_OFFSET
+#define MN_DDC_SET_OFFSET      DOMAIN_CTRL_SET_OFFSET
 #define MN_DDC_CLR_OFFSET      DOMAIN_CTRL_CLR_OFFSET
 #define MN_ID_OFFSET           REGION_ID_OFFSET
 
@@ -236,4 +236,21 @@ static inline unsigned int count_set_bits(uint64_t bitmap)
  */
 #define FOR_EACH_PRESENT_MASTER_INTERFACE(iface_id, bit_map)   \
                        FOR_EACH_BIT(iface_id, bit_map)
+
+/*
+ * Macro that returns the node id bit map for the Miscellaneous Node
+ */
+#define CCN_GET_MN_NODEID_MAP(periphbase)                              \
+       (1 << get_node_id(ccn_reg_read(periphbase, MN_REGION_ID,        \
+                                               REGION_ID_OFFSET)))
+
+/*
+ * This macro returns the bitmap of Home nodes on the basis of the
+ * 'mn_hn_id_reg_offset' parameter from the Miscellaneous node's (MN)
+ * programmer's view. The MN has a register which carries the bitmap of present
+ * Home nodes of each type i.e. HN-Fs, HN-Is & HN-Ds.
+ */
+#define CCN_GET_HN_NODEID_MAP(periphbase, mn_hn_id_reg_offset)         \
+       ccn_reg_read(periphbase, MN_REGION_ID, mn_hn_id_reg_offset)
+
 #endif /* __CCN_PRIVATE_H__ */