1
/* Copyright 2013-2014 IBM Corp.
3
* Licensed under the Apache License, Version 2.0 (the "License");
4
* you may not use this file except in compliance with the License.
5
* You may obtain a copy of the License at
7
* http://www.apache.org/licenses/LICENSE-2.0
9
* Unless required by applicable law or agreed to in writing, software
10
* distributed under the License is distributed on an "AS IS" BASIS,
11
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
13
* See the License for the specific language governing permissions and
14
* limitations under the License.
21
#include <interrupts.h>
22
#include <ccan/str/str.h>
24
#include <fsp-mdst-table.h>
29
#include "hostservices.h"
31
/* Processor Initialization structure, contains
32
* the initial NIA and MSR values for the entry
35
* Note: It appears to be ignoring the entry point
36
* and always going to 0x180
41
__section(".procin.data") struct proc_init_data proc_init_data = {
42
.hdr = HDIF_SIMPLE_HDR("PROCIN", 1, struct proc_init_data),
43
.regs_ptr = HDIF_IDATA_PTR(offsetof(struct proc_init_data, regs), 0x10),
45
.nia = CPU_TO_BE64(0x180),
46
.msr = CPU_TO_BE64(0x9000000000000000ULL), /* SF | HV */
50
__section(".cpuctrl.data") struct sp_addr_table cpu_ctl_spat_area;
51
__section(".cpuctrl.data") struct sp_attn_area cpu_ctl_sp_attn_area1;
52
__section(".cpuctrl.data") struct sp_attn_area cpu_ctl_sp_attn_area2;
53
__section(".cpuctrl.data") struct hsr_data_area cpu_ctl_hsr_area;
55
__section(".cpuctrl.data") struct cpu_ctl_init_data cpu_ctl_init_data = {
56
.hdr = HDIF_SIMPLE_HDR(CPU_CTL_HDIF_SIG, 2, struct cpu_ctl_init_data),
57
.cpu_ctl = HDIF_IDATA_PTR(offsetof(struct cpu_ctl_init_data, cpu_ctl_lt), sizeof(struct cpu_ctl_legacy_table)),
61
.addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_spat_area) + SKIBOOT_BASE),
62
.size = CPU_TO_BE64(sizeof(struct sp_addr_table)),
65
.addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_sp_attn_area1) + SKIBOOT_BASE),
66
.size = CPU_TO_BE64(sizeof(struct sp_attn_area)),
69
.addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_sp_attn_area2) + SKIBOOT_BASE),
70
.size = CPU_TO_BE64(sizeof(struct sp_attn_area)),
73
.addr = CPU_TO_BE64((unsigned long)&(cpu_ctl_hsr_area) + SKIBOOT_BASE),
74
.size = CPU_TO_BE64(sizeof(struct hsr_data_area)),
80
/* Populate MDST table
82
* Note that we only pass sapphire console buffer here so that we can
83
* capture early failure logs. Later dump component (fsp_dump_mdst_init)
84
* creates new table with all the memory sections we are interested and
85
* sends updated table to FSP via MBOX.
87
* To help the FSP distinguishing between TCE tokens and actual physical
88
* addresses, we set the top bit to 1 on physical addresses
90
#define ADDR_TOP_BIT (1ul << 63)
92
__section(".mdst.data") struct dump_mdst_table init_mdst_table[2] = {
94
.addr = CPU_TO_BE64(INMEM_CON_START | ADDR_TOP_BIT),
95
.type = CPU_TO_BE32(DUMP_REGION_CONSOLE),
96
.size = CPU_TO_BE32(INMEM_CON_LEN),
99
.addr = CPU_TO_BE64(HBRT_CON_START | ADDR_TOP_BIT),
100
.type = CPU_TO_BE32(DUMP_REGION_HBRT_LOG),
101
.size = CPU_TO_BE32(HBRT_CON_LEN),
105
/* SP Interface Root Array, aka SPIRA */
106
__section(".spira.data") struct spira spira = {
107
.hdr = HDIF_SIMPLE_HDR("SPIRA ", SPIRA_VERSION, struct spira),
108
.ntuples_ptr = HDIF_IDATA_PTR(offsetof(struct spira, ntuples),
109
sizeof(struct spira_ntuples)),
112
.offset = CPU_TO_BE32(HDIF_ARRAY_OFFSET),
113
.ecnt = CPU_TO_BE32(SPIRA_NTUPLES_COUNT),
115
= CPU_TO_BE32(sizeof(struct spira_ntuple)),
116
.eactsz = CPU_TO_BE32(0x18),
118
/* We only populate some n-tuples */
120
.addr = CPU_TO_BE64(PROCIN_OFF),
121
.alloc_cnt = CPU_TO_BE16(1),
122
.act_cnt = CPU_TO_BE16(1),
124
= CPU_TO_BE32(sizeof(struct proc_init_data)),
127
.addr = CPU_TO_BE64(SPIRA_HEAP_BASE),
128
.alloc_cnt = CPU_TO_BE16(1),
129
.alloc_len = CPU_TO_BE32(SPIRA_HEAP_SIZE),
132
.addr = CPU_TO_BE64(MDST_TABLE_OFF),
133
.alloc_cnt = CPU_TO_BE16(ARRAY_SIZE(init_mdst_table)),
134
.act_cnt = CPU_TO_BE16(ARRAY_SIZE(init_mdst_table)),
136
CPU_TO_BE32(sizeof(init_mdst_table)),
140
.addr = CPU_TO_BE64((unsigned long)&cpu_ctl_init_data),
141
.alloc_cnt = CPU_TO_BE16(1),
142
.act_cnt = CPU_TO_BE16(1),
144
CPU_TO_BE32(sizeof(cpu_ctl_init_data)),
150
/* The Hypervisor SPIRA-H Structure */
151
__section(".spirah.data") struct spirah spirah = {
152
.hdr = HDIF_SIMPLE_HDR(SPIRAH_HDIF_SIG, SPIRAH_VERSION, struct spirah),
153
.ntuples_ptr = HDIF_IDATA_PTR(offsetof(struct spirah, ntuples),
154
sizeof(struct spirah_ntuples)),
157
.offset = CPU_TO_BE32(HDIF_ARRAY_OFFSET),
158
.ecnt = CPU_TO_BE32(SPIRAH_NTUPLES_COUNT),
160
= CPU_TO_BE32(sizeof(struct spira_ntuple)),
161
.eactsz = CPU_TO_BE32(0x18),
163
/* Host Data Areas */
165
.addr = CPU_TO_BE64(SPIRA_HEAP_BASE),
166
.alloc_cnt = CPU_TO_BE16(1),
167
.alloc_len = CPU_TO_BE32(SPIRA_HEAP_SIZE),
169
/* We only populate some n-tuples */
171
.addr = CPU_TO_BE64(PROCIN_OFF),
172
.alloc_cnt = CPU_TO_BE16(1),
173
.act_cnt = CPU_TO_BE16(1),
175
= CPU_TO_BE32(sizeof(struct proc_init_data)),
179
.addr = CPU_TO_BE64((unsigned long)&cpu_ctl_init_data),
180
.alloc_cnt = CPU_TO_BE16(1),
181
.act_cnt = CPU_TO_BE16(1),
183
CPU_TO_BE32(sizeof(cpu_ctl_init_data)),
187
.addr = CPU_TO_BE64(MDST_TABLE_OFF),
188
.alloc_cnt = CPU_TO_BE16(ARRAY_SIZE(init_mdst_table)),
189
.act_cnt = CPU_TO_BE16(ARRAY_SIZE(init_mdst_table)),
191
CPU_TO_BE32(sizeof(init_mdst_table)),
196
/* The service processor SPIRA-S structure */
197
struct spiras *spiras;
199
/* Overridden for testing. */
200
#ifndef spira_check_ptr
201
bool spira_check_ptr(const void *ptr, const char *file, unsigned int line)
205
if (((unsigned long)ptr) >= SPIRA_HEAP_BASE &&
206
((unsigned long)ptr) < (SPIRA_HEAP_BASE + SPIRA_HEAP_SIZE))
209
prerror("SPIRA: Bad pointer %p at %s line %d\n", ptr, file, line);
214
struct HDIF_common_hdr *__get_hdif(struct spira_ntuple *n, const char id[],
215
const char *file, int line)
217
struct HDIF_common_hdr *h = ntuple_addr(n);
218
if (!spira_check_ptr(h, file, line))
221
if (!HDIF_check(h, id)) {
222
prerror("SPIRA: bad tuple %p: expected %s at %s line %d\n",
229
static struct dt_node *add_xscom_node(uint64_t base, uint32_t hw_id,
230
uint32_t proc_chip_id)
232
struct dt_node *node;
236
addr = base | ((uint64_t)hw_id << PPC_BITLSHIFT(28));
237
size = (u64)1 << PPC_BITLSHIFT(28);
239
prlog(PR_INFO, "XSCOM: Found HW ID 0x%x (PCID 0x%x) @ 0x%llx\n",
240
hw_id, proc_chip_id, (long long)addr);
242
node = dt_new_addr(dt_root, "xscom", addr);
246
dt_add_property_cells(node, "ibm,chip-id", hw_id);
247
dt_add_property_cells(node, "ibm,proc-chip-id", proc_chip_id);
248
dt_add_property_cells(node, "#address-cells", 1);
249
dt_add_property_cells(node, "#size-cells", 1);
250
dt_add_property(node, "scom-controller", NULL, 0);
254
dt_add_property_strings(node, "compatible",
255
"ibm,xscom", "ibm,power7-xscom");
258
dt_add_property_strings(node, "compatible",
259
"ibm,xscom", "ibm,power8-xscom");
262
dt_add_property_strings(node, "compatible", "ibm,xscom");
264
dt_add_property_u64s(node, "reg", addr, size);
266
/* Derive bus frquency */
267
freq = dt_prop_get_u64_def(dt_root, "nest-frequency", 0);
270
dt_add_property_cells(node, "bus-frequency",
271
hi32(freq), lo32(freq));
276
struct dt_node *find_xscom_for_chip(uint32_t chip_id)
278
struct dt_node *node;
281
dt_for_each_compatible(dt_root, node, "ibm,xscom") {
282
id = dt_get_chip_id(node);
290
static void add_psihb_node(struct dt_node *np)
292
u32 psi_scom, psi_slen;
293
const char *psi_comp;
296
* We add a few things under XSCOM that aren't added
297
* by any other HDAT path
300
/* PSI host bridge */
303
psi_scom = 0x2010c00;
305
psi_comp = "ibm,power7-psihb-x";
308
psi_scom = 0x2010900;
310
psi_comp = "ibm,power8-psihb-x";
316
struct dt_node *psi_np;
318
psi_np = dt_new_addr(np, "psihb", psi_scom);
322
dt_add_property_cells(psi_np, "reg", psi_scom, psi_slen);
323
dt_add_property_strings(psi_np, "compatible", psi_comp,
328
static void add_xscom_add_pcia_assoc(struct dt_node *np, uint32_t pcid)
330
const struct HDIF_common_hdr *hdr;
335
* The SPPCRD doesn't contain all the affinity data, we have
336
* to dig it out of a core. I assume this is so that node
337
* affinity can be different for groups of cores within the
338
* chip, but for now we are going to ignore that
340
hdr = get_hdif(&spira.ntuples.pcia, SPPCIA_HDIF_SIG);
345
const struct sppcia_core_unique *id;
347
id = HDIF_get_idata(hdr, SPPCIA_IDATA_CORE_UNIQUE, &size);
348
if (!id || size < sizeof(*id))
351
if (be32_to_cpu(id->proc_chip_id) != pcid)
354
dt_add_property_cells(np, "ibm,ccm-node-id",
355
be32_to_cpu(id->ccm_node_id));
356
dt_add_property_cells(np, "ibm,hw-card-id",
357
be32_to_cpu(id->hw_card_id));
358
dt_add_property_cells(np, "ibm,hw-module-id",
359
be32_to_cpu(id->hw_module_id));
360
if (!dt_find_property(np, "ibm,dbob-id"))
361
dt_add_property_cells(np, "ibm,dbob-id",
362
be32_to_cpu(id->drawer_book_octant_blade_id));
363
dt_add_property_cells(np, "ibm,mem-interleave-scope",
364
be32_to_cpu(id->memory_interleaving_scope));
369
static bool add_xscom_sppcrd(uint64_t xscom_base)
371
const struct HDIF_common_hdr *hdif;
372
unsigned int i, vpd_sz;
374
struct dt_node *np, *vpd_node;
376
for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
378
const struct sppcrd_chip_info *cinfo;
381
cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
382
if (!CHECK_SPPTR(cinfo)) {
383
prerror("XSCOM: Bad ChipID data %d\n", i);
387
ve = be32_to_cpu(cinfo->verif_exist_flags) & CHIP_VERIFY_MASK;
388
ve >>= CHIP_VERIFY_SHIFT;
389
if (ve == CHIP_VERIFY_NOT_INSTALLED ||
390
ve == CHIP_VERIFY_UNUSABLE)
393
/* Create the XSCOM node */
394
np = add_xscom_node(xscom_base,
395
be32_to_cpu(cinfo->xscom_id),
396
be32_to_cpu(cinfo->proc_chip_id));
400
version = be16_to_cpu(hdif->version);
402
/* Version 0A has additional OCC related stuff */
403
if (version >= 0x000a) {
404
if (!dt_find_property(np, "ibm,dbob-id"))
405
dt_add_property_cells(np, "ibm,dbob-id",
406
be32_to_cpu(cinfo->dbob_id));
407
dt_add_property_cells(np, "ibm,occ-functional-state",
408
be32_to_cpu(cinfo->occ_state));
412
vpd_node = dt_add_vpd_node(hdif, SPPCRD_IDATA_FRU_ID,
413
SPPCRD_IDATA_KW_VPD);
415
dt_add_property_cells(vpd_node, "ibm,chip-id",
416
be32_to_cpu(cinfo->xscom_id));
418
/* Add module VPD on version A and later */
419
if (version >= 0x000a) {
420
vpd = HDIF_get_idata(hdif, SPPCRD_IDATA_MODULE_VPD,
422
if (CHECK_SPPTR(vpd))
423
dt_add_property(np, "ibm,module-vpd", vpd,
428
* Extract additional associativity information from
429
* the core data. Pick one core on that chip
431
add_xscom_add_pcia_assoc(np, be32_to_cpu(cinfo->proc_chip_id));
433
/* Add PSI Host bridge */
440
static void add_xscom_sppaca(uint64_t xscom_base)
442
const struct HDIF_common_hdr *hdif;
444
struct dt_node *np, *vpd_node;
446
for_each_ntuple_idx(&spira.ntuples.paca, hdif, i, PACA_HDIF_SIG) {
447
const struct sppaca_cpu_id *id;
448
unsigned int chip_id, size;
451
/* We only suport old style PACA on P7 ! */
452
assert(proc_gen == proc_gen_p7);
454
id = HDIF_get_idata(hdif, SPPACA_IDATA_CPU_ID, &size);
456
if (!CHECK_SPPTR(id)) {
457
prerror("XSCOM: Bad processor data %d\n", i);
461
ve = be32_to_cpu(id->verify_exists_flags) & CPU_ID_VERIFY_MASK;
462
ve >>= CPU_ID_VERIFY_SHIFT;
463
if (ve == CPU_ID_VERIFY_NOT_INSTALLED ||
464
ve == CPU_ID_VERIFY_UNUSABLE)
467
/* Convert to HW chip ID */
468
chip_id = P7_PIR2GCID(be32_to_cpu(id->pir));
470
/* do we already have an XSCOM for this chip? */
471
if (find_xscom_for_chip(chip_id))
474
/* Create the XSCOM node */
475
np = add_xscom_node(xscom_base, chip_id,
476
be32_to_cpu(id->processor_chip_id));
481
vpd_node = dt_add_vpd_node(hdif, SPPACA_IDATA_FRU_ID,
482
SPPACA_IDATA_KW_VPD);
484
dt_add_property_cells(vpd_node, "ibm,chip-id", chip_id);
486
/* Add chip associativity data */
487
dt_add_property_cells(np, "ibm,ccm-node-id",
488
be32_to_cpu(id->ccm_node_id));
489
if (size > SPIRA_CPU_ID_MIN_SIZE) {
490
dt_add_property_cells(np, "ibm,hw-card-id",
491
be32_to_cpu(id->hw_card_id));
492
dt_add_property_cells(np, "ibm,hw-module-id",
493
be32_to_cpu(id->hardware_module_id));
494
if (!dt_find_property(np, "ibm,dbob-id"))
495
dt_add_property_cells(np, "ibm,dbob-id",
496
be32_to_cpu(id->drawer_book_octant_blade_id));
497
dt_add_property_cells(np, "ibm,mem-interleave-scope",
498
be32_to_cpu(id->memory_interleaving_scope));
501
/* Add PSI Host bridge */
506
static void add_xscom(void)
509
const struct msvpd_pmover_bsr_synchro *pmbs;
513
ms_vpd = get_hdif(&spira.ntuples.ms_vpd, MSVPD_HDIF_SIG);
515
prerror("XSCOM: Can't find MS VPD\n");
519
pmbs = HDIF_get_idata(ms_vpd, MSVPD_IDATA_PMOVER_SYNCHRO, &size);
520
if (!CHECK_SPPTR(pmbs) || size < sizeof(*pmbs)) {
521
prerror("XSCOM: absent or bad PMBS size %u @ %p\n", size, pmbs);
525
if (!(be32_to_cpu(pmbs->flags) & MSVPD_PMS_FLAG_XSCOMBASE_VALID)) {
526
prerror("XSCOM: No XSCOM base in PMBS, using default\n");
530
xscom_base = be64_to_cpu(pmbs->xscom_addr);
532
/* Some FSP (on P7) give me a crap base address for XSCOM (it has
533
* spurious bits set as far as I can tell). Since only 5 bits 18:22 can
534
* be programmed in hardware, let's isolate these. This seems to give
535
* me the right value on VPL1
537
if (cpu_type == PVR_TYPE_P7)
538
xscom_base &= 0x80003e0000000000ul;
540
/* Get rid of the top bits */
541
xscom_base = cleanup_addr(xscom_base);
543
/* First, try the new proc_chip ntuples for chip data */
544
if (add_xscom_sppcrd(xscom_base))
547
/* Otherwise, check the old-style PACA, looking for unique chips */
548
add_xscom_sppaca(xscom_base);
551
static void add_chiptod_node(unsigned int chip_id, int flags)
553
struct dt_node *node, *xscom_node;
554
const char *compat_str;
557
if ((flags & CHIPTOD_ID_FLAGS_STATUS_MASK) !=
558
CHIPTOD_ID_FLAGS_STATUS_OK)
561
xscom_node = find_xscom_for_chip(chip_id);
563
prerror("CHIPTOD: No xscom for chiptod %d?\n", chip_id);
572
compat_str = "ibm,power7-chiptod";
575
compat_str = "ibm,power8-chiptod";
581
prlog(PR_DEBUG, "CHIPTOD: Found on chip 0x%x %s\n", chip_id,
582
(flags & CHIPTOD_ID_FLAGS_PRIMARY) ? "[primary]" :
583
((flags & CHIPTOD_ID_FLAGS_SECONDARY) ? "[secondary]" : ""));
585
node = dt_new_addr(xscom_node, "chiptod", addr);
589
dt_add_property_cells(node, "reg", addr, len);
590
dt_add_property_strings(node, "compatible", "ibm,power-chiptod",
593
if (flags & CHIPTOD_ID_FLAGS_PRIMARY)
594
dt_add_property(node, "primary", NULL, 0);
595
if (flags & CHIPTOD_ID_FLAGS_SECONDARY)
596
dt_add_property(node, "secondary", NULL, 0);
599
static bool add_chiptod_old(void)
606
* Locate chiptod ID structures in SPIRA
608
if (!get_hdif(&spira.ntuples.chip_tod, "TOD "))
611
for_each_ntuple_idx(&spira.ntuples.chip_tod, hdif, i, "TOD ") {
612
const struct chiptod_chipid *id;
614
id = HDIF_get_idata(hdif, CHIPTOD_IDATA_CHIPID, NULL);
615
if (!CHECK_SPPTR(id)) {
616
prerror("CHIPTOD: Bad ChipID data %d\n", i);
620
add_chiptod_node(pcid_to_chip_id(be32_to_cpu(id->chip_id)),
621
be32_to_cpu(id->flags));
627
static bool add_chiptod_new(uint32_t master_cpu)
630
unsigned int i, master_chip;
634
* Locate Proc Chip ID structures in SPIRA
636
if (!get_hdif(&spira.ntuples.proc_chip, SPPCRD_HDIF_SIG))
639
master_chip = pir_to_chip_id(master_cpu);
641
for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
643
const struct sppcrd_chip_info *cinfo;
644
const struct sppcrd_chip_tod *tinfo;
648
cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
649
if (!CHECK_SPPTR(cinfo)) {
650
prerror("CHIPTOD: Bad ChipID data %d\n", i);
654
ve = be32_to_cpu(cinfo->verif_exist_flags) & CHIP_VERIFY_MASK;
655
ve >>= CHIP_VERIFY_SHIFT;
656
if (ve == CHIP_VERIFY_NOT_INSTALLED ||
657
ve == CHIP_VERIFY_UNUSABLE)
660
tinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_TOD, &size);
661
if (!CHECK_SPPTR(tinfo)) {
662
prerror("CHIPTOD: Bad TOD data %d\n", i);
666
flags = be32_to_cpu(tinfo->flags);
668
/* The FSP may strip the chiptod info from HDAT; if we find
669
* a zero-ed out entry, assume that the chiptod is
670
* present, but we don't have any primary/secondary info. In
671
* this case, pick the primary based on the CPU that was
675
flags = CHIPTOD_ID_FLAGS_STATUS_OK;
676
if (be32_to_cpu(cinfo->xscom_id) == master_chip)
677
flags |= CHIPTOD_ID_FLAGS_PRIMARY;
680
add_chiptod_node(be32_to_cpu(cinfo->xscom_id), flags);
686
static void add_nx_node(u32 gcid)
692
struct dt_node *xscom;
694
xscom = find_xscom_for_chip(gcid);
696
prerror("NX%d: did not found xscom node.\n", gcid);
701
* The NX register space is relatively self contained on P7+ but
702
* a bit more messy on P8. However it's all contained within the
703
* PB chiplet port 1 so we'll stick to that in the "reg" property
704
* and let the NX "driver" deal with the details.
711
cp_str = "ibm,power7-nx";
714
cp_str = "ibm,power8-nx";
719
nx = dt_new_addr(xscom, "nx", addr);
723
dt_add_property_cells(nx, "reg", addr, size);
724
dt_add_property_strings(nx, "compatible", "ibm,power-nx", cp_str);
727
static void add_nx(void)
732
for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
734
const struct sppcrd_chip_info *cinfo;
737
cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO, NULL);
738
if (!CHECK_SPPTR(cinfo)) {
739
prerror("NX: Bad ChipID data %d\n", i);
743
ve = be32_to_cpu(cinfo->verif_exist_flags) & CHIP_VERIFY_MASK;
744
ve >>= CHIP_VERIFY_SHIFT;
745
if (ve == CHIP_VERIFY_NOT_INSTALLED ||
746
ve == CHIP_VERIFY_UNUSABLE)
750
add_nx_node(be32_to_cpu(cinfo->xscom_id));
755
static void add_iplparams_sys_params(const void *iplp, struct dt_node *node)
757
const struct iplparams_sysparams *p;
759
const char *sys_family;
760
const struct HDIF_common_hdr *hdif = iplp;
761
u16 version = be16_to_cpu(hdif->version);
763
p = HDIF_get_idata(iplp, IPLPARAMS_SYSPARAMS, NULL);
764
if (!CHECK_SPPTR(p)) {
765
prerror("IPLPARAMS: No SYS Parameters\n");
766
/* Create a generic compatible property */
767
dt_add_property_string(dt_root, "compatible", "ibm,powernv");
771
node = dt_new(node, "sys-params");
773
dt_add_property_cells(node, "#address-cells", 0);
774
dt_add_property_cells(node, "#size-cells", 0);
776
dt_add_property_nstr(node, "ibm,sys-model", p->sys_model, 4);
778
/* Compatible is 2 entries: ibm,powernv and ibm,<platform>
780
sys_type = be32_to_cpu(p->system_type);
781
switch(sys_type >> 28) {
783
sys_family = "ibm,squadrons";
786
sys_family = "ibm,eclipz";
789
sys_family = "ibm,apollo";
792
sys_family = "ibm,firenze";
796
prerror("IPLPARAMS: Unknown system family\n");
799
dt_add_property_strings(dt_root, "compatible", "ibm,powernv",
802
/* Grab nest frequency when available */
803
if (version >= 0x005b) {
804
u64 freq = be32_to_cpu(p->nest_freq_mhz);
807
dt_add_property_cells(dt_root, "nest-frequency",
808
hi32(freq), lo32(freq));
812
static void add_iplparams_ipl_params(const void *iplp, struct dt_node *node)
814
const struct iplparams_iplparams *p;
815
struct dt_node *led_node;
817
p = HDIF_get_idata(iplp, IPLPARAMS_IPLPARAMS, NULL);
818
if (!CHECK_SPPTR(p)) {
819
prerror("IPLPARAMS: No IPL Parameters\n");
823
node = dt_new(node, "ipl-params");
825
dt_add_property_cells(node, "#address-cells", 0);
826
dt_add_property_cells(node, "#size-cells", 0);
828
/* On an ASM initiated factory reset, this bit will be set
829
* and the FSP expects the firmware to reset the PCI bus
830
* numbers and respond with a Power Down (CE,4D,02) message
832
if (be32_to_cpu(p->other_attrib) & IPLPARAMS_OATTR_RST_PCI_BUSNO)
833
dt_add_property_cells(node, "pci-busno-reset-ipl", 1);
834
dt_add_property_strings(node, "cec-ipl-side",
835
(p->ipl_side & IPLPARAMS_CEC_FW_IPL_SIDE_TEMP) ?
837
dt_add_property_strings(node, "fsp-ipl-side",
838
(p->ipl_side & IPLPARAMS_FSP_FW_IPL_SIDE_TEMP) ?
840
dt_add_property_cells(node, "os-ipl-mode", p->os_ipl_mode);
841
dt_add_property_strings(node, "cec-major-type",
842
p->cec_ipl_maj_type ? "hot" : "cold");
844
/* Add LED type info under '/ibm,opal/led' node */
845
led_node = dt_find_by_path(opal_node, DT_PROPERTY_LED_NODE);
848
if (be32_to_cpu(p->other_attrib) & IPLPARAMS_OATRR_LIGHT_PATH)
849
dt_add_property_strings(led_node, DT_PROPERTY_LED_MODE,
850
LED_MODE_LIGHT_PATH);
852
dt_add_property_strings(led_node, DT_PROPERTY_LED_MODE,
853
LED_MODE_GUIDING_LIGHT);
856
static void add_iplparams_serials(const void *iplp, struct dt_node *node)
858
const struct iplparms_serial *ipser;
859
struct dt_node *ser_node;
862
count = HDIF_get_iarray_size(iplp, IPLPARMS_IDATA_SERIAL);
864
prerror("IPLPARAMS: No serial ports\n");
867
prlog(PR_INFO, "IPLPARAMS: %d serial ports in array\n", count);
869
node = dt_new(node, "fsp-serial");
871
dt_add_property_cells(node, "#address-cells", 1);
872
dt_add_property_cells(node, "#size-cells", 0);
874
for (i = 0; i < count; i++) {
876
ipser = HDIF_get_iarray_item(iplp, IPLPARMS_IDATA_SERIAL,
878
if (!CHECK_SPPTR(ipser))
880
rsrc_id = be16_to_cpu(ipser->rsrc_id);
881
prlog(PR_INFO, "IPLPARAMS: Serial %d rsrc: %04x loc: %s\n",
882
i, rsrc_id, ipser->loc_code);
883
ser_node = dt_new_addr(node, "serial", rsrc_id);
887
dt_add_property_cells(ser_node, "reg", rsrc_id);
888
dt_add_property_nstr(ser_node, "ibm,loc-code",
889
ipser->loc_code, LOC_CODE_SIZE);
890
dt_add_property_string(ser_node, "compatible",
892
/* XXX handle CALLHOME flag ? */
897
* Check for platform dump, if present populate DT
899
static void add_iplparams_platform_dump(const void *iplp, struct dt_node *node)
901
const struct iplparams_dump *ipl_dump;
903
ipl_dump = HDIF_get_idata(iplp, IPLPARAMS_PLATFORM_DUMP, NULL);
904
if (!CHECK_SPPTR(ipl_dump))
907
node = dt_new(node, "platform-dump");
910
if (be32_to_cpu(ipl_dump->dump_id)) {
911
dt_add_property_cells(node, "dump-id",
912
be32_to_cpu(ipl_dump->dump_id));
913
dt_add_property_u64(node, "total-size",
914
be64_to_cpu(ipl_dump->act_dump_sz));
915
dt_add_property_u64(node, "hw-dump-size",
916
be32_to_cpu(ipl_dump->act_hw_dump_sz));
917
dt_add_property_cells(node, "plog-id",
918
be32_to_cpu(ipl_dump->plid));
922
static void add_iplparams(void)
924
struct dt_node *iplp_node;
925
const void *ipl_parms;
927
ipl_parms = get_hdif(&spira.ntuples.ipl_parms, "IPLPMS");
929
prerror("IPLPARAMS: Cannot find IPL Parms in SPIRA\n");
933
iplp_node = dt_new(dt_root, "ipl-params");
935
dt_add_property_cells(iplp_node, "#address-cells", 0);
936
dt_add_property_cells(iplp_node, "#size-cells", 0);
938
add_iplparams_sys_params(ipl_parms, iplp_node);
939
add_iplparams_ipl_params(ipl_parms, iplp_node);
940
add_iplparams_serials(ipl_parms, iplp_node);
941
add_iplparams_platform_dump(ipl_parms, iplp_node);
944
/* Various structure contain a "proc_chip_id" which is an arbitrary
945
* numbering used by HDAT to reference chips, which doesn't correspond
946
* to the HW IDs. We want to use the HW IDs everywhere in the DT so
947
* we convert using this.
949
* Note: On P7, the HW ID is the XSCOM "GCID" including the T bit which
950
* is *different* from the chip ID portion of the interrupt server#
951
* (or PIR). See the explanations in chip.h
953
uint32_t pcid_to_chip_id(uint32_t proc_chip_id)
958
/* First, try the proc_chip ntuples for chip data */
959
for_each_ntuple_idx(&spira.ntuples.proc_chip, hdif, i,
961
const struct sppcrd_chip_info *cinfo;
963
cinfo = HDIF_get_idata(hdif, SPPCRD_IDATA_CHIP_INFO,
965
if (!CHECK_SPPTR(cinfo)) {
966
prerror("XSCOM: Bad ChipID data %d\n", i);
969
if (proc_chip_id == be32_to_cpu(cinfo->proc_chip_id))
970
return be32_to_cpu(cinfo->xscom_id);
973
/* Otherwise, check the old-style PACA, looking for unique chips */
974
for_each_ntuple_idx(&spira.ntuples.paca, hdif, i, PACA_HDIF_SIG) {
975
const struct sppaca_cpu_id *id;
977
/* We only suport old style PACA on P7 ! */
978
assert(proc_gen == proc_gen_p7);
980
id = HDIF_get_idata(hdif, SPPACA_IDATA_CPU_ID, NULL);
982
if (!CHECK_SPPTR(id)) {
983
prerror("XSCOM: Bad processor data %d\n", i);
987
if (proc_chip_id == be32_to_cpu(id->processor_chip_id))
988
return P7_PIR2GCID(be32_to_cpu(id->pir));
991
/* Not found, what to do ? Assert ? For now return a number
992
* guaranteed to not exist
997
/* Create '/ibm,opal/led' node */
998
static void dt_init_led_node(void)
1000
struct dt_node *led_node;
1002
/* Create /ibm,opal node, if its not created already */
1004
opal_node = dt_new(dt_root, "ibm,opal");
1008
/* Crete LED parent node */
1009
led_node = dt_new(opal_node, DT_PROPERTY_LED_NODE);
1013
static void dt_init_vpd_node(void)
1015
struct dt_node *dt_vpd;
1017
dt_vpd = dt_new(dt_root, "vpd");
1019
dt_add_property_string(dt_vpd, "compatible", "ibm,opal-v3-vpd");
1022
static void hostservices_parse(void)
1024
struct HDIF_common_hdr *hs_hdr;
1025
const void *dt_blob;
1027
unsigned int ntuples_size;
1029
ntuples_size = sizeof(struct HDIF_array_hdr) +
1030
be32_to_cpu(spira.ntuples.array_hdr.ecnt) *
1031
sizeof(struct spira_ntuple);
1033
if (offsetof(struct spira_ntuples, hs_data) >= ntuples_size) {
1034
prerror("SPIRA: No host services data found\n");
1038
hs_hdr = get_hdif(&spira.ntuples.hs_data, HSERV_HDIF_SIG);
1040
prerror("SPIRA: No host services data found\n");
1044
dt_blob = HDIF_get_idata(hs_hdr, 0, &size);
1046
prerror("SPIRA: No host services idata found\n");
1049
hservices_from_hdat(dt_blob, size);
1053
* Legacy SPIRA is being deprecated and we have new SPIRA-H/S structures.
1054
* But on older system (p7?) we will continue to get legacy SPIRA.
1056
* SPIRA-S is initialized and provided by FSP. We use SPIRA-S signature
1057
* to identify supported format. Also if required adjust spira pointer.
1059
static void fixup_spira(void)
1062
spiras = (struct spiras *)CPU_TO_BE64(SPIRA_HEAP_BASE);
1065
/* Validate SPIRA-S signature */
1068
if (!HDIF_check(&spiras->hdr, SPIRAS_HDIF_SIG))
1071
prlog(PR_NOTICE, "SPIRA-S found.\n");
1073
spira.ntuples.sp_subsys = spiras->ntuples.sp_subsys;
1074
spira.ntuples.ipl_parms = spiras->ntuples.ipl_parms;
1075
spira.ntuples.nt_enclosure_vpd = spiras->ntuples.nt_enclosure_vpd;
1076
spira.ntuples.slca = spiras->ntuples.slca;
1077
spira.ntuples.backplane_vpd = spiras->ntuples.backplane_vpd;
1078
spira.ntuples.system_vpd = spiras->ntuples.system_vpd;
1079
spira.ntuples.proc_init = spirah.ntuples.proc_init;
1080
spira.ntuples.clock_vpd = spiras->ntuples.clock_vpd;
1081
spira.ntuples.anchor_vpd = spiras->ntuples.anchor_vpd;
1082
spira.ntuples.op_panel_vpd = spiras->ntuples.op_panel_vpd;
1083
spira.ntuples.misc_cec_fru_vpd = spiras->ntuples.misc_cec_fru_vpd;
1084
spira.ntuples.ms_vpd = spiras->ntuples.ms_vpd;
1085
spira.ntuples.cec_iohub_fru = spiras->ntuples.cec_iohub_fru;
1086
spira.ntuples.cpu_ctrl = spirah.ntuples.cpu_ctrl;
1087
spira.ntuples.mdump_src = spirah.ntuples.mdump_src;
1088
spira.ntuples.mdump_dst = spirah.ntuples.mdump_dst;
1089
spira.ntuples.mdump_res = spirah.ntuples.mdump_res;
1090
spira.ntuples.pcia = spiras->ntuples.pcia;
1091
spira.ntuples.proc_chip = spiras->ntuples.proc_chip;
1092
spira.ntuples.hs_data = spiras->ntuples.hs_data;
1095
int parse_hdat(bool is_opal, uint32_t master_cpu)
1097
cpu_type = PVR_TYPE(mfspr(SPR_PVR));
1099
prlog(PR_DEBUG, "Parsing HDAT...\n");
1103
dt_root = dt_new_root("");
1106
* Basic DT root stuff
1108
dt_add_property_cells(dt_root, "#address-cells", 2);
1109
dt_add_property_cells(dt_root, "#size-cells", 2);
1110
dt_add_property_string(dt_root, "lid-type", is_opal ? "opal" : "phyp");
1112
/* Create /vpd node */
1115
/* Create /ibm,opal/led node */
1118
/* Parse SPPACA and/or PCIA */
1120
if (paca_parse() < 0)
1129
/* Add XSCOM node (must be before chiptod & IO ) */
1136
if (!add_chiptod_old() && !add_chiptod_new(master_cpu))
1137
prerror("CHIPTOD: No ChipTOD found !\n");
1142
/* Add IO HUBs and/or PHBs */
1148
/* Host services information. */
1149
hostservices_parse();
1151
/* Parse System Attention Indicator inforamtion */
1152
slca_dt_add_sai_node();
1154
prlog(PR_INFO, "Parsing HDAT...done\n");