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