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 <stdint.h>
18 #include <stdlib.h>
19 #include <stdio.h>
20 
21 #include <lock.h>
22 #include <device.h>
23 #include <compiler.h>
24 #include <hostservices.h>
25 #include <mem_region.h>
26 #include <xscom.h>
27 #include <fsp.h>
28 #include <chip.h>
29 #include <console.h>
30 #include <mem-map.h>
31 #include <timebase.h>
32 
33 #define HOSTBOOT_RUNTIME_INTERFACE_VERSION 1
34 
35 struct host_interfaces {
36 	/** Interface version. */
37 	uint64_t interface_version;
38 
39 	/** Put a string to the console. */
40 	void (*puts)(const char*);
41 	/** Critical failure in runtime execution. */
42 	void (*assert)(void);
43 
44 	/** OPTIONAL. Hint to environment that the page may be executed. */
45 	int (*set_page_execute)(void*);
46 
47 	/** malloc */
48 	void *(*malloc)(size_t);
49 	/** free */
50 	void (*free)(void*);
51 	/** realloc */
52 	void *(*realloc)(void*, size_t);
53 
54 	/** sendErrorLog
55 	 * @param[in] plid Platform Log identifier
56 	 * @param[in] data size in bytes
57 	 * @param[in] pointer to data
58 	 * @return 0 on success else error code
59 	 */
60 	int (*send_error_log)(uint32_t,uint32_t,void *);
61 
62 	/** Scan communication read
63 	 * @param[in] chip_id (based on devtree defn)
64 	 * @param[in] address
65 	 * @param[in] pointer to 8-byte data buffer
66 	 * @return 0 on success else return code
67 	 */
68 	int (*scom_read)(uint64_t, uint64_t, void*);
69 
70 	/** Scan communication write
71 	 * @param[in] chip_id (based on devtree defn)
72 	 * @param[in] address
73 	 * @param[in] pointer to 8-byte data buffer
74 	 * @return 0 on success else return code
75 	 */
76 	int (*scom_write)(uint64_t, uint64_t, const void *);
77 
78 	/** lid_load
79 	 *  Load a LID from PNOR, FSP, etc.
80 	 *
81 	 *  @param[in] LID number.
82 	 *  @param[out] Allocated buffer for LID.
83 	 *  @param[out] Size of LID (in bytes).
84 	 *
85 	 *  @return 0 on success, else RC.
86 	 */
87 	int (*lid_load)(uint32_t lid, void **buf, size_t *len);
88 
89 	/** lid_unload
90 	 *  Release memory from previously loaded LID.
91 	 *
92 	 *  @param[in] Allocated buffer for LID to release.
93 	 *
94 	 *  @return 0 on success, else RC.
95 	 */
96 	int (*lid_unload)(void *buf);
97 
98 	/** Get the address of a reserved memory region by its devtree name.
99 	 *
100 	 *  @param[in] Devtree name (ex. "ibm,hbrt-vpd-image")
101 	 *  @return physical address of region (or NULL).
102 	 **/
103 	uint64_t (*get_reserved_mem)(const char*);
104 
105 	/**
106 	 * @brief  Force a core to be awake, or clear the force
107 	 * @param[in] i_core  Core to wake up (pid)
108 	 * @param[in] i_mode  0=force awake
109 	 *                1=clear force
110 	 *                2=clear all previous forces
111 	 * @return rc  non-zero on error
112 	 */
113 	int (*wakeup)( uint32_t i_core, uint32_t i_mode );
114 
115 	/**
116 	 * @brief Delay/sleep for at least the time given
117 	 * @param[in] seconds
118 	 * @param[in] nano seconds
119 	 */
120 	void (*nanosleep)(uint64_t i_seconds, uint64_t i_nano_seconds);
121 
122 	// Reserve some space for future growth.
123 	void (*reserved[32])(void);
124 };
125 
126 struct runtime_interfaces {
127 	/** Interface version. */
128 	uint64_t interface_version;
129 
130 	/** Execute CxxTests that may be contained in the image.
131 	 *
132 	 * @param[in] - Pointer to CxxTestStats structure for results reporting.
133 	 */
134 	void (*cxxtestExecute)(void *);
135 	/** Get a list of lids numbers of the lids known to HostBoot
136 	 *
137 	 * @param[out] o_num - the number of lids in the list
138 	 * @return a pointer to the list
139 	 */
140 	const uint32_t * (*get_lid_list)(size_t * o_num);
141 
142 	/** Load OCC Image and common data into mainstore, also setup OCC BARSs
143 	 *
144 	 * @param[in] i_homer_addr_phys - The physical mainstore address of the
145 	 *                                start of the HOMER image
146 	 * @param[in] i_homer_addr_va - Virtual memory address of the HOMER image
147 	 * @param[in] i_common_addr_phys - The physical mainstore address of the
148 	 *                                 OCC common area.
149 	 * @param[in] i_common_addr_va - Virtual memory address of the common area
150 	 * @param[in] i_chip - The HW chip id (XSCOM chip ID)
151 	 * @return 0 on success else return code
152 	 */
153 	int(*loadOCC)(uint64_t i_homer_addr_phys,
154 			uint64_t i_homer_addr_va,
155 			uint64_t i_common_addr_phys,
156 			uint64_t i_common_addr_va,
157 			uint64_t i_chip);
158 
159 	/** Start OCC on all chips, by module
160 	 *
161 	 *  @param[in] i_chip - Array of functional HW chip ids
162 	 *  @Note The caller must include a complete modules worth of chips
163 	 *  @param[in] i_num_chips - Number of chips in the array
164 	 *  @return 0 on success else return code
165 	 */
166 	int (*startOCCs)(uint64_t* i_chip,
167 			size_t i_num_chips);
168 
169 	/** Stop OCC hold OCCs in reset
170 	 *
171 	 *  @param[in] i_chip - Array of functional HW chip ids
172 	 *  @Note The caller must include a complete modules worth of chips
173 	 *  @param[in] i_num_chips - Number of chips in the array
174 	 *  @return 0 on success else return code
175 	 */
176 	int (*stopOCCs)(uint64_t* i_chip,
177 			size_t i_num_chips);
178 
179 	/* Reserve some space for future growth. */
180 	void (*reserved[32])(void);
181 };
182 
183 static struct runtime_interfaces *hservice_runtime;
184 
185 static char *hbrt_con_buf = (char *)HBRT_CON_START;
186 static size_t hbrt_con_pos;
187 static bool hbrt_con_wrapped;
188 
189 #define HBRT_CON_IN_LEN		0
190 #define HBRT_CON_OUT_LEN	(HBRT_CON_LEN - HBRT_CON_IN_LEN)
191 
192 static struct memcons hbrt_memcons __section(".data.memcons") = {
193 	.magic		= MEMCONS_MAGIC,
194 	.obuf_phys	= HBRT_CON_START,
195 	.ibuf_phys	= HBRT_CON_START + HBRT_CON_OUT_LEN,
196 	.obuf_size	= HBRT_CON_OUT_LEN,
197 	.ibuf_size	= HBRT_CON_IN_LEN,
198 };
199 
hservice_putc(char c)200 static void hservice_putc(char c)
201 {
202 	uint32_t opos;
203 
204 	hbrt_con_buf[hbrt_con_pos++] = c;
205 	if (hbrt_con_pos >= HBRT_CON_OUT_LEN) {
206 		hbrt_con_pos = 0;
207 		hbrt_con_wrapped = true;
208 	}
209 
210 	/*
211 	 * We must always re-generate memcons.out_pos because
212 	 * under some circumstances, the console script will
213 	 * use a broken putmemproc that does RMW on the full
214 	 * 8 bytes containing out_pos and in_prod, thus corrupting
215 	 * out_pos
216 	 */
217 	opos = hbrt_con_pos;
218 	if (hbrt_con_wrapped)
219 		opos |= MEMCONS_OUT_POS_WRAP;
220 	lwsync();
221 	hbrt_memcons.out_pos = opos;
222 }
223 
hservice_puts(const char * str)224 static void hservice_puts(const char *str)
225 {
226 	char c;
227 
228 	while((c = *(str++)) != 0)
229 		hservice_putc(c);
230 	hservice_putc(10);
231 }
232 
hservice_mark(void)233 static void hservice_mark(void)
234 {
235 	hservice_puts("--------------------------------------------------"
236 		      "--------------------------------------------------\n");
237 }
238 
hservice_assert(void)239 static void hservice_assert(void)
240 {
241 	/**
242 	 * @fwts-label HBRTassert
243 	 * @fwts-advice HBRT triggered assert: you need to debug HBRT
244 	 */
245 	prlog(PR_EMERG, "HBRT: Assertion from hostservices\n");
246 	abort();
247 }
248 
hservice_malloc(size_t size)249 static void *hservice_malloc(size_t size)
250 {
251 	return malloc(size);
252 }
253 
hservice_free(void * ptr)254 static void hservice_free(void *ptr)
255 {
256 	free(ptr);
257 }
258 
259 
hservice_realloc(void * ptr,size_t size)260 static void *hservice_realloc(void *ptr, size_t size)
261 {
262 	return realloc(ptr, size);
263 }
264 
265 struct hbrt_elog_ent {
266 	void *buf;
267 	unsigned int size;
268 	unsigned int plid;
269 	struct list_node link;
270 };
271 static LIST_HEAD(hbrt_elogs);
272 static struct lock hbrt_elog_lock = LOCK_UNLOCKED;
273 static bool hbrt_elog_sending;
274 static void hservice_start_elog_send(void);
275 
hservice_elog_write_complete(struct fsp_msg * msg)276 static void hservice_elog_write_complete(struct fsp_msg *msg)
277 {
278 	struct hbrt_elog_ent *ent = msg->user_data;
279 
280 	lock(&hbrt_elog_lock);
281 	prlog(PR_DEBUG, "HBRT: Completed send of PLID 0x%08x\n", ent->plid);
282 	hbrt_elog_sending = false;
283 	fsp_tce_unmap(PSI_DMA_HBRT_LOG_WRITE_BUF,
284 		      PSI_DMA_HBRT_LOG_WRITE_BUF_SZ);
285 	free(ent->buf);
286 	free(ent);
287 	fsp_freemsg(msg);
288 	hservice_start_elog_send();
289 	unlock(&hbrt_elog_lock);
290 }
291 
hservice_start_elog_send(void)292 static void hservice_start_elog_send(void)
293 {
294 	struct fsp_msg *msg;
295 	struct hbrt_elog_ent *ent;
296 
297  again:
298 	if (list_empty(&hbrt_elogs))
299 		return;
300 	ent = list_pop(&hbrt_elogs, struct hbrt_elog_ent, link);
301 
302 	hbrt_elog_sending = true;
303 
304 	prlog(PR_DEBUG, "HBRT: Starting send of PLID 0x%08x\n", ent->plid);
305 
306 	fsp_tce_map(PSI_DMA_HBRT_LOG_WRITE_BUF, ent->buf,
307 		    PSI_DMA_HBRT_LOG_WRITE_BUF_SZ);
308 
309 	msg = fsp_mkmsg(FSP_CMD_WRITE_SP_DATA, 6, FSP_DATASET_HBRT_BLOB,
310 			0, 0, 0, PSI_DMA_HBRT_LOG_WRITE_BUF,
311 			ent->size);
312 
313 	if (!msg) {
314 		prerror("HBRT: Failed to create error msg log to FSP\n");
315 		goto error;
316 	}
317 	msg->user_data = ent;
318 	if (!fsp_queue_msg(msg, hservice_elog_write_complete))
319 		return;
320 	prerror("FSP: Error queueing elog update\n");
321  error:
322 	if (msg)
323 		fsp_freemsg(msg);
324 	fsp_tce_unmap(PSI_DMA_HBRT_LOG_WRITE_BUF,
325 		      PSI_DMA_HBRT_LOG_WRITE_BUF_SZ);
326 	free(ent->buf);
327 	free(ent);
328 	hbrt_elog_sending = false;
329 	goto again;
330 }
331 
hservice_send_error_log(uint32_t plid,uint32_t dsize,void * data)332 static int hservice_send_error_log(uint32_t plid, uint32_t dsize, void *data)
333 {
334 	struct hbrt_elog_ent *ent;
335 	void *abuf;
336 
337 	prlog(PR_ERR, "HBRT: Error log generated with plid 0x%08x\n", plid);
338 
339 	/* We only know how to send error logs to FSP */
340 	if (!fsp_present()) {
341 		prerror("HBRT: Warning, error log from HBRT discarded !\n");
342 		return OPAL_UNSUPPORTED;
343 	}
344 	if (dsize > PSI_DMA_HBRT_LOG_WRITE_BUF_SZ) {
345 		prerror("HBRT: Warning, error log from HBRT too big (%d) !\n",
346 			dsize);
347 		dsize = PSI_DMA_HBRT_LOG_WRITE_BUF_SZ;
348 	}
349 
350 	lock(&hbrt_elog_lock);
351 
352 	/* Create and populate a tracking structure */
353 	ent = zalloc(sizeof(struct hbrt_elog_ent));
354 	if (!ent) {
355 		unlock(&hbrt_elog_lock);
356 		return OPAL_NO_MEM;
357 	}
358 
359 	/* Grab a 4k aligned page */
360 	abuf = memalign(0x1000, PSI_DMA_HBRT_LOG_WRITE_BUF_SZ);
361 	if (!abuf) {
362 		free(ent);
363 		unlock(&hbrt_elog_lock);
364 		return OPAL_NO_MEM;
365 	}
366 	memset(abuf, 0, PSI_DMA_HBRT_LOG_WRITE_BUF_SZ);
367 	memcpy(abuf, data, dsize);
368 	ent->buf = abuf;
369 	ent->size = dsize;
370 	ent->plid = plid;
371 	list_add_tail(&hbrt_elogs, &ent->link);
372 	if (!hbrt_elog_sending)
373 		hservice_start_elog_send();
374 	unlock(&hbrt_elog_lock);
375 
376 	return 0;
377 }
378 
hservice_scom_read(uint64_t chip_id,uint64_t addr,void * buf)379 static int hservice_scom_read(uint64_t chip_id, uint64_t addr, void *buf)
380 {
381 	return xscom_read(chip_id, addr, buf);
382 }
383 
hservice_scom_write(uint64_t chip_id,uint64_t addr,const void * buf)384 static int hservice_scom_write(uint64_t chip_id, uint64_t addr,
385 			       const void *buf)
386 {
387 	uint64_t val;
388 
389 	memcpy(&val, buf, sizeof(val));
390 	return xscom_write(chip_id, addr, val);
391 }
392 
393 struct hbrt_lid {
394 	void *load_addr;
395 	size_t len;
396 	uint32_t id;
397 	struct list_node link;
398 };
399 static LIST_HEAD(hbrt_lid_list);
400 
401 static bool hbrt_lid_preload_complete = false;
402 
hservices_lid_preload_complete(void)403 bool hservices_lid_preload_complete(void)
404 {
405 	return hbrt_lid_preload_complete;
406 }
407 
408 /* TODO: Few of the following routines can be generalized */
__hservice_lid_load(uint32_t lid,void ** buf,size_t * len)409 static int __hservice_lid_load(uint32_t lid, void **buf, size_t *len)
410 {
411 	int rc;
412 
413 	/* Adjust LID side first or we get a cache mismatch */
414 	lid = fsp_adjust_lid_side(lid);
415 
416 	/*
417 	 * Allocate a new buffer and load the LID into it
418 	 * XXX: We currently use the same size for each HBRT lid.
419 	 */
420 	*buf = malloc(HBRT_LOAD_LID_SIZE);
421 	*len = HBRT_LOAD_LID_SIZE;
422 	rc = fsp_preload_lid(lid, *buf, len);
423 	rc = fsp_wait_lid_loaded(lid);
424 	if (rc != 0)
425 		/* Take advantage of realloc corner case here. */
426 		*len = 0;
427 	*buf = realloc(*buf, *len);
428 
429 	prlog(PR_DEBUG, "HBRT: LID 0x%08x successfully loaded, len=0x%lx\n",
430 			lid, (unsigned long)len);
431 
432 	return rc;
433 }
434 
__hservice_lid_preload(const uint32_t lid)435 static int __hservice_lid_preload(const uint32_t lid)
436 {
437 	struct hbrt_lid *hlid;
438 	void *buf;
439 	size_t len;
440 	int rc;
441 
442 	hlid = zalloc(sizeof(struct hbrt_lid));
443 	if (!hlid) {
444 		prerror("HBRT: Could not allocate struct hbrt_lid\n");
445 		return OPAL_NO_MEM;
446 	}
447 
448 	rc = __hservice_lid_load(lid, &buf, &len);
449 	if (rc) {
450 		free(hlid);
451 		return rc;
452 	}
453 
454 	hlid->load_addr = buf;
455 	hlid->len = len;
456 	hlid->id = lid;
457 	list_add_tail(&hbrt_lid_list, &hlid->link);
458 
459 	return 0;
460 }
461 
462 /* Find and preload all lids needed by hostservices */
hservices_lid_preload(void)463 void hservices_lid_preload(void)
464 {
465 	const uint32_t *lid_list = NULL;
466 	size_t num_lids;
467 	int i;
468 
469 	if (!hservice_runtime)
470 		return;
471 
472 	lid_list = (const uint32_t *)hservice_runtime->get_lid_list(&num_lids);
473 	if (!lid_list) {
474 		prerror("HBRT: get_lid_list() returned NULL\n");
475 		return;
476 	}
477 
478 	prlog(PR_INFO, "HBRT: %d lids to load\n", (int)num_lids);
479 
480 	/* Currently HBRT needs only one (OCC) lid */
481 	for (i = 0; i < num_lids; i++)
482 		__hservice_lid_preload(lid_list[i]);
483 
484 	hbrt_lid_preload_complete = true;
485 	occ_poke_load_queue();
486 }
487 
hservice_lid_load(uint32_t lid,void ** buf,size_t * len)488 static int hservice_lid_load(uint32_t lid, void **buf, size_t *len)
489 {
490 	struct hbrt_lid *hlid;
491 
492 	prlog(PR_INFO, "HBRT: Lid load request for 0x%08x\n", lid);
493 
494 	if (list_empty(&hbrt_lid_list))	{ /* Should not happen */
495 		/**
496 		 * @fwts-label HBRTlidLoadFail
497 		 * @fwts-advice Firmware should have aborted boot
498 		 */
499 		prlog(PR_CRIT, "HBRT: LID Load failed\n");
500 		abort();
501 	}
502 
503 	list_for_each(&hbrt_lid_list, hlid, link) {
504 		if (hlid->id == lid) {
505 			*buf = hlid->load_addr;
506 			*len = hlid->len;
507 			prlog(PR_DEBUG, "HBRT: LID Serviced from cache,"
508 			      " %x, len=0x%lx\n", hlid->id, hlid->len);
509 			return 0;
510 		}
511 	}
512 	return -ENOENT;
513 }
514 
hservice_lid_unload(void * buf __unused)515 static int hservice_lid_unload(void *buf __unused)
516 {
517 	/* We do nothing as the LID is held in cache */
518 	return 0;
519 }
520 
hservice_get_reserved_mem(const char * name)521 static uint64_t hservice_get_reserved_mem(const char *name)
522 {
523 	struct mem_region *region;
524 	uint64_t ret;
525 
526 	/* We assume it doesn't change after we've unlocked it, but
527 	 * lock ensures list is safe to walk. */
528 	lock(&mem_region_lock);
529 	region = find_mem_region(name);
530 	ret = region ? region->start : 0;
531 	unlock(&mem_region_lock);
532 
533 	if (!ret)
534 		prlog(PR_WARNING, "HBRT: Mem region '%s' not found !\n", name);
535 
536 	return ret;
537 }
538 
hservice_nanosleep(uint64_t i_seconds,uint64_t i_nano_seconds)539 static void hservice_nanosleep(uint64_t i_seconds, uint64_t i_nano_seconds)
540 {
541 	struct timespec ts;
542 
543 	ts.tv_sec = i_seconds;
544 	ts.tv_nsec = i_nano_seconds;
545 	nanosleep_nopoll(&ts, NULL);
546 }
547 
hservice_set_special_wakeup(struct cpu_thread * cpu)548 static int hservice_set_special_wakeup(struct cpu_thread *cpu)
549 {
550 	uint64_t val, core_id, poll_target, stamp;
551 	int rc;
552 
553 	/*
554 	 * Note: HWP checks for checkstops, but I assume we don't need to
555 	 * as we wouldn't be running if one was present
556 	 */
557 
558 	/* Grab core ID once */
559 	core_id = pir_to_core_id(cpu->pir);
560 
561 	/*
562 	 * The original HWp reads the XSCOM first but ignores the result
563 	 * and error, let's do the same until I know for sure that is
564 	 * not necessary
565 	 */
566 	xscom_read(cpu->chip_id,
567 		   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
568 		   &val);
569 
570 	/* Then we write special wakeup */
571 	rc = xscom_write(cpu->chip_id,
572 			 XSCOM_ADDR_P8_EX_SLAVE(core_id,
573 						EX_PM_SPECIAL_WAKEUP_PHYP),
574 			 PPC_BIT(0));
575 	if (rc) {
576 		prerror("HBRT: XSCOM error %d asserting special"
577 			" wakeup on 0x%x\n", rc, cpu->pir);
578 		return rc;
579 	}
580 
581 	/*
582 	 * HWP uses the history for Perf register here, dunno why it uses
583 	 * that one instead of the pHyp one, maybe to avoid clobbering it...
584 	 *
585 	 * In any case, it does that to check for run/nap vs.sleep/winkle/other
586 	 * to decide whether to poll on checkstop or not. Since we don't deal
587 	 * with checkstop conditions here, we ignore that part.
588 	 */
589 
590 	/*
591 	 * Now poll for completion of special wakeup. The HWP is nasty here,
592 	 * it will poll at 5ms intervals for up to 200ms. This is not quite
593 	 * acceptable for us at runtime, at least not until we have the
594 	 * ability to "context switch" HBRT. In practice, because we don't
595 	 * winkle, it will never take that long, so we increase the polling
596 	 * frequency to 1us per poll. However we do have to keep the same
597 	 * timeout.
598 	 *
599 	 * We don't use time_wait_ms() either for now as we don't want to
600 	 * poll the FSP here.
601 	 */
602 	stamp = mftb();
603 	poll_target = stamp + msecs_to_tb(200);
604 	val = 0;
605 	while (!(val & EX_PM_GP0_SPECIAL_WAKEUP_DONE)) {
606 		/* Wait 1 us */
607 		hservice_nanosleep(0, 1000);
608 
609 		/* Read PM state */
610 		rc = xscom_read(cpu->chip_id,
611 				XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_GP0),
612 				&val);
613 		if (rc) {
614 			prerror("HBRT: XSCOM error %d reading PM state on"
615 				" 0x%x\n", rc, cpu->pir);
616 			return rc;
617 		}
618 		/* Check timeout */
619 		if (mftb() > poll_target)
620 			break;
621 	}
622 
623 	/* Success ? */
624 	if (val & EX_PM_GP0_SPECIAL_WAKEUP_DONE) {
625 		uint64_t now = mftb();
626 		prlog(PR_TRACE, "HBRT: Special wakeup complete after %ld us\n",
627 		      tb_to_usecs(now - stamp));
628 		return 0;
629 	}
630 
631 	/*
632 	 * We timed out ...
633 	 *
634 	 * HWP has a complex workaround for HW255321 which affects
635 	 * Murano DD1 and Venice DD1. Ignore that for now
636 	 *
637 	 * Instead we just dump some XSCOMs for error logging
638 	 */
639 	prerror("HBRT: Timeout on special wakeup of 0x%0x\n", cpu->pir);
640 	prerror("HBRT:      PM0 = 0x%016llx\n", val);
641 	val = -1;
642 	xscom_read(cpu->chip_id,
643 		   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
644 		   &val);
645 	prerror("HBRT: SPC_WKUP = 0x%016llx\n", val);
646 	val = -1;
647 	xscom_read(cpu->chip_id,
648 		   XSCOM_ADDR_P8_EX_SLAVE(core_id,
649 					  EX_PM_IDLE_STATE_HISTORY_PHYP),
650 		   &val);
651 	prerror("HBRT:  HISTORY = 0x%016llx\n", val);
652 
653 	return OPAL_HARDWARE;
654 }
655 
hservice_clr_special_wakeup(struct cpu_thread * cpu)656 static int hservice_clr_special_wakeup(struct cpu_thread *cpu)
657 {
658 	uint64_t val, core_id;
659 	int rc;
660 
661 	/*
662 	 * Note: HWP checks for checkstops, but I assume we don't need to
663 	 * as we wouldn't be running if one was present
664 	 */
665 
666 	/* Grab core ID once */
667 	core_id = pir_to_core_id(cpu->pir);
668 
669 	/*
670 	 * The original HWp reads the XSCOM first but ignores the result
671 	 * and error, let's do the same until I know for sure that is
672 	 * not necessary
673 	 */
674 	xscom_read(cpu->chip_id,
675 		   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
676 		   &val);
677 
678 	/* Then we write special wakeup */
679 	rc = xscom_write(cpu->chip_id,
680 			 XSCOM_ADDR_P8_EX_SLAVE(core_id,
681 						EX_PM_SPECIAL_WAKEUP_PHYP), 0);
682 	if (rc) {
683 		prerror("HBRT: XSCOM error %d deasserting"
684 			" special wakeup on 0x%x\n", rc, cpu->pir);
685 		return rc;
686 	}
687 
688 	/*
689 	 * The original HWp reads the XSCOM again with the comment
690 	 * "This puts an inherent delay in the propagation of the reset
691 	 * transition"
692 	 */
693 	xscom_read(cpu->chip_id,
694 		   XSCOM_ADDR_P8_EX_SLAVE(core_id, EX_PM_SPECIAL_WAKEUP_PHYP),
695 		   &val);
696 
697 	return 0;
698 }
699 
hservice_wakeup(uint32_t i_core,uint32_t i_mode)700 static int hservice_wakeup(uint32_t i_core, uint32_t i_mode)
701 {
702 	struct cpu_thread *cpu;
703 	int rc = OPAL_SUCCESS;
704 
705 	/*
706 	 * Mask out the top nibble of i_core since it may contain
707 	 * 0x4 (which we use for XSCOM targeting)
708 	 */
709 	i_core &= 0x0fffffff;
710 
711 	/* What do we need to do ? */
712 	switch(i_mode) {
713 	case 0: /* Assert special wakeup */
714 		/* XXX Assume P8 */
715 		cpu = find_cpu_by_pir(i_core << 3);
716 		if (!cpu)
717 			return OPAL_PARAMETER;
718 		prlog(PR_DEBUG, "HBRT: Special wakeup assert for core 0x%x,"
719 		      " count=%d\n", i_core, cpu->hbrt_spec_wakeup);
720 		if (cpu->hbrt_spec_wakeup == 0)
721 			rc = hservice_set_special_wakeup(cpu);
722 		if (rc == 0)
723 			cpu->hbrt_spec_wakeup++;
724 		return rc;
725 	case 1: /* Deassert special wakeup */
726 		/* XXX Assume P8 */
727 		cpu = find_cpu_by_pir(i_core << 3);
728 		if (!cpu)
729 			return OPAL_PARAMETER;
730 		prlog(PR_DEBUG, "HBRT: Special wakeup release for core"
731 		      " 0x%x, count=%d\n", i_core, cpu->hbrt_spec_wakeup);
732 		if (cpu->hbrt_spec_wakeup == 0) {
733 			prerror("HBRT: Special wakeup clear"
734 				" on core 0x%x with count=0\n",
735 				i_core);
736 			return OPAL_WRONG_STATE;
737 		}
738 		/* What to do with count on errors ? */
739 		cpu->hbrt_spec_wakeup--;
740 		if (cpu->hbrt_spec_wakeup == 0)
741 			rc = hservice_clr_special_wakeup(cpu);
742 		return rc;
743 	case 2: /* Clear all special wakeups */
744 		prlog(PR_DEBUG, "HBRT: Special wakeup release for all cores\n");
745 		for_each_cpu(cpu) {
746 			if (cpu->hbrt_spec_wakeup) {
747 				cpu->hbrt_spec_wakeup = 0;
748 				/* What to do on errors ? */
749 				hservice_clr_special_wakeup(cpu);
750 			}
751 		}
752 		return OPAL_SUCCESS;
753 	default:
754 		return OPAL_PARAMETER;
755 	}
756 }
757 
758 static struct host_interfaces hinterface = {
759 	.interface_version = HOSTBOOT_RUNTIME_INTERFACE_VERSION,
760 	.puts = hservice_puts,
761 	.assert = hservice_assert,
762 	.malloc = hservice_malloc,
763 	.free = hservice_free,
764 	.realloc = hservice_realloc,
765 	.send_error_log = hservice_send_error_log,
766 	.scom_read = hservice_scom_read,
767 	.scom_write = hservice_scom_write,
768 	.lid_load = hservice_lid_load,
769 	.lid_unload = hservice_lid_unload,
770 	.get_reserved_mem = hservice_get_reserved_mem,
771 	.wakeup = hservice_wakeup,
772 	.nanosleep = hservice_nanosleep,
773 };
774 
host_services_occ_load(void)775 int host_services_occ_load(void)
776 {
777 	struct proc_chip *chip;
778 	int rc = 0;
779 
780 	prlog(PR_DEBUG, "HBRT: OCC Load requested\n");
781 
782 	if (!(hservice_runtime && hservice_runtime->loadOCC)) {
783 		prerror("HBRT: No hservice_runtime->loadOCC\n");
784 		return -ENOENT;
785 	}
786 
787 	for_each_chip(chip) {
788 
789 		prlog(PR_DEBUG, "HBRT: Calling loadOCC() homer"
790 		      " %016llx, occ_common_area %016llx, chip %04x\n",
791 		      chip->homer_base,
792 		      chip->occ_common_base,
793 		      chip->id);
794 
795 		rc = hservice_runtime->loadOCC(chip->homer_base,
796 						chip->homer_base,
797 						chip->occ_common_base,
798 						chip->occ_common_base,
799 						chip->id);
800 
801 		hservice_mark();
802 		prlog(PR_DEBUG, "HBRT: -> rc = %d\n", rc);
803 	}
804 	return rc;
805 }
806 
host_services_occ_start(void)807 int host_services_occ_start(void)
808 {
809 	struct proc_chip *chip;
810 	int i, rc = 0, nr_chips=0;
811 	uint64_t chipids[MAX_CHIPS];
812 
813 	prlog(PR_INFO, "HBRT: OCC Start requested\n");
814 
815 	if (!(hservice_runtime && hservice_runtime->startOCCs)) {
816 		prerror("HBRT: No hservice_runtime->startOCCs\n");
817 		return -ENOENT;
818 	}
819 
820 	for_each_chip(chip) {
821 		chipids[nr_chips++] = chip->id;
822 	}
823 
824 	for (i = 0; i < nr_chips; i++)
825 		prlog(PR_TRACE, "HBRT: Calling startOCC() for %04llx\n",
826 		      chipids[i]);
827 
828 	/* Lets start all OCC */
829 	rc = hservice_runtime->startOCCs(chipids, nr_chips);
830 	hservice_mark();
831 	prlog(PR_DEBUG, "HBRT: startOCCs() rc  = %d\n", rc);
832 	return rc;
833 }
834 
host_services_occ_stop(void)835 int host_services_occ_stop(void)
836 {
837 	int i, rc = 0, nr_slaves = 0, nr_masters = 0;
838 	uint64_t *master_chipids = NULL, *slave_chipids = NULL;
839 
840 	prlog(PR_INFO, "HBRT: OCC Stop requested\n");
841 
842 	if (!(hservice_runtime && hservice_runtime->stopOCCs)) {
843 		prerror("HBRT: No hservice_runtime->stopOCCs\n");
844 		return -ENOENT;
845 	}
846 
847 	rc = find_master_and_slave_occ(&master_chipids, &slave_chipids,
848 				       &nr_masters, &nr_slaves);
849 	if (rc)
850 		goto out;
851 
852 	for (i = 0; i < nr_slaves; i++)
853 		prlog(PR_TRACE, "HBRT: Calling stopOCC() for %04llx ",
854 		      slave_chipids[i]);
855 
856 	if (!nr_slaves)
857 		goto master;
858 
859 	/* Lets STOP all the slave OCC */
860 	rc = hservice_runtime->stopOCCs(slave_chipids, nr_slaves);
861 	prlog(PR_DEBUG, "HBRT: stopOCCs() slave rc  = %d\n", rc);
862 
863 master:
864 	for (i = 0; i < nr_masters; i++)
865 		prlog(PR_TRACE, "HBRT: Calling stopOCC() for %04llx ",
866 		      master_chipids[i]);
867 
868 	/* Lets STOP all the master OCC */
869 	rc = hservice_runtime->stopOCCs(master_chipids, nr_masters);
870 
871 	hservice_mark();
872 	prlog(PR_DEBUG, "HBRT: stopOCCs() master rc  = %d\n", rc);
873 
874 out:
875 	free(master_chipids);
876 	free(slave_chipids);
877 	return rc;
878 }
879 
host_services_occ_base_setup(void)880 void host_services_occ_base_setup(void)
881 {
882 	struct proc_chip *chip;
883 	uint64_t occ_common;
884 
885 	chip = next_chip(NULL); /* Frist chip */
886 	occ_common = (uint64_t) local_alloc(chip->id, OCC_COMMON_SIZE, OCC_COMMON_SIZE);
887 
888 	for_each_chip(chip) {
889 		chip->occ_common_base = occ_common;
890 		chip->occ_common_size = OCC_COMMON_SIZE;
891 
892 		chip->homer_base = (uint64_t) local_alloc(chip->id, HOMER_IMAGE_SIZE,
893 							HOMER_IMAGE_SIZE);
894 		chip->homer_size = HOMER_IMAGE_SIZE;
895 		memset((void *)chip->homer_base, 0, chip->homer_size);
896 
897 		prlog(PR_DEBUG, "HBRT: Chip %d HOMER base %016llx : %08llx\n",
898 		      chip->id, chip->homer_base, chip->homer_size);
899 		prlog(PR_DEBUG, "HBRT: OCC common base %016llx : %08llx\n",
900 		      chip->occ_common_base, chip->occ_common_size);
901 	}
902 }
903 
hservices_init(void)904 bool hservices_init(void)
905 {
906 	void *code = NULL;
907 	struct runtime_interfaces *(*hbrt_init)(struct host_interfaces *);
908 
909 	struct function_descriptor {
910 		void *addr;
911 		void *toc;
912 	} fdesc;
913 
914 	code = (void *)hservice_get_reserved_mem("ibm,hbrt-code-image");
915 	if (!code) {
916 		prerror("HBRT: No ibm,hbrt-code-image found.\n");
917 		return false;
918 	}
919 
920 	if (memcmp(code, "HBRTVERS", 8) != 0) {
921 		prerror("HBRT: Bad eyecatcher for ibm,hbrt-code-image!\n");
922 		return false;
923 	}
924 
925 	prlog(PR_INFO, "HBRT: Found HostBoot Runtime version %llu\n",
926 	      ((u64 *)code)[1]);
927 
928 	/* We enter at 0x100 into the image. */
929 	fdesc.addr = code + 0x100;
930 	/* It doesn't care about TOC */
931 	fdesc.toc = NULL;
932 
933 	hbrt_init = (void *)&fdesc;
934 
935 	hservice_runtime = hbrt_init(&hinterface);
936 	hservice_mark();
937 	if (!hservice_runtime) {
938 		prerror("HBRT: Host services init failed\n");
939 		return false;
940 	}
941 
942 	prlog(PR_INFO, "HBRT: Interface version %llu\n",
943 	      hservice_runtime->interface_version);
944 
945 	return true;
946 }
947