linux/arch/powerpc/platforms/powernv/opal.c
<<
>>
Prefs
   1/*
   2 * PowerNV OPAL high level interfaces
   3 *
   4 * Copyright 2011 IBM Corp.
   5 *
   6 * This program is free software; you can redistribute it and/or
   7 * modify it under the terms of the GNU General Public License
   8 * as published by the Free Software Foundation; either version
   9 * 2 of the License, or (at your option) any later version.
  10 */
  11
  12#define pr_fmt(fmt)     "opal: " fmt
  13
  14#include <linux/printk.h>
  15#include <linux/types.h>
  16#include <linux/of.h>
  17#include <linux/of_fdt.h>
  18#include <linux/of_platform.h>
  19#include <linux/interrupt.h>
  20#include <linux/notifier.h>
  21#include <linux/slab.h>
  22#include <linux/sched.h>
  23#include <linux/kobject.h>
  24#include <linux/delay.h>
  25#include <linux/memblock.h>
  26#include <linux/kthread.h>
  27#include <linux/freezer.h>
  28
  29#include <asm/machdep.h>
  30#include <asm/opal.h>
  31#include <asm/firmware.h>
  32#include <asm/mce.h>
  33
  34#include "powernv.h"
  35
  36/* /sys/firmware/opal */
  37struct kobject *opal_kobj;
  38
  39struct opal {
  40        u64 base;
  41        u64 entry;
  42        u64 size;
  43} opal;
  44
  45struct mcheck_recoverable_range {
  46        u64 start_addr;
  47        u64 end_addr;
  48        u64 recover_addr;
  49};
  50
  51static struct mcheck_recoverable_range *mc_recoverable_range;
  52static int mc_recoverable_range_len;
  53
  54struct device_node *opal_node;
  55static DEFINE_SPINLOCK(opal_write_lock);
  56static struct atomic_notifier_head opal_msg_notifier_head[OPAL_MSG_TYPE_MAX];
  57static uint32_t opal_heartbeat;
  58static struct task_struct *kopald_tsk;
  59
  60void opal_configure_cores(void)
  61{
  62        /* Do the actual re-init, This will clobber all FPRs, VRs, etc...
  63         *
  64         * It will preserve non volatile GPRs and HSPRG0/1. It will
  65         * also restore HIDs and other SPRs to their original value
  66         * but it might clobber a bunch.
  67         */
  68#ifdef __BIG_ENDIAN__
  69        opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_BE);
  70#else
  71        opal_reinit_cpus(OPAL_REINIT_CPUS_HILE_LE);
  72#endif
  73
  74        /* Restore some bits */
  75        if (cur_cpu_spec->cpu_restore)
  76                cur_cpu_spec->cpu_restore();
  77}
  78
  79int __init early_init_dt_scan_opal(unsigned long node,
  80                                   const char *uname, int depth, void *data)
  81{
  82        const void *basep, *entryp, *sizep;
  83        int basesz, entrysz, runtimesz;
  84
  85        if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
  86                return 0;
  87
  88        basep  = of_get_flat_dt_prop(node, "opal-base-address", &basesz);
  89        entryp = of_get_flat_dt_prop(node, "opal-entry-address", &entrysz);
  90        sizep = of_get_flat_dt_prop(node, "opal-runtime-size", &runtimesz);
  91
  92        if (!basep || !entryp || !sizep)
  93                return 1;
  94
  95        opal.base = of_read_number(basep, basesz/4);
  96        opal.entry = of_read_number(entryp, entrysz/4);
  97        opal.size = of_read_number(sizep, runtimesz/4);
  98
  99        pr_debug("OPAL Base  = 0x%llx (basep=%p basesz=%d)\n",
 100                 opal.base, basep, basesz);
 101        pr_debug("OPAL Entry = 0x%llx (entryp=%p basesz=%d)\n",
 102                 opal.entry, entryp, entrysz);
 103        pr_debug("OPAL Entry = 0x%llx (sizep=%p runtimesz=%d)\n",
 104                 opal.size, sizep, runtimesz);
 105
 106        if (of_flat_dt_is_compatible(node, "ibm,opal-v3")) {
 107                powerpc_firmware_features |= FW_FEATURE_OPAL;
 108                pr_info("OPAL detected !\n");
 109        } else {
 110                panic("OPAL != V3 detected, no longer supported.\n");
 111        }
 112
 113        return 1;
 114}
 115
 116int __init early_init_dt_scan_recoverable_ranges(unsigned long node,
 117                                   const char *uname, int depth, void *data)
 118{
 119        int i, psize, size;
 120        const __be32 *prop;
 121
 122        if (depth != 1 || strcmp(uname, "ibm,opal") != 0)
 123                return 0;
 124
 125        prop = of_get_flat_dt_prop(node, "mcheck-recoverable-ranges", &psize);
 126
 127        if (!prop)
 128                return 1;
 129
 130        pr_debug("Found machine check recoverable ranges.\n");
 131
 132        /*
 133         * Calculate number of available entries.
 134         *
 135         * Each recoverable address range entry is (start address, len,
 136         * recovery address), 2 cells each for start and recovery address,
 137         * 1 cell for len, totalling 5 cells per entry.
 138         */
 139        mc_recoverable_range_len = psize / (sizeof(*prop) * 5);
 140
 141        /* Sanity check */
 142        if (!mc_recoverable_range_len)
 143                return 1;
 144
 145        /* Size required to hold all the entries. */
 146        size = mc_recoverable_range_len *
 147                        sizeof(struct mcheck_recoverable_range);
 148
 149        /*
 150         * Allocate a buffer to hold the MC recoverable ranges. We would be
 151         * accessing them in real mode, hence it needs to be within
 152         * RMO region.
 153         */
 154        mc_recoverable_range =__va(memblock_alloc_base(size, __alignof__(u64),
 155                                                        ppc64_rma_size));
 156        memset(mc_recoverable_range, 0, size);
 157
 158        for (i = 0; i < mc_recoverable_range_len; i++) {
 159                mc_recoverable_range[i].start_addr =
 160                                        of_read_number(prop + (i * 5) + 0, 2);
 161                mc_recoverable_range[i].end_addr =
 162                                        mc_recoverable_range[i].start_addr +
 163                                        of_read_number(prop + (i * 5) + 2, 1);
 164                mc_recoverable_range[i].recover_addr =
 165                                        of_read_number(prop + (i * 5) + 3, 2);
 166
 167                pr_debug("Machine check recoverable range: %llx..%llx: %llx\n",
 168                                mc_recoverable_range[i].start_addr,
 169                                mc_recoverable_range[i].end_addr,
 170                                mc_recoverable_range[i].recover_addr);
 171        }
 172        return 1;
 173}
 174
 175static int __init opal_register_exception_handlers(void)
 176{
 177#ifdef __BIG_ENDIAN__
 178        u64 glue;
 179
 180        if (!(powerpc_firmware_features & FW_FEATURE_OPAL))
 181                return -ENODEV;
 182
 183        /* Hookup some exception handlers except machine check. We use the
 184         * fwnmi area at 0x7000 to provide the glue space to OPAL
 185         */
 186        glue = 0x7000;
 187
 188        /*
 189         * Check if we are running on newer firmware that exports
 190         * OPAL_HANDLE_HMI token. If yes, then don't ask OPAL to patch
 191         * the HMI interrupt and we catch it directly in Linux.
 192         *
 193         * For older firmware (i.e currently released POWER8 System Firmware
 194         * as of today <= SV810_087), we fallback to old behavior and let OPAL
 195         * patch the HMI vector and handle it inside OPAL firmware.
 196         *
 197         * For newer firmware (in development/yet to be released) we will
 198         * start catching/handling HMI directly in Linux.
 199         */
 200        if (!opal_check_token(OPAL_HANDLE_HMI)) {
 201                pr_info("Old firmware detected, OPAL handles HMIs.\n");
 202                opal_register_exception_handler(
 203                                OPAL_HYPERVISOR_MAINTENANCE_HANDLER,
 204                                0, glue);
 205                glue += 128;
 206        }
 207
 208        opal_register_exception_handler(OPAL_SOFTPATCH_HANDLER, 0, glue);
 209#endif
 210
 211        return 0;
 212}
 213machine_early_initcall(powernv, opal_register_exception_handlers);
 214
 215/*
 216 * Opal message notifier based on message type. Allow subscribers to get
 217 * notified for specific messgae type.
 218 */
 219int opal_message_notifier_register(enum opal_msg_type msg_type,
 220                                        struct notifier_block *nb)
 221{
 222        if (!nb || msg_type >= OPAL_MSG_TYPE_MAX) {
 223                pr_warning("%s: Invalid arguments, msg_type:%d\n",
 224                           __func__, msg_type);
 225                return -EINVAL;
 226        }
 227
 228        return atomic_notifier_chain_register(
 229                                &opal_msg_notifier_head[msg_type], nb);
 230}
 231EXPORT_SYMBOL_GPL(opal_message_notifier_register);
 232
 233int opal_message_notifier_unregister(enum opal_msg_type msg_type,
 234                                     struct notifier_block *nb)
 235{
 236        return atomic_notifier_chain_unregister(
 237                        &opal_msg_notifier_head[msg_type], nb);
 238}
 239EXPORT_SYMBOL_GPL(opal_message_notifier_unregister);
 240
 241static void opal_message_do_notify(uint32_t msg_type, void *msg)
 242{
 243        /* notify subscribers */
 244        atomic_notifier_call_chain(&opal_msg_notifier_head[msg_type],
 245                                        msg_type, msg);
 246}
 247
 248static void opal_handle_message(void)
 249{
 250        s64 ret;
 251        /*
 252         * TODO: pre-allocate a message buffer depending on opal-msg-size
 253         * value in /proc/device-tree.
 254         */
 255        static struct opal_msg msg;
 256        u32 type;
 257
 258        ret = opal_get_msg(__pa(&msg), sizeof(msg));
 259        /* No opal message pending. */
 260        if (ret == OPAL_RESOURCE)
 261                return;
 262
 263        /* check for errors. */
 264        if (ret) {
 265                pr_warning("%s: Failed to retrieve opal message, err=%lld\n",
 266                                __func__, ret);
 267                return;
 268        }
 269
 270        type = be32_to_cpu(msg.msg_type);
 271
 272        /* Sanity check */
 273        if (type >= OPAL_MSG_TYPE_MAX) {
 274                pr_warn_once("%s: Unknown message type: %u\n", __func__, type);
 275                return;
 276        }
 277        opal_message_do_notify(type, (void *)&msg);
 278}
 279
 280static irqreturn_t opal_message_notify(int irq, void *data)
 281{
 282        opal_handle_message();
 283        return IRQ_HANDLED;
 284}
 285
 286static int __init opal_message_init(void)
 287{
 288        int ret, i, irq;
 289
 290        for (i = 0; i < OPAL_MSG_TYPE_MAX; i++)
 291                ATOMIC_INIT_NOTIFIER_HEAD(&opal_msg_notifier_head[i]);
 292
 293        irq = opal_event_request(ilog2(OPAL_EVENT_MSG_PENDING));
 294        if (!irq) {
 295                pr_err("%s: Can't register OPAL event irq (%d)\n",
 296                       __func__, irq);
 297                return irq;
 298        }
 299
 300        ret = request_irq(irq, opal_message_notify,
 301                        IRQ_TYPE_LEVEL_HIGH, "opal-msg", NULL);
 302        if (ret) {
 303                pr_err("%s: Can't request OPAL event irq (%d)\n",
 304                       __func__, ret);
 305                return ret;
 306        }
 307
 308        return 0;
 309}
 310
 311int opal_get_chars(uint32_t vtermno, char *buf, int count)
 312{
 313        s64 rc;
 314        __be64 evt, len;
 315
 316        if (!opal.entry)
 317                return -ENODEV;
 318        opal_poll_events(&evt);
 319        if ((be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_INPUT) == 0)
 320                return 0;
 321        len = cpu_to_be64(count);
 322        rc = opal_console_read(vtermno, &len, buf);
 323        if (rc == OPAL_SUCCESS)
 324                return be64_to_cpu(len);
 325        return 0;
 326}
 327
 328int opal_put_chars(uint32_t vtermno, const char *data, int total_len)
 329{
 330        int written = 0;
 331        __be64 olen;
 332        s64 len, rc;
 333        unsigned long flags;
 334        __be64 evt;
 335
 336        if (!opal.entry)
 337                return -ENODEV;
 338
 339        /* We want put_chars to be atomic to avoid mangling of hvsi
 340         * packets. To do that, we first test for room and return
 341         * -EAGAIN if there isn't enough.
 342         *
 343         * Unfortunately, opal_console_write_buffer_space() doesn't
 344         * appear to work on opal v1, so we just assume there is
 345         * enough room and be done with it
 346         */
 347        spin_lock_irqsave(&opal_write_lock, flags);
 348        rc = opal_console_write_buffer_space(vtermno, &olen);
 349        len = be64_to_cpu(olen);
 350        if (rc || len < total_len) {
 351                spin_unlock_irqrestore(&opal_write_lock, flags);
 352                /* Closed -> drop characters */
 353                if (rc)
 354                        return total_len;
 355                opal_poll_events(NULL);
 356                return -EAGAIN;
 357        }
 358
 359        /* We still try to handle partial completions, though they
 360         * should no longer happen.
 361         */
 362        rc = OPAL_BUSY;
 363        while(total_len > 0 && (rc == OPAL_BUSY ||
 364                                rc == OPAL_BUSY_EVENT || rc == OPAL_SUCCESS)) {
 365                olen = cpu_to_be64(total_len);
 366                rc = opal_console_write(vtermno, &olen, data);
 367                len = be64_to_cpu(olen);
 368
 369                /* Closed or other error drop */
 370                if (rc != OPAL_SUCCESS && rc != OPAL_BUSY &&
 371                    rc != OPAL_BUSY_EVENT) {
 372                        written = total_len;
 373                        break;
 374                }
 375                if (rc == OPAL_SUCCESS) {
 376                        total_len -= len;
 377                        data += len;
 378                        written += len;
 379                }
 380                /* This is a bit nasty but we need that for the console to
 381                 * flush when there aren't any interrupts. We will clean
 382                 * things a bit later to limit that to synchronous path
 383                 * such as the kernel console and xmon/udbg
 384                 */
 385                do
 386                        opal_poll_events(&evt);
 387                while(rc == OPAL_SUCCESS &&
 388                        (be64_to_cpu(evt) & OPAL_EVENT_CONSOLE_OUTPUT));
 389        }
 390        spin_unlock_irqrestore(&opal_write_lock, flags);
 391        return written;
 392}
 393
 394static int opal_recover_mce(struct pt_regs *regs,
 395                                        struct machine_check_event *evt)
 396{
 397        int recovered = 0;
 398        uint64_t ea = get_mce_fault_addr(evt);
 399
 400        if (!(regs->msr & MSR_RI)) {
 401                /* If MSR_RI isn't set, we cannot recover */
 402                pr_err("Machine check interrupt unrecoverable: MSR(RI=0)\n");
 403                recovered = 0;
 404        } else if (evt->disposition == MCE_DISPOSITION_RECOVERED) {
 405                /* Platform corrected itself */
 406                recovered = 1;
 407        } else if (ea && !is_kernel_addr(ea)) {
 408                /*
 409                 * Faulting address is not in kernel text. We should be fine.
 410                 * We need to find which process uses this address.
 411                 * For now, kill the task if we have received exception when
 412                 * in userspace.
 413                 *
 414                 * TODO: Queue up this address for hwpoisioning later.
 415                 */
 416                if (user_mode(regs) && !is_global_init(current)) {
 417                        _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip);
 418                        recovered = 1;
 419                } else
 420                        recovered = 0;
 421        } else if (user_mode(regs) && !is_global_init(current) &&
 422                evt->severity == MCE_SEV_ERROR_SYNC) {
 423                /*
 424                 * If we have received a synchronous error when in userspace
 425                 * kill the task.
 426                 */
 427                _exception(SIGBUS, regs, BUS_MCEERR_AR, regs->nip);
 428                recovered = 1;
 429        }
 430        return recovered;
 431}
 432
 433int opal_machine_check(struct pt_regs *regs)
 434{
 435        struct machine_check_event evt;
 436        int ret;
 437
 438        if (!get_mce_event(&evt, MCE_EVENT_RELEASE))
 439                return 0;
 440
 441        /* Print things out */
 442        if (evt.version != MCE_V1) {
 443                pr_err("Machine Check Exception, Unknown event version %d !\n",
 444                       evt.version);
 445                return 0;
 446        }
 447        machine_check_print_event_info(&evt);
 448
 449        if (opal_recover_mce(regs, &evt))
 450                return 1;
 451
 452        /*
 453         * Unrecovered machine check, we are heading to panic path.
 454         *
 455         * We may have hit this MCE in very early stage of kernel
 456         * initialization even before opal-prd has started running. If
 457         * this is the case then this MCE error may go un-noticed or
 458         * un-analyzed if we go down panic path. We need to inform
 459         * BMC/OCC about this error so that they can collect relevant
 460         * data for error analysis before rebooting.
 461         * Use opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR) to do so.
 462         * This function may not return on BMC based system.
 463         */
 464        ret = opal_cec_reboot2(OPAL_REBOOT_PLATFORM_ERROR,
 465                        "Unrecoverable Machine Check exception");
 466        if (ret == OPAL_UNSUPPORTED) {
 467                pr_emerg("Reboot type %d not supported\n",
 468                                        OPAL_REBOOT_PLATFORM_ERROR);
 469        }
 470
 471        /*
 472         * We reached here. There can be three possibilities:
 473         * 1. We are running on a firmware level that do not support
 474         *    opal_cec_reboot2()
 475         * 2. We are running on a firmware level that do not support
 476         *    OPAL_REBOOT_PLATFORM_ERROR reboot type.
 477         * 3. We are running on FSP based system that does not need opal
 478         *    to trigger checkstop explicitly for error analysis. The FSP
 479         *    PRD component would have already got notified about this
 480         *    error through other channels.
 481         *
 482         * If hardware marked this as an unrecoverable MCE, we are
 483         * going to panic anyway. Even if it didn't, it's not safe to
 484         * continue at this point, so we should explicitly panic.
 485         */
 486
 487        panic("PowerNV Unrecovered Machine Check");
 488        return 0;
 489}
 490
 491/* Early hmi handler called in real mode. */
 492int opal_hmi_exception_early(struct pt_regs *regs)
 493{
 494        s64 rc;
 495
 496        /*
 497         * call opal hmi handler. Pass paca address as token.
 498         * The return value OPAL_SUCCESS is an indication that there is
 499         * an HMI event generated waiting to pull by Linux.
 500         */
 501        rc = opal_handle_hmi();
 502        if (rc == OPAL_SUCCESS) {
 503                local_paca->hmi_event_available = 1;
 504                return 1;
 505        }
 506        return 0;
 507}
 508
 509/* HMI exception handler called in virtual mode during check_irq_replay. */
 510int opal_handle_hmi_exception(struct pt_regs *regs)
 511{
 512        s64 rc;
 513        __be64 evt = 0;
 514
 515        /*
 516         * Check if HMI event is available.
 517         * if Yes, then call opal_poll_events to pull opal messages and
 518         * process them.
 519         */
 520        if (!local_paca->hmi_event_available)
 521                return 0;
 522
 523        local_paca->hmi_event_available = 0;
 524        rc = opal_poll_events(&evt);
 525        if (rc == OPAL_SUCCESS && evt)
 526                opal_handle_events(be64_to_cpu(evt));
 527
 528        return 1;
 529}
 530
 531static uint64_t find_recovery_address(uint64_t nip)
 532{
 533        int i;
 534
 535        for (i = 0; i < mc_recoverable_range_len; i++)
 536                if ((nip >= mc_recoverable_range[i].start_addr) &&
 537                    (nip < mc_recoverable_range[i].end_addr))
 538                    return mc_recoverable_range[i].recover_addr;
 539        return 0;
 540}
 541
 542bool opal_mce_check_early_recovery(struct pt_regs *regs)
 543{
 544        uint64_t recover_addr = 0;
 545
 546        if (!opal.base || !opal.size)
 547                goto out;
 548
 549        if ((regs->nip >= opal.base) &&
 550                        (regs->nip < (opal.base + opal.size)))
 551                recover_addr = find_recovery_address(regs->nip);
 552
 553        /*
 554         * Setup regs->nip to rfi into fixup address.
 555         */
 556        if (recover_addr)
 557                regs->nip = recover_addr;
 558
 559out:
 560        return !!recover_addr;
 561}
 562
 563static int opal_sysfs_init(void)
 564{
 565        opal_kobj = kobject_create_and_add("opal", firmware_kobj);
 566        if (!opal_kobj) {
 567                pr_warn("kobject_create_and_add opal failed\n");
 568                return -ENOMEM;
 569        }
 570
 571        return 0;
 572}
 573
 574static ssize_t symbol_map_read(struct file *fp, struct kobject *kobj,
 575                               struct bin_attribute *bin_attr,
 576                               char *buf, loff_t off, size_t count)
 577{
 578        return memory_read_from_buffer(buf, count, &off, bin_attr->private,
 579                                       bin_attr->size);
 580}
 581
 582static BIN_ATTR_RO(symbol_map, 0);
 583
 584static void opal_export_symmap(void)
 585{
 586        const __be64 *syms;
 587        unsigned int size;
 588        struct device_node *fw;
 589        int rc;
 590
 591        fw = of_find_node_by_path("/ibm,opal/firmware");
 592        if (!fw)
 593                return;
 594        syms = of_get_property(fw, "symbol-map", &size);
 595        if (!syms || size != 2 * sizeof(__be64))
 596                return;
 597
 598        /* Setup attributes */
 599        bin_attr_symbol_map.private = __va(be64_to_cpu(syms[0]));
 600        bin_attr_symbol_map.size = be64_to_cpu(syms[1]);
 601
 602        rc = sysfs_create_bin_file(opal_kobj, &bin_attr_symbol_map);
 603        if (rc)
 604                pr_warn("Error %d creating OPAL symbols file\n", rc);
 605}
 606
 607static void __init opal_dump_region_init(void)
 608{
 609        void *addr;
 610        uint64_t size;
 611        int rc;
 612
 613        if (!opal_check_token(OPAL_REGISTER_DUMP_REGION))
 614                return;
 615
 616        /* Register kernel log buffer */
 617        addr = log_buf_addr_get();
 618        if (addr == NULL)
 619                return;
 620
 621        size = log_buf_len_get();
 622        if (size == 0)
 623                return;
 624
 625        rc = opal_register_dump_region(OPAL_DUMP_REGION_LOG_BUF,
 626                                       __pa(addr), size);
 627        /* Don't warn if this is just an older OPAL that doesn't
 628         * know about that call
 629         */
 630        if (rc && rc != OPAL_UNSUPPORTED)
 631                pr_warn("DUMP: Failed to register kernel log buffer. "
 632                        "rc = %d\n", rc);
 633}
 634
 635static void opal_pdev_init(struct device_node *opal_node,
 636                const char *compatible)
 637{
 638        struct device_node *np;
 639
 640        for_each_child_of_node(opal_node, np)
 641                if (of_device_is_compatible(np, compatible))
 642                        of_platform_device_create(np, NULL, NULL);
 643}
 644
 645static void opal_i2c_create_devs(void)
 646{
 647        struct device_node *np;
 648
 649        for_each_compatible_node(np, NULL, "ibm,opal-i2c")
 650                of_platform_device_create(np, NULL, NULL);
 651}
 652
 653static int kopald(void *unused)
 654{
 655        unsigned long timeout = msecs_to_jiffies(opal_heartbeat) + 1;
 656        __be64 events;
 657
 658        set_freezable();
 659        do {
 660                try_to_freeze();
 661                opal_poll_events(&events);
 662                opal_handle_events(be64_to_cpu(events));
 663                schedule_timeout_interruptible(timeout);
 664        } while (!kthread_should_stop());
 665
 666        return 0;
 667}
 668
 669void opal_wake_poller(void)
 670{
 671        if (kopald_tsk)
 672                wake_up_process(kopald_tsk);
 673}
 674
 675static void opal_init_heartbeat(void)
 676{
 677        /* Old firwmware, we assume the HVC heartbeat is sufficient */
 678        if (of_property_read_u32(opal_node, "ibm,heartbeat-ms",
 679                                 &opal_heartbeat) != 0)
 680                opal_heartbeat = 0;
 681
 682        if (opal_heartbeat)
 683                kopald_tsk = kthread_run(kopald, NULL, "kopald");
 684}
 685
 686static int __init opal_init(void)
 687{
 688        struct device_node *np, *consoles, *leds;
 689        int rc;
 690
 691        opal_node = of_find_node_by_path("/ibm,opal");
 692        if (!opal_node) {
 693                pr_warn("Device node not found\n");
 694                return -ENODEV;
 695        }
 696
 697        /* Register OPAL consoles if any ports */
 698        consoles = of_find_node_by_path("/ibm,opal/consoles");
 699        if (consoles) {
 700                for_each_child_of_node(consoles, np) {
 701                        if (strcmp(np->name, "serial"))
 702                                continue;
 703                        of_platform_device_create(np, NULL, NULL);
 704                }
 705                of_node_put(consoles);
 706        }
 707
 708        /* Initialise OPAL messaging system */
 709        opal_message_init();
 710
 711        /* Initialise OPAL asynchronous completion interface */
 712        opal_async_comp_init();
 713
 714        /* Initialise OPAL sensor interface */
 715        opal_sensor_init();
 716
 717        /* Initialise OPAL hypervisor maintainence interrupt handling */
 718        opal_hmi_handler_init();
 719
 720        /* Create i2c platform devices */
 721        opal_i2c_create_devs();
 722
 723        /* Setup a heatbeat thread if requested by OPAL */
 724        opal_init_heartbeat();
 725
 726        /* Create leds platform devices */
 727        leds = of_find_node_by_path("/ibm,opal/leds");
 728        if (leds) {
 729                of_platform_device_create(leds, "opal_leds", NULL);
 730                of_node_put(leds);
 731        }
 732
 733        /* Initialise OPAL message log interface */
 734        opal_msglog_init();
 735
 736        /* Create "opal" kobject under /sys/firmware */
 737        rc = opal_sysfs_init();
 738        if (rc == 0) {
 739                /* Export symbol map to userspace */
 740                opal_export_symmap();
 741                /* Setup dump region interface */
 742                opal_dump_region_init();
 743                /* Setup error log interface */
 744                rc = opal_elog_init();
 745                /* Setup code update interface */
 746                opal_flash_update_init();
 747                /* Setup platform dump extract interface */
 748                opal_platform_dump_init();
 749                /* Setup system parameters interface */
 750                opal_sys_param_init();
 751                /* Setup message log sysfs interface. */
 752                opal_msglog_sysfs_init();
 753        }
 754
 755        /* Initialize platform devices: IPMI backend, PRD & flash interface */
 756        opal_pdev_init(opal_node, "ibm,opal-ipmi");
 757        opal_pdev_init(opal_node, "ibm,opal-flash");
 758        opal_pdev_init(opal_node, "ibm,opal-prd");
 759
 760        /* Initialise platform device: oppanel interface */
 761        opal_pdev_init(opal_node, "ibm,opal-oppanel");
 762
 763        /* Initialise OPAL kmsg dumper for flushing console on panic */
 764        opal_kmsg_init();
 765
 766        return 0;
 767}
 768machine_subsys_initcall(powernv, opal_init);
 769
 770void opal_shutdown(void)
 771{
 772        long rc = OPAL_BUSY;
 773
 774        opal_event_shutdown();
 775
 776        /*
 777         * Then sync with OPAL which ensure anything that can
 778         * potentially write to our memory has completed such
 779         * as an ongoing dump retrieval
 780         */
 781        while (rc == OPAL_BUSY || rc == OPAL_BUSY_EVENT) {
 782                rc = opal_sync_host_reboot();
 783                if (rc == OPAL_BUSY)
 784                        opal_poll_events(NULL);
 785                else
 786                        mdelay(10);
 787        }
 788
 789        /* Unregister memory dump region */
 790        if (opal_check_token(OPAL_UNREGISTER_DUMP_REGION))
 791                opal_unregister_dump_region(OPAL_DUMP_REGION_LOG_BUF);
 792}
 793
 794/* Export this so that test modules can use it */
 795EXPORT_SYMBOL_GPL(opal_invalid_call);
 796EXPORT_SYMBOL_GPL(opal_xscom_read);
 797EXPORT_SYMBOL_GPL(opal_xscom_write);
 798EXPORT_SYMBOL_GPL(opal_ipmi_send);
 799EXPORT_SYMBOL_GPL(opal_ipmi_recv);
 800EXPORT_SYMBOL_GPL(opal_flash_read);
 801EXPORT_SYMBOL_GPL(opal_flash_write);
 802EXPORT_SYMBOL_GPL(opal_flash_erase);
 803EXPORT_SYMBOL_GPL(opal_prd_msg);
 804
 805/* Convert a region of vmalloc memory to an opal sg list */
 806struct opal_sg_list *opal_vmalloc_to_sg_list(void *vmalloc_addr,
 807                                             unsigned long vmalloc_size)
 808{
 809        struct opal_sg_list *sg, *first = NULL;
 810        unsigned long i = 0;
 811
 812        sg = kzalloc(PAGE_SIZE, GFP_KERNEL);
 813        if (!sg)
 814                goto nomem;
 815
 816        first = sg;
 817
 818        while (vmalloc_size > 0) {
 819                uint64_t data = vmalloc_to_pfn(vmalloc_addr) << PAGE_SHIFT;
 820                uint64_t length = min(vmalloc_size, PAGE_SIZE);
 821
 822                sg->entry[i].data = cpu_to_be64(data);
 823                sg->entry[i].length = cpu_to_be64(length);
 824                i++;
 825
 826                if (i >= SG_ENTRIES_PER_NODE) {
 827                        struct opal_sg_list *next;
 828
 829                        next = kzalloc(PAGE_SIZE, GFP_KERNEL);
 830                        if (!next)
 831                                goto nomem;
 832
 833                        sg->length = cpu_to_be64(
 834                                        i * sizeof(struct opal_sg_entry) + 16);
 835                        i = 0;
 836                        sg->next = cpu_to_be64(__pa(next));
 837                        sg = next;
 838                }
 839
 840                vmalloc_addr += length;
 841                vmalloc_size -= length;
 842        }
 843
 844        sg->length = cpu_to_be64(i * sizeof(struct opal_sg_entry) + 16);
 845
 846        return first;
 847
 848nomem:
 849        pr_err("%s : Failed to allocate memory\n", __func__);
 850        opal_free_sg_list(first);
 851        return NULL;
 852}
 853
 854void opal_free_sg_list(struct opal_sg_list *sg)
 855{
 856        while (sg) {
 857                uint64_t next = be64_to_cpu(sg->next);
 858
 859                kfree(sg);
 860
 861                if (next)
 862                        sg = __va(next);
 863                else
 864                        sg = NULL;
 865        }
 866}
 867
 868int opal_error_code(int rc)
 869{
 870        switch (rc) {
 871        case OPAL_SUCCESS:              return 0;
 872
 873        case OPAL_PARAMETER:            return -EINVAL;
 874        case OPAL_ASYNC_COMPLETION:     return -EINPROGRESS;
 875        case OPAL_BUSY_EVENT:           return -EBUSY;
 876        case OPAL_NO_MEM:               return -ENOMEM;
 877        case OPAL_PERMISSION:           return -EPERM;
 878
 879        case OPAL_UNSUPPORTED:          return -EIO;
 880        case OPAL_HARDWARE:             return -EIO;
 881        case OPAL_INTERNAL_ERROR:       return -EIO;
 882        default:
 883                pr_err("%s: unexpected OPAL error %d\n", __func__, rc);
 884                return -EIO;
 885        }
 886}
 887
 888EXPORT_SYMBOL_GPL(opal_poll_events);
 889EXPORT_SYMBOL_GPL(opal_rtc_read);
 890EXPORT_SYMBOL_GPL(opal_rtc_write);
 891EXPORT_SYMBOL_GPL(opal_tpo_read);
 892EXPORT_SYMBOL_GPL(opal_tpo_write);
 893EXPORT_SYMBOL_GPL(opal_i2c_request);
 894/* Export these symbols for PowerNV LED class driver */
 895EXPORT_SYMBOL_GPL(opal_leds_get_ind);
 896EXPORT_SYMBOL_GPL(opal_leds_set_ind);
 897/* Export this symbol for PowerNV Operator Panel class driver */
 898EXPORT_SYMBOL_GPL(opal_write_oppanel_async);
 899