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

hvc_rtas.c (2723B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 * IBM RTAS driver interface to hvc_console.c
      4 *
      5 * (C) Copyright IBM Corporation 2001-2005
      6 * (C) Copyright Red Hat, Inc. 2005
      7 *
      8 * Author(s): Maximino Augilar <IBM STI Design Center>
      9 *	    : Ryan S. Arnold <rsa@us.ibm.com>
     10 *	    : Utz Bacher <utz.bacher@de.ibm.com>
     11 *	    : David Woodhouse <dwmw2@infradead.org>
     12 *
     13 *    inspired by drivers/char/hvc_console.c
     14 *    written by Anton Blanchard and Paul Mackerras
     15 */
     16
     17#include <linux/console.h>
     18#include <linux/delay.h>
     19#include <linux/err.h>
     20#include <linux/init.h>
     21#include <linux/moduleparam.h>
     22#include <linux/types.h>
     23
     24#include <asm/irq.h>
     25#include <asm/rtas.h>
     26#include "hvc_console.h"
     27
     28#define hvc_rtas_cookie 0x67781e15
     29struct hvc_struct *hvc_rtas_dev;
     30
     31static int rtascons_put_char_token = RTAS_UNKNOWN_SERVICE;
     32static int rtascons_get_char_token = RTAS_UNKNOWN_SERVICE;
     33
     34static inline int hvc_rtas_write_console(uint32_t vtermno, const char *buf,
     35		int count)
     36{
     37	int i;
     38
     39	for (i = 0; i < count; i++) {
     40		if (rtas_call(rtascons_put_char_token, 1, 1, NULL, buf[i]))
     41			break;
     42	}
     43
     44	return i;
     45}
     46
     47static int hvc_rtas_read_console(uint32_t vtermno, char *buf, int count)
     48{
     49	int i, c;
     50
     51	for (i = 0; i < count; i++) {
     52		if (rtas_call(rtascons_get_char_token, 0, 2, &c))
     53			break;
     54
     55		buf[i] = c;
     56	}
     57
     58	return i;
     59}
     60
     61static const struct hv_ops hvc_rtas_get_put_ops = {
     62	.get_chars = hvc_rtas_read_console,
     63	.put_chars = hvc_rtas_write_console,
     64};
     65
     66static int __init hvc_rtas_init(void)
     67{
     68	struct hvc_struct *hp;
     69
     70	if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
     71		rtascons_put_char_token = rtas_token("put-term-char");
     72	if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
     73		return -EIO;
     74
     75	if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
     76		rtascons_get_char_token = rtas_token("get-term-char");
     77	if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
     78		return -EIO;
     79
     80	BUG_ON(hvc_rtas_dev);
     81
     82	/* Allocate an hvc_struct for the console device we instantiated
     83	 * earlier.  Save off hp so that we can return it on exit */
     84	hp = hvc_alloc(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops, 16);
     85	if (IS_ERR(hp))
     86		return PTR_ERR(hp);
     87
     88	hvc_rtas_dev = hp;
     89
     90	return 0;
     91}
     92device_initcall(hvc_rtas_init);
     93
     94/* This will happen prior to module init.  There is no tty at this time? */
     95static int __init hvc_rtas_console_init(void)
     96{
     97	rtascons_put_char_token = rtas_token("put-term-char");
     98	if (rtascons_put_char_token == RTAS_UNKNOWN_SERVICE)
     99		return -EIO;
    100
    101	rtascons_get_char_token = rtas_token("get-term-char");
    102	if (rtascons_get_char_token == RTAS_UNKNOWN_SERVICE)
    103		return -EIO;
    104
    105	hvc_instantiate(hvc_rtas_cookie, 0, &hvc_rtas_get_put_ops);
    106	add_preferred_console("hvc", 0, NULL);
    107
    108	return 0;
    109}
    110console_initcall(hvc_rtas_console_init);