blob: 0b2cf3b6d6a5d17ea76e4751eb80b9c6dfd816ad [file] [log] [blame]
// SPDX-License-Identifier: GPL-2.0-only
/*
* Copyright (C) 2022 - Google LLC
*/
#include <nvhe/pkvm.h>
#include <nvhe/spinlock.h>
static void (*__hyp_putc)(char c);
static inline void __hyp_putx4(unsigned int x)
{
x &= 0xf;
if (x <= 9)
x += '0';
else
x += ('a' - 0xa);
__hyp_putc(x);
}
static inline void __hyp_putx4n(unsigned long x, int n)
{
int i = n >> 2;
__hyp_putc('0');
__hyp_putc('x');
while (i--)
__hyp_putx4(x >> (4 * i));
__hyp_putc('\n');
__hyp_putc('\r');
}
static inline bool hyp_serial_enabled(void)
{
return !!READ_ONCE(__hyp_putc);
}
void hyp_puts(const char *s)
{
if (!hyp_serial_enabled())
return;
while (*s)
__hyp_putc(*s++);
__hyp_putc('\n');
__hyp_putc('\r');
}
void hyp_putx64(u64 x)
{
if (hyp_serial_enabled())
__hyp_putx4n(x, 64);
}
void hyp_putc(char c)
{
if (hyp_serial_enabled())
__hyp_putc(c);
}
int __pkvm_register_serial_driver(void (*cb)(char))
{
return cmpxchg(&__hyp_putc, NULL, cb) ? -EBUSY : 0;
}