// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2019 Google LLC
 * Written by Simon Glass <sjg@chromium.org>
 */
#include <command.h>
#include <display_options.h>
#include <log.h>
#include <mapmem.h>
#include <tables_csum.h>
#include <acpi/acpi_table.h>
#include <asm/acpi_table.h>
#include <asm/global_data.h>
#include <linux/errno.h>
#include <dm/acpi.h>

DECLARE_GLOBAL_DATA_PTR;

static const char *show_checksum(void *ptr, uint size, bool chksums)
{
	uint checksum;

	if (!chksums)
		return "";
	checksum = table_compute_checksum(ptr, size);

	return checksum ? "  bad" : "  OK";
}

/**
 * dump_hdr() - Dump an ACPI header
 *
 * Except for the Firmware ACPI Control Structure (FACS)
 * additionally show the revision information.
 *
 * @hdr: ACPI header to dump
 */
static void dump_hdr(struct acpi_table_header *hdr, bool chksums)
{
	bool has_hdr = memcmp(hdr->signature, "FACS", ACPI_NAME_LEN);

	printf("%.*s  %16lx  %5x", ACPI_NAME_LEN, hdr->signature,
	       (ulong)map_to_sysmem(hdr), hdr->length);
	if (has_hdr) {
		printf("  v%02d %.6s %.8s %x %.4s %x%s\n", hdr->revision,
		       hdr->oem_id, hdr->oem_table_id, hdr->oem_revision,
		       hdr->creator_id, hdr->creator_revision,
		       show_checksum(hdr, hdr->length, chksums));
	} else {
		printf("\n");
	}
}

static int dump_table_name(const char *sig)
{
	struct acpi_table_header *hdr;

	hdr = acpi_find_table(sig);
	if (!hdr)
		return -ENOENT;
	printf("%.*s @ %16lx\n", ACPI_NAME_LEN, hdr->signature,
	       (ulong)nomap_to_sysmem(hdr));
	print_buffer(0, hdr, 1, hdr->length, 0);

	return 0;
}

static void list_fadt(struct acpi_fadt *fadt, bool chksums)
{
	if (fadt->header.revision >= 3 && fadt->x_dsdt)
		dump_hdr(nomap_sysmem(fadt->x_dsdt, 0), chksums);
	else if (fadt->dsdt)
		dump_hdr(nomap_sysmem(fadt->dsdt, 0), chksums);
	if (!IS_ENABLED(CONFIG_X86) && !IS_ENABLED(CONFIG_SANDBOX) &&
	    !(fadt->flags & ACPI_FADT_HW_REDUCED_ACPI))
		log_err("FADT not ACPI-hardware-reduced-compliant\n");
	if (fadt->header.revision >= 3 && fadt->x_firmware_ctrl)
		dump_hdr(nomap_sysmem(fadt->x_firmware_ctrl, 0), chksums);
	else if (fadt->firmware_ctrl)
		dump_hdr(nomap_sysmem(fadt->firmware_ctrl, 0), chksums);
}

static void list_rsdt(struct acpi_rsdp *rsdp, bool chksums)
{
	int len, i, count;
	struct acpi_rsdt *rsdt;
	struct acpi_xsdt *xsdt;

	if (rsdp->rsdt_address) {
		rsdt = nomap_sysmem(rsdp->rsdt_address, 0);
		dump_hdr(&rsdt->header, chksums);
	}
	if (rsdp->xsdt_address) {
		xsdt = nomap_sysmem(rsdp->xsdt_address, 0);
		dump_hdr(&xsdt->header, chksums);
		len = xsdt->header.length - sizeof(xsdt->header);
		count = len / sizeof(u64);
	} else if (rsdp->rsdt_address) {
		len = rsdt->header.length - sizeof(rsdt->header);
		count = len / sizeof(u32);
	} else {
		return;
	}

	for (i = 0; i < count; i++) {
		struct acpi_table_header *hdr;
		u64 entry;

		if (rsdp->xsdt_address)
			entry = xsdt->entry[i];
		else
			entry = rsdt->entry[i];
		if (!entry)
			break;
		hdr = nomap_sysmem(entry, 0);
		dump_hdr(hdr, chksums);
		if (!memcmp(hdr->signature, "FACP", ACPI_NAME_LEN))
			list_fadt((struct acpi_fadt *)hdr, chksums);
	}
}

static void list_rsdp(struct acpi_rsdp *rsdp, bool chksums)
{
	printf("RSDP  %16lx  %5x  v%02d %.6s%s%s\n",
	       (ulong)map_to_sysmem(rsdp), rsdp->length, rsdp->revision,
	       rsdp->oem_id, show_checksum(rsdp, 0x14, chksums),
	       show_checksum(rsdp, rsdp->length, chksums));
	list_rsdt(rsdp, chksums);
}

static int do_acpi_list(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	struct acpi_rsdp *rsdp;
	bool chksums;

	chksums = argc >= 2 && !strcmp("-c", argv[1]);
	rsdp = map_sysmem(gd_acpi_start(), 0);
	if (!rsdp) {
		printf("No ACPI tables present\n");
		return 0;
	}
	printf("Name              Base   Size  Detail\n"
	       "----  ----------------  -----  ----------------------------\n");
	list_rsdp(rsdp, chksums);

	return 0;
}

static int do_acpi_set(struct cmd_tbl *cmdtp, int flag, int argc,
		       char *const argv[])
{
	ulong val;

	if (argc < 2) {
		printf("ACPI pointer: %lx\n", gd_acpi_start());
	} else {
		val = hextoul(argv[1], NULL);
		printf("Setting ACPI pointer to %lx\n", val);
		gd_set_acpi_start(val);
	}

	return 0;
}

static int do_acpi_items(struct cmd_tbl *cmdtp, int flag, int argc,
			 char *const argv[])
{
	bool dump_contents;

	dump_contents = argc >= 2 && !strcmp("-d", argv[1]);
	if (!IS_ENABLED(CONFIG_ACPIGEN)) {
		printf("Not supported (enable ACPIGEN)\n");
		return CMD_RET_FAILURE;
	}
	acpi_dump_items(dump_contents ? ACPI_DUMP_CONTENTS : ACPI_DUMP_LIST);

	return 0;
}

static int do_acpi_dump(struct cmd_tbl *cmdtp, int flag, int argc,
			char *const argv[])
{
	const char *name;
	char sig[ACPI_NAME_LEN];
	int ret;

	if (argc < 2)
		return CMD_RET_USAGE;

	name = argv[1];
	if (strlen(name) != ACPI_NAME_LEN) {
		printf("Table name '%s' must be four characters\n", name);
		return CMD_RET_FAILURE;
	}
	str_to_upper(name, sig, ACPI_NAME_LEN);
	ret = dump_table_name(sig);
	if (ret) {
		printf("Table '%.*s' not found\n", ACPI_NAME_LEN, sig);
		return CMD_RET_FAILURE;
	}

	return 0;
}

U_BOOT_LONGHELP(acpi,
	"list [-c] - list ACPI tables [check checksums]\n"
	"acpi items [-d]   - List/dump each piece of ACPI data from devices\n"
	"acpi set [<addr>] - Set or show address of ACPI tables\n"
	"acpi dump <name>  - Dump ACPI table");

U_BOOT_CMD_WITH_SUBCMDS(acpi, "ACPI tables", acpi_help_text,
	U_BOOT_SUBCMD_MKENT(list, 2, 1, do_acpi_list),
	U_BOOT_SUBCMD_MKENT(items, 2, 1, do_acpi_items),
	U_BOOT_SUBCMD_MKENT(set, 2, 1, do_acpi_set),
	U_BOOT_SUBCMD_MKENT(dump, 2, 1, do_acpi_dump));
