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(®_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