// SPDX-License-Identifier: GPL-2.0
#include <linux/stdarg.h>
#include <linux/ctype.h>
#include <linux/efi.h>
#include <linux/kernel.h>
#include <linux/kern_levels.h>
#include <asm /efi.h>
#include <asm /setup.h>
#include "efistub.h"
int efi_loglevel = LOGLEVEL_NOTICE;
/**
* efi_char16_puts ( ) - Write a UCS - 2 encoded string to the console
* @ str : UCS - 2 encoded string
*/
void efi_char16_puts(efi_char16_t *str)
{
efi_call_proto(efi_table_attr(efi_system_table, con_out),
output_string, str);
}
static
u32 utf8_to_utf32(const u8 **s8)
{
u32 c32;
u8 c0, cx;
size_t clen, i;
c0 = cx = *(*s8)++;
/*
* The position of the most - significant 0 bit gives us the length of
* a multi - octet encoding .
*/
for (clen = 0 ; cx & 0 x80; ++clen)
cx <<= 1 ;
/*
* If the 0 bit is in position 8 , this is a valid single - octet
* encoding . If the 0 bit is in position 7 or positions 1 - 3 , the
* encoding is invalid .
* In either case , we just return the first octet .
*/
if (clen < 2 || clen > 4 )
return c0;
/* Get the bits from the first octet. */
c32 = cx >> clen--;
for (i = 0 ; i < clen; ++i) {
/* Trailing octets must have 10 in most significant bits. */
cx = (*s8)[i] ^ 0 x80;
if (cx & 0 xc0)
return c0;
c32 = (c32 << 6 ) | cx;
}
/*
* Check for validity :
* - The character must be in the Unicode range .
* - It must not be a surrogate .
* - It must be encoded using the correct number of octets .
*/
if (c32 > 0 x10ffff ||
(c32 & 0 xf800) == 0 xd800 ||
clen != (c32 >= 0 x80) + (c32 >= 0 x800) + (c32 >= 0 x10000))
return c0;
*s8 += clen;
return c32;
}
/**
* efi_puts ( ) - Write a UTF - 8 encoded string to the console
* @ str : UTF - 8 encoded string
*/
void efi_puts(const char *str)
{
efi_char16_t buf[128 ];
size_t pos = 0 , lim = ARRAY_SIZE(buf);
const u8 *s8 = (const u8 *)str;
u32 c32;
while (*s8) {
if (*s8 == '\n' )
buf[pos++] = L'\r' ;
c32 = utf8_to_utf32(&s8);
if (c32 < 0 x10000) {
/* Characters in plane 0 use a single word. */
buf[pos++] = c32;
} else {
/*
* Characters in other planes encode into a surrogate
* pair .
*/
buf[pos++] = (0 xd800 - (0 x10000 >> 10 )) + (c32 >> 10 );
buf[pos++] = 0 xdc00 + (c32 & 0 x3ff);
}
if (*s8 == '\0' || pos >= lim - 2 ) {
buf[pos] = L'\0' ;
efi_char16_puts(buf);
pos = 0 ;
}
}
}
/**
* efi_printk ( ) - Print a kernel message
* @ fmt : format string
*
* The first letter of the format string is used to determine the logging level
* of the message . If the level is less then the current EFI logging level , the
* message is suppressed . The message will be truncated to 255 bytes .
*
* Return : number of printed characters
*/
int efi_printk(const char *fmt, ...)
{
char printf_buf[256 ];
va_list args;
int printed;
int loglevel = printk_get_level(fmt);
switch (loglevel) {
case '0' ... '9' :
loglevel -= '0' ;
break ;
default :
/*
* Use loglevel - 1 for cases where we just want to print to
* the screen .
*/
loglevel = -1 ;
break ;
}
if (loglevel >= efi_loglevel)
return 0 ;
if (loglevel >= 0 )
efi_puts("EFI stub: " );
fmt = printk_skip_level(fmt);
va_start(args, fmt);
printed = vsnprintf(printf_buf, sizeof (printf_buf), fmt, args);
va_end(args);
efi_puts(printf_buf);
if (printed >= sizeof (printf_buf)) {
efi_puts("[Message truncated]\n" );
return -1 ;
}
return printed;
}
Messung V0.5 in Prozent C=93 H=78 G=85
¤ Dauer der Verarbeitung: 0.8 Sekunden
(vorverarbeitet am 2026-10-02)
¤
*© Formatika GbR, Deutschland