/*
 * A udbg backend which logs messages and reads input from in memory
 * buffers.
 *
 * The console output can be read from memcons_output which is a
 * circular buffer whose next write position is stored in memcons.output_pos.
 *
 * Input may be passed by writing into the memcons_input buffer when it is
 * empty. The input buffer is empty when both input_pos == input_start and
 * *input_start == '\0'.
 *
 * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp
 * Copyright (C) 2013 Alistair Popple, IBM Corp
 *
 *      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.
 */

#include <linux/kernel.h>
#include <asm/barrier.h>
#include <asm/page.h>
#include <asm/processor.h>
#include <asm/udbg.h>

struct memcons {
	char *output_start;
	char *output_pos;
	char *output_end;
	char *input_start;
	char *input_pos;
	char *input_end;
};

static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE];
static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE];

struct memcons memcons = {
	.output_start = memcons_output,
	.output_pos = memcons_output,
	.output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE],
	.input_start = memcons_input,
	.input_pos = memcons_input,
	.input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE],
};

void memcons_putc(char c)
{
	char *new_output_pos;

	*memcons.output_pos = c;
	wmb();
	new_output_pos = memcons.output_pos + 1;
	if (new_output_pos >= memcons.output_end)
		new_output_pos = memcons.output_start;

	memcons.output_pos = new_output_pos;
}

int memcons_getc_poll(void)
{
	char c;
	char *new_input_pos;

	if (*memcons.input_pos) {
		c = *memcons.input_pos;

		new_input_pos = memcons.input_pos + 1;
		if (new_input_pos >= memcons.input_end)
			new_input_pos = memcons.input_start;
		else if (*new_input_pos == '\0')
			new_input_pos = memcons.input_start;

		*memcons.input_pos = '\0';
		wmb();
		memcons.input_pos = new_input_pos;
		return c;
	}

	return -1;
}

int memcons_getc(void)
{
	int c;

	while (1) {
		c = memcons_getc_poll();
		if (c == -1)
			cpu_relax();
		else
			break;
	}

	return c;
}

void udbg_init_memcons(void)
{
	udbg_putc = memcons_putc;
	udbg_getc = memcons_getc;
	udbg_getc_poll = memcons_getc_poll;
}
