/******************************************************************************
 * Copyright (c) 2004, 2008 IBM Corporation
 * All rights reserved.
 * This program and the accompanying materials
 * are made available under the terms of the BSD License
 * which accompanies this distribution, and is available at
 * http://www.opensource.org/licenses/bsd-license.php
 *
 * Contributors:
 *     IBM Corporation - initial implementation
 *****************************************************************************/

#include <stdint.h>
#include <stdarg.h>
#include <stdio.h>
#include <rtas.h>
#include <of.h>
#include <netdriver_int.h>
#include "kernel.h"

extern snk_kernel_t snk_kernel_interface;

typedef int rtas_arg_t;

typedef struct {
	int token;
	int nargs;
	int nret;
	rtas_arg_t args[16];
	rtas_arg_t *rets;	/* Pointer to return values in args[]. */
} rtas_args_t;

rtas_args_t rtas_args;

typedef struct {
	void *rtas_start;
	void *rtas_entry;
	int rtas_size;
	phandle_t dev;
} rtas_t;

extern rtas_t _rtas;
static int instantiate_rtas(void);
void rtas_call_entry(rtas_args_t *, void *, void *);

int
rtas_token(const char *service)
{
	int token;
	int retVal;
	if (_rtas.dev == 0)
		instantiate_rtas();

	retVal = of_getprop(_rtas.dev, service, &token, sizeof(token));
	if (retVal == -1) {
		token = 0;
	}
	return token;
}

int
rtas_call(int token, int nargs, int nret, int *outputs, ...)
{
	va_list list;
	int i;

	rtas_args.token = token;
	rtas_args.nargs = nargs;
	rtas_args.nret = nret;
	rtas_args.rets = (rtas_arg_t *) & (rtas_args.args[nargs]);
	va_start(list, outputs);
	for (i = 0; i < nargs; ++i) {
		rtas_args.args[i] = (rtas_arg_t) (va_arg(list, unsigned int));
	}
	va_end(list);

	for (i = 0; i < nret; ++i)
		rtas_args.rets[i] = 0;

	rtas_call_entry(&rtas_args, _rtas.rtas_start, _rtas.rtas_entry);
	if (nret > 0 && outputs != 0)
		for (i = 0; i < nret; i++)
			outputs[i] = rtas_args.rets[i];
#if 0
	printf("rtas call %x %x %x args: %x %x %x %x %x %x %x %x\n",
	       token, nargs, nret,
	       rtas_args.args[0],
	       rtas_args.args[1],
	       rtas_args.args[2],
	       rtas_args.args[3],
	       rtas_args.args[4], rtas_args.args[5], outputs[0], outputs[1]);
#endif
	return ((nret > 0) ? rtas_args.rets[0] : 0);
}

rtas_t _rtas;

static int
instantiate_rtas(void)
{
	long long *rtas_mem_space;
	ihandle_t ihandle;

	_rtas.dev = of_finddevice("/rtas");
	if ((long) _rtas.dev < 0) {
		snk_kernel_interface.print("\nCould not open /rtas\n");
		return -1;
	}

	of_getprop(_rtas.dev, "rtas-size", &_rtas.rtas_size,
		   sizeof(_rtas.rtas_size));

	if (_rtas.rtas_size <= 0) {
		snk_kernel_interface.print("\nSize of rtas (%x) too small to make sense\n",
		       _rtas.rtas_size);
		return -1;
	}

	rtas_mem_space = (long long *) malloc_aligned(_rtas.rtas_size, 0x100);

	if (!rtas_mem_space) {
		snk_kernel_interface.print("\nFailed to allocated memory for RTAS\n");
		return -1;
	}

	ihandle = of_open("/rtas");

	if ((long) ihandle < 0) {
		snk_kernel_interface.print("Could not open /rtas\n");
		return -1;
	}

	if ((long) (_rtas.rtas_entry = of_call_method_3("instantiate-rtas",
							ihandle,
							p32cast rtas_mem_space))
	    > 0) {
		_rtas.rtas_start = rtas_mem_space;
	} else {
		snk_kernel_interface.print("instantiate-rtas failed\n");
		return -1;
	}
#if 0
	snk_kernel_interface.print("\ninstantiate-rtas at %x size %x entry %x\n",
	       _rtas.rtas_start, _rtas.rtas_size, _rtas.rtas_entry);
#endif
	return 0;
}

static int read_pci_config_token = 0;
static int write_pci_config_token = 0;
static int ibm_read_pci_config_token = 0;
static int ibm_write_pci_config_token = 0;
static int get_time_of_day_token = 0;

void
rtas_init()
{
	int ret;
	ret = instantiate_rtas();
	if (ret)
		return;
	read_pci_config_token = rtas_token("read-pci-config");
	ibm_read_pci_config_token = rtas_token("ibm,read-pci-config");
	write_pci_config_token = rtas_token("write-pci-config");
	ibm_write_pci_config_token = rtas_token("ibm,write-pci-config");
	get_time_of_day_token = rtas_token("get-time-of-day");
}


int
rtas_pci_config_read(long long puid, int size, int bus, int devfn, int offset)
{
	int value[2];

	if (ibm_read_pci_config_token && puid) {
		rtas_call(ibm_read_pci_config_token, 4, 2, value,
			  bus << 16 | devfn << 8 | offset,
			  puid >> 32, puid & 0xffffffffULL, size);
	} else if (read_pci_config_token) {
		rtas_call(read_pci_config_token, 2, 2, value,
			  bus << 16 | devfn << 8 | offset, size);
	}

	return value[1];
}

int
rtas_pci_config_write(long long puid, int size, int bus, int devfn,
		      int offset, int value)
{
	int rc;

	if (ibm_write_pci_config_token && puid) {
		rtas_call(ibm_write_pci_config_token, 5, 1, &rc,
			  bus << 16 | devfn << 8 | offset,
			  puid >> 32, puid & 0xffffffffULL, size, value);
	} else
		rtas_call(write_pci_config_token, 3, 1, &rc,
			  bus << 16 | devfn << 8 | offset, size, value);

	return rc;
}

int
rtas_get_time_of_day(dtime * get)
{
	int rc = -1;
	unsigned int year;
	unsigned int month;
	unsigned int day;
	unsigned int hour;
	unsigned int minute;
	unsigned int second;
	unsigned int nano;

	if (get_time_of_day_token)
		rtas_call(get_time_of_day_token, 0, 8, &rc, &year, &month, &day,
			  &hour, &minute, &second, &nano);

	get->year = year;
	get->month = month;
	get->day = day;
	get->hour = hour;
	get->minute = minute;
	get->second = second;
	get->nano = nano;

	return rc;
}
