// SPDX-License-Identifier: GPL-2.0+
/*
 * Handles writing the declared ACPI tables
 *
 * Copyright 2021 Google LLC
 */

#define LOG_CATEGORY LOGC_ACPI

#include <common.h>
#include <log.h>
#include <malloc.h>
#include <mapmem.h>
#include <acpi/acpi_table.h>
#include <asm/global_data.h>
#include <dm/acpi.h>

DECLARE_GLOBAL_DATA_PTR;

int acpi_write_one(struct acpi_ctx *ctx, const struct acpi_writer *entry)
{
	int ret;

	log_debug("%s: writing table '%s'\n", entry->name,
		  entry->table);
	ctx->tab_start = ctx->current;
	ret = entry->h_write(ctx, entry);
	if (ret == -ENOENT) {
		log_debug("%s: Omitted due to being empty\n",
			  entry->name);
		ret = 0;
		ctx->current = ctx->tab_start;	/* drop the table */
		return ret;
	}
	if (ret)
		return log_msg_ret("write", ret);

	if (entry->flags & ACPIWF_ALIGN64)
		acpi_align64(ctx);
	else
		acpi_align(ctx);

	return 0;
}

#ifndef CONFIG_QEMU
static int acpi_write_all(struct acpi_ctx *ctx)
{
	const struct acpi_writer *writer =
		 ll_entry_start(struct acpi_writer, acpi_writer);
	const int n_ents = ll_entry_count(struct acpi_writer, acpi_writer);
	const struct acpi_writer *entry;
	int ret;

	for (entry = writer; entry != writer + n_ents; entry++) {
		ret = acpi_write_one(ctx, entry);
		if (ret && ret != -ENOENT)
			return log_msg_ret("one", ret);
	}

	return 0;
}

/*
 * QEMU's version of write_acpi_tables is defined in drivers/misc/qfw.c
 */
ulong write_acpi_tables(ulong start_addr)
{
	struct acpi_ctx *ctx;
	ulong addr;
	int ret;

	ctx = malloc(sizeof(*ctx));
	if (!ctx)
		return log_msg_ret("mem", -ENOMEM);

	log_debug("ACPI: Writing ACPI tables at %lx\n", start_addr);

	acpi_reset_items();
	acpi_setup_ctx(ctx, start_addr);

	ret = acpi_write_all(ctx);
	if (ret) {
		log_err("Failed to write ACPI tables (err=%d)\n", ret);
		return log_msg_ret("write", -ENOMEM);
	}

	addr = map_to_sysmem(ctx->current);
	log_debug("ACPI current = %lx\n", addr);

	return addr;
}

int write_dev_tables(struct acpi_ctx *ctx, const struct acpi_writer *entry)
{
	int ret;

	ret = acpi_write_dev_tables(ctx);
	if (ret)
		return log_msg_ret("write", ret);

	return 0;
}
ACPI_WRITER(8dev, NULL, write_dev_tables, 0);

ulong acpi_get_rsdp_addr(void)
{
	if (!gd->acpi_ctx)
		return 0;

	return map_to_sysmem(gd->acpi_ctx->rsdp);
}
#endif /* QEMU */

void acpi_setup_ctx(struct acpi_ctx *ctx, ulong start)
{
	gd->acpi_ctx = ctx;
	memset(ctx, '\0', sizeof(*ctx));

	/* Align ACPI tables to 16-byte boundary */
	start = ALIGN(start, 16);
	ctx->base = map_sysmem(start, 0);
	ctx->current = ctx->base;

	gd_set_acpi_start(start);
}
