~pmdj/ubuntu/trusty/qemu/2.9+applesmc+fadtv3

« back to all changes in this revision

Viewing changes to roms/skiboot/hdata/fsp.c

  • Committer: Phil Dennis-Jordan
  • Date: 2017-07-21 08:03:43 UTC
  • mfrom: (1.1.1)
  • Revision ID: phil@philjordan.eu-20170721080343-2yr2vdj7713czahv
New upstream release 2.9.0.

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright 2013-2014 IBM Corp.
 
2
 *
 
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
 
6
 *
 
7
 *      http://www.apache.org/licenses/LICENSE-2.0
 
8
 *
 
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
 
12
 * implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
#include <device.h>
 
18
#include "spira.h"
 
19
#include <cpu.h>
 
20
#include <vpd.h>
 
21
#include <ccan/str/str.h>
 
22
#include <interrupts.h>
 
23
 
 
24
#include "hdata.h"
 
25
 
 
26
static struct dt_node *fsp_create_node(const void *spss, int i,
 
27
                                       struct dt_node *parent)
 
28
{
 
29
        const struct spss_sp_impl *sp_impl;
 
30
        struct dt_node *node;
 
31
        unsigned int mask;
 
32
 
 
33
        /* Find an check the SP Implementation structure */
 
34
        sp_impl = HDIF_get_idata(spss, SPSS_IDATA_SP_IMPL, NULL);
 
35
        if (!CHECK_SPPTR(sp_impl)) {
 
36
                prerror("FSP #%d: SPSS/SP_Implementation not found !\n", i);
 
37
                return NULL;
 
38
        }
 
39
 
 
40
        prlog(PR_INFO, "FSP #%d: FSP HW version %d, SW version %d,"
 
41
              " chip DD%d.%d\n", i,
 
42
              be16_to_cpu(sp_impl->hw_version),
 
43
              be16_to_cpu(sp_impl->sw_version),
 
44
              sp_impl->chip_version >> 4, sp_impl->chip_version & 0xf);
 
45
        mask = SPSS_SP_IMPL_FLAGS_INSTALLED | SPSS_SP_IMPL_FLAGS_FUNCTIONAL;
 
46
        if ((be16_to_cpu(sp_impl->func_flags) & mask) != mask) {
 
47
                prerror("FSP #%d: FSP not installed or not functional\n", i);
 
48
                return NULL;
 
49
        }
 
50
 
 
51
        node = dt_new_addr(parent, "fsp", i);
 
52
        assert(node);
 
53
        dt_add_property_cells(node, "reg", i);
 
54
 
 
55
        if (be16_to_cpu(sp_impl->hw_version) == 1) {
 
56
                dt_add_property_strings(node, "compatible", "ibm,fsp",
 
57
                                "ibm,fsp1");
 
58
                /* Offset into the FSP MMIO space where the mailbox
 
59
                 * registers are */
 
60
                /* seen in the FSP1 spec */
 
61
                dt_add_property_cells(node, "reg-offset", 0xb0016000);
 
62
        } else if (be16_to_cpu(sp_impl->hw_version) == 2) {
 
63
                dt_add_property_strings(node, "compatible", "ibm,fsp",
 
64
                                "ibm,fsp2");
 
65
                dt_add_property_cells(node, "reg-offset", 0xb0011000);
 
66
        }
 
67
        dt_add_property_cells(node, "hw-version", be16_to_cpu(sp_impl->hw_version));
 
68
        dt_add_property_cells(node, "sw-version", be16_to_cpu(sp_impl->sw_version));
 
69
 
 
70
        if (be16_to_cpu(sp_impl->func_flags) & SPSS_SP_IMPL_FLAGS_PRIMARY)
 
71
                dt_add_property(node, "primary", NULL, 0);
 
72
 
 
73
        return node;
 
74
}
 
75
 
 
76
static uint32_t fsp_create_link(const struct spss_iopath *iopath, int index,
 
77
                                int fsp_index)
 
78
{
 
79
        struct dt_node *node;
 
80
        const char *ststr;
 
81
        bool current = false;
 
82
        bool working = false;
 
83
        uint32_t chip_id;
 
84
 
 
85
        switch(be16_to_cpu(iopath->psi.link_status)) {
 
86
        case SPSS_IO_PATH_PSI_LINK_BAD_FRU:
 
87
                ststr = "Broken";
 
88
                break;
 
89
        case SPSS_IO_PATH_PSI_LINK_CURRENT:
 
90
                ststr = "Active";
 
91
                current = working = true;
 
92
                break;
 
93
        case SPSS_IO_PATH_PSI_LINK_BACKUP:
 
94
                ststr = "Backup";
 
95
                working = true;
 
96
                break;
 
97
        default:
 
98
                ststr = "Unknown";
 
99
        }
 
100
        prlog(PR_DEBUG, "FSP #%d: IO PATH %d is %s PSI Link, GXHB at %llx\n",
 
101
              fsp_index, index, ststr, (long long)be64_to_cpu(iopath->psi.gxhb_base));
 
102
 
 
103
        chip_id = pcid_to_chip_id(be32_to_cpu(iopath->psi.proc_chip_id));
 
104
        node = dt_find_compatible_node_on_chip(dt_root, NULL, "ibm,psihb-x",
 
105
                                               chip_id);
 
106
        if (!node) {
 
107
                prerror("FSP #%d: Can't find psihb node for link %d\n",
 
108
                        fsp_index, index);
 
109
        } else {
 
110
                if (current)
 
111
                        dt_add_property(node, "boot-link", NULL, 0);
 
112
                dt_add_property_strings(node, "status", working ? "ok" : "bad");
 
113
        }
 
114
 
 
115
        return chip_id;
 
116
}
 
117
 
 
118
static void fsp_create_links(const void *spss, int index,
 
119
                             struct dt_node *fsp_node)
 
120
{
 
121
        uint32_t *links = NULL;
 
122
        unsigned int i, lp, lcount = 0;
 
123
        int count;
 
124
 
 
125
        count = HDIF_get_iarray_size(spss, SPSS_IDATA_SP_IOPATH);
 
126
        if (count < 0) {
 
127
                prerror("FSP #%d: Can't find IO PATH array size !\n", index);
 
128
                return;
 
129
        }
 
130
        prlog(PR_DEBUG, "FSP #%d: Found %d IO PATH\n", index, count);
 
131
 
 
132
        /* Iterate all links */
 
133
        for (i = 0; i < count; i++) {
 
134
                const struct spss_iopath *iopath;
 
135
                unsigned int iopath_sz;
 
136
                uint32_t chip;
 
137
 
 
138
                iopath = HDIF_get_iarray_item(spss, SPSS_IDATA_SP_IOPATH,
 
139
                                              i, &iopath_sz);
 
140
                if (!CHECK_SPPTR(iopath)) {
 
141
                        prerror("FSP #%d: Can't find IO PATH %d\n", index, i);
 
142
                        break;
 
143
                }
 
144
                if (be16_to_cpu(iopath->iopath_type) != SPSS_IOPATH_TYPE_PSI) {
 
145
                        prerror("FSP #%d: Unsupported IO PATH %d type 0x%04x\n",
 
146
                                index, i, iopath->iopath_type);
 
147
                        continue;
 
148
                }
 
149
 
 
150
                chip = fsp_create_link(iopath, i, index);
 
151
                lp = lcount++;
 
152
                links = realloc(links, 4 * lcount);
 
153
                links[lp] = chip;
 
154
        }
 
155
        if (links)
 
156
                dt_add_property(fsp_node, "ibm,psi-links", links, lcount * 4);
 
157
 
 
158
        free(links);
 
159
}
 
160
 
 
161
void fsp_parse(void)
 
162
{
 
163
        const void *base_spss, *spss;
 
164
        struct dt_node *fsp_root, *fsp_node;
 
165
        int i;
 
166
 
 
167
        /*
 
168
         * Note on DT representation of the PSI links and FSPs:
 
169
         *
 
170
         * We create a XSCOM node for each PSI host bridge(one per chip),
 
171
         *
 
172
         * This is done in spira.c
 
173
         *
 
174
         * We do not create the /psi MMIO variant at this stage, it will
 
175
         * be added by the psi driver in skiboot.
 
176
         *
 
177
         * We do not put the FSP(s) as children of these. Instead, we create
 
178
         * a top-level /fsps node with the FSPs as children.
 
179
         *
 
180
         * Each FSP then has a "links" property which is an array of chip IDs
 
181
         */
 
182
 
 
183
        /* Find SPSS in SPIRA */
 
184
        base_spss = get_hdif(&spira.ntuples.sp_subsys, SPSS_HDIF_SIG);
 
185
        if (!base_spss) {
 
186
                prlog(PR_WARNING, "FSP: No SPSS in SPIRA !\n");
 
187
                return;
 
188
        }
 
189
 
 
190
        fsp_root = dt_new(dt_root, "fsps");
 
191
        assert(fsp_root);
 
192
        dt_add_property_cells(fsp_root, "#address-cells", 1);
 
193
        dt_add_property_cells(fsp_root, "#size-cells", 0);
 
194
 
 
195
        /* Iterate FSPs in SPIRA */
 
196
        for_each_ntuple_idx(&spira.ntuples.sp_subsys, spss, i, SPSS_HDIF_SIG) {
 
197
                fsp_node = fsp_create_node(spss, i, fsp_root);
 
198
                if (fsp_node)
 
199
                        fsp_create_links(spss, i, fsp_node);
 
200
        }
 
201
}
 
202