linux/drivers/firmware/psci/psci.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0-only
   2/*
   3 *
   4 * Copyright (C) 2015 ARM Limited
   5 */
   6
   7#define pr_fmt(fmt) "psci: " fmt
   8
   9#include <linux/acpi.h>
  10#include <linux/arm-smccc.h>
  11#include <linux/cpuidle.h>
  12#include <linux/errno.h>
  13#include <linux/linkage.h>
  14#include <linux/of.h>
  15#include <linux/pm.h>
  16#include <linux/printk.h>
  17#include <linux/psci.h>
  18#include <linux/reboot.h>
  19#include <linux/slab.h>
  20#include <linux/suspend.h>
  21
  22#include <uapi/linux/psci.h>
  23
  24#include <asm/cpuidle.h>
  25#include <asm/cputype.h>
  26#include <asm/hypervisor.h>
  27#include <asm/system_misc.h>
  28#include <asm/smp_plat.h>
  29#include <asm/suspend.h>
  30
  31/*
  32 * While a 64-bit OS can make calls with SMC32 calling conventions, for some
  33 * calls it is necessary to use SMC64 to pass or return 64-bit values.
  34 * For such calls PSCI_FN_NATIVE(version, name) will choose the appropriate
  35 * (native-width) function ID.
  36 */
  37#ifdef CONFIG_64BIT
  38#define PSCI_FN_NATIVE(version, name)   PSCI_##version##_FN64_##name
  39#else
  40#define PSCI_FN_NATIVE(version, name)   PSCI_##version##_FN_##name
  41#endif
  42
  43/*
  44 * The CPU any Trusted OS is resident on. The trusted OS may reject CPU_OFF
  45 * calls to its resident CPU, so we must avoid issuing those. We never migrate
  46 * a Trusted OS even if it claims to be capable of migration -- doing so will
  47 * require cooperation with a Trusted OS driver.
  48 */
  49static int resident_cpu = -1;
  50struct psci_operations psci_ops;
  51static enum arm_smccc_conduit psci_conduit = SMCCC_CONDUIT_NONE;
  52
  53bool psci_tos_resident_on(int cpu)
  54{
  55        return cpu == resident_cpu;
  56}
  57
  58typedef unsigned long (psci_fn)(unsigned long, unsigned long,
  59                                unsigned long, unsigned long);
  60static psci_fn *invoke_psci_fn;
  61
  62static struct psci_0_1_function_ids psci_0_1_function_ids;
  63
  64struct psci_0_1_function_ids get_psci_0_1_function_ids(void)
  65{
  66        return psci_0_1_function_ids;
  67}
  68
  69#define PSCI_0_2_POWER_STATE_MASK               \
  70                                (PSCI_0_2_POWER_STATE_ID_MASK | \
  71                                PSCI_0_2_POWER_STATE_TYPE_MASK | \
  72                                PSCI_0_2_POWER_STATE_AFFL_MASK)
  73
  74#define PSCI_1_0_EXT_POWER_STATE_MASK           \
  75                                (PSCI_1_0_EXT_POWER_STATE_ID_MASK | \
  76                                PSCI_1_0_EXT_POWER_STATE_TYPE_MASK)
  77
  78static u32 psci_cpu_suspend_feature;
  79static bool psci_system_reset2_supported;
  80
  81static inline bool psci_has_ext_power_state(void)
  82{
  83        return psci_cpu_suspend_feature &
  84                                PSCI_1_0_FEATURES_CPU_SUSPEND_PF_MASK;
  85}
  86
  87bool psci_has_osi_support(void)
  88{
  89        return psci_cpu_suspend_feature & PSCI_1_0_OS_INITIATED;
  90}
  91
  92static inline bool psci_power_state_loses_context(u32 state)
  93{
  94        const u32 mask = psci_has_ext_power_state() ?
  95                                        PSCI_1_0_EXT_POWER_STATE_TYPE_MASK :
  96                                        PSCI_0_2_POWER_STATE_TYPE_MASK;
  97
  98        return state & mask;
  99}
 100
 101bool psci_power_state_is_valid(u32 state)
 102{
 103        const u32 valid_mask = psci_has_ext_power_state() ?
 104                               PSCI_1_0_EXT_POWER_STATE_MASK :
 105                               PSCI_0_2_POWER_STATE_MASK;
 106
 107        return !(state & ~valid_mask);
 108}
 109
 110static unsigned long __invoke_psci_fn_hvc(unsigned long function_id,
 111                        unsigned long arg0, unsigned long arg1,
 112                        unsigned long arg2)
 113{
 114        struct arm_smccc_res res;
 115
 116        arm_smccc_hvc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
 117        return res.a0;
 118}
 119
 120static unsigned long __invoke_psci_fn_smc(unsigned long function_id,
 121                        unsigned long arg0, unsigned long arg1,
 122                        unsigned long arg2)
 123{
 124        struct arm_smccc_res res;
 125
 126        arm_smccc_smc(function_id, arg0, arg1, arg2, 0, 0, 0, 0, &res);
 127        return res.a0;
 128}
 129
 130static int psci_to_linux_errno(int errno)
 131{
 132        switch (errno) {
 133        case PSCI_RET_SUCCESS:
 134                return 0;
 135        case PSCI_RET_NOT_SUPPORTED:
 136                return -EOPNOTSUPP;
 137        case PSCI_RET_INVALID_PARAMS:
 138        case PSCI_RET_INVALID_ADDRESS:
 139                return -EINVAL;
 140        case PSCI_RET_DENIED:
 141                return -EPERM;
 142        }
 143
 144        return -EINVAL;
 145}
 146
 147static u32 psci_0_1_get_version(void)
 148{
 149        return PSCI_VERSION(0, 1);
 150}
 151
 152static u32 psci_0_2_get_version(void)
 153{
 154        return invoke_psci_fn(PSCI_0_2_FN_PSCI_VERSION, 0, 0, 0);
 155}
 156
 157int psci_set_osi_mode(bool enable)
 158{
 159        unsigned long suspend_mode;
 160        int err;
 161
 162        suspend_mode = enable ? PSCI_1_0_SUSPEND_MODE_OSI :
 163                        PSCI_1_0_SUSPEND_MODE_PC;
 164
 165        err = invoke_psci_fn(PSCI_1_0_FN_SET_SUSPEND_MODE, suspend_mode, 0, 0);
 166        return psci_to_linux_errno(err);
 167}
 168
 169static int __psci_cpu_suspend(u32 fn, u32 state, unsigned long entry_point)
 170{
 171        int err;
 172
 173        err = invoke_psci_fn(fn, state, entry_point, 0);
 174        return psci_to_linux_errno(err);
 175}
 176
 177static int psci_0_1_cpu_suspend(u32 state, unsigned long entry_point)
 178{
 179        return __psci_cpu_suspend(psci_0_1_function_ids.cpu_suspend,
 180                                  state, entry_point);
 181}
 182
 183static int psci_0_2_cpu_suspend(u32 state, unsigned long entry_point)
 184{
 185        return __psci_cpu_suspend(PSCI_FN_NATIVE(0_2, CPU_SUSPEND),
 186                                  state, entry_point);
 187}
 188
 189static int __psci_cpu_off(u32 fn, u32 state)
 190{
 191        int err;
 192
 193        err = invoke_psci_fn(fn, state, 0, 0);
 194        return psci_to_linux_errno(err);
 195}
 196
 197static int psci_0_1_cpu_off(u32 state)
 198{
 199        return __psci_cpu_off(psci_0_1_function_ids.cpu_off, state);
 200}
 201
 202static int psci_0_2_cpu_off(u32 state)
 203{
 204        return __psci_cpu_off(PSCI_0_2_FN_CPU_OFF, state);
 205}
 206
 207static int __psci_cpu_on(u32 fn, unsigned long cpuid, unsigned long entry_point)
 208{
 209        int err;
 210
 211        err = invoke_psci_fn(fn, cpuid, entry_point, 0);
 212        return psci_to_linux_errno(err);
 213}
 214
 215static int psci_0_1_cpu_on(unsigned long cpuid, unsigned long entry_point)
 216{
 217        return __psci_cpu_on(psci_0_1_function_ids.cpu_on, cpuid, entry_point);
 218}
 219
 220static int psci_0_2_cpu_on(unsigned long cpuid, unsigned long entry_point)
 221{
 222        return __psci_cpu_on(PSCI_FN_NATIVE(0_2, CPU_ON), cpuid, entry_point);
 223}
 224
 225static int __psci_migrate(u32 fn, unsigned long cpuid)
 226{
 227        int err;
 228
 229        err = invoke_psci_fn(fn, cpuid, 0, 0);
 230        return psci_to_linux_errno(err);
 231}
 232
 233static int psci_0_1_migrate(unsigned long cpuid)
 234{
 235        return __psci_migrate(psci_0_1_function_ids.migrate, cpuid);
 236}
 237
 238static int psci_0_2_migrate(unsigned long cpuid)
 239{
 240        return __psci_migrate(PSCI_FN_NATIVE(0_2, MIGRATE), cpuid);
 241}
 242
 243static int psci_affinity_info(unsigned long target_affinity,
 244                unsigned long lowest_affinity_level)
 245{
 246        return invoke_psci_fn(PSCI_FN_NATIVE(0_2, AFFINITY_INFO),
 247                              target_affinity, lowest_affinity_level, 0);
 248}
 249
 250static int psci_migrate_info_type(void)
 251{
 252        return invoke_psci_fn(PSCI_0_2_FN_MIGRATE_INFO_TYPE, 0, 0, 0);
 253}
 254
 255static unsigned long psci_migrate_info_up_cpu(void)
 256{
 257        return invoke_psci_fn(PSCI_FN_NATIVE(0_2, MIGRATE_INFO_UP_CPU),
 258                              0, 0, 0);
 259}
 260
 261static void set_conduit(enum arm_smccc_conduit conduit)
 262{
 263        switch (conduit) {
 264        case SMCCC_CONDUIT_HVC:
 265                invoke_psci_fn = __invoke_psci_fn_hvc;
 266                break;
 267        case SMCCC_CONDUIT_SMC:
 268                invoke_psci_fn = __invoke_psci_fn_smc;
 269                break;
 270        default:
 271                WARN(1, "Unexpected PSCI conduit %d\n", conduit);
 272        }
 273
 274        psci_conduit = conduit;
 275}
 276
 277static int get_set_conduit_method(struct device_node *np)
 278{
 279        const char *method;
 280
 281        pr_info("probing for conduit method from DT.\n");
 282
 283        if (of_property_read_string(np, "method", &method)) {
 284                pr_warn("missing \"method\" property\n");
 285                return -ENXIO;
 286        }
 287
 288        if (!strcmp("hvc", method)) {
 289                set_conduit(SMCCC_CONDUIT_HVC);
 290        } else if (!strcmp("smc", method)) {
 291                set_conduit(SMCCC_CONDUIT_SMC);
 292        } else {
 293                pr_warn("invalid \"method\" property: %s\n", method);
 294                return -EINVAL;
 295        }
 296        return 0;
 297}
 298
 299static void psci_sys_reset(enum reboot_mode reboot_mode, const char *cmd)
 300{
 301        if ((reboot_mode == REBOOT_WARM || reboot_mode == REBOOT_SOFT) &&
 302            psci_system_reset2_supported) {
 303                /*
 304                 * reset_type[31] = 0 (architectural)
 305                 * reset_type[30:0] = 0 (SYSTEM_WARM_RESET)
 306                 * cookie = 0 (ignored by the implementation)
 307                 */
 308                invoke_psci_fn(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2), 0, 0, 0);
 309        } else {
 310                invoke_psci_fn(PSCI_0_2_FN_SYSTEM_RESET, 0, 0, 0);
 311        }
 312}
 313
 314static void psci_sys_poweroff(void)
 315{
 316        invoke_psci_fn(PSCI_0_2_FN_SYSTEM_OFF, 0, 0, 0);
 317}
 318
 319static int __init psci_features(u32 psci_func_id)
 320{
 321        return invoke_psci_fn(PSCI_1_0_FN_PSCI_FEATURES,
 322                              psci_func_id, 0, 0);
 323}
 324
 325#ifdef CONFIG_CPU_IDLE
 326static int psci_suspend_finisher(unsigned long state)
 327{
 328        u32 power_state = state;
 329        phys_addr_t pa_cpu_resume = __pa_symbol(function_nocfi(cpu_resume));
 330
 331        return psci_ops.cpu_suspend(power_state, pa_cpu_resume);
 332}
 333
 334int psci_cpu_suspend_enter(u32 state)
 335{
 336        int ret;
 337
 338        if (!psci_power_state_loses_context(state))
 339                ret = psci_ops.cpu_suspend(state, 0);
 340        else
 341                ret = cpu_suspend(state, psci_suspend_finisher);
 342
 343        return ret;
 344}
 345#endif
 346
 347static int psci_system_suspend(unsigned long unused)
 348{
 349        phys_addr_t pa_cpu_resume = __pa_symbol(function_nocfi(cpu_resume));
 350
 351        return invoke_psci_fn(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND),
 352                              pa_cpu_resume, 0, 0);
 353}
 354
 355static int psci_system_suspend_enter(suspend_state_t state)
 356{
 357        return cpu_suspend(0, psci_system_suspend);
 358}
 359
 360static const struct platform_suspend_ops psci_suspend_ops = {
 361        .valid          = suspend_valid_only_mem,
 362        .enter          = psci_system_suspend_enter,
 363};
 364
 365static void __init psci_init_system_reset2(void)
 366{
 367        int ret;
 368
 369        ret = psci_features(PSCI_FN_NATIVE(1_1, SYSTEM_RESET2));
 370
 371        if (ret != PSCI_RET_NOT_SUPPORTED)
 372                psci_system_reset2_supported = true;
 373}
 374
 375static void __init psci_init_system_suspend(void)
 376{
 377        int ret;
 378
 379        if (!IS_ENABLED(CONFIG_SUSPEND))
 380                return;
 381
 382        ret = psci_features(PSCI_FN_NATIVE(1_0, SYSTEM_SUSPEND));
 383
 384        if (ret != PSCI_RET_NOT_SUPPORTED)
 385                suspend_set_ops(&psci_suspend_ops);
 386}
 387
 388static void __init psci_init_cpu_suspend(void)
 389{
 390        int feature = psci_features(PSCI_FN_NATIVE(0_2, CPU_SUSPEND));
 391
 392        if (feature != PSCI_RET_NOT_SUPPORTED)
 393                psci_cpu_suspend_feature = feature;
 394}
 395
 396/*
 397 * Detect the presence of a resident Trusted OS which may cause CPU_OFF to
 398 * return DENIED (which would be fatal).
 399 */
 400static void __init psci_init_migrate(void)
 401{
 402        unsigned long cpuid;
 403        int type, cpu = -1;
 404
 405        type = psci_ops.migrate_info_type();
 406
 407        if (type == PSCI_0_2_TOS_MP) {
 408                pr_info("Trusted OS migration not required\n");
 409                return;
 410        }
 411
 412        if (type == PSCI_RET_NOT_SUPPORTED) {
 413                pr_info("MIGRATE_INFO_TYPE not supported.\n");
 414                return;
 415        }
 416
 417        if (type != PSCI_0_2_TOS_UP_MIGRATE &&
 418            type != PSCI_0_2_TOS_UP_NO_MIGRATE) {
 419                pr_err("MIGRATE_INFO_TYPE returned unknown type (%d)\n", type);
 420                return;
 421        }
 422
 423        cpuid = psci_migrate_info_up_cpu();
 424        if (cpuid & ~MPIDR_HWID_BITMASK) {
 425                pr_warn("MIGRATE_INFO_UP_CPU reported invalid physical ID (0x%lx)\n",
 426                        cpuid);
 427                return;
 428        }
 429
 430        cpu = get_logical_index(cpuid);
 431        resident_cpu = cpu >= 0 ? cpu : -1;
 432
 433        pr_info("Trusted OS resident on physical CPU 0x%lx\n", cpuid);
 434}
 435
 436static void __init psci_init_smccc(void)
 437{
 438        u32 ver = ARM_SMCCC_VERSION_1_0;
 439        int feature;
 440
 441        feature = psci_features(ARM_SMCCC_VERSION_FUNC_ID);
 442
 443        if (feature != PSCI_RET_NOT_SUPPORTED) {
 444                u32 ret;
 445                ret = invoke_psci_fn(ARM_SMCCC_VERSION_FUNC_ID, 0, 0, 0);
 446                if (ret >= ARM_SMCCC_VERSION_1_1) {
 447                        arm_smccc_version_init(ret, psci_conduit);
 448                        ver = ret;
 449                }
 450        }
 451
 452        /*
 453         * Conveniently, the SMCCC and PSCI versions are encoded the
 454         * same way. No, this isn't accidental.
 455         */
 456        pr_info("SMC Calling Convention v%d.%d\n",
 457                PSCI_VERSION_MAJOR(ver), PSCI_VERSION_MINOR(ver));
 458
 459}
 460
 461static void __init psci_0_2_set_functions(void)
 462{
 463        pr_info("Using standard PSCI v0.2 function IDs\n");
 464
 465        psci_ops = (struct psci_operations){
 466                .get_version = psci_0_2_get_version,
 467                .cpu_suspend = psci_0_2_cpu_suspend,
 468                .cpu_off = psci_0_2_cpu_off,
 469                .cpu_on = psci_0_2_cpu_on,
 470                .migrate = psci_0_2_migrate,
 471                .affinity_info = psci_affinity_info,
 472                .migrate_info_type = psci_migrate_info_type,
 473        };
 474
 475        arm_pm_restart = psci_sys_reset;
 476
 477        pm_power_off = psci_sys_poweroff;
 478}
 479
 480/*
 481 * Probe function for PSCI firmware versions >= 0.2
 482 */
 483static int __init psci_probe(void)
 484{
 485        u32 ver = psci_0_2_get_version();
 486
 487        pr_info("PSCIv%d.%d detected in firmware.\n",
 488                        PSCI_VERSION_MAJOR(ver),
 489                        PSCI_VERSION_MINOR(ver));
 490
 491        if (PSCI_VERSION_MAJOR(ver) == 0 && PSCI_VERSION_MINOR(ver) < 2) {
 492                pr_err("Conflicting PSCI version detected.\n");
 493                return -EINVAL;
 494        }
 495
 496        psci_0_2_set_functions();
 497
 498        psci_init_migrate();
 499
 500        if (PSCI_VERSION_MAJOR(ver) >= 1) {
 501                psci_init_smccc();
 502                psci_init_cpu_suspend();
 503                psci_init_system_suspend();
 504                psci_init_system_reset2();
 505                kvm_init_hyp_services();
 506        }
 507
 508        return 0;
 509}
 510
 511typedef int (*psci_initcall_t)(const struct device_node *);
 512
 513/*
 514 * PSCI init function for PSCI versions >=0.2
 515 *
 516 * Probe based on PSCI PSCI_VERSION function
 517 */
 518static int __init psci_0_2_init(struct device_node *np)
 519{
 520        int err;
 521
 522        err = get_set_conduit_method(np);
 523        if (err)
 524                return err;
 525
 526        /*
 527         * Starting with v0.2, the PSCI specification introduced a call
 528         * (PSCI_VERSION) that allows probing the firmware version, so
 529         * that PSCI function IDs and version specific initialization
 530         * can be carried out according to the specific version reported
 531         * by firmware
 532         */
 533        return psci_probe();
 534}
 535
 536/*
 537 * PSCI < v0.2 get PSCI Function IDs via DT.
 538 */
 539static int __init psci_0_1_init(struct device_node *np)
 540{
 541        u32 id;
 542        int err;
 543
 544        err = get_set_conduit_method(np);
 545        if (err)
 546                return err;
 547
 548        pr_info("Using PSCI v0.1 Function IDs from DT\n");
 549
 550        psci_ops.get_version = psci_0_1_get_version;
 551
 552        if (!of_property_read_u32(np, "cpu_suspend", &id)) {
 553                psci_0_1_function_ids.cpu_suspend = id;
 554                psci_ops.cpu_suspend = psci_0_1_cpu_suspend;
 555        }
 556
 557        if (!of_property_read_u32(np, "cpu_off", &id)) {
 558                psci_0_1_function_ids.cpu_off = id;
 559                psci_ops.cpu_off = psci_0_1_cpu_off;
 560        }
 561
 562        if (!of_property_read_u32(np, "cpu_on", &id)) {
 563                psci_0_1_function_ids.cpu_on = id;
 564                psci_ops.cpu_on = psci_0_1_cpu_on;
 565        }
 566
 567        if (!of_property_read_u32(np, "migrate", &id)) {
 568                psci_0_1_function_ids.migrate = id;
 569                psci_ops.migrate = psci_0_1_migrate;
 570        }
 571
 572        return 0;
 573}
 574
 575static int __init psci_1_0_init(struct device_node *np)
 576{
 577        int err;
 578
 579        err = psci_0_2_init(np);
 580        if (err)
 581                return err;
 582
 583        if (psci_has_osi_support()) {
 584                pr_info("OSI mode supported.\n");
 585
 586                /* Default to PC mode. */
 587                psci_set_osi_mode(false);
 588        }
 589
 590        return 0;
 591}
 592
 593static const struct of_device_id psci_of_match[] __initconst = {
 594        { .compatible = "arm,psci",     .data = psci_0_1_init},
 595        { .compatible = "arm,psci-0.2", .data = psci_0_2_init},
 596        { .compatible = "arm,psci-1.0", .data = psci_1_0_init},
 597        {},
 598};
 599
 600int __init psci_dt_init(void)
 601{
 602        struct device_node *np;
 603        const struct of_device_id *matched_np;
 604        psci_initcall_t init_fn;
 605        int ret;
 606
 607        np = of_find_matching_node_and_match(NULL, psci_of_match, &matched_np);
 608
 609        if (!np || !of_device_is_available(np))
 610                return -ENODEV;
 611
 612        init_fn = (psci_initcall_t)matched_np->data;
 613        ret = init_fn(np);
 614
 615        of_node_put(np);
 616        return ret;
 617}
 618
 619#ifdef CONFIG_ACPI
 620/*
 621 * We use PSCI 0.2+ when ACPI is deployed on ARM64 and it's
 622 * explicitly clarified in SBBR
 623 */
 624int __init psci_acpi_init(void)
 625{
 626        if (!acpi_psci_present()) {
 627                pr_info("is not implemented in ACPI.\n");
 628                return -EOPNOTSUPP;
 629        }
 630
 631        pr_info("probing for conduit method from ACPI.\n");
 632
 633        if (acpi_psci_use_hvc())
 634                set_conduit(SMCCC_CONDUIT_HVC);
 635        else
 636                set_conduit(SMCCC_CONDUIT_SMC);
 637
 638        return psci_probe();
 639}
 640#endif
 641