uboot/lib/acpi/acpigen.c
<<
>>
Prefs
   1// SPDX-License-Identifier: GPL-2.0
   2/*
   3 * Generation of ACPI (Advanced Configuration and Power Interface) tables
   4 *
   5 * Copyright 2019 Google LLC
   6 * Mostly taken from coreboot
   7 */
   8
   9#define LOG_CATEGORY LOGC_ACPI
  10
  11#include <common.h>
  12#include <dm.h>
  13#include <log.h>
  14#include <uuid.h>
  15#include <acpi/acpigen.h>
  16#include <acpi/acpi_device.h>
  17#include <acpi/acpi_table.h>
  18#include <dm/acpi.h>
  19
  20/* CPU path format */
  21#define ACPI_CPU_STRING "\\_PR.CP%02d"
  22
  23u8 *acpigen_get_current(struct acpi_ctx *ctx)
  24{
  25        return ctx->current;
  26}
  27
  28void acpigen_emit_byte(struct acpi_ctx *ctx, uint data)
  29{
  30        *(u8 *)ctx->current++ = data;
  31}
  32
  33void acpigen_emit_word(struct acpi_ctx *ctx, uint data)
  34{
  35        acpigen_emit_byte(ctx, data & 0xff);
  36        acpigen_emit_byte(ctx, (data >> 8) & 0xff);
  37}
  38
  39void acpigen_emit_dword(struct acpi_ctx *ctx, uint data)
  40{
  41        /* Output the value in little-endian format */
  42        acpigen_emit_byte(ctx, data & 0xff);
  43        acpigen_emit_byte(ctx, (data >> 8) & 0xff);
  44        acpigen_emit_byte(ctx, (data >> 16) & 0xff);
  45        acpigen_emit_byte(ctx, (data >> 24) & 0xff);
  46}
  47
  48/*
  49 * Maximum length for an ACPI object generated by this code,
  50 *
  51 * If you need to change this, change acpigen_write_len_f(ctx) and
  52 * acpigen_pop_len(ctx)
  53 */
  54#define ACPIGEN_MAXLEN 0xfffff
  55
  56void acpigen_write_len_f(struct acpi_ctx *ctx)
  57{
  58        assert(ctx->ltop < (ACPIGEN_LENSTACK_SIZE - 1));
  59        ctx->len_stack[ctx->ltop++] = ctx->current;
  60        acpigen_emit_byte(ctx, 0);
  61        acpigen_emit_byte(ctx, 0);
  62        acpigen_emit_byte(ctx, 0);
  63}
  64
  65void acpigen_pop_len(struct acpi_ctx *ctx)
  66{
  67        int len;
  68        char *p;
  69
  70        assert(ctx->ltop > 0);
  71        p = ctx->len_stack[--ctx->ltop];
  72        len = ctx->current - (void *)p;
  73        assert(len <= ACPIGEN_MAXLEN);
  74        /* generate store length for 0xfffff max */
  75        p[0] = ACPI_PKG_LEN_3_BYTES | (len & 0xf);
  76        p[1] = len >> 4 & 0xff;
  77        p[2] = len >> 12 & 0xff;
  78}
  79
  80void acpigen_emit_ext_op(struct acpi_ctx *ctx, uint op)
  81{
  82        acpigen_emit_byte(ctx, EXT_OP_PREFIX);
  83        acpigen_emit_byte(ctx, op);
  84}
  85
  86char *acpigen_write_package(struct acpi_ctx *ctx, int nr_el)
  87{
  88        char *p;
  89
  90        acpigen_emit_byte(ctx, PACKAGE_OP);
  91        acpigen_write_len_f(ctx);
  92        p = ctx->current;
  93        acpigen_emit_byte(ctx, nr_el);
  94
  95        return p;
  96}
  97
  98void acpigen_write_byte(struct acpi_ctx *ctx, unsigned int data)
  99{
 100        acpigen_emit_byte(ctx, BYTE_PREFIX);
 101        acpigen_emit_byte(ctx, data & 0xff);
 102}
 103
 104void acpigen_write_word(struct acpi_ctx *ctx, unsigned int data)
 105{
 106        acpigen_emit_byte(ctx, WORD_PREFIX);
 107        acpigen_emit_word(ctx, data);
 108}
 109
 110void acpigen_write_dword(struct acpi_ctx *ctx, unsigned int data)
 111{
 112        acpigen_emit_byte(ctx, DWORD_PREFIX);
 113        acpigen_emit_dword(ctx, data);
 114}
 115
 116void acpigen_write_qword(struct acpi_ctx *ctx, u64 data)
 117{
 118        acpigen_emit_byte(ctx, QWORD_PREFIX);
 119        acpigen_emit_dword(ctx, data & 0xffffffff);
 120        acpigen_emit_dword(ctx, (data >> 32) & 0xffffffff);
 121}
 122
 123void acpigen_write_zero(struct acpi_ctx *ctx)
 124{
 125        acpigen_emit_byte(ctx, ZERO_OP);
 126}
 127
 128void acpigen_write_one(struct acpi_ctx *ctx)
 129{
 130        acpigen_emit_byte(ctx, ONE_OP);
 131}
 132
 133void acpigen_write_integer(struct acpi_ctx *ctx, u64 data)
 134{
 135        if (data == 0)
 136                acpigen_write_zero(ctx);
 137        else if (data == 1)
 138                acpigen_write_one(ctx);
 139        else if (data <= 0xff)
 140                acpigen_write_byte(ctx, (unsigned char)data);
 141        else if (data <= 0xffff)
 142                acpigen_write_word(ctx, (unsigned int)data);
 143        else if (data <= 0xffffffff)
 144                acpigen_write_dword(ctx, (unsigned int)data);
 145        else
 146                acpigen_write_qword(ctx, data);
 147}
 148
 149void acpigen_write_name_zero(struct acpi_ctx *ctx, const char *name)
 150{
 151        acpigen_write_name(ctx, name);
 152        acpigen_write_zero(ctx);
 153}
 154
 155void acpigen_write_name_one(struct acpi_ctx *ctx, const char *name)
 156{
 157        acpigen_write_name(ctx, name);
 158        acpigen_write_one(ctx);
 159}
 160
 161void acpigen_write_name_byte(struct acpi_ctx *ctx, const char *name, uint val)
 162{
 163        acpigen_write_name(ctx, name);
 164        acpigen_write_byte(ctx, val);
 165}
 166
 167void acpigen_write_name_word(struct acpi_ctx *ctx, const char *name, uint val)
 168{
 169        acpigen_write_name(ctx, name);
 170        acpigen_write_word(ctx, val);
 171}
 172
 173void acpigen_write_name_dword(struct acpi_ctx *ctx, const char *name, uint val)
 174{
 175        acpigen_write_name(ctx, name);
 176        acpigen_write_dword(ctx, val);
 177}
 178
 179void acpigen_write_name_qword(struct acpi_ctx *ctx, const char *name, u64 val)
 180{
 181        acpigen_write_name(ctx, name);
 182        acpigen_write_qword(ctx, val);
 183}
 184
 185void acpigen_write_name_integer(struct acpi_ctx *ctx, const char *name, u64 val)
 186{
 187        acpigen_write_name(ctx, name);
 188        acpigen_write_integer(ctx, val);
 189}
 190
 191void acpigen_write_name_string(struct acpi_ctx *ctx, const char *name,
 192                               const char *string)
 193{
 194        acpigen_write_name(ctx, name);
 195        acpigen_write_string(ctx, string);
 196}
 197
 198void acpigen_emit_stream(struct acpi_ctx *ctx, const char *data, int size)
 199{
 200        int i;
 201
 202        for (i = 0; i < size; i++)
 203                acpigen_emit_byte(ctx, data[i]);
 204}
 205
 206void acpigen_emit_string(struct acpi_ctx *ctx, const char *str)
 207{
 208        acpigen_emit_stream(ctx, str, str ? strlen(str) : 0);
 209        acpigen_emit_byte(ctx, '\0');
 210}
 211
 212void acpigen_write_string(struct acpi_ctx *ctx, const char *str)
 213{
 214        acpigen_emit_byte(ctx, STRING_PREFIX);
 215        acpigen_emit_string(ctx, str);
 216}
 217
 218/*
 219 * The naming conventions for ACPI namespace names are a bit tricky as
 220 * each element has to be 4 chars wide ("All names are a fixed 32 bits.")
 221 * and "By convention, when an ASL compiler pads a name shorter than 4
 222 * characters, it is done so with trailing underscores ('_')".
 223 *
 224 * Check sections 5.3, 20.2.2 and 20.4 of ACPI spec 6.3 for details.
 225 */
 226static void acpigen_emit_simple_namestring(struct acpi_ctx *ctx,
 227                                           const char *name)
 228{
 229        const char *ptr;
 230        int i;
 231
 232        for (i = 0, ptr = name; i < 4; i++) {
 233                if (!*ptr || *ptr == '.')
 234                        acpigen_emit_byte(ctx, '_');
 235                else
 236                        acpigen_emit_byte(ctx, *ptr++);
 237        }
 238}
 239
 240static void acpigen_emit_double_namestring(struct acpi_ctx *ctx,
 241                                           const char *name, int dotpos)
 242{
 243        acpigen_emit_byte(ctx, DUAL_NAME_PREFIX);
 244        acpigen_emit_simple_namestring(ctx, name);
 245        acpigen_emit_simple_namestring(ctx, &name[dotpos + 1]);
 246}
 247
 248static void acpigen_emit_multi_namestring(struct acpi_ctx *ctx,
 249                                          const char *name)
 250{
 251        unsigned char *pathlen;
 252        int count = 0;
 253
 254        acpigen_emit_byte(ctx, MULTI_NAME_PREFIX);
 255        pathlen = ctx->current;
 256        acpigen_emit_byte(ctx, 0);
 257
 258        while (*name) {
 259                acpigen_emit_simple_namestring(ctx, name);
 260                /* find end or next entity */
 261                while (*name != '.' && *name)
 262                        name++;
 263                /* forward to next */
 264                if (*name == '.')
 265                        name++;
 266                count++;
 267        }
 268
 269        *pathlen = count;
 270}
 271
 272void acpigen_emit_namestring(struct acpi_ctx *ctx, const char *namepath)
 273{
 274        int dotcount;
 275        int dotpos;
 276        int i;
 277
 278        /* We can start with a '\' */
 279        if (*namepath == '\\') {
 280                acpigen_emit_byte(ctx, '\\');
 281                namepath++;
 282        }
 283
 284        /* And there can be any number of '^' */
 285        while (*namepath == '^') {
 286                acpigen_emit_byte(ctx, '^');
 287                namepath++;
 288        }
 289
 290        for (i = 0, dotcount = 0; namepath[i]; i++) {
 291                if (namepath[i] == '.') {
 292                        dotcount++;
 293                        dotpos = i;
 294                }
 295        }
 296
 297        /* If we have only \\ or only ^* then we need to add a null name */
 298        if (!*namepath)
 299                acpigen_emit_byte(ctx, ZERO_OP);
 300        else if (dotcount == 0)
 301                acpigen_emit_simple_namestring(ctx, namepath);
 302        else if (dotcount == 1)
 303                acpigen_emit_double_namestring(ctx, namepath, dotpos);
 304        else
 305                acpigen_emit_multi_namestring(ctx, namepath);
 306}
 307
 308void acpigen_write_name(struct acpi_ctx *ctx, const char *namepath)
 309{
 310        acpigen_emit_byte(ctx, NAME_OP);
 311        acpigen_emit_namestring(ctx, namepath);
 312}
 313
 314void acpigen_write_scope(struct acpi_ctx *ctx, const char *scope)
 315{
 316        acpigen_emit_byte(ctx, SCOPE_OP);
 317        acpigen_write_len_f(ctx);
 318        acpigen_emit_namestring(ctx, scope);
 319}
 320
 321static void acpigen_write_method_internal(struct acpi_ctx *ctx,
 322                                          const char *name, uint flags)
 323{
 324        acpigen_emit_byte(ctx, METHOD_OP);
 325        acpigen_write_len_f(ctx);
 326        acpigen_emit_namestring(ctx, name);
 327        acpigen_emit_byte(ctx, flags);
 328}
 329
 330/* Method (name, nargs, NotSerialized) */
 331void acpigen_write_method(struct acpi_ctx *ctx, const char *name, int nargs)
 332{
 333        acpigen_write_method_internal(ctx, name,
 334                                      nargs & ACPI_METHOD_NARGS_MASK);
 335}
 336
 337/* Method (name, nargs, Serialized) */
 338void acpigen_write_method_serialized(struct acpi_ctx *ctx, const char *name,
 339                                     int nargs)
 340{
 341        acpigen_write_method_internal(ctx, name,
 342                                      (nargs & ACPI_METHOD_NARGS_MASK) |
 343                                      ACPI_METHOD_SERIALIZED_MASK);
 344}
 345
 346void acpigen_write_processor(struct acpi_ctx *ctx, uint cpuindex,
 347                             u32 pblock_addr, uint pblock_len)
 348{
 349        /*
 350         * Processor (\_PR.CPnn, cpuindex, pblock_addr, pblock_len)
 351         * {
 352         */
 353        char pscope[16];
 354
 355        acpigen_emit_ext_op(ctx, PROCESSOR_OP);
 356        acpigen_write_len_f(ctx);
 357
 358        snprintf(pscope, sizeof(pscope), ACPI_CPU_STRING, cpuindex);
 359        acpigen_emit_namestring(ctx, pscope);
 360        acpigen_emit_byte(ctx, cpuindex);
 361        acpigen_emit_dword(ctx, pblock_addr);
 362        acpigen_emit_byte(ctx, pblock_len);
 363}
 364
 365void acpigen_write_processor_package(struct acpi_ctx *ctx,
 366                                     const char *const name,
 367                                     const uint first_core,
 368                                     const uint core_count)
 369{
 370        uint i;
 371        char pscope[16];
 372
 373        acpigen_write_name(ctx, name);
 374        acpigen_write_package(ctx, core_count);
 375        for (i = first_core; i < first_core + core_count; ++i) {
 376                snprintf(pscope, sizeof(pscope), ACPI_CPU_STRING, i);
 377                acpigen_emit_namestring(ctx, pscope);
 378        }
 379        acpigen_pop_len(ctx);
 380}
 381
 382void acpigen_write_processor_cnot(struct acpi_ctx *ctx, const uint num_cores)
 383{
 384        int core_id;
 385
 386        acpigen_write_method(ctx, "\\_PR.CNOT", 1);
 387        for (core_id = 0; core_id < num_cores; core_id++) {
 388                char buffer[30];
 389
 390                snprintf(buffer, sizeof(buffer), ACPI_CPU_STRING, core_id);
 391                acpigen_emit_byte(ctx, NOTIFY_OP);
 392                acpigen_emit_namestring(ctx, buffer);
 393                acpigen_emit_byte(ctx, ARG0_OP);
 394        }
 395        acpigen_pop_len(ctx);
 396}
 397
 398void acpigen_write_device(struct acpi_ctx *ctx, const char *name)
 399{
 400        acpigen_emit_ext_op(ctx, DEVICE_OP);
 401        acpigen_write_len_f(ctx);
 402        acpigen_emit_namestring(ctx, name);
 403}
 404
 405void acpigen_write_sta(struct acpi_ctx *ctx, uint status)
 406{
 407        /* Method (_STA, 0, NotSerialized) { Return (status) } */
 408        acpigen_write_method(ctx, "_STA", 0);
 409        acpigen_emit_byte(ctx, RETURN_OP);
 410        acpigen_write_byte(ctx, status);
 411        acpigen_pop_len(ctx);
 412}
 413
 414static void acpigen_write_register(struct acpi_ctx *ctx,
 415                                   const struct acpi_gen_regaddr *addr)
 416{
 417        /* See ACPI v6.3 section 6.4.3.7: Generic Register Descriptor */
 418        acpigen_emit_byte(ctx, ACPI_DESCRIPTOR_REGISTER);
 419        acpigen_emit_byte(ctx, 0x0c);           /* Register Length 7:0 */
 420        acpigen_emit_byte(ctx, 0x00);           /* Register Length 15:8 */
 421        acpigen_emit_byte(ctx, addr->space_id);
 422        acpigen_emit_byte(ctx, addr->bit_width);
 423        acpigen_emit_byte(ctx, addr->bit_offset);
 424        acpigen_emit_byte(ctx, addr->access_size);
 425        acpigen_emit_dword(ctx, addr->addrl);
 426        acpigen_emit_dword(ctx, addr->addrh);
 427}
 428
 429void acpigen_write_resourcetemplate_header(struct acpi_ctx *ctx)
 430{
 431        /*
 432         * A ResourceTemplate() is a Buffer() with a
 433         * (Byte|Word|DWord) containing the length, followed by one or more
 434         * resource items, terminated by the end tag.
 435         * (small item 0xf, len 1)
 436         */
 437        acpigen_emit_byte(ctx, BUFFER_OP);
 438        acpigen_write_len_f(ctx);
 439        acpigen_emit_byte(ctx, WORD_PREFIX);
 440        ctx->len_stack[ctx->ltop++] = ctx->current;
 441
 442        /*
 443         * Add two dummy bytes for the ACPI word (keep aligned with the
 444         * calculation in acpigen_write_resourcetemplate_footer() below)
 445         */
 446        acpigen_emit_byte(ctx, 0x00);
 447        acpigen_emit_byte(ctx, 0x00);
 448}
 449
 450void acpigen_write_resourcetemplate_footer(struct acpi_ctx *ctx)
 451{
 452        char *p = ctx->len_stack[--ctx->ltop];
 453        int len;
 454        /*
 455         * See ACPI v6.3 section 6.4.2.9: End Tag
 456         * 0x79 <checksum>
 457         * 0x00 is treated as a good checksum according to the spec
 458         * and is what iasl generates.
 459         */
 460        acpigen_emit_byte(ctx, ACPI_END_TAG);
 461        acpigen_emit_byte(ctx, 0x00);
 462
 463        /*
 464         * Start counting past the 2-bytes length added in
 465         * acpigen_write_resourcetemplate_header() above
 466         */
 467        len = (char *)ctx->current - (p + 2);
 468
 469        /* patch len word */
 470        p[0] = len & 0xff;
 471        p[1] = (len >> 8) & 0xff;
 472
 473        acpigen_pop_len(ctx);
 474}
 475
 476void acpigen_write_register_resource(struct acpi_ctx *ctx,
 477                                     const struct acpi_gen_regaddr *addr)
 478{
 479        acpigen_write_resourcetemplate_header(ctx);
 480        acpigen_write_register(ctx, addr);
 481        acpigen_write_resourcetemplate_footer(ctx);
 482}
 483
 484void acpigen_write_ppc(struct acpi_ctx *ctx, uint num_pstates)
 485{
 486        /*
 487         * Method (_PPC, 0, NotSerialized)
 488         * {
 489         *      Return (num_pstates)
 490         * }
 491         */
 492        acpigen_write_method(ctx, "_PPC", 0);
 493        acpigen_emit_byte(ctx, RETURN_OP);
 494        acpigen_write_byte(ctx, num_pstates);
 495        acpigen_pop_len(ctx);
 496}
 497
 498/*
 499 * Generates a func with max supported P-states saved
 500 * in the variable PPCM.
 501 */
 502void acpigen_write_ppc_nvs(struct acpi_ctx *ctx)
 503{
 504        /*
 505         * Method (_PPC, 0, NotSerialized)
 506         * {
 507         *      Return (PPCM)
 508         * }
 509         */
 510        acpigen_write_method(ctx, "_PPC", 0);
 511        acpigen_emit_byte(ctx, RETURN_OP);
 512        acpigen_emit_namestring(ctx, "PPCM");
 513        acpigen_pop_len(ctx);
 514}
 515
 516void acpigen_write_tpc(struct acpi_ctx *ctx, const char *gnvs_tpc_limit)
 517{
 518        /*
 519         * // Sample _TPC method
 520         * Method (_TPC, 0, NotSerialized)
 521         * {
 522         *      Return (\TLVL)
 523         * }
 524         */
 525        acpigen_write_method(ctx, "_TPC", 0);
 526        acpigen_emit_byte(ctx, RETURN_OP);
 527        acpigen_emit_namestring(ctx, gnvs_tpc_limit);
 528        acpigen_pop_len(ctx);
 529}
 530
 531void acpigen_write_prw(struct acpi_ctx *ctx, uint wake, uint level)
 532{
 533        /* Name (_PRW, Package () { wake, level } */
 534        acpigen_write_name(ctx, "_PRW");
 535        acpigen_write_package(ctx, 2);
 536        acpigen_write_integer(ctx, wake);
 537        acpigen_write_integer(ctx, level);
 538        acpigen_pop_len(ctx);
 539}
 540
 541void acpigen_write_pss_package(struct acpi_ctx *ctx, u32 core_freq, u32 power,
 542                               u32 trans_lat, u32 busm_lat, u32 control,
 543                               u32 status)
 544{
 545        acpigen_write_package(ctx, 6);
 546        acpigen_write_dword(ctx, core_freq);
 547        acpigen_write_dword(ctx, power);
 548        acpigen_write_dword(ctx, trans_lat);
 549        acpigen_write_dword(ctx, busm_lat);
 550        acpigen_write_dword(ctx, control);
 551        acpigen_write_dword(ctx, status);
 552        acpigen_pop_len(ctx);
 553
 554        log_debug("PSS: %uMHz power %u control 0x%x status 0x%x\n",
 555                  core_freq, power, control, status);
 556}
 557
 558void acpigen_write_psd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
 559                               enum psd_coord coordtype)
 560{
 561        acpigen_write_name(ctx, "_PSD");
 562        acpigen_write_package(ctx, 1);
 563        acpigen_write_package(ctx, 5);
 564        acpigen_write_byte(ctx, 5);     // 5 values
 565        acpigen_write_byte(ctx, 0);     // revision 0
 566        acpigen_write_dword(ctx, domain);
 567        acpigen_write_dword(ctx, coordtype);
 568        acpigen_write_dword(ctx, numprocs);
 569        acpigen_pop_len(ctx);
 570        acpigen_pop_len(ctx);
 571}
 572
 573static void acpigen_write_cst_package_entry(struct acpi_ctx *ctx,
 574                                            const struct acpi_cstate *cstate)
 575{
 576        acpigen_write_package(ctx, 4);
 577        acpigen_write_register_resource(ctx, &cstate->resource);
 578        acpigen_write_dword(ctx, cstate->ctype);
 579        acpigen_write_dword(ctx, cstate->latency);
 580        acpigen_write_dword(ctx, cstate->power);
 581        acpigen_pop_len(ctx);
 582}
 583
 584void acpigen_write_cst_package(struct acpi_ctx *ctx,
 585                               const struct acpi_cstate *cstate, int nentries)
 586{
 587        int i;
 588
 589        acpigen_write_name(ctx, "_CST");
 590        acpigen_write_package(ctx, nentries + 1);
 591        acpigen_write_dword(ctx, nentries);
 592
 593        for (i = 0; i < nentries; i++)
 594                acpigen_write_cst_package_entry(ctx, cstate + i);
 595
 596        acpigen_pop_len(ctx);
 597}
 598
 599void acpigen_write_csd_package(struct acpi_ctx *ctx, uint domain, uint numprocs,
 600                               enum csd_coord coordtype, uint index)
 601{
 602        acpigen_write_name(ctx, "_CSD");
 603        acpigen_write_package(ctx, 1);
 604        acpigen_write_package(ctx, 6);
 605        acpigen_write_byte(ctx, 6);     // 6 values
 606        acpigen_write_byte(ctx, 0);     // revision 0
 607        acpigen_write_dword(ctx, domain);
 608        acpigen_write_dword(ctx, coordtype);
 609        acpigen_write_dword(ctx, numprocs);
 610        acpigen_write_dword(ctx, index);
 611        acpigen_pop_len(ctx);
 612        acpigen_pop_len(ctx);
 613}
 614
 615void acpigen_write_tss_package(struct acpi_ctx *ctx,
 616                               struct acpi_tstate *entry, int nentries)
 617{
 618        /*
 619         * Sample _TSS package with 100% and 50% duty cycles
 620         * Name (_TSS, Package (0x02)
 621         * {
 622         *      Package(){100, 1000, 0, 0x00, 0)
 623         *      Package(){50, 520, 0, 0x18, 0)
 624         * })
 625         */
 626        struct acpi_tstate *tstate = entry;
 627        int i;
 628
 629        acpigen_write_name(ctx, "_TSS");
 630        acpigen_write_package(ctx, nentries);
 631
 632        for (i = 0; i < nentries; i++) {
 633                acpigen_write_package(ctx, 5);
 634                acpigen_write_dword(ctx, tstate->percent);
 635                acpigen_write_dword(ctx, tstate->power);
 636                acpigen_write_dword(ctx, tstate->latency);
 637                acpigen_write_dword(ctx, tstate->control);
 638                acpigen_write_dword(ctx, tstate->status);
 639                acpigen_pop_len(ctx);
 640                tstate++;
 641        }
 642
 643        acpigen_pop_len(ctx);
 644}
 645
 646void acpigen_write_tsd_package(struct acpi_ctx *ctx, u32 domain, u32 numprocs,
 647                               enum psd_coord coordtype)
 648{
 649        acpigen_write_name(ctx, "_TSD");
 650        acpigen_write_package(ctx, 1);
 651        acpigen_write_package(ctx, 5);
 652        acpigen_write_byte(ctx, 5);     // 5 values
 653        acpigen_write_byte(ctx, 0);     // revision 0
 654        acpigen_write_dword(ctx, domain);
 655        acpigen_write_dword(ctx, coordtype);
 656        acpigen_write_dword(ctx, numprocs);
 657        acpigen_pop_len(ctx);
 658        acpigen_pop_len(ctx);
 659}
 660
 661/*
 662 * ToUUID(uuid)
 663 *
 664 * ACPI 6.3 Section 19.6.142 table 19-438 defines a special output order for the
 665 * bytes that make up a UUID Buffer object:
 666 *
 667 * UUID byte order for input to this function:
 668 *   aabbccdd-eeff-gghh-iijj-kkllmmnnoopp
 669 *
 670 * UUID byte order output by this function:
 671 *   ddccbbaa-ffee-hhgg-iijj-kkllmmnnoopp
 672 */
 673int acpigen_write_uuid(struct acpi_ctx *ctx, const char *uuid)
 674{
 675        u8 buf[UUID_BIN_LEN];
 676        int ret;
 677
 678        /* Parse UUID string into bytes */
 679        ret = uuid_str_to_bin(uuid, buf, UUID_STR_FORMAT_GUID);
 680        if (ret)
 681                return log_msg_ret("bad hex", -EINVAL);
 682
 683        /* BufferOp */
 684        acpigen_emit_byte(ctx, BUFFER_OP);
 685        acpigen_write_len_f(ctx);
 686
 687        /* Buffer length in bytes */
 688        acpigen_write_word(ctx, UUID_BIN_LEN);
 689
 690        /* Output UUID in expected order */
 691        acpigen_emit_stream(ctx, (char *)buf, UUID_BIN_LEN);
 692
 693        acpigen_pop_len(ctx);
 694
 695        return 0;
 696}
 697
 698void acpigen_write_power_res(struct acpi_ctx *ctx, const char *name, uint level,
 699                             uint order, const char *const dev_states[],
 700                             size_t dev_states_count)
 701{
 702        size_t i;
 703
 704        for (i = 0; i < dev_states_count; i++) {
 705                acpigen_write_name(ctx, dev_states[i]);
 706                acpigen_write_package(ctx, 1);
 707                acpigen_emit_simple_namestring(ctx, name);
 708                acpigen_pop_len(ctx);           /* Package */
 709        }
 710
 711        acpigen_emit_ext_op(ctx, POWER_RES_OP);
 712
 713        acpigen_write_len_f(ctx);
 714
 715        acpigen_emit_simple_namestring(ctx, name);
 716        acpigen_emit_byte(ctx, level);
 717        acpigen_emit_word(ctx, order);
 718}
 719
 720/* Sleep (ms) */
 721void acpigen_write_sleep(struct acpi_ctx *ctx, u64 sleep_ms)
 722{
 723        acpigen_emit_ext_op(ctx, SLEEP_OP);
 724        acpigen_write_integer(ctx, sleep_ms);
 725}
 726
 727void acpigen_write_store(struct acpi_ctx *ctx)
 728{
 729        acpigen_emit_byte(ctx, STORE_OP);
 730}
 731
 732/* Or (arg1, arg2, res) */
 733void acpigen_write_or(struct acpi_ctx *ctx, u8 arg1, u8 arg2, u8 res)
 734{
 735        acpigen_emit_byte(ctx, OR_OP);
 736        acpigen_emit_byte(ctx, arg1);
 737        acpigen_emit_byte(ctx, arg2);
 738        acpigen_emit_byte(ctx, res);
 739}
 740
 741/* And (arg1, arg2, res) */
 742void acpigen_write_and(struct acpi_ctx *ctx, u8 arg1, u8 arg2, u8 res)
 743{
 744        acpigen_emit_byte(ctx, AND_OP);
 745        acpigen_emit_byte(ctx, arg1);
 746        acpigen_emit_byte(ctx, arg2);
 747        acpigen_emit_byte(ctx, res);
 748}
 749
 750/* Not (arg, res) */
 751void acpigen_write_not(struct acpi_ctx *ctx, u8 arg, u8 res)
 752{
 753        acpigen_emit_byte(ctx, NOT_OP);
 754        acpigen_emit_byte(ctx, arg);
 755        acpigen_emit_byte(ctx, res);
 756}
 757
 758/* Store (str, DEBUG) */
 759void acpigen_write_debug_string(struct acpi_ctx *ctx, const char *str)
 760{
 761        acpigen_write_store(ctx);
 762        acpigen_write_string(ctx, str);
 763        acpigen_emit_ext_op(ctx, DEBUG_OP);
 764}
 765
 766void acpigen_write_if(struct acpi_ctx *ctx)
 767{
 768        acpigen_emit_byte(ctx, IF_OP);
 769        acpigen_write_len_f(ctx);
 770}
 771
 772void acpigen_write_if_lequal_op_int(struct acpi_ctx *ctx, uint op, u64 val)
 773{
 774        acpigen_write_if(ctx);
 775        acpigen_emit_byte(ctx, LEQUAL_OP);
 776        acpigen_emit_byte(ctx, op);
 777        acpigen_write_integer(ctx, val);
 778}
 779
 780void acpigen_write_else(struct acpi_ctx *ctx)
 781{
 782        acpigen_emit_byte(ctx, ELSE_OP);
 783        acpigen_write_len_f(ctx);
 784}
 785
 786void acpigen_write_to_buffer(struct acpi_ctx *ctx, uint src, uint dst)
 787{
 788        acpigen_emit_byte(ctx, TO_BUFFER_OP);
 789        acpigen_emit_byte(ctx, src);
 790        acpigen_emit_byte(ctx, dst);
 791}
 792
 793void acpigen_write_to_integer(struct acpi_ctx *ctx, uint src, uint dst)
 794{
 795        acpigen_emit_byte(ctx, TO_INTEGER_OP);
 796        acpigen_emit_byte(ctx, src);
 797        acpigen_emit_byte(ctx, dst);
 798}
 799
 800void acpigen_write_byte_buffer(struct acpi_ctx *ctx, u8 *arr, size_t size)
 801{
 802        size_t i;
 803
 804        acpigen_emit_byte(ctx, BUFFER_OP);
 805        acpigen_write_len_f(ctx);
 806        acpigen_write_integer(ctx, size);
 807
 808        for (i = 0; i < size; i++)
 809                acpigen_emit_byte(ctx, arr[i]);
 810
 811        acpigen_pop_len(ctx);
 812}
 813
 814void acpigen_write_return_byte_buffer(struct acpi_ctx *ctx, u8 *arr,
 815                                      size_t size)
 816{
 817        acpigen_emit_byte(ctx, RETURN_OP);
 818        acpigen_write_byte_buffer(ctx, arr, size);
 819}
 820
 821void acpigen_write_return_singleton_buffer(struct acpi_ctx *ctx, uint arg)
 822{
 823        u8 buf = arg;
 824
 825        acpigen_write_return_byte_buffer(ctx, &buf, 1);
 826}
 827
 828void acpigen_write_return_byte(struct acpi_ctx *ctx, uint arg)
 829{
 830        acpigen_emit_byte(ctx, RETURN_OP);
 831        acpigen_write_byte(ctx, arg);
 832}
 833
 834void acpigen_write_dsm_start(struct acpi_ctx *ctx)
 835{
 836        /* Method (_DSM, 4, Serialized) */
 837        acpigen_write_method_serialized(ctx, "_DSM", 4);
 838
 839        /* ToBuffer (Arg0, Local0) */
 840        acpigen_write_to_buffer(ctx, ARG0_OP, LOCAL0_OP);
 841}
 842
 843int acpigen_write_dsm_uuid_start(struct acpi_ctx *ctx, const char *uuid)
 844{
 845        int ret;
 846
 847        /* If (LEqual (Local0, ToUUID(uuid))) */
 848        acpigen_write_if(ctx);
 849        acpigen_emit_byte(ctx, LEQUAL_OP);
 850        acpigen_emit_byte(ctx, LOCAL0_OP);
 851        ret = acpigen_write_uuid(ctx, uuid);
 852        if (ret)
 853                return log_msg_ret("uuid", ret);
 854
 855        /* ToInteger (Arg2, Local1) */
 856        acpigen_write_to_integer(ctx, ARG2_OP, LOCAL1_OP);
 857
 858        return 0;
 859}
 860
 861void acpigen_write_dsm_uuid_start_cond(struct acpi_ctx *ctx, int seq)
 862{
 863        /* If (LEqual (Local1, i)) */
 864        acpigen_write_if_lequal_op_int(ctx, LOCAL1_OP, seq);
 865}
 866
 867void acpigen_write_dsm_uuid_end_cond(struct acpi_ctx *ctx)
 868{
 869        acpigen_pop_len(ctx);   /* If */
 870}
 871
 872void acpigen_write_dsm_uuid_end(struct acpi_ctx *ctx)
 873{
 874        /* Default case: Return (Buffer (One) { 0x0 }) */
 875        acpigen_write_return_singleton_buffer(ctx, 0x0);
 876
 877        acpigen_pop_len(ctx);   /* If (LEqual (Local0, ToUUID(uuid))) */
 878}
 879
 880void acpigen_write_dsm_end(struct acpi_ctx *ctx)
 881{
 882        /* Return (Buffer (One) { 0x0 }) */
 883        acpigen_write_return_singleton_buffer(ctx, 0x0);
 884
 885        acpigen_pop_len(ctx);   /* Method _DSM */
 886}
 887
 888/**
 889 * acpigen_get_dw0_in_local5() - Generate code to put dw0 cfg0 in local5
 890 *
 891 * Store (\_SB.GPC0 (addr), Local5)
 892 *
 893 * \_SB.GPC0 is used to read cfg0 value from dw0. It is typically defined in
 894 * the board's gpiolib.asl
 895 *
 896 * The value needs to be stored in a local variable so that it can be used in
 897 * expressions in the ACPI code.
 898 *
 899 * @ctx: ACPI context pointer
 900 * @dw0_read: Name to use to read dw0, e.g. "\\_SB.GPC0"
 901 * @addr: GPIO pin configuration register address
 902 *
 903 */
 904static void acpigen_get_dw0_in_local5(struct acpi_ctx *ctx,
 905                                      const char *dw0_read, ulong addr)
 906{
 907        acpigen_write_store(ctx);
 908        acpigen_emit_namestring(ctx, dw0_read);
 909        acpigen_write_integer(ctx, addr);
 910        acpigen_emit_byte(ctx, LOCAL5_OP);
 911}
 912
 913/**
 914 * acpigen_set_gpio_val() - Emit code to set value of TX GPIO to on/off
 915 *
 916 * @ctx: ACPI context pointer
 917 * @dw0_read: Method name to use to read dw0, e.g. "\\_SB.GPC0"
 918 * @dw0_write: Method name to use to read dw0, e.g. "\\_SB.SPC0"
 919 * @gpio_num: GPIO number to adjust
 920 * @vaL: true to set on, false to set off
 921 */
 922static int acpigen_set_gpio_val(struct acpi_ctx *ctx, u32 tx_state_val,
 923                                const char *dw0_read, const char *dw0_write,
 924                                struct acpi_gpio *gpio, bool val)
 925{
 926        acpigen_get_dw0_in_local5(ctx, dw0_read, gpio->pin0_addr);
 927
 928        /* Store (0x40, Local0) */
 929        acpigen_write_store(ctx);
 930        acpigen_write_integer(ctx, tx_state_val);
 931        acpigen_emit_byte(ctx, LOCAL0_OP);
 932
 933        if (val) {
 934                /* Or (Local5, PAD_CFG0_TX_STATE, Local5) */
 935                acpigen_write_or(ctx, LOCAL5_OP, LOCAL0_OP, LOCAL5_OP);
 936        } else {
 937                /* Not (PAD_CFG0_TX_STATE, Local6) */
 938                acpigen_write_not(ctx, LOCAL0_OP, LOCAL6_OP);
 939
 940                /* And (Local5, Local6, Local5) */
 941                acpigen_write_and(ctx, LOCAL5_OP, LOCAL6_OP, LOCAL5_OP);
 942        }
 943
 944        /*
 945         * \_SB.SPC0 (addr, Local5)
 946         * \_SB.SPC0 is used to write cfg0 value in dw0. It is defined in
 947         * gpiolib.asl.
 948         */
 949        acpigen_emit_namestring(ctx, dw0_write);
 950        acpigen_write_integer(ctx, gpio->pin0_addr);
 951        acpigen_emit_byte(ctx, LOCAL5_OP);
 952
 953        return 0;
 954}
 955
 956int acpigen_set_enable_tx_gpio(struct acpi_ctx *ctx, u32 tx_state_val,
 957                               const char *dw0_read, const char *dw0_write,
 958                               struct acpi_gpio *gpio, bool enable)
 959{
 960        bool set;
 961        int ret;
 962
 963        set = gpio->polarity == ACPI_GPIO_ACTIVE_HIGH ? enable : !enable;
 964        ret = acpigen_set_gpio_val(ctx, tx_state_val, dw0_read, dw0_write, gpio,
 965                                   set);
 966        if (ret)
 967                return log_msg_ret("call", ret);
 968
 969        return 0;
 970}
 971