/*
 * This file is part of the coreboot project.
 *
 * Copyright (C) 2011 The ChromiumOS Authors.  All rights reserved.
 * Copyright (C) 2017 Siemens AG
 *
 * 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; version 2 of the License.
 *
 * 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 <assert.h>
#include <stddef.h>
#include <stdint.h>
#include <console/console.h>
#include <cbmem.h>
#include <symbols.h>
#include <timer.h>
#include <timestamp.h>
#include <smp/node.h>

#define MAX_TIMESTAMPS 192

DECLARE_OPTIONAL_REGION(timestamp);

/* This points to the active timestamp_table and can change within a stage
   as CBMEM comes available. */
static struct timestamp_table *glob_ts_table;

static void timestamp_cache_init(struct timestamp_table *ts_cache,
				 uint64_t base)
{
	ts_cache->num_entries = 0;
	ts_cache->base_time = base;
	ts_cache->max_entries = (REGION_SIZE(timestamp) -
		offsetof(struct timestamp_table, entries))
		/ sizeof(struct timestamp_entry);
}

static struct timestamp_table *timestamp_cache_get(void)
{
	struct timestamp_table *ts_cache = NULL;

	if (!ENV_ROMSTAGE_OR_BEFORE)
		return NULL;

	if (REGION_SIZE(timestamp) < sizeof(*ts_cache)) {
		BUG();
	} else {
		ts_cache = (void *)_timestamp;
	}

	return ts_cache;
}

static struct timestamp_table *timestamp_alloc_cbmem_table(void)
{
	struct timestamp_table *tst;

	tst = cbmem_add(CBMEM_ID_TIMESTAMP,
			sizeof(struct timestamp_table) +
			MAX_TIMESTAMPS * sizeof(struct timestamp_entry));

	if (!tst)
		return NULL;

	tst->base_time = 0;
	tst->max_entries = MAX_TIMESTAMPS;
	tst->num_entries = 0;

	return tst;
}

/* Determine if one should proceed into timestamp code. This is for protecting
 * systems that have multiple processors running in romstage -- namely AMD
 * based x86 platforms. */
static int timestamp_should_run(void)
{
	/*
	 * Only check boot_cpu() in other stages than
	 * ENV_PAYLOAD_LOADER on x86.
	 */
	if ((!ENV_PAYLOAD_LOADER && CONFIG(ARCH_X86)) && !boot_cpu())
		return 0;

	return 1;
}

static struct timestamp_table *timestamp_table_get(void)
{
	if (glob_ts_table)
		return glob_ts_table;

	glob_ts_table = timestamp_cache_get();

	return glob_ts_table;
}

static void timestamp_table_set(struct timestamp_table *ts)
{
	glob_ts_table = ts;
}

static const char *timestamp_name(enum timestamp_id id)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(timestamp_ids); i++) {
		if (timestamp_ids[i].id == id)
			return timestamp_ids[i].name;
	}

	return "Unknown timestamp ID";
}

static void timestamp_add_table_entry(struct timestamp_table *ts_table,
				      enum timestamp_id id, uint64_t ts_time)
{
	struct timestamp_entry *tse;

	if (ts_table->num_entries >= ts_table->max_entries)
		return;

	tse = &ts_table->entries[ts_table->num_entries++];
	tse->entry_id = id;
	tse->entry_stamp = ts_time;

	if (ts_table->num_entries == ts_table->max_entries)
		printk(BIOS_ERR, "ERROR: Timestamp table full\n");
}

void timestamp_add(enum timestamp_id id, uint64_t ts_time)
{
	struct timestamp_table *ts_table;

	if (!timestamp_should_run())
		return;

	ts_table = timestamp_table_get();

	if (!ts_table) {
		printk(BIOS_ERR, "ERROR: No timestamp table found\n");
		return;
	}

	ts_time -= ts_table->base_time;
	timestamp_add_table_entry(ts_table, id, ts_time);

	if (CONFIG(TIMESTAMPS_ON_CONSOLE))
		printk(BIOS_INFO, "Timestamp - %s: %llu\n", timestamp_name(id), ts_time);
}

void timestamp_add_now(enum timestamp_id id)
{
	timestamp_add(id, timestamp_get());
}

void timestamp_init(uint64_t base)
{
	struct timestamp_table *ts_cache;

	assert(ENV_ROMSTAGE_OR_BEFORE);

	if (!timestamp_should_run())
		return;

	ts_cache = timestamp_cache_get();

	if (!ts_cache) {
		printk(BIOS_ERR, "ERROR: No timestamp cache to init\n");
		return;
	}

	timestamp_cache_init(ts_cache, base);
	timestamp_table_set(ts_cache);
}

static void timestamp_sync_cache_to_cbmem(struct timestamp_table *ts_cbmem_table)
{
	uint32_t i;
	struct timestamp_table *ts_cache_table;

	ts_cache_table = timestamp_table_get();
	if (!ts_cache_table) {
		printk(BIOS_ERR, "ERROR: No timestamp cache found\n");
		return;
	}

	/*
	 * There's no need to worry about the base_time fields being out of
	 * sync because only the following configuration is used/supported:
	 *
	 *    Timestamps get initialized before ramstage, which implies
	 *    CBMEM initialization in romstage.
	 *    This requires the board to define a TIMESTAMP() region in its
	 *    memlayout.ld (default on x86). The base_time from timestamp_init()
	 *    (usually called from bootblock.c on most non-x86 boards) persists
	 *    in that region until it gets synced to CBMEM in romstage.
	 *    In ramstage, the BSS cache's base_time will be 0 until the second
	 *    sync, which will adjust the timestamps in there to the correct
	 *    base_time (from CBMEM) with the timestamp_add_table_entry() below.
	 *
	 * If you try to initialize timestamps before ramstage but don't define
	 * a TIMESTAMP region, all operations will fail (safely), and coreboot
	 * will behave as if timestamps collection was disabled.
	 */

	/* Inherit cache base_time. */
	ts_cbmem_table->base_time = ts_cache_table->base_time;

	for (i = 0; i < ts_cache_table->num_entries; i++) {
		struct timestamp_entry *tse = &ts_cache_table->entries[i];
		timestamp_add_table_entry(ts_cbmem_table, tse->entry_id,
					  tse->entry_stamp);
	}

	/* Cache no longer required. */
	ts_cache_table->num_entries = 0;
}

static void timestamp_reinit(int is_recovery)
{
	struct timestamp_table *ts_cbmem_table;

	if (!timestamp_should_run())
		return;

	/* First time into romstage we make a clean new table. For platforms that travel
	   through this path on resume, ARCH_X86 S3, timestamps are also reset. */
	if (ENV_ROMSTAGE) {
		ts_cbmem_table = timestamp_alloc_cbmem_table();
	} else {
		/* Find existing table in cbmem. */
		ts_cbmem_table = cbmem_find(CBMEM_ID_TIMESTAMP);
	}

	if (ts_cbmem_table == NULL) {
		printk(BIOS_ERR, "ERROR: No timestamp table allocated\n");
		timestamp_table_set(NULL);
		return;
	}

	if (ENV_ROMSTAGE)
		timestamp_sync_cache_to_cbmem(ts_cbmem_table);

	/* Seed the timestamp tick frequency in ENV_PAYLOAD_LOADER. */
	if (ENV_PAYLOAD_LOADER)
		ts_cbmem_table->tick_freq_mhz = timestamp_tick_freq_mhz();

	timestamp_table_set(ts_cbmem_table);
}

void timestamp_rescale_table(uint16_t N, uint16_t M)
{
	uint32_t i;
	struct timestamp_table *ts_table;

	if (!timestamp_should_run())
		return;

	if (N == 0 || M == 0)
		return;

	ts_table = timestamp_table_get();

	/* No timestamp table found */
	if (ts_table == NULL) {
		printk(BIOS_ERR, "ERROR: No timestamp table found\n");
		return;
	}

	ts_table->base_time /= M;
	ts_table->base_time *= N;
	for (i = 0; i < ts_table->num_entries; i++) {
		struct timestamp_entry *tse = &ts_table->entries[i];
		tse->entry_stamp /= M;
		tse->entry_stamp *= N;
	}
}

/*
 * Get the time in microseconds since boot (or more precise: since timestamp
 * table was initialized).
 */
uint32_t get_us_since_boot(void)
{
	struct timestamp_table *ts = timestamp_table_get();

	if (ts == NULL || ts->tick_freq_mhz == 0)
		return 0;
	return (timestamp_get() - ts->base_time) / ts->tick_freq_mhz;
}

ROMSTAGE_CBMEM_INIT_HOOK(timestamp_reinit)
POSTCAR_CBMEM_INIT_HOOK(timestamp_reinit)
RAMSTAGE_CBMEM_INIT_HOOK(timestamp_reinit)

/* Provide default timestamp implementation using monotonic timer. */
uint64_t  __weak timestamp_get(void)
{
	struct mono_time t1, t2;

	if (!CONFIG(HAVE_MONOTONIC_TIMER))
		return 0;

	mono_time_set_usecs(&t1, 0);
	timer_monotonic_get(&t2);

	return mono_time_diff_microseconds(&t1, &t2);
}

/* Like timestamp_get() above this matches up with microsecond granularity. */
int __weak timestamp_tick_freq_mhz(void)
{
	return 1;
}
