1 /* Copyright 2013-2019 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 <skiboot.h>
18 #include <xscom.h>
19 #include <io.h>
20 #include <cpu.h>
21 #include <chip.h>
22 #include <mem_region.h>
23 #include <hostservices.h>
24
25 #define P8_PBA_BAR0 0x2013f00
26 #define P8_PBA_BARMASK0 0x2013f04
27
28 #define P9_PBA_BAR0 0x5012B00
29 #define P9_PBA_BARMASK0 0x5012B04
30
31 #define PBA_MASK_ALL_BITS 0x000001FFFFF00000ULL /* Bits 23:43 */
32
33 enum P8_BAR {
34 P8_BAR_HOMER = 0,
35 P8_BAR_CENTAUR = 1,
36 P8_BAR_SLW = 2,
37 P8_BAR_OCC_COMMON = 3,
38 };
39
40 enum P9_BAR {
41 P9_BAR_HOMER = 0,
42 P9_BAR_CENTAUR = 1,
43 P9_BAR_OCC_COMMON = 2,
44 P9_BAR_SBE = 3,
45 };
46
47 static u64 pba_bar0, pba_barmask0;
48 static u8 bar_homer, bar_slw, bar_occ_common;
49
read_pba_bar(struct proc_chip * chip,unsigned int bar_no,uint64_t * base,uint64_t * size)50 static bool read_pba_bar(struct proc_chip *chip, unsigned int bar_no,
51 uint64_t *base, uint64_t *size)
52 {
53 uint64_t bar, mask;
54 int rc;
55
56 rc = xscom_read(chip->id, pba_bar0 + bar_no, &bar);
57 if (rc) {
58 prerror("SLW: Error %d reading PBA BAR%d on chip %d\n",
59 rc, bar_no, chip->id);
60 return false;
61 }
62 rc = xscom_read(chip->id, pba_barmask0 + bar_no, &mask);
63 if (rc) {
64 prerror("SLW: Error %d reading PBA BAR MASK%d on chip %d\n",
65 rc, bar_no, chip->id);
66 return false;
67 }
68 prlog(PR_DEBUG, " PBA BAR%d : 0x%016llx\n", bar_no, bar);
69 prlog(PR_DEBUG, " PBA MASK%d: 0x%016llx\n", bar_no, mask);
70
71 if (mask == PBA_MASK_ALL_BITS) {
72 /*
73 * This could happen if all HOMER users are not enabled during
74 * early system bringup. Skip using the PBA BAR.
75 */
76 mask = 0;
77 bar = 0;
78 prerror(" PBA MASK%d uninitalized skipping BAR\n", bar_no);
79 }
80
81 *base = bar & 0x0ffffffffffffffful;
82 *size = (mask | 0xfffff) + 1;
83
84 return (*base) != 0;
85 }
86
homer_init_chip(struct proc_chip * chip)87 static void homer_init_chip(struct proc_chip *chip)
88 {
89 uint64_t hbase = 0, hsize = 0;
90 uint64_t sbase, ssize, obase, osize;
91
92 /*
93 * PBA BARs assigned by HB:
94 *
95 * P8:
96 * 0 : Entire HOMER
97 * 1 : OCC to Centaur path (we don't care)
98 * 2 : SLW image
99 * 3 : OCC Common area
100 *
101 * We need to reserve the memory covered by BAR 0 and BAR 3, however
102 * on earlier HBs, BAR0 isn't set so we need BAR 2 instead in that
103 * case to cover SLW (OCC not running).
104 *
105 * P9:
106 * 0 : Entire HOMER
107 * 1 : OCC to Centaur path (Cumulus only)
108 * 2 : OCC Common area
109 * 3 : SBE communication
110 *
111 */
112 if (read_pba_bar(chip, bar_homer, &hbase, &hsize)) {
113 prlog(PR_DEBUG, " HOMER Image at 0x%llx size %lldMB\n",
114 hbase, hsize / 0x100000);
115
116 if (!mem_range_is_reserved(hbase, hsize)) {
117 prlog(PR_WARNING,
118 "HOMER image is not reserved! Reserving\n");
119 mem_reserve_fw("ibm,homer-image", hbase, hsize);
120 }
121
122 chip->homer_base = hbase;
123 chip->homer_size = hsize;
124 }
125
126 /*
127 * We always read the SLW BAR since we need to grab info about the
128 * SLW image in the struct proc_chip for use by the slw.c code
129 */
130 if (proc_gen == proc_gen_p8 &&
131 read_pba_bar(chip, bar_slw, &sbase, &ssize)) {
132 prlog(PR_DEBUG, " SLW Image at 0x%llx size %lldMB\n",
133 sbase, ssize / 0x100000);
134
135 /*
136 * Only reserve it if we have no homer image or if it
137 * doesn't fit in it (only check the base).
138 */
139 if ((sbase < hbase || sbase > (hbase + hsize) ||
140 (hbase == 0 && sbase > 0)) &&
141 !mem_range_is_reserved(sbase, ssize)) {
142 prlog(PR_WARNING,
143 "SLW image is not reserved! Reserving\n");
144 mem_reserve_fw("ibm,slw-image", sbase, ssize);
145 }
146
147 chip->slw_base = sbase;
148 chip->slw_bar_size = ssize;
149 chip->slw_image_size = ssize; /* will be adjusted later */
150 }
151
152 if (read_pba_bar(chip, bar_occ_common, &obase, &osize)) {
153 prlog(PR_DEBUG, " OCC Common Area at 0x%llx size %lldMB\n",
154 obase, osize / 0x100000);
155 chip->occ_common_base = obase;
156 chip->occ_common_size = osize;
157 }
158 }
159
160
host_services_occ_base_setup(void)161 static void host_services_occ_base_setup(void)
162 {
163 struct proc_chip *chip;
164 uint64_t occ_common;
165
166 chip = next_chip(NULL); /* Frist chip */
167 occ_common = (uint64_t) local_alloc(chip->id, OCC_COMMON_SIZE, OCC_COMMON_SIZE);
168
169 for_each_chip(chip) {
170 chip->occ_common_base = occ_common;
171 chip->occ_common_size = OCC_COMMON_SIZE;
172
173 chip->homer_base = (uint64_t) local_alloc(chip->id, HOMER_IMAGE_SIZE,
174 HOMER_IMAGE_SIZE);
175 chip->homer_size = HOMER_IMAGE_SIZE;
176 memset((void *)chip->homer_base, 0, chip->homer_size);
177
178 prlog(PR_DEBUG, "HBRT: Chip %d HOMER base %016llx : %08llx\n",
179 chip->id, chip->homer_base, chip->homer_size);
180 prlog(PR_DEBUG, "HBRT: OCC common base %016llx : %08llx\n",
181 chip->occ_common_base, chip->occ_common_size);
182 }
183 }
184
homer_init(void)185 void homer_init(void)
186 {
187 struct proc_chip *chip;
188
189 if (chip_quirk(QUIRK_NO_PBA))
190 return;
191
192 switch (proc_gen) {
193 case proc_gen_p8:
194 pba_bar0 = P8_PBA_BAR0;
195 pba_barmask0 = P8_PBA_BARMASK0;
196 bar_homer = P8_BAR_HOMER;
197 bar_slw = P8_BAR_SLW;
198 bar_occ_common = P8_BAR_OCC_COMMON;
199 break;
200 case proc_gen_p9:
201 pba_bar0 = P9_PBA_BAR0;
202 pba_barmask0 = P9_PBA_BARMASK0;
203 bar_homer = P9_BAR_HOMER;
204 bar_occ_common = P9_BAR_OCC_COMMON;
205 break;
206 default:
207 return;
208 };
209
210 /*
211 * XXX This is temporary, on P8 we look for any configured
212 * SLW/OCC BAR and reserve the memory. Eventually, this will be
213 * done via HostBoot using the device-tree "reserved-ranges"
214 * or we'll load the SLW & OCC images ourselves using Host Services.
215 */
216 for_each_chip(chip) {
217 prlog(PR_DEBUG, "HOMER: Init chip %d\n", chip->id);
218 homer_init_chip(chip);
219 }
220
221 /*
222 * Check is PBA BARs are already loaded with HOMER and
223 * skip host services.
224 */
225
226 chip = next_chip(NULL);
227 /* Both HOMER images and OCC areas are setup */
228 if (chip->homer_base && chip->occ_common_base) {
229 /* Reserve OCC common area from BAR */
230 if (!mem_range_is_reserved(chip->occ_common_base,
231 chip->occ_common_size)) {
232 prlog(PR_WARNING,
233 "OCC common area is not reserved! Reserving\n");
234 mem_reserve_fw("ibm,occ-common-area",
235 chip->occ_common_base,
236 chip->occ_common_size);
237 }
238 } else if (chip->homer_base) {
239 /*
240 * HOMER is setup but not OCC!! Do not allocate HOMER
241 * regions. This case is possible during early system
242 * bringup where OCC images are not yet operational.
243 */
244 } else {
245 /* Allocate memory for HOMER and OCC common area */
246 host_services_occ_base_setup();
247 }
248 }
249
250