Coverage Report

Created: 2026-03-11 06:21

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