/*
 * Information about kernel needed for proca ta
 *
 * Copyright (C) 2018 Samsung Electronics, Inc.
 * Hryhorii Tur, <hryhorii.tur@partner.samsung.com>
 *
 * This software is licensed under the terms of the GNU General Public
 * License version 2, as published by the Free Software Foundation, and
 * may be copied, distributed, and modified under those terms.
 *
 * 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.
 */

#include <linux/proca.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/version.h>

#include "proca_config.h"
#include "proca_log.h"
#include "proca_porting.h"
#include "gaf/proca_gaf.h"

#define PROCA_CONFIG_VERSION 3U
#define PROCA_CONFIG_MAGIC 0xCD0436EAU

static int append_sys_ram_range(struct resource *res, void *arg)
{
	struct proca_config *conf = arg;

	PROCA_DEBUG_LOG("System RAM region %llx-%llx was found\n",
			res->start, res->end);

	if (conf->sys_ram_ranges_num == MAX_MEMORY_RANGES_NUM) {
		PROCA_ERROR_LOG("Unsupported number of sys ram regions %llu\n",
		       MAX_MEMORY_RANGES_NUM);
		return -ENOMEM;
	}
	conf->sys_ram_ranges[conf->sys_ram_ranges_num].start = res->start;
	conf->sys_ram_ranges[conf->sys_ram_ranges_num].end = res->end;

	++conf->sys_ram_ranges_num;

	return 0;
}

#if LINUX_VERSION_CODE >= KERNEL_VERSION(4, 19, 42)
#define __walk_system_ram_res_cb append_sys_ram_range
#else
static int __walk_system_ram_res_cb(u64 start, u64 end, void *arg)
{
	struct resource res;

	res.start = start;
	res.end = end;
	return append_sys_ram_range(&res, arg);
}
#endif

static int prepare_sys_ram_ranges(struct proca_config *conf)
{
	int ret = 0;

	ret = walk_system_ram_res(0, ULONG_MAX, conf, __walk_system_ram_res_cb);
	if (ret)
		conf->sys_ram_ranges_num = 0;

	PROCA_DEBUG_LOG("Found %llu system RAM ranges\n",
			conf->sys_ram_ranges_num);

	return ret;
}

static void prepare_kernel_constants(struct proca_config *conf)
{
	conf->page_offset = PAGE_OFFSET;
	conf->va_bits = VA_BITS;
	conf->va_start = VA_START;
	conf->kimage_vaddr = get_kimage_vaddr();
	conf->kimage_voffset = get_kimage_voffset();
}

static void dump_proca_config(const struct proca_config *conf)
{
	size_t i;

	PROCA_DEBUG_LOG("version:  %u\n", conf->version);
	PROCA_DEBUG_LOG("size:     %u\n", conf->size);
	PROCA_DEBUG_LOG("magic:    %u\n", conf->magic);

	PROCA_DEBUG_LOG("gaf_addr:         %pK\n", conf->gaf_addr);
	PROCA_DEBUG_LOG("proca_table_addr: %pK\n", conf->proca_table_addr);

	PROCA_DEBUG_LOG("page_offset:    %llx\n",  conf->page_offset);
	PROCA_DEBUG_LOG("va_bits:        %llu\n",  conf->va_bits);
	PROCA_DEBUG_LOG("va_start:       %llx\n",  conf->va_start);
	PROCA_DEBUG_LOG("kimage_vaddr:   %llx\n",  conf->kimage_vaddr);
	PROCA_DEBUG_LOG("kimage_voffset: %llx\n",  conf->kimage_voffset);

	PROCA_DEBUG_LOG("Discovered %llu system RAM ranges:\n",
			conf->sys_ram_ranges_num);

	for (i = 0; i < conf->sys_ram_ranges_num; ++i) {
		PROCA_DEBUG_LOG("%llx-%llx.\n",
				conf->sys_ram_ranges[i].start,
				conf->sys_ram_ranges[i].end);
	}
}

int init_proca_config(struct proca_config *conf,
		      const struct proca_table *proca_table_addr)
{
	int ret;

	BUG_ON(!conf || !proca_table_addr);

	prepare_kernel_constants(conf);
	conf->gaf_addr = proca_gaf_get_addr();
	conf->proca_table_addr = proca_table_addr;
	conf->version = PROCA_CONFIG_VERSION;
	conf->size = sizeof(*conf);
	conf->magic = PROCA_CONFIG_MAGIC;
	ret = prepare_sys_ram_ranges(conf);
	if (ret)
		return ret;
	dump_proca_config(conf);
	return ret;
}

