aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--hdata/fsp.c4
-rw-r--r--hdata/hdata.h1
-rw-r--r--hdata/spira.c28
-rw-r--r--hw/phys-map.c18
-rw-r--r--hw/test/phys-map-test.c7
-rw-r--r--include/phys-map.h3
6 files changed, 57 insertions, 4 deletions
diff --git a/hdata/fsp.c b/hdata/fsp.c
index 42f1121..30cda53 100644
--- a/hdata/fsp.c
+++ b/hdata/fsp.c
@@ -361,6 +361,7 @@ static void bmc_create_node(const struct HDIF_common_hdr *sp)
struct dt_node *lpcm, *lpc, *n;
u64 lpcm_base, lpcm_end;
uint32_t chip_id;
+ uint32_t topology_idx;
int size;
bmc_node = dt_new(dt_root, "bmc");
@@ -399,8 +400,9 @@ static void bmc_create_node(const struct HDIF_common_hdr *sp)
* phys map offset
*/
chip_id = pcid_to_chip_id(be32_to_cpu(iopath->lpc.chip_id));
+ topology_idx = pcid_to_topology_idx(be32_to_cpu(iopath->lpc.chip_id));
- phys_map_get(chip_id, LPC_BUS, 0, &lpcm_base, NULL);
+ __phys_map_get(topology_idx, chip_id, LPC_BUS, 0, &lpcm_base, NULL);
lpcm = dt_new_addr(dt_root, "lpcm-opb", lpcm_base);
assert(lpcm);
diff --git a/hdata/hdata.h b/hdata/hdata.h
index bae4eaa..6aad829 100644
--- a/hdata/hdata.h
+++ b/hdata/hdata.h
@@ -24,6 +24,7 @@ extern void vpd_data_parse(struct dt_node *node,
extern struct dt_node *find_xscom_for_chip(uint32_t chip_id);
extern uint32_t pcid_to_chip_id(uint32_t proc_chip_id);
+extern uint32_t pcid_to_topology_idx(uint32_t proc_chip_id);
extern uint32_t get_xscom_id(const struct sppcrd_chip_info *cinfo);
extern struct dt_node *add_core_common(struct dt_node *cpus,
diff --git a/hdata/spira.c b/hdata/spira.c
index 7d56f3f..baa2375 100644
--- a/hdata/spira.c
+++ b/hdata/spira.c
@@ -1418,6 +1418,34 @@ uint32_t pcid_to_chip_id(uint32_t proc_chip_id)
return (uint32_t)-1;
}
+uint32_t pcid_to_topology_idx(uint32_t proc_chip_id)
+{
+ unsigned int i;
+ const void *hdif;
+
+ /* First, try the proc_chip ntuples for chip data */
+ for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
+ SPPCRD_HDIF_SIG) {
+ const struct sppcrd_chip_info *cinfo;
+
+ cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
+ if (!CHECK_SPPTR(cinfo)) {
+ prerror("XSCOM: Bad ChipID data %d\n", i);
+ continue;
+ }
+ if (proc_chip_id == be32_to_cpu(cinfo->proc_chip_id)) {
+ if (proc_gen <= proc_gen_p9)
+ return get_xscom_id(cinfo);
+ else
+ return ((u32)cinfo->topology_id_table[cinfo->primary_topology_loc]);
+ }
+ }
+
+ /* Not found, what to do ? Assert ? For now return a number
+ * guaranteed to not exist
+ */
+ return (uint32_t)-1;
+}
/* Create '/ibm,opal/led' node */
static void dt_init_led_node(void)
{
diff --git a/hw/phys-map.c b/hw/phys-map.c
index 2c4d8e4..194e495 100644
--- a/hw/phys-map.c
+++ b/hw/phys-map.c
@@ -277,7 +277,7 @@ static inline bool phys_map_entry_null(const struct phys_map_entry *e)
/* This crashes skiboot on error as any bad calls here are almost
* certainly a developer error
*/
-void phys_map_get(uint64_t gcid, enum phys_map_type type,
+void __phys_map_get(uint64_t topology_idx, uint64_t gcid, enum phys_map_type type,
int index, uint64_t *addr, uint64_t *size) {
const struct phys_map_entry *e;
uint64_t a;
@@ -302,7 +302,7 @@ void phys_map_get(uint64_t gcid, enum phys_map_type type,
break;
}
a = e->addr;
- a += gcid << phys_map->chip_select_shift;
+ a += topology_idx << (phys_map->chip_select_shift);
if (addr)
*addr = a;
@@ -322,6 +322,20 @@ error:
assert(0);
}
+void phys_map_get(uint64_t gcid, enum phys_map_type type,
+ int index, uint64_t *addr, uint64_t *size)
+{
+ struct proc_chip *chip;
+ uint64_t topology_idx = gcid;
+
+ if (proc_gen >= proc_gen_p10) {
+ chip = get_chip(gcid);
+ topology_idx = chip->primary_topology;
+ }
+
+ return __phys_map_get(topology_idx, gcid, type, index, addr, size);
+}
+
void phys_map_init(unsigned long pvr)
{
const char *name = "unused";
diff --git a/hw/test/phys-map-test.c b/hw/test/phys-map-test.c
index 2aabdb8..aa5b733 100644
--- a/hw/test/phys-map-test.c
+++ b/hw/test/phys-map-test.c
@@ -79,6 +79,11 @@ static inline bool map_call_entry_null(const struct map_call_entry *t)
/* Pick a chip ID, any ID. */
#define FAKE_CHIP_ID 8
+struct proc_chip *get_chip(uint32_t chip_id __unused)
+{
+ return NULL;
+}
+
static void check_map_call(void)
{
uint64_t start, size, end;
@@ -98,7 +103,7 @@ static void check_map_call(void)
/* Loop over table entries ... */
for (e = phys_map->table; !phys_map_entry_null(e); e++) {
- phys_map_get(FAKE_CHIP_ID, e->type, e->index, &start, &size);
+ __phys_map_get(FAKE_CHIP_ID, FAKE_CHIP_ID, e->type, e->index, &start, &size);
/* Check for alignment */
if ((e->type != SYSTEM_MEM) && (e->type != RESV)) {
diff --git a/include/phys-map.h b/include/phys-map.h
index ae7a4aa..97351a7 100644
--- a/include/phys-map.h
+++ b/include/phys-map.h
@@ -48,6 +48,9 @@ enum phys_map_type {
extern void phys_map_get(uint64_t gcid, enum phys_map_type type,
int index, uint64_t *addr, uint64_t *size);
+extern void __phys_map_get(uint64_t topology_idx, uint64_t gcid,
+ enum phys_map_type type, int index, uint64_t *addr, uint64_t *size);
+
extern void phys_map_init(unsigned long pvr);
#endif /* __PHYS_MAP_H */