2 * Copyright (C) 2013 Intel Corporation; author Matt Fleming
4 * This file is part of the Linux kernel, and is made available under
5 * the terms of the GNU General Public License version 2.
8 #include <linux/console.h>
10 #include <linux/font.h>
12 #include <linux/kernel.h>
13 #include <asm/setup.h>
15 static const struct font_desc *font;
16 static u32 efi_x, efi_y;
18 static __init void early_efi_clear_scanline(unsigned int y)
20 unsigned long base, *dst;
23 base = boot_params.screen_info.lfb_base;
24 len = boot_params.screen_info.lfb_linelength;
26 dst = early_ioremap(base + y*len, len);
31 early_iounmap(dst, len);
34 static __init void early_efi_scroll_up(void)
36 unsigned long base, *dst, *src;
40 base = boot_params.screen_info.lfb_base;
41 len = boot_params.screen_info.lfb_linelength;
42 height = boot_params.screen_info.lfb_height;
44 for (i = 0; i < height - font->height; i++) {
45 dst = early_ioremap(base + i*len, len);
49 src = early_ioremap(base + (i + font->height) * len, len);
51 early_iounmap(dst, len);
55 memmove(dst, src, len);
57 early_iounmap(src, len);
58 early_iounmap(dst, len);
62 static void early_efi_write_char(u32 *dst, unsigned char c, unsigned int h)
64 const u32 color_black = 0x00000000;
65 const u32 color_white = 0x00ffffff;
70 src = font->data + c * font->height;
73 for (m = 0; m < 8; m++) {
74 if ((s8 >> (7 - m)) & 1)
83 early_efi_write(struct console *con, const char *str, unsigned int num)
85 struct screen_info *si;
91 base = boot_params.screen_info.lfb_base;
92 si = &boot_params.screen_info;
93 len = si->lfb_linelength;
97 unsigned int h, count = 0;
99 for (s = str; *s && *s != '\n'; s++) {
105 linemax = (si->lfb_width - efi_x) / font->width;
109 for (h = 0; h < font->height; h++) {
112 dst = early_ioremap(base + (efi_y + h) * len, len);
121 early_efi_write_char(dst + x*4, *s, h);
126 early_iounmap(dst, len);
130 efi_x += count * font->width;
133 if (num > 0 && *s == '\n') {
135 efi_y += font->height;
140 if (efi_x >= si->lfb_width) {
142 efi_y += font->height;
145 if (efi_y + font->height > si->lfb_height) {
148 efi_y -= font->height;
149 early_efi_scroll_up();
151 for (i = 0; i < font->height; i++)
152 early_efi_clear_scanline(efi_y + i);
157 static __init int early_efi_setup(struct console *con, char *options)
159 struct screen_info *si;
163 si = &boot_params.screen_info;
164 xres = si->lfb_width;
165 yres = si->lfb_height;
168 * early_efi_write_char() implicitly assumes a framebuffer with
171 if (si->lfb_depth != 32)
174 font = get_default_font(xres, yres, -1, -1);
178 efi_y = rounddown(yres, font->height) - font->height;
179 for (i = 0; i < (yres - efi_y) / font->height; i++)
180 early_efi_scroll_up();
185 struct console early_efi_console = {
187 .write = early_efi_write,
188 .setup = early_efi_setup,
189 .flags = CON_PRINTBUFFER,