Permalink
Browse files

x86: Add EFI framebuffer debug console

All modern UEFI system come with the so-called Graphic Output Protocol
which provides a simple framebuffer device. This can also be used as
alternative to UART-based debug consoles. And it can replace the VGA
console which is no longer working on such systems (VGA is legacy).

As we are now filling a graphic buffer, we are in need of a console
font. The altc-8x16 we use here was taken from KBD version 2.0.4
(https://www.kernel.org/pub/linux/utils/kbd) and is licensed under
GPL-2.0-or-later. Leave a note about this also in the LICENSING file.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
  • Loading branch information...
jan-kiszka committed Jul 9, 2018
1 parent 651e492 commit 790ac72a3ee5df69a3b686bf4dd8ab950e9e3931
@@ -19,9 +19,9 @@ Possible debug outputs for x86:
- JAILHOUSE_CON_TYPE_8250 /* 8250-compatible UART (PIO or MMIO) */
- JAILHOUSE_CON_TYPE_VGA /* VGA console */
- JAILHOUSE_CON_TYPE_EFIFB /* EFI framebuffer console */
VGA output is only available for x86. For further documentation on VGA output
see [vga-console.md](vga-console.md).
For further documentation on VGA output see [vga-console.md](vga-console.md).
Possible debug outputs for arm and arm64:
@@ -42,6 +42,11 @@ Possible register distances (MMIO only, PIO is implicitly 1-byte), to be or'ed:
- JAILHOUSE_CON_REGDIST_1 /* 1-byte distance */
- JAILHOUSE_CON_REGDIST_4 /* 4-bytes distance */
Possible framebuffer formats (EFIFB only);
- JAILHOUSE_CON_FB_1024x768 /* 1024x786 pixel, 32 bit each */
- JAILHOUSE_CON_FB_1920x1080 /* 1920x1080 pixel, 32 bit each */
### .address and .size
The address member denotes the base address of the Debug console (PIO or MMIO
base address). The .size parameter is only required for MMIO.
@@ -86,6 +91,15 @@ Example configuration for MMIO based debug output on ARM (8250 UART):
.flags = JAILHOUSE_CON_MMIO_32, /* choose 32-bit MMIO access */
},
Example configuration for EFI framebuffer debug out on x86:
.debug_console = {
.address = 0x80000000, /* framebuffer base address */
.size = 0x300000, /* 1024x786x4 */
.type = JAILHOUSE_CON_TYPE_EFIFB, /* choose the EFIFB driver */
.flags = JAILHOUSE_CON_FB_1024x768 /* format */
},
Example configuration for disabled debug output (architecture independent):
.debug_console = {
@@ -153,7 +167,7 @@ arm: none, 8250, hscif, imx, mvebu, pl011, scifa, xuartps
Similar to the hypervisor configuration, a zero value for con-divider will skip
initialisation of the UART interface.
On x86, VGA output is not available for inmates.
On x86, VGA and EFI framebuffer output are not available for inmates.
### Examples
Example command line parameters for PIO based debug output on x86, where the
View
@@ -9,6 +9,11 @@ Whenever a file is provided under an additional or different license than
GPLv2, this is stated in the file header. Any file that may lack such a
header has to be considered licensed under GPLv2 (default license).
The binary font file hypervisor/arch/x86/altc-8x16 was taken from the KBD
project in version 2.0.4 (https://www.kernel.org/pub/linux/utils/kbd,
http://kbd-project.org) which is distributed under the GNU GPL version 2 or
later (SPDX identifier GPL-2.0-or-later).
If two licenses are specified in a file header, you are free to pick the one
that suits best your particular use case. You can also continue to use the
file under the dual license. When choosing only one, remove the reference to
@@ -19,7 +19,11 @@ ccflags-$(CONFIG_JAILHOUSE_GCOV) += -fprofile-arcs -ftest-coverage
always := lib-amd.a lib-intel.a
common-objs-y := apic.o dbg-write.o entry.o setup.o control.o mmio.o iommu.o \
paging.o pci.o i8042.o vcpu.o vga.o ivshmem.o
paging.o pci.o i8042.o vcpu.o vga.o efifb.o ivshmem.o
CFLAGS_efifb.o := -I$(src)
$(obj)/efifb.o: $(src)/altc-8x16
# units initialization order as defined by linking order:
# iommu, ioapic, [test-device], [cat], <generic units>
View
Binary file not shown.
@@ -15,6 +15,7 @@
#include <jailhouse/control.h>
#include <jailhouse/printk.h>
#include <jailhouse/uart.h>
#include <asm/efifb.h>
#include <asm/io.h>
#include <asm/vga.h>
@@ -49,5 +50,8 @@ void arch_dbg_write_init(void)
} else if (dbg_type == JAILHOUSE_CON_TYPE_VGA) {
vga_init();
arch_dbg_write = vga_write;
} else if (dbg_type == JAILHOUSE_CON_TYPE_EFIFB) {
efifb_init();
arch_dbg_write = efifb_write;
}
}
View
@@ -0,0 +1,116 @@
/*
* Jailhouse, a Linux-based partitioning hypervisor
*
* Copyright (c) Siemens AG, 2018
*
* Authors:
* Jan Kiszka <jan.kiszka@siemens.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/
#include <jailhouse/control.h>
#include <jailhouse/processor.h>
#include <jailhouse/string.h>
#include <asm/efifb.h>
#define EFIFB_MAX_WIDTH 1920
#define EFIFB_MAX_HEIGHT 1080
#define EFIFB_FONT_WIDTH 8
#define EFIFB_FONT_HEIGHT 16
#define EFIFB_LINE_LEN (EFIFB_FONT_WIDTH * efifb_width)
#define EFIFB_FG_COLOR 0x00ff00 /* green */
#define EFIFB_BG_COLOR 0x000000 /* black */
asm(
" .pushsection \".rodata\"\n"
"font8x16:\n"
" .incbin \"altc-8x16\"\n"
" .popsection\n"
);
extern const u8 font8x16[];
static unsigned int efifb_width, efifb_height;
static char efifb_buffer[EFIFB_MAX_HEIGHT][EFIFB_MAX_WIDTH];
static u32 row_line;
static void efifb_write_char(unsigned int line, unsigned int row, char c)
{
unsigned int x, y, font_line, color, offs;
for (y = 0; y < EFIFB_FONT_HEIGHT; y++) {
font_line = font8x16[c * EFIFB_FONT_HEIGHT + y];
for (x = 0; x < EFIFB_FONT_WIDTH; x++) {
if (font_line & (1 << (EFIFB_FONT_WIDTH - x)))
color = EFIFB_FG_COLOR;
else
color = EFIFB_BG_COLOR;
offs = (row * EFIFB_FONT_WIDTH) + x +
(line * EFIFB_FONT_HEIGHT + y) * EFIFB_LINE_LEN;
((u32 *)hypervisor_header.debug_console_base)[offs] =
color;
}
}
efifb_buffer[line][row] = c;
}
static void efifb_scroll(void)
{
unsigned int row, line;
for (line = 0; line < (efifb_height - 1); line++)
for (row = 0; row < efifb_width; row++)
efifb_write_char(line, row,
efifb_buffer[line + 1][row]);
for (row = 0; row < efifb_width; row++)
efifb_write_char(efifb_height - 1, row, ' ');
}
void efifb_write(const char *msg)
{
/*
* panic_printk() avoids locking 'printk_lock' due to a potential
* deadlock in case a crash occurs while holding it. For avoiding
* a data race between printk and panic_printk, we take a local
* snapshot of both static variables and update them on return.
*/
u16 row = (u16)(row_line >> 16);
u16 line = (u16)row_line;
while (*msg != 0) {
if (panic_in_progress && panic_cpu != phys_processor_id())
return;
if (row == efifb_width || *msg == '\n') {
row = 0;
if (line == efifb_height - 1)
efifb_scroll();
else
line++;
}
if (*msg != '\n' && *msg != '\r') {
efifb_write_char(line, row, *msg);
row++;
}
msg++;
}
row_line = ((u32)row << 16) | (u32)line;
}
void efifb_init(void)
{
if (FB_IS_1920x1080(system_config->debug_console.flags)) {
efifb_width = 1920 / EFIFB_FONT_WIDTH;
efifb_height = 1080 / EFIFB_FONT_HEIGHT;
} else {
efifb_width = 1024 / EFIFB_FONT_WIDTH;
efifb_height = 876 / EFIFB_FONT_HEIGHT;
}
}
@@ -0,0 +1,14 @@
/*
* Jailhouse, a Linux-based partitioning hypervisor
*
* Copyright (c) Siemens AG, 2018
*
* Authors:
* Jan Kiszka <jan.kiszka@siemens.com>
*
* This work is licensed under the terms of the GNU GPL, version 2. See
* the COPYING file in the top-level directory.
*/
void efifb_init(void);
void efifb_write(const char *msg);
@@ -49,6 +49,7 @@
#define JAILHOUSE_CON_TYPE_HSCIF 0x0006
#define JAILHOUSE_CON_TYPE_SCIFA 0x0007
#define JAILHOUSE_CON_TYPE_IMX 0x0008
#define JAILHOUSE_CON_TYPE_EFIFB 0x0009
/* Flags: bit 0 is used to select PIO (cleared) or MMIO (set) access */
#define JAILHOUSE_CON_ACCESS_PIO 0x0000
@@ -65,7 +66,13 @@
#define CON_USES_REGDIST_1(flags) (((flags) & JAILHOUSE_CON_REGDIST_4) == 0)
/* Bits 2-11: Reserved */
/* Flags: bit 2 is used to select framebuffer format */
#define JAILHOUSE_CON_FB_1024x768 0x0000
#define JAILHOUSE_CON_FB_1920x1080 0x0004
#define FB_IS_1920x1080(flags) !!((flags) & JAILHOUSE_CON_FB_1920x1080)
/* Bits 3-11: Reserved */
/* Bit 12 is used to indicate to clear instead of to set the clock gate */
#define JAILHOUSE_CON_INVERTED_GATE 0x1000

0 comments on commit 790ac72

Please sign in to comment.