/*
 * Beat hypervisor call I/F
 *
 * (C) Copyright 2007 TOSHIBA CORPORATION
 *
 * This code is based on arch/powerpc/platforms/pseries/plpar_wrapper.h.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
 */
#ifndef BEAT_HCALL
#include <linux/string.h>
#include "beat_syscall.h"

/* defined in hvCall.S */
extern s64 beat_hcall_norets(u64 opcode, ...);
extern s64 beat_hcall_norets8(u64 opcode, u64 arg1, u64 arg2, u64 arg3,
	u64 arg4, u64 arg5, u64 arg6, u64 arg7, u64 arg8);
extern s64 beat_hcall1(u64 opcode, u64 retbuf[1], ...);
extern s64 beat_hcall2(u64 opcode, u64 retbuf[2], ...);
extern s64 beat_hcall3(u64 opcode, u64 retbuf[3], ...);
extern s64 beat_hcall4(u64 opcode, u64 retbuf[4], ...);
extern s64 beat_hcall5(u64 opcode, u64 retbuf[5], ...);
extern s64 beat_hcall6(u64 opcode, u64 retbuf[6], ...);

static inline s64 beat_downcount_of_interrupt(u64 plug_id)
{
	return beat_hcall_norets(HV_downcount_of_interrupt, plug_id);
}

static inline s64 beat_set_interrupt_mask(u64 index,
	u64 val0, u64 val1, u64 val2, u64 val3)
{
	return beat_hcall_norets(HV_set_interrupt_mask, index,
	       val0, val1, val2, val3);
}

static inline s64 beat_destruct_irq_plug(u64 plug_id)
{
	return beat_hcall_norets(HV_destruct_irq_plug, plug_id);
}

static inline s64 beat_construct_and_connect_irq_plug(u64 plug_id,
	u64 outlet_id)
{
	return beat_hcall_norets(HV_construct_and_connect_irq_plug, plug_id,
	       outlet_id);
}

static inline s64 beat_detect_pending_interrupts(u64 index, u64 *retbuf)
{
	return beat_hcall4(HV_detect_pending_interrupts, retbuf, index);
}

static inline s64 beat_pause(u64 style)
{
	return beat_hcall_norets(HV_pause, style);
}

static inline s64 beat_read_htab_entries(u64 htab_id, u64 index, u64 *retbuf)
{
	return beat_hcall5(HV_read_htab_entries, retbuf, htab_id, index);
}

static inline s64 beat_insert_htab_entry(u64 htab_id, u64 group,
	u64 bitmask, u64 hpte_v, u64 hpte_r, u64 *slot)
{
	u64 dummy[3];
	s64 ret;

	ret = beat_hcall3(HV_insert_htab_entry, dummy, htab_id, group,
		bitmask, hpte_v, hpte_r);
	*slot = dummy[0];
	return ret;
}

static inline s64 beat_write_htab_entry(u64 htab_id, u64 slot,
	u64 hpte_v, u64 hpte_r, u64 mask_v, u64 mask_r,
	u64 *ret_v, u64 *ret_r)
{
	u64 dummy[2];
	s64 ret;

	ret = beat_hcall2(HV_write_htab_entry, dummy, htab_id, slot,
		hpte_v, hpte_r, mask_v, mask_r);
	*ret_v = dummy[0];
	*ret_r = dummy[1];
	return ret;
}

static inline s64 beat_insert_htab_entry3(u64 htab_id, u64 group,
	u64 hpte_v, u64 hpte_r, u64 mask_v, u64 value_v, u64 *slot)
{
	u64 dummy[1];
	s64 ret;

	ret = beat_hcall1(HV_insert_htab_entry3, dummy, htab_id, group,
		hpte_v, hpte_r, mask_v, value_v);
	*slot = dummy[0];
	return ret;
}

static inline s64 beat_invalidate_htab_entry3(u64 htab_id, u64 group,
	u64 va, u64 pss)
{
	return beat_hcall_norets(HV_invalidate_htab_entry3,
		htab_id, group, va, pss);
}

static inline s64 beat_update_htab_permission3(u64 htab_id, u64 group,
	u64 va, u64 pss, u64 ptel_mask, u64 ptel_value)
{
	return beat_hcall_norets(HV_update_htab_permission3,
		htab_id, group, va, pss, ptel_mask, ptel_value);
}

static inline s64 beat_clear_htab3(u64 htab_id)
{
	return beat_hcall_norets(HV_clear_htab3, htab_id);
}

static inline void beat_shutdown_logical_partition(u64 code)
{
	(void)beat_hcall_norets(HV_shutdown_logical_partition, code);
}

static inline s64 beat_rtc_write(u64 time_from_epoch)
{
	return beat_hcall_norets(HV_rtc_write, time_from_epoch);
}

static inline s64 beat_rtc_read(u64 *time_from_epoch)
{
	u64 dummy[1];
	s64 ret;

	ret = beat_hcall1(HV_rtc_read, dummy);
	*time_from_epoch = dummy[0];
	return ret;
}

#define	BEAT_NVRW_CNT	(sizeof(u64) * 6)

static inline s64 beat_eeprom_write(u64 index, u64 length, u8 *buffer)
{
	u64	b[6];

	if (length > BEAT_NVRW_CNT)
		return -1;
	memcpy(b, buffer, sizeof(b));
	return beat_hcall_norets8(HV_eeprom_write, index, length,
		b[0], b[1], b[2], b[3], b[4], b[5]);
}

static inline s64 beat_eeprom_read(u64 index, u64 length, u8 *buffer)
{
	u64	b[6];
	s64	ret;

	if (length > BEAT_NVRW_CNT)
		return -1;
	ret = beat_hcall6(HV_eeprom_read, b, index, length);
	memcpy(buffer, b, length);
	return ret;
}

static inline s64 beat_set_dabr(u64 value, u64 style)
{
	return beat_hcall_norets(HV_set_dabr, value, style);
}

static inline s64 beat_get_characters_from_console(u64 termno, u64 *len,
	u8 *buffer)
{
	u64 dummy[3];
	s64 ret;

	ret = beat_hcall3(HV_get_characters_from_console, dummy, termno, len);
	*len = dummy[0];
	memcpy(buffer, dummy + 1, *len);
	return ret;
}

static inline s64 beat_put_characters_to_console(u64 termno, u64 len,
	u8 *buffer)
{
	u64 b[2];

	memcpy(b, buffer, len);
	return beat_hcall_norets(HV_put_characters_to_console, termno, len,
		b[0], b[1]);
}

static inline s64 beat_get_spe_privileged_state_1_registers(
		u64 id, u64 offsetof, u64 *value)
{
	u64 dummy[1];
	s64 ret;

	ret = beat_hcall1(HV_get_spe_privileged_state_1_registers, dummy, id,
		offsetof);
	*value = dummy[0];
	return ret;
}

static inline s64 beat_set_irq_mask_for_spe(u64 id, u64 class, u64 mask)
{
	return beat_hcall_norets(HV_set_irq_mask_for_spe, id, class, mask);
}

static inline s64 beat_clear_interrupt_status_of_spe(u64 id, u64 class,
	u64 mask)
{
	return beat_hcall_norets(HV_clear_interrupt_status_of_spe,
		id, class, mask);
}

static inline s64 beat_set_spe_privileged_state_1_registers(
		u64 id, u64 offsetof, u64 value)
{
	return beat_hcall_norets(HV_set_spe_privileged_state_1_registers,
		id, offsetof, value);
}

static inline s64 beat_get_interrupt_status_of_spe(u64 id, u64 class, u64 *val)
{
	u64 dummy[1];
	s64 ret;

	ret = beat_hcall1(HV_get_interrupt_status_of_spe, dummy, id, class);
	*val = dummy[0];
	return ret;
}

static inline s64 beat_put_iopte(u64 ioas_id, u64 io_addr, u64 real_addr,
	u64 ioid, u64 flags)
{
	return beat_hcall_norets(HV_put_iopte, ioas_id, io_addr, real_addr,
		ioid, flags);
}

static inline s64 beat_construct_event_receive_port(u64 *port)
{
	u64 dummy[1];
	s64 ret;

	ret = beat_hcall1(HV_construct_event_receive_port, dummy);
	*port = dummy[0];
	return ret;
}

static inline s64 beat_destruct_event_receive_port(u64 port)
{
	s64 ret;

	ret = beat_hcall_norets(HV_destruct_event_receive_port, port);
	return ret;
}

static inline s64 beat_create_repository_node(u64 path[4], u64 data[2])
{
	s64 ret;

	ret = beat_hcall_norets(HV_create_repository_node2,
		path[0], path[1], path[2], path[3], data[0], data[1]);
	return ret;
}

static inline s64 beat_get_repository_node_value(u64 lpid, u64 path[4],
	u64 data[2])
{
	s64 ret;

	ret = beat_hcall2(HV_get_repository_node_value2, data,
		lpid, path[0], path[1], path[2], path[3]);
	return ret;
}

#endif
