cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

udbg_memcons.c (2184B)


      1// SPDX-License-Identifier: GPL-2.0-or-later
      2/*
      3 * A udbg backend which logs messages and reads input from in memory
      4 * buffers.
      5 *
      6 * The console output can be read from memcons_output which is a
      7 * circular buffer whose next write position is stored in memcons.output_pos.
      8 *
      9 * Input may be passed by writing into the memcons_input buffer when it is
     10 * empty. The input buffer is empty when both input_pos == input_start and
     11 * *input_start == '\0'.
     12 *
     13 * Copyright (C) 2003-2005 Anton Blanchard and Milton Miller, IBM Corp
     14 * Copyright (C) 2013 Alistair Popple, IBM Corp
     15 */
     16
     17#include <linux/kernel.h>
     18#include <asm/barrier.h>
     19#include <asm/page.h>
     20#include <asm/processor.h>
     21#include <asm/udbg.h>
     22
     23struct memcons {
     24	char *output_start;
     25	char *output_pos;
     26	char *output_end;
     27	char *input_start;
     28	char *input_pos;
     29	char *input_end;
     30};
     31
     32static char memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE];
     33static char memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE];
     34
     35struct memcons memcons = {
     36	.output_start = memcons_output,
     37	.output_pos = memcons_output,
     38	.output_end = &memcons_output[CONFIG_PPC_MEMCONS_OUTPUT_SIZE],
     39	.input_start = memcons_input,
     40	.input_pos = memcons_input,
     41	.input_end = &memcons_input[CONFIG_PPC_MEMCONS_INPUT_SIZE],
     42};
     43
     44void memcons_putc(char c)
     45{
     46	char *new_output_pos;
     47
     48	*memcons.output_pos = c;
     49	wmb();
     50	new_output_pos = memcons.output_pos + 1;
     51	if (new_output_pos >= memcons.output_end)
     52		new_output_pos = memcons.output_start;
     53
     54	memcons.output_pos = new_output_pos;
     55}
     56
     57int memcons_getc_poll(void)
     58{
     59	char c;
     60	char *new_input_pos;
     61
     62	if (*memcons.input_pos) {
     63		c = *memcons.input_pos;
     64
     65		new_input_pos = memcons.input_pos + 1;
     66		if (new_input_pos >= memcons.input_end)
     67			new_input_pos = memcons.input_start;
     68		else if (*new_input_pos == '\0')
     69			new_input_pos = memcons.input_start;
     70
     71		*memcons.input_pos = '\0';
     72		wmb();
     73		memcons.input_pos = new_input_pos;
     74		return c;
     75	}
     76
     77	return -1;
     78}
     79
     80int memcons_getc(void)
     81{
     82	int c;
     83
     84	while (1) {
     85		c = memcons_getc_poll();
     86		if (c == -1)
     87			cpu_relax();
     88		else
     89			break;
     90	}
     91
     92	return c;
     93}
     94
     95void __init udbg_init_memcons(void)
     96{
     97	udbg_putc = memcons_putc;
     98	udbg_getc = memcons_getc;
     99	udbg_getc_poll = memcons_getc_poll;
    100}