// SPDX-License-Identifier: GPL-2.0-only
/*
 * OpRegion handler to allow AML to call native firmware
 *
 * (c) Copyright 2007 Hewlett-Packard Development Company, L.P.
 *	Bjorn Helgaas <bjorn.helgaas@hp.com>
 *
 * This driver implements HP Open Source Review Board proposal 1842,
 * which was approved on 9/20/2006.
 *
 * For technical documentation, see the HP SPPA Firmware EAS, Appendix F.
 *
 * ACPI does not define a mechanism for AML methods to call native firmware
 * interfaces such as PAL or SAL.  This OpRegion handler adds such a mechanism.
 * After the handler is installed, an AML method can call native firmware by
 * storing the arguments and firmware entry point to specific offsets in the
 * OpRegion.  When AML reads the "return value" offset from the OpRegion, this
 * handler loads up the arguments, makes the firmware call, and returns the
 * result.
 */

#include <linux/module.h>
#include <linux/acpi.h>
#include <asm/sal.h>

MODULE_AUTHOR("Bjorn Helgaas <bjorn.helgaas@hp.com>");
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("ACPI opregion handler for native firmware calls");

static bool force_register;
module_param_named(force, force_register, bool, 0);
MODULE_PARM_DESC(force, "Install opregion handler even without HPQ5001 device");

#define AML_NFW_SPACE		0xA1

struct ia64_pdesc {
	void *ip;
	void *gp;
};

/*
 * N.B.  The layout of this structure is defined in the HP SPPA FW EAS, and
 *	 the member offsets are embedded in AML methods.
 */
struct ia64_nfw_context {
	u64 arg[8];
	struct ia64_sal_retval ret;
	u64 ip;
	u64 gp;
	u64 pad[2];
};

static void *virt_map(u64 address)
{
	if (address & (1UL << 63))
		return (void *) (__IA64_UNCACHED_OFFSET | address);

	return __va(address);
}

static void aml_nfw_execute(struct ia64_nfw_context *c)
{
	struct ia64_pdesc virt_entry;
	ia64_sal_handler entry;

	virt_entry.ip = virt_map(c->ip);
	virt_entry.gp = virt_map(c->gp);

	entry = (ia64_sal_handler) &virt_entry;

	IA64_FW_CALL(entry, c->ret,
		     c->arg[0], c->arg[1], c->arg[2], c->arg[3],
		     c->arg[4], c->arg[5], c->arg[6], c->arg[7]);
}

static void aml_nfw_read_arg(u8 *offset, u32 bit_width, u64 *value)
{
	switch (bit_width) {
	case 8:
		*value = *(u8 *)offset;
		break;
	case 16:
		*value = *(u16 *)offset;
		break;
	case 32:
		*value = *(u32 *)offset;
		break;
	case 64:
		*value = *(u64 *)offset;
		break;
	}
}

static void aml_nfw_write_arg(u8 *offset, u32 bit_width, u64 *value)
{
	switch (bit_width) {
	case 8:
		*(u8 *) offset = *value;
		break;
	case 16:
		*(u16 *) offset = *value;
		break;
	case 32:
		*(u32 *) offset = *value;
		break;
	case 64:
		*(u64 *) offset = *value;
		break;
	}
}

static acpi_status aml_nfw_handler(u32 function, acpi_physical_address address,
	u32 bit_width, u64 *value, void *handler_context,
	void *region_context)
{
	struct ia64_nfw_context *context = handler_context;
	u8 *offset = (u8 *) context + address;

	if (bit_width !=  8 && bit_width != 16 &&
	    bit_width != 32 && bit_width != 64)
		return AE_BAD_PARAMETER;

	if (address + (bit_width >> 3) > sizeof(struct ia64_nfw_context))
		return AE_BAD_PARAMETER;

	switch (function) {
	case ACPI_READ:
		if (address == offsetof(struct ia64_nfw_context, ret))
			aml_nfw_execute(context);
		aml_nfw_read_arg(offset, bit_width, value);
		break;
	case ACPI_WRITE:
		aml_nfw_write_arg(offset, bit_width, value);
		break;
	}

	return AE_OK;
}

static struct ia64_nfw_context global_context;
static int global_handler_registered;

static int aml_nfw_add_global_handler(void)
{
	acpi_status status;

	if (global_handler_registered)
		return 0;

	status = acpi_install_address_space_handler(ACPI_ROOT_OBJECT,
		AML_NFW_SPACE, aml_nfw_handler, NULL, &global_context);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	global_handler_registered = 1;
	printk(KERN_INFO "Global 0x%02X opregion handler registered\n",
		AML_NFW_SPACE);
	return 0;
}

static int aml_nfw_remove_global_handler(void)
{
	acpi_status status;

	if (!global_handler_registered)
		return 0;

	status = acpi_remove_address_space_handler(ACPI_ROOT_OBJECT,
		AML_NFW_SPACE, aml_nfw_handler);
	if (ACPI_FAILURE(status))
		return -ENODEV;

	global_handler_registered = 0;
	printk(KERN_INFO "Global 0x%02X opregion handler removed\n",
		AML_NFW_SPACE);
	return 0;
}

static int aml_nfw_add(struct acpi_device *device)
{
	/*
	 * We would normally allocate a new context structure and install
	 * the address space handler for the specific device we found.
	 * But the HP-UX implementation shares a single global context
	 * and always puts the handler at the root, so we'll do the same.
	 */
	return aml_nfw_add_global_handler();
}

static int aml_nfw_remove(struct acpi_device *device)
{
	return aml_nfw_remove_global_handler();
}

static const struct acpi_device_id aml_nfw_ids[] = {
	{"HPQ5001", 0},
	{"", 0}
};

static struct acpi_driver acpi_aml_nfw_driver = {
	.name = "native firmware",
	.ids = aml_nfw_ids,
	.ops = {
		.add = aml_nfw_add,
		.remove = aml_nfw_remove,
		},
};

static int __init aml_nfw_init(void)
{
	int result;

	if (force_register)
		aml_nfw_add_global_handler();

	result = acpi_bus_register_driver(&acpi_aml_nfw_driver);
	if (result < 0) {
		aml_nfw_remove_global_handler();
		return result;
	}

	return 0;
}

static void __exit aml_nfw_exit(void)
{
	acpi_bus_unregister_driver(&acpi_aml_nfw_driver);
	aml_nfw_remove_global_handler();
}

module_init(aml_nfw_init);
module_exit(aml_nfw_exit);
