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