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