// SPDX-License-Identifier: GPL-2.0-only
/*
 * Extensible SAL Interface (ESI) support routines.
 *
 * Copyright (C) 2006 Hewlett-Packard Co
 * 	Alex Williamson <alex.williamson@hp.com>
 */
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/module.h>
#include <linux/string.h>

#include <asm/esi.h>
#include <asm/sal.h>

MODULE_AUTHOR("Alex Williamson <alex.williamson@hp.com>");
MODULE_DESCRIPTION("Extensible SAL Interface (ESI) support");
MODULE_LICENSE("GPL");

#define MODULE_NAME	"esi"

#define ESI_TABLE_GUID					\
    EFI_GUID(0x43EA58DC, 0xCF28, 0x4b06, 0xB3,		\
	     0x91, 0xB7, 0x50, 0x59, 0x34, 0x2B, 0xD4)

enum esi_systab_entry_type {
	ESI_DESC_ENTRY_POINT = 0
};

/*
 * Entry type:	Size:
 *	0	48
 */
#define ESI_DESC_SIZE(type)	"\060"[(unsigned) (type)]

typedef struct ia64_esi_desc_entry_point {
	u8 type;
	u8 reserved1[15];
	u64 esi_proc;
	u64 gp;
	efi_guid_t guid;
} ia64_esi_desc_entry_point_t;

struct pdesc {
	void *addr;
	void *gp;
};

static struct ia64_sal_systab *esi_systab;

static int __init esi_init (void)
{
	efi_config_table_t *config_tables;
	struct ia64_sal_systab *systab;
	unsigned long esi = 0;
	char *p;
	int i;

	config_tables = __va(efi.systab->tables);

	for (i = 0; i < (int) efi.systab->nr_tables; ++i) {
		if (efi_guidcmp(config_tables[i].guid, ESI_TABLE_GUID) == 0) {
			esi = config_tables[i].table;
			break;
		}
	}

	if (!esi)
		return -ENODEV;

	systab = __va(esi);

	if (strncmp(systab->signature, "ESIT", 4) != 0) {
		printk(KERN_ERR "bad signature in ESI system table!");
		return -ENODEV;
	}

	p = (char *) (systab + 1);
	for (i = 0; i < systab->entry_count; i++) {
		/*
		 * The first byte of each entry type contains the type
		 * descriptor.
		 */
		switch (*p) {
		      case ESI_DESC_ENTRY_POINT:
			break;
		      default:
			printk(KERN_WARNING "Unknown table type %d found in "
			       "ESI table, ignoring rest of table\n", *p);
			return -ENODEV;
		}

		p += ESI_DESC_SIZE(*p);
	}

	esi_systab = systab;
	return 0;
}


int ia64_esi_call (efi_guid_t guid, struct ia64_sal_retval *isrvp,
		   enum esi_proc_type proc_type, u64 func,
		   u64 arg1, u64 arg2, u64 arg3, u64 arg4, u64 arg5, u64 arg6,
		   u64 arg7)
{
	struct ia64_fpreg fr[6];
	unsigned long flags = 0;
	int i;
	char *p;

	if (!esi_systab)
		return -1;

	p = (char *) (esi_systab + 1);
	for (i = 0; i < esi_systab->entry_count; i++) {
		if (*p == ESI_DESC_ENTRY_POINT) {
			ia64_esi_desc_entry_point_t *esi = (void *)p;
			if (!efi_guidcmp(guid, esi->guid)) {
				ia64_sal_handler esi_proc;
				struct pdesc pdesc;

				pdesc.addr = __va(esi->esi_proc);
				pdesc.gp = __va(esi->gp);

				esi_proc = (ia64_sal_handler) &pdesc;

				ia64_save_scratch_fpregs(fr);
				if (proc_type == ESI_PROC_SERIALIZED)
					spin_lock_irqsave(&sal_lock, flags);
				else if (proc_type == ESI_PROC_MP_SAFE)
					local_irq_save(flags);
				else
					preempt_disable();
				*isrvp = (*esi_proc)(func, arg1, arg2, arg3,
						     arg4, arg5, arg6, arg7);
				if (proc_type == ESI_PROC_SERIALIZED)
					spin_unlock_irqrestore(&sal_lock,
							       flags);
				else if (proc_type == ESI_PROC_MP_SAFE)
					local_irq_restore(flags);
				else
					preempt_enable();
				ia64_load_scratch_fpregs(fr);
				return 0;
			}
		}
		p += ESI_DESC_SIZE(*p);
	}
	return -1;
}
EXPORT_SYMBOL_GPL(ia64_esi_call);

int ia64_esi_call_phys (efi_guid_t guid, struct ia64_sal_retval *isrvp,
			u64 func, u64 arg1, u64 arg2, u64 arg3, u64 arg4,
			u64 arg5, u64 arg6, u64 arg7)
{
	struct ia64_fpreg fr[6];
	unsigned long flags;
	u64 esi_params[8];
	char *p;
	int i;

	if (!esi_systab)
		return -1;

	p = (char *) (esi_systab + 1);
	for (i = 0; i < esi_systab->entry_count; i++) {
		if (*p == ESI_DESC_ENTRY_POINT) {
			ia64_esi_desc_entry_point_t *esi = (void *)p;
			if (!efi_guidcmp(guid, esi->guid)) {
				ia64_sal_handler esi_proc;
				struct pdesc pdesc;

				pdesc.addr = (void *)esi->esi_proc;
				pdesc.gp = (void *)esi->gp;

				esi_proc = (ia64_sal_handler) &pdesc;

				esi_params[0] = func;
				esi_params[1] = arg1;
				esi_params[2] = arg2;
				esi_params[3] = arg3;
				esi_params[4] = arg4;
				esi_params[5] = arg5;
				esi_params[6] = arg6;
				esi_params[7] = arg7;
				ia64_save_scratch_fpregs(fr);
				spin_lock_irqsave(&sal_lock, flags);
				*isrvp = esi_call_phys(esi_proc, esi_params);
				spin_unlock_irqrestore(&sal_lock, flags);
				ia64_load_scratch_fpregs(fr);
				return 0;
			}
		}
		p += ESI_DESC_SIZE(*p);
	}
	return -1;
}
EXPORT_SYMBOL_GPL(ia64_esi_call_phys);

static void __exit esi_exit (void)
{
}

module_init(esi_init);
module_exit(esi_exit);	/* makes module removable... */
