|
@@ -22,6 +22,7 @@
|
|
|
#include <asm/page.h>
|
|
|
#include <asm/hvcall.h>
|
|
|
#include <asm/firmware.h>
|
|
|
+#include <asm/prom.h>
|
|
|
|
|
|
|
|
|
#define MODULE_VERS "1.0"
|
|
@@ -38,26 +39,58 @@ static int sysfs_entries;
|
|
|
static u32 cpu_to_drc_index(int cpu)
|
|
|
{
|
|
|
struct device_node *dn = NULL;
|
|
|
- const int *indexes;
|
|
|
- int i;
|
|
|
+ int thread_index;
|
|
|
int rc = 1;
|
|
|
u32 ret = 0;
|
|
|
|
|
|
dn = of_find_node_by_path("/cpus");
|
|
|
if (dn == NULL)
|
|
|
goto err;
|
|
|
- indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
|
|
|
- if (indexes == NULL)
|
|
|
- goto err_of_node_put;
|
|
|
+
|
|
|
/* Convert logical cpu number to core number */
|
|
|
- i = cpu_core_index_of_thread(cpu);
|
|
|
- /*
|
|
|
- * The first element indexes[0] is the number of drc_indexes
|
|
|
- * returned in the list. Hence i+1 will get the drc_index
|
|
|
- * corresponding to core number i.
|
|
|
- */
|
|
|
- WARN_ON(i > indexes[0]);
|
|
|
- ret = indexes[i + 1];
|
|
|
+ thread_index = cpu_core_index_of_thread(cpu);
|
|
|
+
|
|
|
+ if (firmware_has_feature(FW_FEATURE_DRC_INFO)) {
|
|
|
+ struct property *info = NULL;
|
|
|
+ struct of_drc_info drc;
|
|
|
+ int j;
|
|
|
+ u32 num_set_entries;
|
|
|
+ const __be32 *value;
|
|
|
+
|
|
|
+ info = of_find_property(dn, "ibm,drc-info", NULL);
|
|
|
+ if (info == NULL)
|
|
|
+ goto err_of_node_put;
|
|
|
+
|
|
|
+ value = of_prop_next_u32(info, NULL, &num_set_entries);
|
|
|
+ if (!value)
|
|
|
+ goto err_of_node_put;
|
|
|
+
|
|
|
+ for (j = 0; j < num_set_entries; j++) {
|
|
|
+
|
|
|
+ of_read_drc_info_cell(&info, &value, &drc);
|
|
|
+ if (strncmp(drc.drc_type, "CPU", 3))
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ if (thread_index < drc.last_drc_index)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
+ ret = drc.drc_index_start + (thread_index * drc.sequential_inc);
|
|
|
+ } else {
|
|
|
+ const __be32 *indexes;
|
|
|
+
|
|
|
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
|
|
|
+ if (indexes == NULL)
|
|
|
+ goto err_of_node_put;
|
|
|
+
|
|
|
+ /*
|
|
|
+ * The first element indexes[0] is the number of drc_indexes
|
|
|
+ * returned in the list. Hence thread_index+1 will get the
|
|
|
+ * drc_index corresponding to core number thread_index.
|
|
|
+ */
|
|
|
+ ret = indexes[thread_index + 1];
|
|
|
+ }
|
|
|
+
|
|
|
rc = 0;
|
|
|
|
|
|
err_of_node_put:
|
|
@@ -72,34 +105,71 @@ static int drc_index_to_cpu(u32 drc_index)
|
|
|
{
|
|
|
struct device_node *dn = NULL;
|
|
|
const int *indexes;
|
|
|
- int i, cpu = 0;
|
|
|
+ int thread_index = 0, cpu = 0;
|
|
|
int rc = 1;
|
|
|
|
|
|
dn = of_find_node_by_path("/cpus");
|
|
|
if (dn == NULL)
|
|
|
goto err;
|
|
|
- indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
|
|
|
- if (indexes == NULL)
|
|
|
- goto err_of_node_put;
|
|
|
- /*
|
|
|
- * First element in the array is the number of drc_indexes
|
|
|
- * returned. Search through the list to find the matching
|
|
|
- * drc_index and get the core number
|
|
|
- */
|
|
|
- for (i = 0; i < indexes[0]; i++) {
|
|
|
- if (indexes[i + 1] == drc_index)
|
|
|
+
|
|
|
+ if (firmware_has_feature(FW_FEATURE_DRC_INFO)) {
|
|
|
+ struct property *info = NULL;
|
|
|
+ struct of_drc_info drc;
|
|
|
+ int j;
|
|
|
+ u32 num_set_entries;
|
|
|
+ const __be32 *value;
|
|
|
+
|
|
|
+ info = of_find_property(dn, "ibm,drc-info", NULL);
|
|
|
+ if (info == NULL)
|
|
|
+ goto err_of_node_put;
|
|
|
+
|
|
|
+ value = of_prop_next_u32(info, NULL, &num_set_entries);
|
|
|
+ if (!value)
|
|
|
+ goto err_of_node_put;
|
|
|
+
|
|
|
+ for (j = 0; j < num_set_entries; j++) {
|
|
|
+
|
|
|
+ of_read_drc_info_cell(&info, &value, &drc);
|
|
|
+ if (strncmp(drc.drc_type, "CPU", 3))
|
|
|
+ goto err;
|
|
|
+
|
|
|
+ if (drc_index > drc.last_drc_index) {
|
|
|
+ cpu += drc.num_sequential_elems;
|
|
|
+ continue;
|
|
|
+ }
|
|
|
+ cpu += ((drc_index - drc.drc_index_start) /
|
|
|
+ drc.sequential_inc);
|
|
|
+
|
|
|
+ thread_index = cpu_first_thread_of_core(cpu);
|
|
|
+ rc = 0;
|
|
|
break;
|
|
|
+ }
|
|
|
+ } else {
|
|
|
+ unsigned long int i;
|
|
|
+
|
|
|
+ indexes = of_get_property(dn, "ibm,drc-indexes", NULL);
|
|
|
+ if (indexes == NULL)
|
|
|
+ goto err_of_node_put;
|
|
|
+ /*
|
|
|
+ * First element in the array is the number of drc_indexes
|
|
|
+ * returned. Search through the list to find the matching
|
|
|
+ * drc_index and get the core number
|
|
|
+ */
|
|
|
+ for (i = 0; i < indexes[0]; i++) {
|
|
|
+ if (indexes[i + 1] == drc_index)
|
|
|
+ break;
|
|
|
+ }
|
|
|
+ /* Convert core number to logical cpu number */
|
|
|
+ thread_index = cpu_first_thread_of_core(i);
|
|
|
+ rc = 0;
|
|
|
}
|
|
|
- /* Convert core number to logical cpu number */
|
|
|
- cpu = cpu_first_thread_of_core(i);
|
|
|
- rc = 0;
|
|
|
|
|
|
err_of_node_put:
|
|
|
of_node_put(dn);
|
|
|
err:
|
|
|
if (rc)
|
|
|
printk(KERN_WARNING "drc_index_to_cpu(%d) failed", drc_index);
|
|
|
- return cpu;
|
|
|
+ return thread_index;
|
|
|
}
|
|
|
|
|
|
/*
|