1 /* Copyright 2014-2015 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  * imitations under the License.
15  */
16 
17 #define _GNU_SOURCE
18 
19 #include <assert.h>
20 #include <stdio.h>
21 #include <unistd.h>
22 #include <getopt.h>
23 #include <sys/mman.h>
24 #include <sys/types.h>
25 #include <sys/stat.h>
26 #include <fcntl.h>
27 #include <stdlib.h>
28 #include <string.h>
29 #include <stdint.h>
30 #include <sys/stat.h>
31 #include <errno.h>
32 #include <stdbool.h>
33 #include <stdarg.h>
34 #include <time.h>
35 #include <poll.h>
36 #include <dirent.h>
37 
38 #include <endian.h>
39 
40 #include <sys/ioctl.h>
41 #include <sys/time.h>
42 #include <sys/socket.h>
43 #include <sys/un.h>
44 
45 #include <linux/ipmi.h>
46 #include <linux/limits.h>
47 
48 #include <asm/opal-prd.h>
49 
50 #include <opal-api.h>
51 #include <types.h>
52 
53 #include <ccan/list/list.h>
54 
55 #include "opal-prd.h"
56 #include "hostboot-interface.h"
57 #include "module.h"
58 #include "pnor.h"
59 #include "i2c.h"
60 
61 struct prd_range {
62 	const char		*name;
63 	uint64_t		physaddr;
64 	uint64_t		size;
65 	void			*buf;
66 	bool			multiple;
67 	uint32_t		instance;
68 };
69 
70 struct prd_msgq_item {
71 	struct list_node	list;
72 	struct opal_prd_msg	msg;
73 };
74 
75 struct opal_prd_ctx {
76 	int			fd;
77 	int			socket;
78 	struct opal_prd_info	info;
79 	struct prd_range	*ranges;
80 	int			n_ranges;
81 	bool			fw_range_instances;
82 	long			page_size;
83 	void			*code_addr;
84 	size_t			code_size;
85 	bool			debug;
86 	struct pnor		pnor;
87 	char			*hbrt_file_name;
88 	bool			use_syslog;
89 	bool			expert_mode;
90 	struct list_head	msgq;
91 	struct opal_prd_msg	*msg;
92 	size_t			msg_alloc_len;
93 	void			(*vlog)(int, const char *, va_list);
94 };
95 
96 enum control_msg_type {
97 	CONTROL_MSG_ENABLE_OCCS		= 0x00,
98 	CONTROL_MSG_DISABLE_OCCS	= 0x01,
99 	CONTROL_MSG_TEMP_OCC_RESET	= 0x02,
100 	CONTROL_MSG_TEMP_OCC_ERROR	= 0x03,
101 	CONTROL_MSG_ATTR_OVERRIDE	= 0x04,
102 	CONTROL_MSG_HTMGT_PASSTHRU	= 0x05,
103 	CONTROL_MSG_RUN_CMD		= 0x30,
104 };
105 
106 struct control_msg {
107 	enum control_msg_type	type;
108 	int			response;
109 	union {
110 		struct {
111 			unsigned int	argc;
112 		} run_cmd;
113 		struct {
114 			uint64_t	chip;
115 		} occ_reset;
116 		struct {
117 			uint64_t	chip;
118 		} occ_error;
119 	};
120 	unsigned int		data_len;
121 	unsigned char		data[];
122 
123 };
124 
125 #define MAX_CONTROL_MSG_BUF	4096
126 
127 static struct opal_prd_ctx *ctx;
128 
129 static const char *opal_prd_devnode = "/dev/opal-prd";
130 static const char *opal_prd_socket = "/run/opal-prd-control";
131 static const char *hbrt_code_region_name = "ibm,hbrt-code-image";
132 static const int opal_prd_version = 1;
133 static uint64_t opal_prd_ipoll = 0xf000000000000000;
134 
135 static const int max_msgq_len = 16;
136 
137 static const char *ipmi_devnode = "/dev/ipmi0";
138 static const int ipmi_timeout_ms = 5000;
139 
140 static const char *devicetree_base =
141 		"/sys/firmware/devicetree/base";
142 
143 /* Memory error handling */
144 static const char *mem_offline_soft =
145 		"/sys/devices/system/memory/soft_offline_page";
146 static const char *mem_offline_hard =
147 		"/sys/devices/system/memory/hard_offline_page";
148 
149 #define ADDR_STRING_SZ 20 /* Hold %16lx */
150 
151 /* This is the "real" HBRT call table for calling into HBRT as
152  * provided by it. It will be used by the assembly thunk
153  */
154 struct runtime_interfaces *hservice_runtime;
155 struct runtime_interfaces hservice_runtime_fixed;
156 
157 /* This is the callback table provided by assembly code */
158 extern struct host_interfaces hinterface;
159 
160 /* Create opd to call hostservice init */
161 struct func_desc {
162 	void *addr;
163 	void *toc;
164 } hbrt_entry;
165 
166 static int read_prd_msg(struct opal_prd_ctx *ctx);
167 
find_range(const char * name,uint32_t instance)168 static struct prd_range *find_range(const char *name, uint32_t instance)
169 {
170 	struct prd_range *range;
171 	unsigned int i;
172 
173 	for (i = 0; i < ctx->n_ranges; i++) {
174 		range = &ctx->ranges[i];
175 
176 		if (strcmp(range->name, name))
177 			continue;
178 
179 		if (range->multiple && range->instance != instance)
180 			continue;
181 
182 		return range;
183 	}
184 
185 	return NULL;
186 }
187 
pr_log_stdio(int priority,const char * fmt,va_list ap)188 static void pr_log_stdio(int priority, const char *fmt, va_list ap)
189 {
190 	if (!ctx->debug && priority >= LOG_DEBUG)
191 		return;
192 
193 	vprintf(fmt, ap);
194 	printf("\n");
195 }
196 
197 /* standard logging prefixes:
198  * HBRT:  Messages from hostboot runtime code
199  * FW:    Interactions with OPAL firmware
200  * IMAGE: HBRT image loading
201  * MEM:   Memory failure interface
202  * SCOM:  Chip SCOM interface
203  * IPMI:  IPMI interface
204  * PNOR:  PNOR interface
205  * I2C:   i2c interface
206  * PM:    PM/OCC interface
207  * CTRL:  User-triggered control events
208  * KMOD:   Kernel module functions
209  */
210 
pr_log(int priority,const char * fmt,...)211 void pr_log(int priority, const char *fmt, ...)
212 {
213 	va_list ap;
214 
215 	va_start(ap, fmt);
216 	ctx->vlog(priority, fmt, ap);
217 	va_end(ap);
218 }
219 
pr_log_nocall(const char * name)220 static void pr_log_nocall(const char *name)
221 {
222 	pr_log(LOG_WARNING, "HBRT: Call %s not provided", name);
223 }
224 
hexdump(const uint8_t * data,uint32_t len)225 static void hexdump(const uint8_t *data, uint32_t len)
226 {
227 	int i;
228 
229 	for (i = 0; i < len; i++) {
230 		if (i % 16 == 0)
231 			printf("\n");
232 		else if(i % 4 == 0)
233 			printf(" ");
234 
235 		printf("%02x", data[i]);
236 	}
237 
238 	printf("\n");
239 }
240 
pr_log_daemon_init(void)241 static void pr_log_daemon_init(void)
242 {
243 	if (ctx->use_syslog) {
244 		openlog("opal-prd", LOG_NDELAY, LOG_DAEMON);
245 		ctx->vlog = vsyslog;
246 	}
247 }
248 
249 /* Check service processor type */
is_fsp_system(void)250 static bool is_fsp_system(void)
251 {
252 	char *path;
253 	int rc;
254 
255 	rc = asprintf(&path, "%s/fsps", devicetree_base);
256 	if (rc < 0) {
257 		pr_log(LOG_ERR, "FW: error creating '/fsps' path %m");
258 		return false;
259 	}
260 
261 	return access(path, F_OK) ? false : true;
262 }
263 
264 /**
265  * ABI check that we can't perform at build-time: we want to ensure that the
266  * layout of struct host_interfaces matches that defined in the thunk.
267  */
check_abi(void)268 static void check_abi(void)
269 {
270 	extern unsigned char __hinterface_start, __hinterface_pad,
271 	       __hinterface_end;
272 
273 	/* ensure our struct size matches the thunk definition */
274 	assert((&__hinterface_end - &__hinterface_start)
275 			== sizeof(struct host_interfaces));
276 
277 	/* ensure the padding layout is as expected */
278 	assert((void *)&__hinterface_start == (void *)&hinterface);
279 	assert((void *)&__hinterface_pad == (void *)&hinterface.reserved);
280 }
281 
282 /* HBRT init wrappers */
283 extern struct runtime_interfaces *call_hbrt_init(struct host_interfaces *);
284 
285 /* hservice Call wrappers */
286 
287 extern void call_cxxtestExecute(void *);
288 extern int call_handle_attns(uint64_t i_proc,
289 			uint64_t i_ipollStatus,
290 			uint64_t i_ipollMask);
291 extern void call_process_occ_error (uint64_t i_chipId);
292 extern int call_enable_attns(void);
293 extern int call_enable_occ_actuation(bool i_occActivation);
294 extern void call_process_occ_reset(uint64_t i_chipId);
295 extern int call_mfg_htmgt_pass_thru(uint16_t i_cmdLength, uint8_t *i_cmdData,
296 				uint16_t *o_rspLength, uint8_t *o_rspData);
297 extern int call_apply_attr_override(uint8_t *i_data, size_t size);
298 extern int call_run_command(int argc, const char **argv, char **o_outString);
299 extern int call_sbe_message_passing(uint32_t i_chipId);
300 extern uint64_t call_get_ipoll_events(void);
301 extern int call_firmware_notify(uint64_t len, void *data);
302 extern int call_reset_pm_complex(uint64_t chip);
303 
hservice_puts(const char * str)304 void hservice_puts(const char *str)
305 {
306 	int priority = LOG_INFO;
307 
308 	/* Interpret the 2-character ERR_MRK/FAIL_MRK/WARN_MRK prefixes that
309 	 * may be present on HBRT log messages, and bump the log priority as
310 	 * appropriate.
311 	 */
312 	if (strlen(str) >= 2 && str[1] == '>') {
313 		switch (str[0]) {
314 		case 'E':
315 		case 'F':
316 			priority = LOG_ERR;
317 			break;
318 		case 'W':
319 			priority = LOG_WARNING;
320 			break;
321 		}
322 	}
323 
324 	pr_log(priority, "HBRT: %s", str);
325 }
326 
hservice_assert(void)327 void hservice_assert(void)
328 {
329 	pr_log(LOG_ERR, "HBRT: Failed assertion! exiting.");
330 	exit(EXIT_FAILURE);
331 }
332 
hservice_malloc(size_t size)333 void *hservice_malloc(size_t size)
334 {
335 	return malloc(size);
336 }
337 
hservice_free(void * ptr)338 void hservice_free(void *ptr)
339 {
340 	free(ptr);
341 }
342 
hservice_realloc(void * ptr,size_t size)343 void *hservice_realloc(void *ptr, size_t size)
344 {
345 	return realloc(ptr, size);
346 }
347 
hservice_scom_read(uint64_t chip_id,uint64_t addr,void * buf)348 int hservice_scom_read(uint64_t chip_id, uint64_t addr, void *buf)
349 {
350 	int rc;
351 	struct opal_prd_scom scom;
352 
353 	scom.chip = chip_id;
354 	scom.addr = addr;
355 
356 	rc = ioctl(ctx->fd, OPAL_PRD_SCOM_READ, &scom);
357 	if (rc) {
358 		pr_log(LOG_ERR, "SCOM: ioctl read(chip 0x%lx, addr 0x%lx) "
359 				"failed: %m", chip_id, addr);
360 		return 0;
361 	}
362 	rc = (int)scom.rc;
363 
364 	pr_debug("SCOM: read: chip 0x%lx, addr 0x%lx, val 0x%lx, rc %d",
365 		 chip_id, addr, scom.data, rc);
366 
367 	*(uint64_t *)buf = htobe64(scom.data);
368 
369 	return rc;
370 }
371 
hservice_scom_write(uint64_t chip_id,uint64_t addr,const void * buf)372 int hservice_scom_write(uint64_t chip_id, uint64_t addr,
373                                const void *buf)
374 {
375 	int rc;
376 	struct opal_prd_scom scom;
377 
378 	scom.chip = chip_id;
379 	scom.addr = addr;
380 	scom.data = be64toh(*(uint64_t *)buf);
381 
382 	rc = ioctl(ctx->fd, OPAL_PRD_SCOM_WRITE, &scom);
383 	if (rc) {
384 		pr_log(LOG_ERR, "SCOM: ioctl write(chip 0x%lx, addr 0x%lx) "
385 				"failed: %m", chip_id, addr);
386 		return 0;
387 	}
388 	rc = (int)scom.rc;
389 
390 	pr_debug("SCOM: write: chip 0x%lx, addr 0x%lx, val 0x%lx, rc %d",
391 		 chip_id, addr, scom.data, rc);
392 
393 	return rc;
394 }
395 
hservice_get_reserved_mem(const char * name,uint32_t instance)396 uint64_t hservice_get_reserved_mem(const char *name, uint32_t instance)
397 {
398 	struct prd_range *range;
399 
400 	pr_debug("IMAGE: hservice_get_reserved_mem: %s, %d", name, instance);
401 
402 	range = find_range(name, instance);
403 	if (!range) {
404 		pr_log(LOG_WARNING, "IMAGE: get_reserved_mem: "
405 				"no such range %s", name);
406 		return 0;
407 	}
408 
409 	if (!range->buf) {
410 		uint64_t align_physaddr, offset;
411 
412 		pr_debug("IMAGE: Mapping 0x%016lx 0x%08lx %s[%d]",
413 				range->physaddr, range->size,
414 				range->name, range->instance);
415 
416 		align_physaddr = range->physaddr & ~(ctx->page_size-1);
417 		offset = range->physaddr & (ctx->page_size-1);
418 		range->buf = mmap(NULL, range->size, PROT_WRITE | PROT_READ,
419 					MAP_SHARED, ctx->fd, align_physaddr);
420 
421 		if (range->buf == MAP_FAILED)
422 			pr_log(LOG_ERR,
423 				"IMAGE: mmap of %s[%d](0x%016lx) failed: %m",
424 				name, instance, range->physaddr);
425 		else
426 			range->buf += offset;
427 	}
428 
429 	if (range->buf == MAP_FAILED) {
430 		pr_log(LOG_WARNING,
431 				"IMAGE: get_reserved_mem: %s[%d] has no vaddr",
432 				name, instance);
433 		return 0;
434 	}
435 
436 	pr_debug(
437 		"IMAGE: hservice_get_reserved_mem: %s[%d](0x%016lx) address %p",
438 			name, range->instance, range->physaddr,
439 			range->buf);
440 
441 	return (uint64_t)range->buf;
442 }
443 
hservice_nanosleep(uint64_t i_seconds,uint64_t i_nano_seconds)444 void hservice_nanosleep(uint64_t i_seconds, uint64_t i_nano_seconds)
445 {
446 	const struct timespec ns = {
447 		.tv_sec = i_seconds,
448 		.tv_nsec = i_nano_seconds
449 	};
450 
451 	nanosleep(&ns, NULL);
452 }
453 
hservice_set_page_execute(void * addr)454 int hservice_set_page_execute(void *addr)
455 {
456 	/* HBRT calls this on the pages that are already being executed,
457 	 * nothing to do here */
458 	return -1;
459 }
460 
hservice_clock_gettime(clockid_t i_clkId,struct timespec * o_tp)461 int hservice_clock_gettime(clockid_t i_clkId, struct timespec *o_tp)
462 {
463 	struct timespec tmp;
464 	int rc;
465 
466 	rc = clock_gettime(i_clkId, &tmp);
467 	if (rc)
468 		return rc;
469 
470 	o_tp->tv_sec = htobe64(tmp.tv_sec);
471 	o_tp->tv_nsec = htobe64(tmp.tv_nsec);
472 
473 	return 0;
474 }
475 
hservice_pnor_read(uint32_t i_proc,const char * i_partitionName,uint64_t i_offset,void * o_data,size_t i_sizeBytes)476 int hservice_pnor_read(uint32_t i_proc, const char* i_partitionName,
477 		uint64_t i_offset, void* o_data, size_t i_sizeBytes)
478 {
479 	return pnor_operation(&ctx->pnor, i_partitionName, i_offset, o_data,
480 			      i_sizeBytes, PNOR_OP_READ);
481 }
482 
hservice_pnor_write(uint32_t i_proc,const char * i_partitionName,uint64_t i_offset,void * o_data,size_t i_sizeBytes)483 int hservice_pnor_write(uint32_t i_proc, const char* i_partitionName,
484 		uint64_t i_offset, void* o_data, size_t i_sizeBytes)
485 {
486 	return pnor_operation(&ctx->pnor, i_partitionName, i_offset, o_data,
487 			      i_sizeBytes, PNOR_OP_WRITE);
488 }
489 
hservice_i2c_read(uint64_t i_master,uint16_t i_devAddr,uint32_t i_offsetSize,uint32_t i_offset,uint32_t i_length,void * o_data)490 int hservice_i2c_read(uint64_t i_master, uint16_t i_devAddr,
491 		uint32_t i_offsetSize, uint32_t i_offset,
492 		uint32_t i_length, void* o_data)
493 {
494 	uint32_t chip_id;
495 	uint8_t engine, port;
496 
497 	chip_id = (i_master & HBRT_I2C_MASTER_CHIP_MASK) >>
498 		HBRT_I2C_MASTER_CHIP_SHIFT;
499 	engine = (i_master & HBRT_I2C_MASTER_ENGINE_MASK) >>
500 		HBRT_I2C_MASTER_ENGINE_SHIFT;
501 	port = (i_master & HBRT_I2C_MASTER_PORT_MASK) >>
502 		HBRT_I2C_MASTER_PORT_SHIFT;
503 	return i2c_read(chip_id, engine, port, i_devAddr, i_offsetSize,
504 			i_offset, i_length, o_data);
505 }
506 
hservice_i2c_write(uint64_t i_master,uint16_t i_devAddr,uint32_t i_offsetSize,uint32_t i_offset,uint32_t i_length,void * i_data)507 int hservice_i2c_write(uint64_t i_master, uint16_t i_devAddr,
508 		uint32_t i_offsetSize, uint32_t i_offset,
509 		uint32_t i_length, void* i_data)
510 {
511 	uint32_t chip_id;
512 	uint8_t engine, port;
513 
514 	chip_id = (i_master & HBRT_I2C_MASTER_CHIP_MASK) >>
515 		HBRT_I2C_MASTER_CHIP_SHIFT;
516 	engine = (i_master & HBRT_I2C_MASTER_ENGINE_MASK) >>
517 		HBRT_I2C_MASTER_ENGINE_SHIFT;
518 	port = (i_master & HBRT_I2C_MASTER_PORT_MASK) >>
519 		HBRT_I2C_MASTER_PORT_SHIFT;
520 	return i2c_write(chip_id, engine, port, i_devAddr, i_offsetSize,
521 			 i_offset, i_length, i_data);
522 }
523 
ipmi_init(struct opal_prd_ctx * ctx)524 static void ipmi_init(struct opal_prd_ctx *ctx)
525 {
526 	insert_module("ipmi_devintf");
527 }
528 
ipmi_send(int fd,uint8_t netfn,uint8_t cmd,long seq,uint8_t * buf,size_t len)529 static int ipmi_send(int fd, uint8_t netfn, uint8_t cmd, long seq,
530 		uint8_t *buf, size_t len)
531 {
532 	struct ipmi_system_interface_addr addr;
533 	struct ipmi_req req;
534 	int rc;
535 
536 	memset(&addr, 0, sizeof(addr));
537 	addr.addr_type = IPMI_SYSTEM_INTERFACE_ADDR_TYPE;
538 	addr.channel = IPMI_BMC_CHANNEL;
539 
540 	memset(&req, 0, sizeof(req));
541 	req.addr = (unsigned char *)&addr;
542 	req.addr_len = sizeof(addr);
543 
544 	req.msgid = seq;
545 	req.msg.netfn = netfn;
546 	req.msg.cmd = cmd;
547 	req.msg.data = buf;
548 	req.msg.data_len = len;
549 
550 	rc = ioctl(fd, IPMICTL_SEND_COMMAND, &req);
551 	if (rc < 0)
552 		return -1;
553 
554 	return 0;
555 }
556 
ipmi_recv(int fd,uint8_t * netfn,uint8_t * cmd,long * seq,uint8_t * buf,size_t * len)557 static int ipmi_recv(int fd, uint8_t *netfn, uint8_t *cmd, long *seq,
558 		uint8_t *buf, size_t *len)
559 {
560 	struct ipmi_recv recv;
561 	struct ipmi_addr addr;
562 	int rc;
563 
564 	recv.addr = (unsigned char *)&addr;
565 	recv.addr_len = sizeof(addr);
566 	recv.msg.data = buf;
567 	recv.msg.data_len = *len;
568 
569 	rc = ioctl(fd, IPMICTL_RECEIVE_MSG_TRUNC, &recv);
570 	if (rc < 0 && errno != EMSGSIZE) {
571 		pr_log(LOG_WARNING, "IPMI: recv (%zd bytes) failed: %m", *len);
572 		return -1;
573 	} else if (rc < 0 && errno == EMSGSIZE) {
574 		pr_log(LOG_NOTICE, "IPMI: truncated message (netfn %d, cmd %d, "
575 				"size %zd), continuing anyway",
576 				recv.msg.netfn, recv.msg.cmd, *len);
577 	}
578 
579 	*netfn = recv.msg.netfn;
580 	*cmd = recv.msg.cmd;
581 	*seq = recv.msgid;
582 	*len = recv.msg.data_len;
583 
584 	return 0;
585 }
586 
hservice_ipmi_msg(uint8_t netfn,uint8_t cmd,void * tx_buf,size_t tx_size,void * rx_buf,size_t * rx_size)587 int hservice_ipmi_msg(uint8_t netfn, uint8_t cmd,
588 		void *tx_buf, size_t tx_size,
589 		void *rx_buf, size_t *rx_size)
590 {
591 	struct timeval start, now, delta;
592 	struct pollfd pollfds[1];
593 	static long seq;
594 	size_t size;
595 	int rc, fd;
596 
597 	size = be64toh(*rx_size);
598 
599 	fd = open(ipmi_devnode, O_RDWR);
600 	if (fd < 0) {
601 		pr_log(LOG_WARNING, "IPMI: Failed to open IPMI device %s: %m",
602 				ipmi_devnode);
603 		return -1;
604 	}
605 
606 	seq++;
607 	pr_debug("IPMI: sending %zd bytes (netfn 0x%02x, cmd 0x%02x)",
608 			tx_size, netfn, cmd);
609 
610 	rc = ipmi_send(fd, netfn, cmd, seq, tx_buf, tx_size);
611 	if (rc) {
612 		pr_log(LOG_WARNING, "IPMI: send failed");
613 		goto out;
614 	}
615 
616 	gettimeofday(&start, NULL);
617 
618 	pollfds[0].fd = fd;
619 	pollfds[0].events = POLLIN;
620 
621 	for (;;) {
622 		long rx_seq;
623 		int timeout;
624 
625 		gettimeofday(&now, NULL);
626 		timersub(&now, &start, &delta);
627 		timeout = ipmi_timeout_ms - ((delta.tv_sec * 1000) +
628 				(delta.tv_usec / 1000));
629 		if (timeout < 0)
630 			timeout = 0;
631 
632 		rc = poll(pollfds, 1, timeout);
633 		if (rc < 0) {
634 			pr_log(LOG_ERR, "IPMI: poll(%s) failed: %m",
635 					ipmi_devnode);
636 			break;
637 		}
638 
639 		if (rc == 0) {
640 			pr_log(LOG_WARNING, "IPMI: response timeout (>%dms)",
641 					ipmi_timeout_ms);
642 			rc = -1;
643 			break;
644 		}
645 
646 		rc = ipmi_recv(fd, &netfn, &cmd, &rx_seq, rx_buf, &size);
647 		if (rc)
648 			break;
649 
650 		if (seq != rx_seq) {
651 			pr_log(LOG_NOTICE, "IPMI: out-of-sequence reply: %ld, "
652 					"expected %ld. Dropping message.",
653 					rx_seq, seq);
654 			continue;
655 		}
656 
657 		pr_debug("IPMI: received %zd bytes", tx_size);
658 		*rx_size = be64toh(size);
659 		rc = 0;
660 		break;
661 	}
662 
663 out:
664 	close(fd);
665 	return rc;
666 }
667 
hservice_memory_error(uint64_t i_start_addr,uint64_t i_endAddr,enum MemoryError_t i_errorType)668 int hservice_memory_error(uint64_t i_start_addr, uint64_t i_endAddr,
669 		enum MemoryError_t i_errorType)
670 {
671 	const char *sysfsfile, *typestr;
672 	char buf[ADDR_STRING_SZ];
673 	int memfd, rc, n;
674 	uint64_t addr;
675 
676 	switch(i_errorType) {
677 	case MEMORY_ERROR_CE:
678 		sysfsfile = mem_offline_soft;
679 		typestr = "correctable";
680 		break;
681 	case MEMORY_ERROR_UE:
682 		sysfsfile = mem_offline_hard;
683 		typestr = "uncorrectable";
684 		break;
685 	default:
686 		pr_log(LOG_WARNING, "MEM: Invalid memory error type %d",
687 				i_errorType);
688 		return -1;
689 	}
690 
691 	pr_log(LOG_ERR, "MEM: Memory error: range %016lx-%016lx, type: %s",
692 			i_start_addr, i_endAddr, typestr);
693 
694 
695 	memfd = open(sysfsfile, O_WRONLY);
696 	if (memfd < 0) {
697 		pr_log(LOG_CRIT, "MEM: Failed to offline memory! "
698 				"Unable to open sysfs node %s: %m", sysfsfile);
699 		return -1;
700 	}
701 
702 	for (addr = i_start_addr; addr <= i_endAddr; addr += ctx->page_size) {
703 		n = snprintf(buf, ADDR_STRING_SZ, "0x%lx", addr);
704 		rc = write(memfd, buf, n);
705 		if (rc != n) {
706 			pr_log(LOG_CRIT, "MEM: Failed to offline memory! "
707 					"page addr: %016lx type: %d: %m",
708 				addr, i_errorType);
709 			return rc;
710 		}
711 	}
712 
713 	return 0;
714 }
715 
hservice_get_interface_capabilities(uint64_t set)716 uint64_t hservice_get_interface_capabilities(uint64_t set)
717 {
718 	if (set == HBRT_CAPS_SET1_OPAL)
719 		return HBRT_CAPS_OPAL_HAS_XSCOM_RC;
720 
721 	return 0;
722 }
723 
hservice_firmware_request(uint64_t req_len,void * req,uint64_t * resp_lenp,void * resp)724 uint64_t hservice_firmware_request(uint64_t req_len, void *req,
725 		uint64_t *resp_lenp, void *resp)
726 {
727 	struct opal_prd_msg *msg = ctx->msg;
728 	uint64_t resp_len;
729 	size_t size;
730 	int rc, n;
731 
732 	resp_len = be64_to_cpu(*resp_lenp);
733 
734 	pr_log(LOG_DEBUG,
735 			"HBRT: firmware request: %lu bytes req, %lu bytes resp",
736 			req_len, resp_len);
737 
738 	/* sanity check for potential overflows */
739 	if (req_len > 0xffff || resp_len > 0xffff)
740 		return -1;
741 
742 	size = sizeof(msg->hdr) + sizeof(msg->token) +
743 		sizeof(msg->fw_req) + req_len;
744 
745 	/* we need the entire message to fit within the 2-byte size field */
746 	if (size > 0xffff)
747 		return -1;
748 
749 	/* variable sized message, so we may need to expand our buffer */
750 	if (size > ctx->msg_alloc_len) {
751 		msg = realloc(ctx->msg, size);
752 		if (!msg) {
753 			pr_log(LOG_ERR,
754 				"FW: failed to expand message buffer: %m");
755 			return -1;
756 		}
757 		ctx->msg = msg;
758 		ctx->msg_alloc_len = size;
759 	}
760 
761 	memset(msg, 0, size);
762 
763 	/* construct request message... */
764 	msg->hdr.type = OPAL_PRD_MSG_TYPE_FIRMWARE_REQUEST;
765 	msg->hdr.size = htobe16(size);
766 	msg->fw_req.req_len = htobe64(req_len);
767 	msg->fw_req.resp_len = htobe64(resp_len);
768 	memcpy(msg->fw_req.data, req, req_len);
769 
770 	hexdump((void *)msg, size);
771 
772 	/* ... and send to firmware */
773 	rc = write(ctx->fd, msg, size);
774 	if (rc != size) {
775 		pr_log(LOG_WARNING,
776 			"FW: Failed to send FIRMWARE_REQUEST message: %m");
777 		return -1;
778 	}
779 
780 	/* We have an "inner" poll loop here, as we want to ensure that the
781 	 * next entry into HBRT is the return from this function. So, only
782 	 * read from the prd fd, and queue anything that isn't a response
783 	 * to this request
784 	 */
785 	n = 0;
786 	for (;;) {
787 		struct prd_msgq_item *item;
788 
789 		rc = read_prd_msg(ctx);
790 		if (rc)
791 			return -1;
792 
793 		msg = ctx->msg;
794 		if (msg->hdr.type == OPAL_PRD_MSG_TYPE_FIRMWARE_RESPONSE) {
795 			size = be64toh(msg->fw_resp.len);
796 			if (size > resp_len)
797 				return -1;
798 
799 			/* success! a valid response that fits into HBRT's
800 			 * resp buffer */
801 			memcpy(resp, msg->fw_resp.data, size);
802 			*resp_lenp = htobe64(size);
803 			return 0;
804 		}
805 
806 		/* not a response? queue up for later consumption */
807 		if (++n > max_msgq_len) {
808 			pr_log(LOG_ERR,
809 				"FW: too many messages queued (%d) while "
810 				"waiting for FIRMWARE_RESPONSE", n);
811 			return -1;
812 		}
813 		size = be16toh(msg->hdr.size);
814 		item = malloc(sizeof(*item) + size);
815 		memcpy(&item->msg, msg, size);
816 		list_add_tail(&ctx->msgq, &item->list);
817 	}
818 }
819 
hservices_init(struct opal_prd_ctx * ctx,void * code)820 int hservices_init(struct opal_prd_ctx *ctx, void *code)
821 {
822 	uint64_t *s, *d;
823 	int i, sz;
824 
825 	pr_debug("IMAGE: code address: %p", code);
826 
827 	/* We enter at 0x100 into the image. */
828 	/* Load func desc in BE since we reverse it in thunk */
829 
830 	hbrt_entry.addr = (void *)htobe64((unsigned long)code + 0x100);
831 	hbrt_entry.toc = 0; /* No toc for init entry point */
832 
833 	if (memcmp(code, "HBRTVERS", 8) != 0) {
834 		pr_log(LOG_ERR, "IMAGE: Bad signature for "
835 				"ibm,hbrt-code-image! exiting");
836 		return -1;
837 	}
838 
839 	pr_debug("IMAGE: calling ibm,hbrt_init()");
840 	hservice_runtime = call_hbrt_init(&hinterface);
841 	if (!hservice_runtime) {
842 		pr_log(LOG_ERR, "IMAGE: hbrt_init failed, exiting");
843 		return -1;
844 	}
845 
846 	pr_log(LOG_NOTICE, "IMAGE: hbrt_init complete, version %016lx",
847 			hservice_runtime->interface_version);
848 
849 	sz = sizeof(struct runtime_interfaces)/sizeof(uint64_t);
850 	s = (uint64_t *)hservice_runtime;
851 	d = (uint64_t *)&hservice_runtime_fixed;
852 	/* Byte swap the function pointers */
853 	for (i = 0; i < sz; i++)
854 		d[i] = be64toh(s[i]);
855 
856 	return 0;
857 }
858 
fixup_hinterface_table(void)859 static void fixup_hinterface_table(void)
860 {
861 	uint64_t *t64;
862 	unsigned int i, sz;
863 
864 	/* Swap interface version */
865 	hinterface.interface_version =
866 		htobe64(hinterface.interface_version);
867 
868 	/* Swap OPDs */
869 	sz = sizeof(struct host_interfaces) / sizeof(uint64_t);
870 	t64 = (uint64_t *)&hinterface;
871 	for (i = 1; i < sz; i++) {
872 		uint64_t *opd = (uint64_t *)t64[i];
873 		if (!opd)
874 			continue;
875 		t64[i] = htobe64(t64[i]);
876 		opd[0] = htobe64(opd[0]);
877 		opd[1] = htobe64(opd[1]);
878 		opd[2] = htobe64(opd[2]);
879 	}
880 }
881 
map_hbrt_file(struct opal_prd_ctx * ctx,const char * name)882 static int map_hbrt_file(struct opal_prd_ctx *ctx, const char *name)
883 {
884 	struct stat statbuf;
885 	int fd, rc;
886 	void *buf;
887 
888 	fd = open(name, O_RDONLY);
889 	if (fd < 0) {
890 		pr_log(LOG_ERR, "IMAGE: HBRT file open(%s) failed: %m", name);
891 		return -1;
892 	}
893 
894 	rc = fstat(fd, &statbuf);
895 	if (rc < 0) {
896 		pr_log(LOG_ERR, "IMAGE: HBRT file fstat(%s) failed: %m", name);
897 		close(fd);
898 		return -1;
899 	}
900 
901 	buf = mmap(NULL, statbuf.st_size, PROT_READ | PROT_WRITE | PROT_EXEC,
902 			MAP_PRIVATE, fd, 0);
903 	close(fd);
904 
905 	if (buf == MAP_FAILED) {
906 		pr_log(LOG_ERR, "IMAGE: HBRT file mmap(%s, 0x%zx) failed: %m",
907 				name, statbuf.st_size);
908 		return -1;
909 	}
910 
911 	ctx->code_addr = buf;
912 	ctx->code_size = statbuf.st_size;
913 	return -0;
914 }
915 
map_hbrt_physmem(struct opal_prd_ctx * ctx,const char * name)916 static int map_hbrt_physmem(struct opal_prd_ctx *ctx, const char *name)
917 {
918 	struct prd_range *range;
919 	void *buf;
920 
921 	range = find_range(name, 0);
922 	if (!range) {
923 		pr_log(LOG_ERR, "IMAGE: can't find code region %s", name);
924 		return -1;
925 	}
926 
927 	buf = mmap(NULL, range->size, PROT_READ | PROT_WRITE | PROT_EXEC,
928 			MAP_PRIVATE, ctx->fd, range->physaddr);
929 	if (buf == MAP_FAILED) {
930 		pr_log(LOG_ERR, "IMAGE: mmap(range:%s, "
931 				"phys:0x%016lx, size:0x%016lx) failed: %m",
932 				name, range->physaddr, range->size);
933 		return -1;
934 	}
935 
936 	ctx->code_addr = buf;
937 	ctx->code_size = range->size;
938 	return 0;
939 }
940 
dump_hbrt_map(struct opal_prd_ctx * ctx)941 static void dump_hbrt_map(struct opal_prd_ctx *ctx)
942 {
943 	const char *dump_name = "hbrt.bin";
944 	int fd, rc;
945 
946 	if (!ctx->debug)
947 		return;
948 
949 	fd = open(dump_name, O_WRONLY | O_CREAT, 0644);
950 	if (fd < 0) {
951 		pr_log(LOG_NOTICE, "IMAGE: couldn't debug image %s for writing",
952 				dump_name);
953 		return;
954 	}
955 
956 	rc = ftruncate(fd, 0);
957 	if (rc < 0) {
958 		pr_log(LOG_NOTICE, "IMAGE: couldn't truncate image %s for writing",
959 				dump_name);
960 		return;
961 	}
962 	rc = write(fd, ctx->code_addr, ctx->code_size);
963 	close(fd);
964 
965 	if (rc != ctx->code_size)
966 		pr_log(LOG_NOTICE, "IMAGE: write to %s failed: %m", dump_name);
967 	else
968 		pr_debug("IMAGE: dumped HBRT binary to %s", dump_name);
969 }
970 
open_and_read(const char * path,void ** bufp,int * lenp)971 static int open_and_read(const char *path, void **bufp, int *lenp)
972 {
973 	struct stat statbuf;
974 	int fd, rc, bytes;
975 	void *buf;
976 
977 	fd = open(path, O_RDONLY);
978 	if (fd < 0)
979 		return -1;
980 
981 	rc = fstat(fd, &statbuf);
982 	if (rc) {
983 		close(fd);
984 		return -1;
985 	}
986 
987 	buf = malloc(statbuf.st_size);
988 
989 	for (rc = bytes = 0; bytes < statbuf.st_size; bytes += rc) {
990 		rc = read(fd, buf + bytes, statbuf.st_size - bytes);
991 		if (rc < 0) {
992 			if (errno == EINTR)
993 				continue;
994 			break;
995 		} else if (rc == 0)
996 			break;
997 	}
998 
999 	if (bytes == statbuf.st_size)
1000 		rc = 0;
1001 
1002 	if (rc == 0) {
1003 		if (lenp)
1004 			*lenp = bytes;
1005 		if (bufp)
1006 			*bufp = buf;
1007 	} else {
1008 		free(buf);
1009 	}
1010 
1011 	close(fd);
1012 
1013 	return rc == 0 ? 0 : -1;
1014 }
1015 
prd_init_one_range(struct opal_prd_ctx * ctx,const char * path,struct dirent * dirent)1016 static int prd_init_one_range(struct opal_prd_ctx *ctx, const char *path,
1017 		struct dirent *dirent)
1018 {
1019 	char *label_path, *reg_path, *instance_path;
1020 	struct prd_range *range;
1021 	int label_len, len, rc;
1022 	__be64 *reg;
1023 	char *label;
1024 	void *buf;
1025 
1026 	rc = asprintf(&label_path, "%s/%s/ibm,prd-label", path, dirent->d_name);
1027 	if (rc < 0) {
1028 		pr_log(LOG_ERR, "FW: error creating 'ibm,prd-label' path "
1029 				"node: %m");
1030 		return -1;
1031 	}
1032 	rc = asprintf(&instance_path, "%s/%s/ibm,prd-instance",
1033 			path, dirent->d_name);
1034 	if (rc < 0) {
1035 		pr_log(LOG_ERR, "FW: error creating 'ibm,prd-instance' path "
1036 				"node: %m");
1037 		return -1;
1038 	}
1039 	rc = asprintf(&reg_path, "%s/%s/reg", path, dirent->d_name);
1040 	if (rc < 0) {
1041 		pr_log(LOG_ERR, "FW: error creating 'reg' path "
1042 				" node: %m");
1043 		return -1;
1044 	}
1045 
1046 	reg = NULL;
1047 	label = NULL;
1048 	rc = -1;
1049 
1050 	rc = open_and_read(label_path, &buf, &label_len);
1051 	if (rc)
1052 		goto out_free;
1053 
1054 	label = buf;
1055 
1056 	if (label[label_len-1] != '\0')
1057 		pr_log(LOG_INFO, "FW: node %s has invalid ibm,prd-label - "
1058 				"not nul-terminated",
1059 				dirent->d_name);
1060 
1061 	rc = open_and_read(reg_path, &buf, &len);
1062 	if (rc)
1063 		goto out_free;
1064 
1065 	reg = buf;
1066 
1067 	if (len != 2 * sizeof(*reg)) {
1068 		pr_log(LOG_ERR, "FW: node %s has invalid 'reg' size: %d",
1069 				dirent->d_name, len);
1070 		goto out_free;
1071 	}
1072 
1073 
1074 	ctx->ranges = realloc(ctx->ranges, ++ctx->n_ranges * sizeof(*range));
1075 	range = &ctx->ranges[ctx->n_ranges - 1];
1076 	range->name = strndup(label, label_len);
1077 	range->physaddr = be64toh(reg[0]);
1078 	range->size = be64toh(reg[1]);
1079 	range->buf = NULL;
1080 	range->multiple = false;
1081 	range->instance = 0;
1082 
1083 	/* optional instance */
1084 	rc = open_and_read(instance_path, &buf, &len);
1085 	if (!rc && len == sizeof(uint32_t)) {
1086 		range->multiple = true;
1087 		range->instance = be32toh(*(uint32_t *)buf);
1088 		ctx->fw_range_instances = true;
1089 	}
1090 	rc = 0;
1091 
1092 out_free:
1093 	free(reg);
1094 	free(label);
1095 	free(instance_path);
1096 	free(reg_path);
1097 	free(label_path);
1098 	return rc;
1099 }
1100 
compare_ranges(const void * ap,const void * bp)1101 static int compare_ranges(const void *ap, const void *bp)
1102 {
1103 	const struct prd_range *a = ap, *b = bp;
1104 	int rc;
1105 
1106 	rc = strcmp(a->name, b->name);
1107 	if (rc)
1108 		return rc;
1109 
1110 	if (a->physaddr < b->physaddr)
1111 		return -1;
1112 	else if (a->physaddr > b->physaddr)
1113 		return 1;
1114 
1115 	return 0;
1116 }
1117 
assign_range_instances(struct opal_prd_ctx * ctx)1118 static void assign_range_instances(struct opal_prd_ctx *ctx)
1119 {
1120 	int i;
1121 
1122 	if (!ctx->n_ranges)
1123 		return;
1124 
1125 	ctx->ranges[0].multiple = false;
1126 	ctx->ranges[0].instance = 0;
1127 
1128 	for (i = 1; i < ctx->n_ranges; i++) {
1129 		struct prd_range *cur, *prev;
1130 
1131 		cur = &ctx->ranges[i];
1132 		prev = &ctx->ranges[i-1];
1133 
1134 		if (!strcmp(cur->name, prev->name)) {
1135 			prev->multiple = true;
1136 			cur->multiple = true;
1137 			cur->instance = prev->instance + 1;
1138 		} else {
1139 			cur->multiple = false;
1140 			cur->instance = 0;
1141 		}
1142 	}
1143 }
1144 
print_ranges(struct opal_prd_ctx * ctx)1145 static void print_ranges(struct opal_prd_ctx *ctx)
1146 {
1147 	int i;
1148 
1149 	if (ctx->n_ranges == 0)
1150 		pr_log(LOG_INFO, "FW: No PRD ranges");
1151 
1152 	pr_log(LOG_DEBUG, "FW: %d PRD ranges, instances assigned by %s",
1153 			ctx->n_ranges,
1154 			ctx->fw_range_instances ? "firmware" : "userspace");
1155 
1156 	for (i = 0; i < ctx->n_ranges; i++) {
1157 		struct prd_range *range = &ctx->ranges[i];
1158 		char instance_str[20];
1159 
1160 		if (range->multiple)
1161 			snprintf(instance_str, sizeof(instance_str),
1162 					" [%d]", range->instance);
1163 		else
1164 			instance_str[0] = '\0';
1165 
1166 		pr_log(LOG_DEBUG, "FW:  %016lx-%016lx %s%s", range->physaddr,
1167 				range->physaddr + range->size - 1,
1168 				range->name,
1169 				instance_str);
1170 	}
1171 }
1172 
prd_init_ranges(struct opal_prd_ctx * ctx)1173 static int prd_init_ranges(struct opal_prd_ctx *ctx)
1174 {
1175 	struct dirent *dirent;
1176 	char *path;
1177 	DIR *dir;
1178 	int rc;
1179 
1180 	rc = asprintf(&path, "%s/reserved-memory", devicetree_base);
1181 	if (rc < 0) {
1182 		pr_log(LOG_ERR, "FW: error creating 'reserved-memory' path "
1183 				"node: %m");
1184 		return -1;
1185 	}
1186 
1187 	rc = -1;
1188 
1189 	dir = opendir(path);
1190 	if (!dir) {
1191 		pr_log(LOG_ERR, "FW: can't open reserved-memory device-tree "
1192 				"node: %m");
1193 		goto out_free;
1194 	}
1195 
1196 	for (;;) {
1197 		dirent = readdir(dir);
1198 		if (!dirent)
1199 			break;
1200 
1201 		prd_init_one_range(ctx, path, dirent);
1202 	}
1203 
1204 	rc = 0;
1205 	/* sort ranges and assign instance numbers for duplicates (if the
1206 	 * firmware doesn't number instances for us) */
1207 	qsort(ctx->ranges, ctx->n_ranges, sizeof(struct prd_range),
1208 			compare_ranges);
1209 
1210 	if (!ctx->fw_range_instances)
1211 		assign_range_instances(ctx);
1212 
1213 	print_ranges(ctx);
1214 
1215 out_free:
1216 	free(path);
1217 	closedir(dir);
1218 	return rc;
1219 }
1220 
find_string(const char * buffer,size_t len,const char * s)1221 bool find_string(const char *buffer, size_t len, const char *s)
1222 {
1223 	const char *c, *end;
1224 
1225 	if (!buffer)
1226 		return false;
1227 	c = buffer;
1228 	end = c + len;
1229 
1230 	while (c < end) {
1231 		if (!strcasecmp(s, c))
1232 			return true;
1233 		c += strlen(c) + 1;
1234 	}
1235 	return false;
1236 }
1237 
is_prd_supported(void)1238 static int is_prd_supported(void)
1239 {
1240 	char *path;
1241 	int rc;
1242 	int len;
1243 	char *buf;
1244 
1245 	rc = asprintf(&path, "%s/ibm,opal/diagnostics/compatible",
1246 		      devicetree_base);
1247 	if (rc < 0) {
1248 		pr_log(LOG_ERR, "FW: error creating 'compatible' node path: %m");
1249 		return -1;
1250 	}
1251 
1252 	rc = open_and_read(path, (void *) &buf, &len);
1253 	if (rc)
1254 		goto out_free;
1255 
1256 	if (buf[len - 1] != '\0')
1257 		pr_log(LOG_INFO, "FW: node %s is not nul-terminated", path);
1258 
1259 	rc = find_string(buf, len, "ibm,opal-prd") ? 0 : -1;
1260 
1261 	free(buf);
1262 out_free:
1263 	free(path);
1264 	return rc;
1265 }
1266 
prd_init(struct opal_prd_ctx * ctx)1267 static int prd_init(struct opal_prd_ctx *ctx)
1268 {
1269 	int rc;
1270 
1271 	ctx->page_size = sysconf(_SC_PAGE_SIZE);
1272 
1273 	/* set up the device, and do our get_info ioctl */
1274 	ctx->fd = open(opal_prd_devnode, O_RDWR);
1275 	if (ctx->fd < 0) {
1276 		pr_log(LOG_ERR, "FW: Can't open PRD device %s: %m",
1277 				opal_prd_devnode);
1278 		return -1;
1279 	}
1280 
1281 	rc = ioctl(ctx->fd, OPAL_PRD_GET_INFO, &ctx->info);
1282 	if (rc) {
1283 		pr_log(LOG_ERR, "FW: Can't query PRD information: %m");
1284 		return -1;
1285 	}
1286 
1287 	rc = prd_init_ranges(ctx);
1288 	if (rc) {
1289 		pr_log(LOG_ERR, "FW: can't parse PRD memory information");
1290 		return -1;
1291 	}
1292 
1293 	return 0;
1294 }
1295 
handle_msg_attn(struct opal_prd_ctx * ctx,struct opal_prd_msg * msg)1296 static int handle_msg_attn(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg)
1297 {
1298 	uint64_t proc, ipoll_mask, ipoll_status;
1299 	int rc;
1300 
1301 	proc = be64toh(msg->attn.proc);
1302 	ipoll_status = be64toh(msg->attn.ipoll_status);
1303 	ipoll_mask = be64toh(msg->attn.ipoll_mask);
1304 
1305 	if (!hservice_runtime->handle_attns) {
1306 		pr_log_nocall("handle_attns");
1307 		return -1;
1308 	}
1309 
1310 	rc = call_handle_attns(proc, ipoll_status, ipoll_mask);
1311 	if (rc) {
1312 		pr_log(LOG_ERR, "HBRT: handle_attns(%lx,%lx,%lx) failed, rc %d",
1313 				proc, ipoll_status, ipoll_mask, rc);
1314 		return -1;
1315 	}
1316 
1317 	/* send the response */
1318 	msg->hdr.type = OPAL_PRD_MSG_TYPE_ATTN_ACK;
1319 	msg->hdr.size = htobe16(sizeof(*msg));
1320 	msg->attn_ack.proc = htobe64(proc);
1321 	msg->attn_ack.ipoll_ack = htobe64(ipoll_status);
1322 	rc = write(ctx->fd, msg, sizeof(*msg));
1323 
1324 	if (rc != sizeof(*msg)) {
1325 		pr_log(LOG_WARNING, "FW: Failed to send ATTN_ACK message: %m");
1326 		return -1;
1327 	}
1328 
1329 	return 0;
1330 }
1331 
handle_msg_occ_error(struct opal_prd_ctx * ctx,struct opal_prd_msg * msg)1332 static int handle_msg_occ_error(struct opal_prd_ctx *ctx,
1333 		struct opal_prd_msg *msg)
1334 {
1335 	uint32_t proc;
1336 
1337 	proc = be64toh(msg->occ_error.chip);
1338 
1339 	pr_debug("FW: firmware signaled OCC error for proc 0x%x", proc);
1340 
1341 	if (!hservice_runtime->process_occ_error) {
1342 		pr_log_nocall("process_occ_error");
1343 		return -1;
1344 	}
1345 
1346 	call_process_occ_error(proc);
1347 	return 0;
1348 }
1349 
pm_complex_reset(uint64_t chip)1350 static int pm_complex_reset(uint64_t chip)
1351 {
1352 	int rc;
1353 
1354 	/*
1355 	 * FSP system -> reset_pm_complex
1356 	 * BMC system -> process_occ_reset
1357 	 */
1358 	if (is_fsp_system()) {
1359 		if (!hservice_runtime->reset_pm_complex) {
1360 			pr_log_nocall("reset_pm_complex");
1361 			return -1;
1362 		}
1363 
1364 		pr_debug("PM: calling pm_complex_reset(%ld)", chip);
1365 		rc = call_reset_pm_complex(chip);
1366 	} else {
1367 		if (!hservice_runtime->process_occ_reset) {
1368 			pr_log_nocall("process_occ_reset");
1369 			return -1;
1370 		}
1371 
1372 		pr_debug("PM: calling process_occ_reset(%ld)", chip);
1373 		call_process_occ_reset(chip);
1374 		rc = 0;
1375 	}
1376 
1377 	return rc;
1378 }
1379 
handle_msg_occ_reset(struct opal_prd_ctx * ctx,struct opal_prd_msg * msg)1380 static int handle_msg_occ_reset(struct opal_prd_ctx *ctx,
1381 		struct opal_prd_msg *msg)
1382 {
1383 	uint32_t proc;
1384 	int rc;
1385 
1386 	proc = be64toh(msg->occ_reset.chip);
1387 
1388 	pr_debug("FW: firmware requested OCC reset for proc 0x%x", proc);
1389 
1390 	rc = pm_complex_reset(proc);
1391 
1392 	return rc;
1393 }
1394 
handle_msg_firmware_notify(struct opal_prd_ctx * ctx,struct opal_prd_msg * msg)1395 static int handle_msg_firmware_notify(struct opal_prd_ctx *ctx,
1396 		struct opal_prd_msg *msg)
1397 {
1398 	uint64_t len;
1399 	void *buf;
1400 
1401 	len = be64toh(msg->fw_notify.len);
1402 	buf = msg->fw_notify.data;
1403 
1404 	pr_debug("FW: firmware notification, %ld bytes", len);
1405 
1406 	if (!hservice_runtime->firmware_notify) {
1407 		pr_log_nocall("firmware_notify");
1408 		return -1;
1409 	}
1410 
1411 	call_firmware_notify(len, buf);
1412 
1413 	return 0;
1414 }
1415 
handle_msg_sbe_passthrough(struct opal_prd_ctx * ctx,struct opal_prd_msg * msg)1416 static int handle_msg_sbe_passthrough(struct opal_prd_ctx *ctx,
1417 				      struct opal_prd_msg *msg)
1418 {
1419 	uint32_t proc;
1420 	int rc;
1421 
1422 	proc = be64toh(msg->sbe_passthrough.chip);
1423 
1424 	pr_debug("FW: firmware sent SBE pass through command for proc 0x%x\n",
1425 		 proc);
1426 
1427 	if (!hservice_runtime->sbe_message_passing) {
1428 		pr_log_nocall("sbe_message_passing");
1429 		return -1;
1430 	}
1431 
1432 	rc = call_sbe_message_passing(proc);
1433 	return rc;
1434 }
1435 
handle_prd_msg(struct opal_prd_ctx * ctx,struct opal_prd_msg * msg)1436 static int handle_prd_msg(struct opal_prd_ctx *ctx, struct opal_prd_msg *msg)
1437 {
1438 	int rc = -1;
1439 
1440 	switch (msg->hdr.type) {
1441 	case OPAL_PRD_MSG_TYPE_ATTN:
1442 		rc = handle_msg_attn(ctx, msg);
1443 		break;
1444 	case OPAL_PRD_MSG_TYPE_OCC_RESET:
1445 		rc = handle_msg_occ_reset(ctx, msg);
1446 		break;
1447 	case OPAL_PRD_MSG_TYPE_OCC_ERROR:
1448 		rc = handle_msg_occ_error(ctx, msg);
1449 		break;
1450 	case OPAL_PRD_MSG_TYPE_FIRMWARE_NOTIFY:
1451 		rc = handle_msg_firmware_notify(ctx, msg);
1452 		break;
1453 	case OPAL_PRD_MSG_TYPE_SBE_PASSTHROUGH:
1454 		rc = handle_msg_sbe_passthrough(ctx, msg);
1455 		break;
1456 	default:
1457 		pr_log(LOG_WARNING, "Invalid incoming message type 0x%x",
1458 				msg->hdr.type);
1459 	}
1460 
1461 	return rc;
1462 }
1463 
1464 #define list_for_each_pop(h, i, type, member) \
1465 	for (i = list_pop((h), type, member); \
1466 		i; \
1467 		i = list_pop((h), type, member))
1468 
1469 
process_msgq(struct opal_prd_ctx * ctx)1470 static int process_msgq(struct opal_prd_ctx *ctx)
1471 {
1472 	struct prd_msgq_item *item;
1473 
1474 	list_for_each_pop(&ctx->msgq, item, struct prd_msgq_item, list) {
1475 		handle_prd_msg(ctx, &item->msg);
1476 		free(item);
1477 	}
1478 
1479 	return 0;
1480 }
1481 
read_prd_msg(struct opal_prd_ctx * ctx)1482 static int read_prd_msg(struct opal_prd_ctx *ctx)
1483 {
1484 	struct opal_prd_msg *msg;
1485 	int size;
1486 	int rc;
1487 
1488 	msg = ctx->msg;
1489 
1490 	rc = read(ctx->fd, msg, ctx->msg_alloc_len);
1491 	if (rc < 0 && errno == EAGAIN)
1492 		return -1;
1493 
1494 	/* we need at least enough for the message header... */
1495 	if (rc < 0) {
1496 		pr_log(LOG_WARNING, "FW: error reading from firmware: %m");
1497 		return -1;
1498 	}
1499 
1500 	if (rc < sizeof(msg->hdr)) {
1501 		pr_log(LOG_WARNING, "FW: short message read from firmware");
1502 		return -1;
1503 	}
1504 
1505 	/* ... and for the reported message size to be sane */
1506 	size = htobe16(msg->hdr.size);
1507 	if (size < sizeof(msg->hdr)) {
1508 		pr_log(LOG_ERR, "FW: Mismatched message size "
1509 				"between opal-prd and firmware "
1510 				"(%d from FW, %zd expected)",
1511 				size, sizeof(msg->hdr));
1512 		return -1;
1513 	}
1514 
1515 	/* expand our message buffer if necessary... */
1516 	if (size > ctx->msg_alloc_len) {
1517 		msg = realloc(ctx->msg, size);
1518 		if (!msg) {
1519 			pr_log(LOG_ERR,
1520 				"FW: Can't expand PRD message buffer: %m");
1521 			return -1;
1522 		}
1523 		ctx->msg = msg;
1524 		ctx->msg_alloc_len = size;
1525 	}
1526 
1527 	/* ... and complete the read */
1528 	if (size > rc) {
1529 		size_t pos;
1530 
1531 		for (pos = rc; pos < size;) {
1532 			rc = read(ctx->fd, msg + pos, size - pos);
1533 
1534 			if (rc < 0 && errno == EAGAIN)
1535 				continue;
1536 
1537 			if (rc <= 0) {
1538 				pr_log(LOG_WARNING,
1539 					"FW: error reading from firmware: %m");
1540 				return -1;
1541 			}
1542 
1543 			pos += rc;
1544 		}
1545 	}
1546 
1547 	return 0;
1548 }
1549 
handle_prd_control_occ_error(struct control_msg * send_msg,struct control_msg * recv_msg)1550 static void handle_prd_control_occ_error(struct control_msg *send_msg,
1551 		struct control_msg *recv_msg)
1552 {
1553 	uint64_t chip;
1554 
1555 	if (!hservice_runtime->process_occ_error) {
1556 		pr_log_nocall("process_occ_error");
1557 		return;
1558 	}
1559 
1560 	chip = recv_msg->occ_error.chip;
1561 
1562 	pr_debug("CTRL: calling process_occ_error(%lu)", chip);
1563 	call_process_occ_error(chip);
1564 
1565 	send_msg->data_len = 0;
1566 	send_msg->response = 0;
1567 }
1568 
handle_prd_control_occ_reset(struct control_msg * send_msg,struct control_msg * msg)1569 static void handle_prd_control_occ_reset(struct control_msg *send_msg,
1570 		struct control_msg *msg)
1571 {
1572 	struct opal_prd_msg omsg;
1573 	uint64_t chip;
1574 	int rc;
1575 
1576 	/* notify OPAL of the impending reset */
1577 	memset(&omsg, 0, sizeof(omsg));
1578 	omsg.hdr.type = OPAL_PRD_MSG_TYPE_OCC_RESET_NOTIFY;
1579 	omsg.hdr.size = htobe16(sizeof(omsg));
1580 	rc = write(ctx->fd, &omsg, sizeof(omsg));
1581 	if (rc != sizeof(omsg))
1582 		pr_log(LOG_WARNING, "FW: Failed to send OCC_RESET message: %m");
1583 
1584 	chip = msg->occ_reset.chip;
1585 
1586 	/* do reset */
1587 	pr_debug("CTRL: Calling OCC reset on chip %ld", chip);
1588 	pm_complex_reset(chip);
1589 
1590 	send_msg->data_len = 0;
1591 	send_msg->response = 0;
1592 }
1593 
handle_prd_control_occ_actuation(struct control_msg * msg,bool enable)1594 static void handle_prd_control_occ_actuation(struct control_msg *msg,
1595 					     bool enable)
1596 {
1597 	if (!hservice_runtime->enable_occ_actuation) {
1598 		pr_log_nocall("enable_occ_actuation");
1599 		return;
1600 	}
1601 
1602 	pr_debug("CTRL: calling enable_occ_actuation(%s)",
1603 			enable ? "true" : "false");
1604 	msg->data_len = 0;
1605 	msg->response = call_enable_occ_actuation(enable);
1606 }
1607 
handle_prd_control_attr_override(struct control_msg * send_msg,struct control_msg * recv_msg)1608 static void handle_prd_control_attr_override(struct control_msg *send_msg,
1609 					     struct control_msg *recv_msg)
1610 {
1611 	if (!hservice_runtime->apply_attr_override) {
1612 		pr_log_nocall("apply_attr_override");
1613 		return;
1614 	}
1615 
1616 	pr_debug("CTRL: calling apply_attr_override");
1617 	send_msg->response = call_apply_attr_override(
1618 			recv_msg->data, recv_msg->data_len);
1619 	send_msg->data_len = 0;
1620 }
1621 
handle_prd_control_htmgt_passthru(struct control_msg * send_msg,struct control_msg * recv_msg)1622 static void handle_prd_control_htmgt_passthru(struct control_msg *send_msg,
1623 					      struct control_msg *recv_msg)
1624 {
1625 	uint16_t rsp_len;
1626 
1627 	if (!hservice_runtime->mfg_htmgt_pass_thru) {
1628 		pr_log_nocall("mfg_htmgt_pass_thru");
1629 		return;
1630 	}
1631 
1632 	pr_debug("CTRL: calling mfg_htmgt_pass_thru");
1633 	send_msg->response = call_mfg_htmgt_pass_thru(recv_msg->data_len,
1634 						      recv_msg->data, &rsp_len,
1635 						      send_msg->data);
1636 	send_msg->data_len = be16toh(rsp_len);
1637 	if (send_msg->data_len > MAX_CONTROL_MSG_BUF) {
1638 		pr_log(LOG_ERR, "CTRL: response buffer overrun, data len: %d",
1639 				send_msg->data_len);
1640 		send_msg->data_len = MAX_CONTROL_MSG_BUF;
1641 	}
1642 }
1643 
handle_prd_control_run_cmd(struct control_msg * send_msg,struct control_msg * recv_msg)1644 static void handle_prd_control_run_cmd(struct control_msg *send_msg,
1645 				       struct control_msg *recv_msg)
1646 {
1647 	char *runcmd_output, *s;
1648 	const char **argv;
1649 	int i, argc;
1650 	size_t size;
1651 
1652 	if (!hservice_runtime->run_command) {
1653 		pr_log_nocall("run_command");
1654 		return;
1655 	}
1656 
1657 	argc = recv_msg->run_cmd.argc;
1658 	pr_debug("CTRL: run_command, argc:%d\n", argc);
1659 
1660 	argv = malloc(argc * sizeof(*argv));
1661 	if (!argv) {
1662 		pr_log(LOG_ERR, "CTRL: argv buffer malloc failed: %m");
1663 		return;
1664 	}
1665 
1666 	s = (char *)recv_msg->data;
1667 	size = 0;
1668 	for (i = 0; i < argc; i++) {
1669 		argv[i] = (char *)htobe64((uint64_t)&s[size]);
1670 		size += (strlen(&s[size]) + 1);
1671 	}
1672 
1673 	/* Call HBRT */
1674 	send_msg->response = call_run_command(argc, argv, &runcmd_output);
1675 	runcmd_output = (char *)be64toh((uint64_t)runcmd_output);
1676 	free(argv);
1677 
1678 	s = (char *)send_msg->data;
1679 	if (runcmd_output) {
1680 		size = strlen(runcmd_output);
1681 		if (size >= MAX_CONTROL_MSG_BUF) {
1682 			pr_log(LOG_WARNING, "CTRL: output message truncated");
1683 			runcmd_output[MAX_CONTROL_MSG_BUF] = '\0';
1684 			size = MAX_CONTROL_MSG_BUF;
1685 		}
1686 
1687 		strcpy(s, runcmd_output);
1688 		send_msg->data_len = size + 1;
1689 		free(runcmd_output);
1690 	} else {
1691 		strcpy(s, "Null");
1692 		send_msg->data_len = strlen("Null") + 1;
1693 	}
1694 }
1695 
handle_prd_control(struct opal_prd_ctx * ctx,int fd)1696 static void handle_prd_control(struct opal_prd_ctx *ctx, int fd)
1697 {
1698 	struct control_msg msg, *recv_msg, *send_msg;
1699 	bool enabled = false;
1700 	int rc, size;
1701 
1702 	/* Default reply, in the error path */
1703 	send_msg = &msg;
1704 
1705 	/* Peek into the socket to ascertain the size of the available data */
1706 	rc = recv(fd, &msg, sizeof(msg), MSG_PEEK);
1707 	if (rc != sizeof(msg)) {
1708 		pr_log(LOG_WARNING, "CTRL: failed to receive control "
1709 				"message: %m");
1710 		msg.response = -1;
1711 		msg.data_len = 0;
1712 		goto out_send;
1713 	}
1714 
1715 	size = sizeof(*recv_msg) + msg.data_len;
1716 
1717 	/* Default reply, in the error path */
1718 	msg.data_len = 0;
1719 	msg.response = -1;
1720 
1721 	recv_msg = malloc(size);
1722 	if (!recv_msg) {
1723 		pr_log(LOG_ERR, "CTRL: message buffer malloc failed: %m");
1724 		goto out_send;
1725 	}
1726 
1727 	rc = recv(fd, recv_msg, size, MSG_TRUNC);
1728 	if (rc != size) {
1729 		pr_log(LOG_WARNING, "CTRL: failed to receive control "
1730 				"message: %m");
1731 		goto out_free_recv;
1732 	}
1733 
1734 	send_msg = malloc(sizeof(*send_msg) + MAX_CONTROL_MSG_BUF);
1735 	if (!send_msg) {
1736 		pr_log(LOG_ERR, "CTRL: message buffer malloc failed: %m");
1737 		send_msg = &msg;
1738 		goto out_free_recv;
1739 	}
1740 
1741 	send_msg->type = recv_msg->type;
1742 	send_msg->response = -1;
1743 	switch (recv_msg->type) {
1744 	case CONTROL_MSG_ENABLE_OCCS:
1745 		enabled = true;
1746 		/* fall through */
1747 	case CONTROL_MSG_DISABLE_OCCS:
1748 		handle_prd_control_occ_actuation(send_msg, enabled);
1749 		break;
1750 	case CONTROL_MSG_TEMP_OCC_RESET:
1751 		handle_prd_control_occ_reset(send_msg, recv_msg);
1752 		break;
1753 	case CONTROL_MSG_TEMP_OCC_ERROR:
1754 		handle_prd_control_occ_error(send_msg, recv_msg);
1755 		break;
1756 	case CONTROL_MSG_ATTR_OVERRIDE:
1757 		handle_prd_control_attr_override(send_msg, recv_msg);
1758 		break;
1759 	case CONTROL_MSG_HTMGT_PASSTHRU:
1760 		handle_prd_control_htmgt_passthru(send_msg, recv_msg);
1761 		break;
1762 	case CONTROL_MSG_RUN_CMD:
1763 		handle_prd_control_run_cmd(send_msg, recv_msg);
1764 		break;
1765 	default:
1766 		pr_log(LOG_WARNING, "CTRL: Unknown control message action %d",
1767 				recv_msg->type);
1768 		send_msg->data_len = 0;
1769 		break;
1770 	}
1771 
1772 out_free_recv:
1773 	free(recv_msg);
1774 out_send:
1775 	size = sizeof(*send_msg) + send_msg->data_len;
1776 	rc = send(fd, send_msg, size, MSG_DONTWAIT | MSG_NOSIGNAL);
1777 	if (rc && (errno == EAGAIN || errno == EWOULDBLOCK || errno == EPIPE))
1778 		pr_debug("CTRL: control send() returned %d, ignoring failure",
1779 				rc);
1780 	else if (rc != size)
1781 		pr_log(LOG_NOTICE, "CTRL: Failed to send control response: %m");
1782 
1783 	if (send_msg != &msg)
1784 		free(send_msg);
1785 }
1786 
run_attn_loop(struct opal_prd_ctx * ctx)1787 static int run_attn_loop(struct opal_prd_ctx *ctx)
1788 {
1789 	struct pollfd pollfds[2];
1790 	struct opal_prd_msg msg;
1791 	int rc, fd;
1792 
1793 	if (hservice_runtime->enable_attns) {
1794 		pr_debug("HBRT: calling enable_attns");
1795 		rc = call_enable_attns();
1796 		if (rc) {
1797 			pr_log(LOG_ERR, "HBRT: enable_attns() failed, "
1798 					"aborting");
1799 			return -1;
1800 		}
1801 	}
1802 
1803 	if (hservice_runtime->get_ipoll_events) {
1804 		pr_debug("HBRT: calling get_ipoll_events");
1805 		opal_prd_ipoll = call_get_ipoll_events();
1806 	}
1807 
1808 	pr_debug("HBRT: enabling IPOLL events 0x%016lx", opal_prd_ipoll);
1809 
1810 	/* send init message, to unmask interrupts */
1811 	msg.hdr.type = OPAL_PRD_MSG_TYPE_INIT;
1812 	msg.hdr.size = htobe16(sizeof(msg));
1813 	msg.init.version = htobe64(opal_prd_version);
1814 	msg.init.ipoll = htobe64(opal_prd_ipoll);
1815 
1816 	pr_debug("FW: writing init message");
1817 	rc = write(ctx->fd, &msg, sizeof(msg));
1818 	if (rc != sizeof(msg)) {
1819 		pr_log(LOG_ERR, "FW: Init message failed: %m. Aborting.");
1820 		return -1;
1821 	}
1822 
1823 	pollfds[0].fd = ctx->fd;
1824 	pollfds[0].events = POLLIN | POLLERR;
1825 	pollfds[1].fd = ctx->socket;
1826 	pollfds[1].events = POLLIN | POLLERR;
1827 
1828 	for (;;) {
1829 		/* run through any pending messages */
1830 		process_msgq(ctx);
1831 
1832 		rc = poll(pollfds, 2, -1);
1833 		if (rc < 0) {
1834 			pr_log(LOG_ERR, "FW: event poll failed: %m");
1835 			exit(EXIT_FAILURE);
1836 		}
1837 
1838 		if (!rc)
1839 			continue;
1840 
1841 		if (pollfds[0].revents & POLLIN) {
1842 			rc = read_prd_msg(ctx);
1843 			if (!rc)
1844 				handle_prd_msg(ctx, ctx->msg);
1845 		}
1846 
1847 		if (pollfds[1].revents & POLLIN) {
1848 			fd = accept(ctx->socket, NULL, NULL);
1849 			if (fd < 0) {
1850 				pr_log(LOG_NOTICE, "CTRL: accept failed: %m");
1851 				continue;
1852 			}
1853 			handle_prd_control(ctx, fd);
1854 			close(fd);
1855 		}
1856 	}
1857 
1858 	return 0;
1859 }
1860 
init_control_socket(struct opal_prd_ctx * ctx)1861 static int init_control_socket(struct opal_prd_ctx *ctx)
1862 {
1863 	struct sockaddr_un addr;
1864 	int fd, rc;
1865 
1866 	unlink(opal_prd_socket);
1867 
1868 	addr.sun_family = AF_UNIX;
1869 	strcpy(addr.sun_path, opal_prd_socket);
1870 
1871 	fd = socket(AF_LOCAL, SOCK_STREAM, 0);
1872 	if (fd < 0) {
1873 		pr_log(LOG_WARNING, "CTRL: Can't open control socket %s: %m",
1874 				opal_prd_socket);
1875 		return -1;
1876 	}
1877 
1878 	rc = bind(fd, (struct sockaddr *)&addr, sizeof(addr));
1879 	if (rc) {
1880 		pr_log(LOG_WARNING, "CTRL: Can't bind control socket %s: %m",
1881 				opal_prd_socket);
1882 		close(fd);
1883 		return -1;
1884 	}
1885 
1886 	rc = listen(fd, 0);
1887 	if (rc) {
1888 		pr_log(LOG_WARNING, "CTRL: Can't listen on "
1889 				"control socket %s: %m", opal_prd_socket);
1890 		close(fd);
1891 		return -1;
1892 	}
1893 
1894 	pr_log(LOG_INFO, "CTRL: Listening on control socket %s",
1895 			opal_prd_socket);
1896 
1897 	ctx->socket = fd;
1898 	return 0;
1899 }
1900 
1901 
run_prd_daemon(struct opal_prd_ctx * ctx)1902 static int run_prd_daemon(struct opal_prd_ctx *ctx)
1903 {
1904 	int rc;
1905 
1906 	/* log to syslog */
1907 	pr_log_daemon_init();
1908 
1909 	pr_debug("CTRL: Starting PRD daemon\n");
1910 
1911 	ctx->fd = -1;
1912 	ctx->socket = -1;
1913 
1914 	/* set up our message buffer */
1915 	ctx->msg_alloc_len = sizeof(*ctx->msg);
1916 	ctx->msg = malloc(ctx->msg_alloc_len);
1917 	if (!ctx->msg) {
1918 		pr_log(LOG_ERR, "FW: Can't allocate PRD message buffer: %m");
1919 		return -1;
1920 	}
1921 
1922 
1923 	list_head_init(&ctx->msgq);
1924 
1925 	i2c_init();
1926 
1927 #ifdef DEBUG_I2C
1928 	{
1929 		uint8_t foo[128];
1930 		int i;
1931 
1932 		rc = i2c_read(0, 1, 2, 0x50, 2, 0x10, 128, foo);
1933 		pr_debug("I2C: read rc: %d", rc);
1934 		for (i = 0; i < sizeof(foo); i += 8) {
1935 			pr_debug("I2C: %02x %02x %02x %02x %02x %02x %02x %02x",
1936 			       foo[i + 0], foo[i + 1], foo[i + 2], foo[i + 3],
1937 			       foo[i + 4], foo[i + 5], foo[i + 6], foo[i + 7]);
1938 		}
1939 	}
1940 #endif
1941 	rc = init_control_socket(ctx);
1942 	if (rc) {
1943 		pr_log(LOG_WARNING, "CTRL: Error initialising PRD control: %m");
1944 		goto out_close;
1945 	}
1946 
1947 
1948 	rc = prd_init(ctx);
1949 	if (rc) {
1950 		pr_log(LOG_ERR, "FW: Error initialising PRD channel");
1951 		goto out_close;
1952 	}
1953 
1954 	if (ctx->hbrt_file_name) {
1955 		rc = map_hbrt_file(ctx, ctx->hbrt_file_name);
1956 		if (rc) {
1957 			pr_log(LOG_ERR, "IMAGE: Can't access hbrt file %s",
1958 					ctx->hbrt_file_name);
1959 			goto out_close;
1960 		}
1961 	} else {
1962 		rc = map_hbrt_physmem(ctx, hbrt_code_region_name);
1963 		if (rc) {
1964 			pr_log(LOG_ERR, "IMAGE: Can't access hbrt "
1965 					"physical memory");
1966 			goto out_close;
1967 		}
1968 		dump_hbrt_map(ctx);
1969 	}
1970 
1971 	pr_debug("IMAGE: hbrt map at %p, size 0x%zx",
1972 			ctx->code_addr, ctx->code_size);
1973 
1974 	fixup_hinterface_table();
1975 
1976 	if (pnor_available(&ctx->pnor)) {
1977 		rc = pnor_init(&ctx->pnor);
1978 		if (rc) {
1979 			pr_log(LOG_ERR, "PNOR: Failed to open pnor: %m");
1980 			goto out_close;
1981 		}
1982 	} else {
1983 		/* Disable PNOR function pointers */
1984 		hinterface.pnor_read = NULL;
1985 		hinterface.pnor_write = NULL;
1986 	}
1987 
1988 	ipmi_init(ctx);
1989 
1990 	pr_debug("HBRT: calling hservices_init");
1991 	rc = hservices_init(ctx, ctx->code_addr);
1992 	if (rc) {
1993 		pr_log(LOG_ERR, "HBRT: Can't initialise HBRT");
1994 		goto out_close;
1995 	}
1996 	pr_debug("HBRT: hservices_init done");
1997 
1998 	/* Test a scom */
1999 	if (ctx->debug) {
2000 		uint64_t val;
2001 		pr_debug("SCOM: trying scom read");
2002 		fflush(stdout);
2003 		hservice_scom_read(0x00, 0xf000f, &val);
2004 		pr_debug("SCOM:  f00f: %lx", be64toh(val));
2005 	}
2006 
2007 	run_attn_loop(ctx);
2008 	rc = 0;
2009 
2010 out_close:
2011 	pr_debug("CTRL: stopping PRD daemon\n");
2012 	pnor_close(&ctx->pnor);
2013 	if (ctx->fd != -1)
2014 		close(ctx->fd);
2015 	if (ctx->socket != -1)
2016 		close(ctx->socket);
2017 	if (ctx->msg)
2018 		free(ctx->msg);
2019 	return rc;
2020 }
2021 
send_prd_control(struct control_msg * send_msg,struct control_msg ** recv_msg)2022 static int send_prd_control(struct control_msg *send_msg,
2023 			    struct control_msg **recv_msg)
2024 {
2025 	struct sockaddr_un addr;
2026 	struct control_msg *msg;
2027 	int sd, rc, size;
2028 
2029 	sd = socket(AF_UNIX, SOCK_STREAM, 0);
2030 	if (!sd) {
2031 		pr_log(LOG_ERR, "CTRL: Failed to create control socket: %m");
2032 		return -1;
2033 	}
2034 
2035 	addr.sun_family = AF_UNIX;
2036 	strcpy(addr.sun_path, opal_prd_socket);
2037 
2038 	rc = connect(sd, (struct sockaddr *)&addr, sizeof(addr));
2039 	if (rc) {
2040 		pr_log(LOG_ERR, "CTRL: Failed to connect to prd daemon: %m");
2041 		goto out_close;
2042 	}
2043 
2044 	size = sizeof(*send_msg) + send_msg->data_len;
2045 	rc = send(sd, send_msg, size, 0);
2046 	if (rc != size) {
2047 		pr_log(LOG_ERR, "CTRL: Failed to send control message: %m");
2048 		rc = -1;
2049 		goto out_close;
2050 	}
2051 
2052 	size = sizeof(*msg) + MAX_CONTROL_MSG_BUF;
2053 	msg = malloc(size);
2054 	if (!msg) {
2055 		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
2056 		rc = -1;
2057 		goto out_close;
2058 	}
2059 
2060 	*recv_msg = msg;
2061 
2062 	/* wait for our reply */
2063 	rc = recv(sd, msg, size, 0);
2064 	if (rc < 0) {
2065 		pr_log(LOG_ERR, "CTRL: Failed to receive control message: %m");
2066 		goto out_close;
2067 
2068 	} else if (rc != (sizeof(*msg) + msg->data_len)) {
2069 		pr_log(LOG_WARNING, "CTRL: Short read from control socket");
2070 		rc = -1;
2071 		goto out_close;
2072 	}
2073 
2074 	rc = msg->response;
2075 
2076 out_close:
2077 	close(sd);
2078 	return rc;
2079 }
2080 
send_occ_control(struct opal_prd_ctx * ctx,int argc,char * argv[])2081 static int send_occ_control(struct opal_prd_ctx *ctx, int argc, char *argv[])
2082 {
2083 	struct control_msg send_msg, *recv_msg = NULL;
2084 	unsigned long chip = 0;
2085 	const char *op;
2086 	int rc;
2087 
2088 	assert(argc >= 1);
2089 	op = argv[0];
2090 
2091 	/* some commands accept a 'chip' argument, so parse it here */
2092 	if (argc > 1) {
2093 		char *arg, *end;
2094 		arg = argv[1];
2095 		chip = strtoul(arg, &end, 0);
2096 		if (end == arg) {
2097 			pr_log(LOG_ERR, "CTRL: invalid argument %s", arg);
2098 			return -1;
2099 		}
2100 	}
2101 
2102 	memset(&send_msg, 0, sizeof(send_msg));
2103 
2104 	if (!strcmp(op, "enable"))
2105 		send_msg.type = CONTROL_MSG_ENABLE_OCCS;
2106 	else if (!strcmp(op, "disable"))
2107 		send_msg.type = CONTROL_MSG_DISABLE_OCCS;
2108 
2109 	else if (!strcmp(op, "reset")) {
2110 		send_msg.type = CONTROL_MSG_TEMP_OCC_RESET;
2111 		send_msg.occ_reset.chip = (uint64_t)chip;
2112 
2113 	} else if (!strcmp(op, "process-error")) {
2114 		send_msg.type = CONTROL_MSG_TEMP_OCC_ERROR;
2115 		send_msg.occ_error.chip = (uint64_t)chip;
2116 	} else {
2117 		pr_log(LOG_ERR, "CTRL: Invalid OCC action '%s'", op);
2118 		return -1;
2119 	}
2120 
2121 	rc = send_prd_control(&send_msg, &recv_msg);
2122 	if (recv_msg) {
2123 		if (recv_msg->response || ctx->debug)
2124 			pr_debug("CTRL: OCC action %s returned status %d", op,
2125 					recv_msg->response);
2126 		free(recv_msg);
2127 	}
2128 
2129 	return rc;
2130 }
2131 
send_attr_override(struct opal_prd_ctx * ctx,uint32_t argc,char * argv[])2132 static int send_attr_override(struct opal_prd_ctx *ctx, uint32_t argc,
2133 			      char *argv[])
2134 {
2135 	struct control_msg *send_msg, *recv_msg = NULL;
2136 	struct stat statbuf;
2137 	size_t sz;
2138 	FILE *fd;
2139 	int rc;
2140 
2141 	rc = stat(argv[0], &statbuf);
2142 	if (rc) {
2143 		pr_log(LOG_ERR, "CTRL: stat() failed on the file: %m");
2144 		return -1;
2145 	}
2146 
2147 	send_msg = malloc(sizeof(*send_msg) + statbuf.st_size);
2148 	if (!send_msg) {
2149 		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
2150 		return -1;
2151 	}
2152 
2153 	send_msg->type = CONTROL_MSG_ATTR_OVERRIDE;
2154 	send_msg->data_len = statbuf.st_size;
2155 
2156 	fd = fopen(argv[0], "r");
2157 	if (!fd) {
2158 		pr_log(LOG_NOTICE, "CTRL: can't open %s: %m", argv[0]);
2159 		rc = -1;
2160 		goto out_free;
2161 	}
2162 
2163 	sz = fread(send_msg->data, 1, send_msg->data_len, fd);
2164 	fclose(fd);
2165 	if (sz != statbuf.st_size) {
2166 		pr_log(LOG_ERR, "CTRL: short read from the file");
2167 		rc = -1;
2168 		goto out_free;
2169 	}
2170 
2171 	rc = send_prd_control(send_msg, &recv_msg);
2172 	if (recv_msg) {
2173 		if (recv_msg->response || ctx->debug)
2174 			pr_debug("CTRL: attribute override returned status %d",
2175 					recv_msg->response);
2176 		free(recv_msg);
2177 	}
2178 
2179 out_free:
2180 	free(send_msg);
2181 	return rc;
2182 }
2183 
send_htmgt_passthru(struct opal_prd_ctx * ctx,int argc,char * argv[])2184 static int send_htmgt_passthru(struct opal_prd_ctx *ctx, int argc, char *argv[])
2185 {
2186 	struct control_msg *send_msg, *recv_msg = NULL;
2187 	int rc, i;
2188 
2189 	if (!ctx->expert_mode) {
2190 		pr_log(LOG_WARNING, "CTRL: need to be in expert mode");
2191 		return -1;
2192 	}
2193 
2194 	send_msg = malloc(sizeof(*send_msg) + argc);
2195 	if (!send_msg) {
2196 		pr_log(LOG_ERR, "CTRL: message buffer malloc failed: %m");
2197 		return -1;
2198 	}
2199 
2200 	send_msg->type = CONTROL_MSG_HTMGT_PASSTHRU;
2201 	send_msg->data_len = argc;
2202 
2203 	if (ctx->debug)
2204 		pr_debug("CTRL: HTMGT passthru arguments:");
2205 
2206 	for (i = 0; i < argc; i++) {
2207 		if (ctx->debug)
2208 			pr_debug("argv[%d] = %s", i, argv[i]);
2209 
2210 		sscanf(argv[i], "%hhx", &send_msg->data[i]);
2211 	}
2212 
2213 	rc = send_prd_control(send_msg, &recv_msg);
2214 	free(send_msg);
2215 
2216 	if (recv_msg) {
2217 		if (recv_msg->response || ctx->debug)
2218 			pr_debug("CTRL: HTMGT passthru returned status %d",
2219 					recv_msg->response);
2220 		if (recv_msg->response == 0 && recv_msg->data_len)
2221 			hexdump(recv_msg->data, recv_msg->data_len);
2222 
2223 		free(recv_msg);
2224 	}
2225 
2226 	return rc;
2227 }
2228 
send_run_command(struct opal_prd_ctx * ctx,int argc,char * argv[])2229 static int send_run_command(struct opal_prd_ctx *ctx, int argc, char *argv[])
2230 {
2231 	struct control_msg *send_msg, *recv_msg = NULL;
2232 	uint32_t size = 0;
2233 	int rc, i;
2234 	char *s;
2235 
2236 	if (!ctx->expert_mode) {
2237 		pr_log(LOG_WARNING, "CTRL: need to be in expert mode");
2238 		return -1;
2239 	}
2240 
2241 	if (ctx->debug) {
2242 		pr_debug("CTRL: run command arguments:");
2243 		for (i=0; i < argc; i++)
2244 			pr_debug("argv[%d] = %s", i, argv[i]);
2245 	}
2246 
2247 	for (i = 0; i < argc; i++)
2248 		size += (strlen(argv[i]) + 1);
2249 
2250 	send_msg = malloc(sizeof(*send_msg) + size);
2251 	if (!send_msg) {
2252 		pr_log(LOG_ERR, "CTRL: msg buffer malloc failed: %m");
2253 		return -1;
2254 	}
2255 
2256 	/* Setup message */
2257 	send_msg->type = CONTROL_MSG_RUN_CMD;
2258 	send_msg->run_cmd.argc = argc;
2259 	send_msg->data_len = size;
2260 	s = (char *)send_msg->data;
2261 	for (i = 0; i < argc; i++) {
2262 		strcpy(s, argv[i]);
2263 		s = s + strlen(argv[i]) + 1;
2264 	}
2265 
2266 	rc = send_prd_control(send_msg, &recv_msg);
2267 	free(send_msg);
2268 	if (recv_msg) {
2269 		if (!rc)
2270 			pr_log(LOG_INFO, "Received: %s", recv_msg->data);
2271 
2272 		if (recv_msg->response || ctx->debug)
2273 			pr_debug("CTRL: run command returned status %d",
2274 					recv_msg->response);
2275 		free(recv_msg);
2276 	}
2277 
2278 	return rc;
2279 }
2280 
usage(const char * progname)2281 static void usage(const char *progname)
2282 {
2283 	printf("Usage:\n");
2284 	printf("\t%s [--debug] [--file <hbrt-image>] [--pnor <device>]\n",
2285 			progname);
2286 	printf("\t%s occ <enable|disable|reset [chip]>\n", progname);
2287 	printf("\t%s pm-complex reset [chip]>\n", progname);
2288 	printf("\t%s htmgt-passthru <bytes...>\n", progname);
2289 	printf("\t%s override <FILE>\n", progname);
2290 	printf("\t%s run [arg 0] [arg 1]..[arg n]\n", progname);
2291 	printf("\n");
2292 	printf("Options:\n"
2293 "\t--debug            verbose logging for debug information\n"
2294 "\t--pnor DEVICE      use PNOR MTD device\n"
2295 "\t--file FILE        use FILE for hostboot runtime code (instead of code\n"
2296 "\t                     exported by firmware)\n"
2297 "\t--stdio            log to stdio, instead of syslog\n");
2298 }
2299 
print_version(void)2300 static void print_version(void)
2301 {
2302 	extern const char version[];
2303 	printf("opal-prd %s\n", version);
2304 }
2305 
2306 static struct option opal_diag_options[] = {
2307 	{"file", required_argument, NULL, 'f'},
2308 	{"pnor", required_argument, NULL, 'p'},
2309 	{"debug", no_argument, NULL, 'd'},
2310 	{"help", no_argument, NULL, 'h'},
2311 	{"version", no_argument, NULL, 'v'},
2312 	{"stdio", no_argument, NULL, 's'},
2313 	{"expert-mode", no_argument, NULL, 'e'},
2314 	{ 0 },
2315 };
2316 
2317 enum action {
2318 	ACTION_RUN_DAEMON,
2319 	ACTION_OCC_CONTROL,
2320 	ACTION_ATTR_OVERRIDE,
2321 	ACTION_HTMGT_PASSTHRU,
2322 	ACTION_RUN_COMMAND,
2323 };
2324 
parse_action(const char * str,enum action * action)2325 static int parse_action(const char *str, enum action *action)
2326 {
2327 	int rc;
2328 
2329 	if (!strcmp(str, "occ")) {
2330 		*action = ACTION_OCC_CONTROL;
2331 		rc = 0;
2332 
2333 		if (is_fsp_system()) {
2334 			pr_log(LOG_ERR, "CTRL: occ commands are not "
2335 			       "supported on this system");
2336 			rc = -1;
2337 		}
2338 	} else if (!strcmp(str, "pm-complex")) {
2339 		*action = ACTION_OCC_CONTROL;
2340 		rc = 0;
2341 
2342 		if (!is_fsp_system()) {
2343 			pr_log(LOG_ERR, "CTRL: pm-complex commands are not "
2344 			       "supported on this system");
2345 			rc = -1;
2346 		}
2347 	} else if (!strcmp(str, "daemon")) {
2348 		*action = ACTION_RUN_DAEMON;
2349 		rc = 0;
2350 	} else if (!strcmp(str, "override")) {
2351 		*action = ACTION_ATTR_OVERRIDE;
2352 		rc = 0;
2353 	} else if (!strcmp(str, "htmgt-passthru")) {
2354 		*action = ACTION_HTMGT_PASSTHRU;
2355 		rc = 0;
2356 	} else if (!strcmp(str, "run")) {
2357 		*action = ACTION_RUN_COMMAND;
2358 		return 0;
2359 	} else {
2360 		pr_log(LOG_ERR, "CTRL: unknown argument '%s'", str);
2361 		rc = -1;
2362 	}
2363 
2364 	return rc;
2365 }
2366 
main(int argc,char * argv[])2367 int main(int argc, char *argv[])
2368 {
2369 	struct opal_prd_ctx _ctx;
2370 	enum action action;
2371 	int rc;
2372 
2373 	check_abi();
2374 
2375 	ctx = &_ctx;
2376 	memset(ctx, 0, sizeof(*ctx));
2377 	ctx->vlog = pr_log_stdio;
2378 	ctx->use_syslog = true;
2379 
2380 	/* Parse options */
2381 	for (;;) {
2382 		int c;
2383 
2384 		c = getopt_long(argc, argv, "f:p:dhse", opal_diag_options, NULL);
2385 		if (c == -1)
2386 			break;
2387 
2388 		switch (c) {
2389 		case 'f':
2390 			ctx->hbrt_file_name = optarg;
2391 			break;
2392 		case 'd':
2393 			ctx->debug = true;
2394 			break;
2395 		case 'p':
2396 			ctx->pnor.path = strndup(optarg, PATH_MAX);
2397 			break;
2398 		case 's':
2399 			ctx->use_syslog = false;
2400 			break;
2401 		case 'h':
2402 			usage(argv[0]);
2403 			return EXIT_SUCCESS;
2404 		case 'e':
2405 			ctx->expert_mode = true;
2406 			break;
2407 		case 'v':
2408 			print_version();
2409 			return EXIT_SUCCESS;
2410 		case '?':
2411 		default:
2412 			usage(argv[0]);
2413 			return EXIT_FAILURE;
2414 		}
2415 	}
2416 
2417 	if (optind < argc) {
2418 		rc = parse_action(argv[optind], &action);
2419 		if (rc)
2420 			return EXIT_FAILURE;
2421 		optind++;
2422 	} else {
2423 		action = ACTION_RUN_DAEMON;
2424 	}
2425 
2426 	if (is_prd_supported() < 0) {
2427 		pr_log(LOG_ERR, "CTRL: PowerNV OPAL runtime diagnostic "
2428 				"is not supported on this system");
2429 		return -1;
2430 	}
2431 
2432 	switch (action) {
2433 	case ACTION_RUN_DAEMON:
2434 		rc = run_prd_daemon(ctx);
2435 		break;
2436 	case ACTION_OCC_CONTROL:
2437 		if (optind >= argc) {
2438 			pr_log(LOG_ERR, "CTRL: occ command requires "
2439 					"an argument");
2440 			return EXIT_FAILURE;
2441 		}
2442 
2443 		rc = send_occ_control(ctx, argc - optind, &argv[optind]);
2444 		break;
2445 	case ACTION_ATTR_OVERRIDE:
2446 		if (optind >= argc) {
2447 			pr_log(LOG_ERR, "CTRL: attribute override command "
2448 					"requires an argument");
2449 			return EXIT_FAILURE;
2450 		}
2451 
2452 		rc = send_attr_override(ctx, argc - optind, &argv[optind]);
2453 		break;
2454 	case ACTION_HTMGT_PASSTHRU:
2455 		if (optind >= argc) {
2456 			pr_log(LOG_ERR, "CTRL: htmgt passthru requires at least "
2457 					"one argument");
2458 			return EXIT_FAILURE;
2459 		}
2460 
2461 		rc = send_htmgt_passthru(ctx, argc - optind, &argv[optind]);
2462 		break;
2463 	case ACTION_RUN_COMMAND:
2464 		if (optind >= argc) {
2465 			pr_log(LOG_ERR, "CTRL: run command requires "
2466 					"argument(s)");
2467 			return EXIT_FAILURE;
2468 		}
2469 
2470 		rc = send_run_command(ctx, argc - optind, &argv[optind]);
2471 		break;
2472 	default:
2473 		break;
2474 	}
2475 
2476 	return rc == 0 ? EXIT_SUCCESS : EXIT_FAILURE;
2477 }
2478