blob: 11fc38419af9bda0a206cde06302310c02637fef [file] [log] [blame]
Simon Glass98528d42020-07-07 13:11:42 -06001// 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>
Simon Glass0f277632020-07-07 13:11:50 -060013#include <log.h>
Simon Glass98528d42020-07-07 13:11:42 -060014#include <acpi/acpigen.h>
15#include <dm/acpi.h>
16
17u8 *acpigen_get_current(struct acpi_ctx *ctx)
18{
19 return ctx->current;
20}
21
22void acpigen_emit_byte(struct acpi_ctx *ctx, uint data)
23{
24 *(u8 *)ctx->current++ = data;
25}
26
27void acpigen_emit_word(struct acpi_ctx *ctx, uint data)
28{
29 acpigen_emit_byte(ctx, data & 0xff);
30 acpigen_emit_byte(ctx, (data >> 8) & 0xff);
31}
32
33void acpigen_emit_dword(struct acpi_ctx *ctx, uint data)
34{
35 /* Output the value in little-endian format */
36 acpigen_emit_byte(ctx, data & 0xff);
37 acpigen_emit_byte(ctx, (data >> 8) & 0xff);
38 acpigen_emit_byte(ctx, (data >> 16) & 0xff);
39 acpigen_emit_byte(ctx, (data >> 24) & 0xff);
40}
Simon Glass071c4a52020-07-07 13:11:45 -060041
Simon Glass0f277632020-07-07 13:11:50 -060042/*
43 * Maximum length for an ACPI object generated by this code,
44 *
45 * If you need to change this, change acpigen_write_len_f(ctx) and
46 * acpigen_pop_len(ctx)
47 */
48#define ACPIGEN_MAXLEN 0xfffff
49
50void acpigen_write_len_f(struct acpi_ctx *ctx)
51{
52 assert(ctx->ltop < (ACPIGEN_LENSTACK_SIZE - 1));
53 ctx->len_stack[ctx->ltop++] = ctx->current;
54 acpigen_emit_byte(ctx, 0);
55 acpigen_emit_byte(ctx, 0);
56 acpigen_emit_byte(ctx, 0);
57}
58
59void acpigen_pop_len(struct acpi_ctx *ctx)
60{
61 int len;
62 char *p;
63
64 assert(ctx->ltop > 0);
65 p = ctx->len_stack[--ctx->ltop];
66 len = ctx->current - (void *)p;
67 assert(len <= ACPIGEN_MAXLEN);
68 /* generate store length for 0xfffff max */
69 p[0] = ACPI_PKG_LEN_3_BYTES | (len & 0xf);
70 p[1] = len >> 4 & 0xff;
71 p[2] = len >> 12 & 0xff;
72}
73
Simon Glass071c4a52020-07-07 13:11:45 -060074void acpigen_emit_stream(struct acpi_ctx *ctx, const char *data, int size)
75{
76 int i;
77
78 for (i = 0; i < size; i++)
79 acpigen_emit_byte(ctx, data[i]);
80}
81
82void acpigen_emit_string(struct acpi_ctx *ctx, const char *str)
83{
84 acpigen_emit_stream(ctx, str, str ? strlen(str) : 0);
85 acpigen_emit_byte(ctx, '\0');
86}