env: add ENV_IS_ANYWHERE
Subsystems (2)
PATCH 1/1 env: add ENV_IS_ANYWHERE
Useful for devices which would otherwise have to use ENV_IS_NOWHERE. Tries to find and load uboot.env from any block device (which may be, for example, hot-pluggable sd-card, SATA or USB disk, so the exact location is not known at the time u-boot is compiled).
--- cmd/bootefi.c | 5 ++ cmd/nvedit.c | 6 +- cmd/usb.c | 4 +- common/Kconfig | 11 ++++ common/Makefile | 1 + common/board_r.c | 11 ++++ common/env_anywhere.c | 156 ++++++++++++++++++++++++++++++++++++++++++++++++++ include/environment.h | 5 ++ 8 files changed, 196 insertions(+), 3 deletions(-) create mode 100644 common/env_anywhere.c
cmd/bootefi.c +5 -0
@@ -10,6 +10,7 @@#include <command.h> #include <dm.h> #include <efi_loader.h> +#include <environment.h> #include <errno.h> #include <libfdt.h> #include <libfdt_env.h>
@@ -318,6 +319,10 @@ void efi_set_bootdev(const char *dev, const char *devnr, const char *path) part =parse_partnum (devnr); bootefi_device_path =efi_dp_from_part (desc, part); + +#ifdef CONFIG_ENV_IS_ANYWHERE +env_set_location (desc, part); +#endif }else {#ifdef CONFIG_NET bootefi_device_path =efi_dp_from_eth ();
cmd/nvedit.c +4 -2
@@ -53,9 +53,11 @@ DECLARE_GLOBAL_DATA_PTR; !defined (CONFIG_ENV_IS_IN_SPI_FLASH ) && \ !defined (CONFIG_ENV_IS_IN_REMOTE ) && \ !defined (CONFIG_ENV_IS_IN_UBI ) && \ - !defined(CONFIG_ENV_IS_NOWHERE) + !defined (CONFIG_ENV_IS_NOWHERE ) && \ + !defined(CONFIG_ENV_IS_ANYWHERE)# error Define one of CONFIG_ENV_IS_IN_{EEPROM|FLASH|DATAFLASH|MMC|FAT|EXT4|\ -NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE +NAND|NVRAM|ONENAND|SATA|SPI_FLASH|REMOTE|UBI} or CONFIG_ENV_IS_NOWHERE or \ +CONFIG_ENV_IS_ANYWHERE#endif /*
cmd/usb.c +3 -1
@@ -23,7 +23,7 @@#include <usb.h> #ifdef CONFIG_USB_STORAGE -static int usb_stor_curr_dev =-1 ;/* current device */ +int usb_stor_curr_dev =-1 ;/* current device */ #endif #if defined(CONFIG_USB_HOST_ETHER ) && !defined(CONFIG_DM_ETH )static int __maybe_unused usb_ether_curr_dev =-1 ;/* current ethernet device */
@@ -567,6 +567,7 @@ static void do_usb_start(void) {bootstage_mark_name (BOOTSTAGE_ID_USB_START ,"usb_start" ); +#ifndef CONFIG_ENV_IS_ANYWHERE if (usb_init () <0 )return ;
@@ -575,6 +576,7 @@ static void do_usb_start(void)/* try to recognize storage devices immediately */ usb_stor_curr_dev =usb_stor_scan (1 );# endif +#endif #ifndef CONFIG_DM_USB # ifdef CONFIG_USB_KEYBOARD drv_usb_kbd_init ();
common/Kconfig +11 -0
@@ -210,6 +210,17 @@ config ENV_IS_NOWHERE Define this if you don't want to or can't have an environment stored on a storage medium +config ENV_IS_ANYWHERE + bool "Environment is on any partition" + depends on BLK + help + Define this if you want to store the environment on the first + partition found containing /uboot.env. Environment will be saved + to same partition it was loaded from. This is suitable for boards + which may be booting from various removable devices (ie. sd-card, + usb-disk, etc) and you don't know@the time u-boot is built what + the boot media will be. + endchoice config ENV_OFFSET
common/Makefile +1 -0
@@ -51,6 +51,7 @@ obj-$(CONFIG_ENV_IS_IN_SPI_FLASH) += env_sf.o obj-$(CONFIG_ENV_IS_IN_REMOTE) += env_remote.o obj-$(CONFIG_ENV_IS_IN_UBI) += env_ubi.o obj-$(CONFIG_ENV_IS_NOWHERE) += env_nowhere.o +obj-$(CONFIG_ENV_IS_ANYWHERE) += env_anywhere.o obj-$(CONFIG_CMD_BEDBUG) += bedbug.o obj-$(CONFIG_$(SPL_)OF_LIBFDT) += fdt_support.o
common/board_r.c +11 -0
@@ -693,6 +693,14 @@ static int run_main_loop(void)return 0 ; } +#ifdef CONFIG_ENV_IS_ANYWHERE +static int env_relocate_late (void ) +{ +env_relocate_spec_late (); +return 0 ; +} +#endif +/* * Over time we hope to remove these functions with code fragments and * stub funtcions, and instead call the relevant function directly.
@@ -898,6 +906,9 @@ static init_fnc_t init_sequence_r[] = {#ifdef CONFIG_PS2KBD initr_kbd,#endif +#ifdef CONFIG_ENV_IS_ANYWHERE + env_relocate_late, +#endif run_main_loop, };
common/env_anywhere.c new file +156 -0
156 lines not on this page · raw message
include/environment.h +5 -0
@@ -177,6 +177,11 @@ extern env_t *env_ptr;extern void env_relocate_spec (void );extern unsigned char env_get_char_spec (int ); +#ifdef CONFIG_ENV_IS_ANYWHERE +void env_relocate_spec_late (void ); +void env_set_location (struct blk_desc *desc,int part); +#endif +#if defined(CONFIG_NEEDS_MANUAL_RELOC )extern void env_reloc (void );#endif
Signature · 1 line
2.13.0
PATCH 1/1 vsprintf.c: add wide string (%ls) support
This is convenient for efi_loader which deals a lot with utf16.
--- lib/vsprintf.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)
lib/vsprintf.c +37 -2
@@ -270,6 +270,35 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +static size_t strnlen16 (const u16 * s,size_t count) +{ +const u16 *sc; + +for (sc = s; count-- && *sc; ++sc) +/* nothing */ ; +return sc - s; +} + +static char *string16 (char *buf,char *end,u16 *s,int field_width, +int precision,int flags) +{ +int len, i; + +if (s ==NULL ) + s =L"<NULL>" ; + + len =strnlen16 (s, precision); + +if (!(flags &LEFT )) +while (len < field_width--) +ADDCH (buf,' ' ); +for (i =0 ; i < len; ++i) +ADDCH (buf, *s++); +while (len < field_width--) +ADDCH (buf,' ' ); +return buf; +} +#ifdef CONFIG_CMD_NET static const char hex_asc[] ="0123456789abcdef" ;#define hex_asc_lo (x) hex_asc[((x) & 0x0f)]
@@ -528,8 +557,14 @@ repeat:continue ;case 's' : - str = string(str, end, va_arg(args, char *), - field_width, precision, flags); +if (qualifier =='l' ) { + str = string16(str, end, va_arg(args, u16 *), + field_width, precision, flags); + + }else { + str = string(str, end, va_arg(args, char *), + field_width, precision, flags); + }continue ;case 'p' :
Signature · 1 line
2.13.0
PATCH 1/1 vsprintf.c: add wide string (%ls) support
Quoted 21 lines · Rob Clark
This is convenient for
efi_loaderwhich deals a lot with utf16.Signed-off-by Rob Clark <[email protected]>--- lib/vsprintf.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)lib/vsprintf.c +6
-0@@ -270,6 +270,35 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +static size_t strnlen16 (const u16 * s,size_t count) +{ +const u16 *sc; + +for (sc = s; count-- && *sc; ++sc) +/* nothing */ ;
lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 288
Quoted 10 lines
lib/vsprintf.c +10
-0+return sc - s; +} + +static char *string16 (char *buf,char *end,u16 *s,int field_width, +int precision,int flags) +{ +int len, i; + +if (s ==NULL ) + s =L"<NULL>" ;
The L notation creates a wchar_t string. The width of wchar_t depends on gcc compiler flag -fshort-wchar.
vsprintf.c is not compiled with -fshort-wchar. So change this to
const u16 null[] = { '<', 'N', 'U', 'L', 'L', '>', 0}; s = null;
Quoted 17 lines
lib/vsprintf.c +13
-0+ + len =strnlen16 (s, precision); + +if (!(flags &LEFT )) +while (len < field_width--) +ADDCH (buf,' ' ); +for (i =0 ; i < len; ++i) +ADDCH (buf, *s++); +while (len < field_width--) +ADDCH (buf,' ' ); +return buf; +} +#ifdef CONFIG_CMD_NET static const char hex_asc[] ="0123456789abcdef" ;#define hex_asc_lo (x) hex_asc[((x) & 0x0f)]
lib/vsprintf.c repeat: · line 560
Quoted 6 lines
lib/vsprintf.c +1
-2@@ -528,8 +557,14 @@ repeat:continue ;case 's' : - str = string(str, end, va_arg(args, char *), - field_width, precision, flags); +if (qualifier =='l' ) {
According to ISO 9899:1999 %ls is used to indicate a wchar_t string, which may be u32 * or u16 * depending on GCC flag -fshort-wchar.
Wouldn't it make sense to use some other notation, e.g. %S, to indicate that we explicitly mean u16 *?
Please, add a comment into the code indicating why we need u16 * support referring to the UEFI spec.
Best regards
Heinrich
Quoted 11 lines
lib/vsprintf.c +7
-0+ str = string16(str, end, va_arg(args, u16 *), + field_width, precision, flags); + + }else { + str = string(str, end, va_arg(args, char *), + field_width, precision, flags); + }continue ;case 'p' :
PATCH 1/1 vsprintf.c: add wide string (%ls) support
Quoted 36 lines · Heinrich Schuchardt
Quoted 21 lines · Rob Clark
This is convenient for
efi_loaderwhich deals a lot with utf16.Signed-off-by Rob Clark <[email protected]>--- lib/vsprintf.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)lib/vsprintf.c +6
-0@@ -270,6 +270,35 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +static size_t strnlen16 (const u16 * s,size_t count) +{ +const u16 *sc; + +for (sc = s; count-- && *sc; ++sc) +/* nothing */ ;lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 288
Quoted 10 lines
lib/vsprintf.c +10
-0+return sc - s; +} + +static char *string16 (char *buf,char *end,u16 *s,int field_width, +int precision,int flags) +{ +int len, i; + +if (s ==NULL ) + s =L"<NULL>" ;The L notation creates a
wchar_tstring. The width ofwchar_tdepends on gcc compiler flag -fshort-wchar.
Quoted 4 lines
vsprintf.cis not compiled with -fshort-wchar. So change this toconst u16 null[] = { '<', 'N', 'U', 'L', 'L', '>', 0}; s = null;
oh, I have another patch that adds -fshort-wchar globally.. which I probably should have split out and sent with this.
The problem is we cannot mix objects using short-wchar and ones that don't without a compiler warning. Travis would complain a lot more but I guess BOOTEFI_HELLO is not normally enabled.
With addition of efi_bootmgr.c we really want to be able to use L"string" to be u16.. and I don't think u-boot has any good reason to use 32b wchar.
But maybe for this code I should use wchar_t instead of u16.
BR,
-R
Quoted 49 lines
Quoted 17 lines
lib/vsprintf.c +13
-0+ + len =strnlen16 (s, precision); + +if (!(flags &LEFT )) +while (len < field_width--) +ADDCH (buf,' ' ); +for (i =0 ; i < len; ++i) +ADDCH (buf, *s++); +while (len < field_width--) +ADDCH (buf,' ' ); +return buf; +} +#ifdef CONFIG_CMD_NET static const char hex_asc[] ="0123456789abcdef" ;#define hex_asc_lo (x) hex_asc[((x) & 0x0f)]lib/vsprintf.c repeat: · line 560
Quoted 6 lines
lib/vsprintf.c +1
-2@@ -528,8 +557,14 @@ repeat:continue ;case 's' : - str = string(str, end, va_arg(args, char *), - field_width, precision, flags); +if (qualifier =='l' ) {According to ISO 9899:1999 %ls is used to indicate a
wchar_tstring, which may be u32 * or u16 * depending on GCC flag -fshort-wchar.Wouldn't it make sense to use some other notation, e.g. %S, to indicate that we explicitly mean u16 *?
Please, add a comment into the code indicating why we need u16 * support referring to the UEFI spec.
Best regards
Heinrich
Quoted 11 lines
lib/vsprintf.c +7
-0+ str = string16(str, end, va_arg(args, u16 *), + field_width, precision, flags); + + }else { + str = string(str, end, va_arg(args, char *), + field_width, precision, flags); + }continue ;case 'p' :
PATCH 1/1 vsprintf.c: add wide string (%ls) support
Quoted 49 lines · Rob Clark
Quoted 36 lines · Heinrich Schuchardt
Quoted 21 lines · Rob Clark
This is convenient for
efi_loaderwhich deals a lot with utf16.Signed-off-by Rob Clark <[email protected]>--- lib/vsprintf.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)lib/vsprintf.c +6
-0@@ -270,6 +270,35 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +static size_t strnlen16 (const u16 * s,size_t count) +{ +const u16 *sc; + +for (sc = s; count-- && *sc; ++sc) +/* nothing */ ;lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 288
Quoted 10 lines
lib/vsprintf.c +10
-0+return sc - s; +} + +static char *string16 (char *buf,char *end,u16 *s,int field_width, +int precision,int flags) +{ +int len, i; + +if (s ==NULL ) + s =L"<NULL>" ;The L notation creates a
wchar_tstring. The width ofwchar_tdepends on gcc compiler flag -fshort-wchar.Quoted 4 lines
vsprintf.cis not compiled with -fshort-wchar. So change this toconst u16 null[] = { '<', 'N', 'U', 'L', 'L', '>', 0}; s = null;
oh, I have another patch that adds -fshort-wchar globally.. which I probably should have split out and sent with this.
The problem is we cannot mix objects using short-wchar and ones that don't without a compiler warning. Travis would complain a lot more but I guess
BOOTEFI_HELLOis not normally enabled.
Quoted 8 lines
With addition of
efi_bootmgr.cwe really want to be able to use L"string" to be u16.. and I don't think u-boot has any good reason to use 32b wchar.But maybe for this code I should use
wchar_tinstead of u16.BR,
-R
ext4 filenames may contain letters with Unicode values > 2**16, e.g. using Takri letters: 𑚀�𑚂
So ext4ls probably should be enabled to display these on a Unicode console.
Using -fshort-wchar globally is not necessary. Only UEFI requires 16 bit wchar_t. We should rather not enforce the UEFI standard on the rest of the code.
Quoted 9 lines
Quoted 9 lines
lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 296
Quoted 9 lines
lib/vsprintf.c +8
-0+ + len =strnlen16 (s, precision); + +if (!(flags &LEFT )) +while (len < field_width--) +ADDCH (buf,' ' ); +for (i =0 ; i < len; ++i) +ADDCH (buf, *s++);
I would prefer to see a conversion to UTF-8 here.
Conversion from 32bit Unicode (Or the capped 16bit Unicode of EFI) is quite easy. This is what I used in another project:
uint32_t u = s[i];
char c[5];
if (u < 0x80) {
c[0] = u & 0x7F;
c[1] = 0;
str.append(c);
} else if (u < 0x800) {
c[1] = 0x80 | (u & 0x3F);
u >>= 6;
c[0] = 0xC0 | (u & 0x1F);
c[2] = 0;
str.append(c);
} else if (u < 0x10000) {
c[2] = 0x80 | (u & 0x3F);
u >>= 6;
c[1] = 0x80 | (u & 0x3F);
u >>= 6;
c[0] = 0xE0 | (u & 0x0F);
c[3] = 0;
str.append(c);
} else if (u < 0x200000) {
c[3] = 0x80 | (u & 0x3F);
u >>= 6;
c[2] = 0x80 | (u & 0x3F);
u >>= 6;
c[1] = 0x80 | (u & 0x3F);
u >>= 6;
c[0] = 0xF0 | (u & 0x07);
c[4] = 0;
str.append(c);
} else {
throw invalid;
}Best regards
Heinrich
Quoted 42 lines
Quoted 41 lines
Quoted 9 lines
lib/vsprintf.c +5
-0+while (len < field_width--) +ADDCH (buf,' ' ); +return buf; +} +#ifdef CONFIG_CMD_NET static const char hex_asc[] ="0123456789abcdef" ;#define hex_asc_lo (x) hex_asc[((x) & 0x0f)]lib/vsprintf.c repeat: · line 560
Quoted 6 lines
lib/vsprintf.c +1
-2@@ -528,8 +557,14 @@ repeat:continue ;case 's' : - str = string(str, end, va_arg(args, char *), - field_width, precision, flags); +if (qualifier =='l' ) {According to ISO 9899:1999 %ls is used to indicate a
wchar_tstring, which may be u32 * or u16 * depending on GCC flag -fshort-wchar.Wouldn't it make sense to use some other notation, e.g. %S, to indicate that we explicitly mean u16 *?
Please, add a comment into the code indicating why we need u16 * support referring to the UEFI spec.
Best regards
Heinrich
Quoted 11 lines
lib/vsprintf.c +7
-0+ str = string16(str, end, va_arg(args, u16 *), + field_width, precision, flags); + + }else { + str = string(str, end, va_arg(args, char *), + field_width, precision, flags); + }continue ;case 'p' :
PATCH 1/1 vsprintf.c: add wide string (%ls) support
Quoted 59 lines · Heinrich Schuchardt
Quoted 49 lines · Rob Clark
Quoted 36 lines · Heinrich Schuchardt
Quoted 21 lines · Rob Clark
This is convenient for
efi_loaderwhich deals a lot with utf16.Signed-off-by Rob Clark <[email protected]>--- lib/vsprintf.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)lib/vsprintf.c +6
-0@@ -270,6 +270,35 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +static size_t strnlen16 (const u16 * s,size_t count) +{ +const u16 *sc; + +for (sc = s; count-- && *sc; ++sc) +/* nothing */ ;lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 288
Quoted 10 lines
lib/vsprintf.c +10
-0+return sc - s; +} + +static char *string16 (char *buf,char *end,u16 *s,int field_width, +int precision,int flags) +{ +int len, i; + +if (s ==NULL ) + s =L"<NULL>" ;The L notation creates a
wchar_tstring. The width ofwchar_tdepends on gcc compiler flag -fshort-wchar.Quoted 4 lines
vsprintf.cis not compiled with -fshort-wchar. So change this toconst u16 null[] = { '<', 'N', 'U', 'L', 'L', '>', 0}; s = null;
oh, I have another patch that adds -fshort-wchar globally.. which I probably should have split out and sent with this.
The problem is we cannot mix objects using short-wchar and ones that don't without a compiler warning. Travis would complain a lot more but I guess
BOOTEFI_HELLOis not normally enabled.Quoted 8 lines
With addition of
efi_bootmgr.cwe really want to be able to use L"string" to be u16.. and I don't think u-boot has any good reason to use 32b wchar.But maybe for this code I should use
wchar_tinstead of u16.BR,
-R
Quoted 8 lines
ext4 filenames may contain letters with Unicode values > 2**16, e.g. using Takri letters: 𑚀�𑚂
So ext4ls probably should be enabled to display these on a Unicode console.
Using -fshort-wchar globally is not necessary. Only UEFI requires 16 bit
wchar_t. We should rather not enforce the UEFI standard on the rest of the code.
The alternative is disabling a gcc warning about mixing 32b and 16b wchar.. and really mixing 32b and 16b wchar seems like a bad idea.
We could use -fshort-wchar only if EFI_LOADER is enabled. Technically if we are a UEFI implementation, we do not need to have ext2/ext4 (or really anything other than fat/vfat).
Quoted 40 lines
Quoted 9 lines
Quoted 9 lines
lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 296
Quoted 9 lines
lib/vsprintf.c +8
-0+ + len =strnlen16 (s, precision); + +if (!(flags &LEFT )) +while (len < field_width--) +ADDCH (buf,' ' ); +for (i =0 ; i < len; ++i) +ADDCH (buf, *s++);I would prefer to see a conversion to UTF-8 here.
Conversion from 32bit Unicode (Or the capped 16bit Unicode of EFI) is quite easy. This is what I used in another project:
uint32_t u = s[i]; char c[5]; if (u < 0x80) { c[0] = u & 0x7F; c[1] = 0; str.append(c); } else if (u < 0x800) { c[1] = 0x80 | (u & 0x3F); u >>= 6; c[0] = 0xC0 | (u & 0x1F); c[2] = 0; str.append(c); } else if (u < 0x10000) { c[2] = 0x80 | (u & 0x3F); u >>= 6; c[1] = 0x80 | (u & 0x3F); u >>= 6; c[0] = 0xE0 | (u & 0x0F); c[3] = 0; str.append(c); } else if (u < 0x200000) { c[3] = 0x80 | (u & 0x3F); u >>= 6; c[2] = 0x80 | (u & 0x3F); u >>= 6;
Quoted 8 lines
c[1] = 0x80 | (u & 0x3F);
u >>= 6;
c[0] = 0xF0 | (u & 0x07);
c[4] = 0;
str.append(c);
} else {
throw invalid;
}I did add a utf16_to_utf8() (based on code from grub) as part of the efi-variables patch, since there we are dealing with utf16 coming from outside of grub. I guess I could use that. I think that mostly matters if we end up printing strings that originate outside of u-boot, but I guess that will be the case for filenames in a device-path.
BR,
-R
Quoted 47 lines
Best regards
Heinrich
Quoted 42 lines
Quoted 41 lines
Quoted 9 lines
lib/vsprintf.c +5
-0+while (len < field_width--) +ADDCH (buf,' ' ); +return buf; +} +#ifdef CONFIG_CMD_NET static const char hex_asc[] ="0123456789abcdef" ;#define hex_asc_lo (x) hex_asc[((x) & 0x0f)]lib/vsprintf.c repeat: · line 560
Quoted 6 lines
lib/vsprintf.c +1
-2@@ -528,8 +557,14 @@ repeat:continue ;case 's' : - str = string(str, end, va_arg(args, char *), - field_width, precision, flags); +if (qualifier =='l' ) {According to ISO 9899:1999 %ls is used to indicate a
wchar_tstring, which may be u32 * or u16 * depending on GCC flag -fshort-wchar.Wouldn't it make sense to use some other notation, e.g. %S, to indicate that we explicitly mean u16 *?
Please, add a comment into the code indicating why we need u16 * support referring to the UEFI spec.
Best regards
Heinrich
Quoted 11 lines
lib/vsprintf.c +7
-0+ str = string16(str, end, va_arg(args, u16 *), + field_width, precision, flags); + + }else { + str = string(str, end, va_arg(args, char *), + field_width, precision, flags); + }continue ;case 'p' :
PATCH 1/1 vsprintf.c: add wide string (%ls) support
Quoted 69 lines · Rob Clark
Quoted 59 lines · Heinrich Schuchardt
Quoted 49 lines · Rob Clark
Quoted 36 lines · Heinrich Schuchardt
Quoted 21 lines · Rob Clark
This is convenient for
efi_loaderwhich deals a lot with utf16.Signed-off-by Rob Clark <[email protected]>--- lib/vsprintf.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)lib/vsprintf.c +6
-0@@ -270,6 +270,35 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +static size_t strnlen16 (const u16 * s,size_t count) +{ +const u16 *sc; + +for (sc = s; count-- && *sc; ++sc) +/* nothing */ ;lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 288
Quoted 10 lines
lib/vsprintf.c +10
-0+return sc - s; +} + +static char *string16 (char *buf,char *end,u16 *s,int field_width, +int precision,int flags) +{ +int len, i; + +if (s ==NULL ) + s =L"<NULL>" ;The L notation creates a
wchar_tstring. The width ofwchar_tdepends on gcc compiler flag -fshort-wchar.Quoted 4 lines
vsprintf.cis not compiled with -fshort-wchar. So change this toconst u16 null[] = { '<', 'N', 'U', 'L', 'L', '>', 0}; s = null;
oh, I have another patch that adds -fshort-wchar globally.. which I probably should have split out and sent with this.
The problem is we cannot mix objects using short-wchar and ones that don't without a compiler warning. Travis would complain a lot more but I guess
BOOTEFI_HELLOis not normally enabled.Quoted 8 lines
With addition of
efi_bootmgr.cwe really want to be able to use L"string" to be u16.. and I don't think u-boot has any good reason to use 32b wchar.But maybe for this code I should use
wchar_tinstead of u16.BR,
-RQuoted 8 lines
ext4 filenames may contain letters with Unicode values > 2**16, e.g. using Takri letters: 𑚀�𑚂
So ext4ls probably should be enabled to display these on a Unicode console.
Using -fshort-wchar globally is not necessary. Only UEFI requires 16 bit
wchar_t. We should rather not enforce the UEFI standard on the rest of the code.
Quoted 6 lines
The alternative is disabling a gcc warning about mixing 32b and 16b wchar.. and really mixing 32b and 16b wchar seems like a bad idea.
We could use -fshort-wchar only if
EFI_LOADERis enabled. Technically if we are a UEFI implementation, we do not need to have ext2/ext4 (or really anything other than fat/vfat).
You can avoid the problem of variable width wchar by using constants starting with u (e.g. u"Hello world") which are char16_t (introduced with C11, #include <uchar.h>) and converting to utf-8 for console output.
This way we do not need -fshort-wchar at all.
Best regards
Heinrich
Quoted 108 lines
Quoted 41 lines
Quoted 10 lines
Quoted 10 lines
lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 296
Quoted 10 lines
lib/vsprintf.c +8
-0+ + len =strnlen16 (s, precision); + +if (!(flags &LEFT )) +while (len < field_width--) +ADDCH (buf,' ' ); +for (i =0 ; i < len; ++i) +ADDCH (buf, *s++);I would prefer to see a conversion to UTF-8 here.
Conversion from 32bit Unicode (Or the capped 16bit Unicode of EFI) is quite easy. This is what I used in another project:
uint32_t u = s[i]; char c[5]; if (u < 0x80) { c[0] = u & 0x7F; c[1] = 0; str.append(c); } else if (u < 0x800) { c[1] = 0x80 | (u & 0x3F); u >>= 6; c[0] = 0xC0 | (u & 0x1F); c[2] = 0; str.append(c); } else if (u < 0x10000) { c[2] = 0x80 | (u & 0x3F); u >>= 6; c[1] = 0x80 | (u & 0x3F); u >>= 6; c[0] = 0xE0 | (u & 0x0F); c[3] = 0; str.append(c); } else if (u < 0x200000) { c[3] = 0x80 | (u & 0x3F); u >>= 6; c[2] = 0x80 | (u & 0x3F); u >>= 6;Quoted 8 lines
c[1] = 0x80 | (u & 0x3F); u >>= 6; c[0] = 0xF0 | (u & 0x07); c[4] = 0; str.append(c); } else { throw invalid; }I did add a
utf16_to_utf8()(based on code from grub) as part of the efi-variables patch, since there we are dealing with utf16 coming from outside of grub. I guess I could use that. I think that mostly matters if we end up printing strings that originate outside of u-boot, but I guess that will be the case for filenames in a device-path.BR,
-RQuoted 47 lines
Best regards
Heinrich
Quoted 42 lines
Quoted 41 lines
Quoted 9 lines
lib/vsprintf.c +5
-0+while (len < field_width--) +ADDCH (buf,' ' ); +return buf; +} +#ifdef CONFIG_CMD_NET static const char hex_asc[] ="0123456789abcdef" ;#define hex_asc_lo (x) hex_asc[((x) & 0x0f)]lib/vsprintf.c repeat: · line 560
Quoted 6 lines
lib/vsprintf.c +1
-2@@ -528,8 +557,14 @@ repeat:continue ;case 's' : - str = string(str, end, va_arg(args, char *), - field_width, precision, flags); +if (qualifier =='l' ) {According to ISO 9899:1999 %ls is used to indicate a
wchar_tstring, which may be u32 * or u16 * depending on GCC flag -fshort-wchar.Wouldn't it make sense to use some other notation, e.g. %S, to indicate that we explicitly mean u16 *?
Please, add a comment into the code indicating why we need u16 * support referring to the UEFI spec.
Best regards
Heinrich
Quoted 11 lines
lib/vsprintf.c +7
-0+ str = string16(str, end, va_arg(args, u16 *), + field_width, precision, flags); + + }else { + str = string(str, end, va_arg(args, char *), + field_width, precision, flags); + }continue ;case 'p' :
PATCH 1/1 vsprintf.c: add wide string (%ls) support
Quoted 77 lines · Heinrich Schuchardt
Quoted 69 lines · Rob Clark
Quoted 59 lines · Heinrich Schuchardt
Quoted 49 lines · Rob Clark
Quoted 36 lines · Heinrich Schuchardt
Quoted 21 lines · Rob Clark
This is convenient for
efi_loaderwhich deals a lot with utf16.Signed-off-by Rob Clark <[email protected]>--- lib/vsprintf.c | 39 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 37 insertions(+), 2 deletions(-)lib/vsprintf.c +6
-0@@ -270,6 +270,35 @@ static char *string(char *buf, char *end, char *s, int field_width,return buf; } +static size_t strnlen16 (const u16 * s,size_t count) +{ +const u16 *sc; + +for (sc = s; count-- && *sc; ++sc) +/* nothing */ ;lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 288
Quoted 10 lines
lib/vsprintf.c +10
-0+return sc - s; +} + +static char *string16 (char *buf,char *end,u16 *s,int field_width, +int precision,int flags) +{ +int len, i; + +if (s ==NULL ) + s =L"<NULL>" ;The L notation creates a
wchar_tstring. The width ofwchar_tdepends on gcc compiler flag -fshort-wchar.Quoted 4 lines
vsprintf.cis not compiled with -fshort-wchar. So change this toconst u16 null[] = { '<', 'N', 'U', 'L', 'L', '>', 0}; s = null;
oh, I have another patch that adds -fshort-wchar globally.. which I probably should have split out and sent with this.
The problem is we cannot mix objects using short-wchar and ones that don't without a compiler warning. Travis would complain a lot more but I guess
BOOTEFI_HELLOis not normally enabled.Quoted 8 lines
With addition of
efi_bootmgr.cwe really want to be able to use L"string" to be u16.. and I don't think u-boot has any good reason to use 32b wchar.But maybe for this code I should use
wchar_tinstead of u16.BR,
-RQuoted 8 lines
ext4 filenames may contain letters with Unicode values > 2**16, e.g. using Takri letters: 𑚀�𑚂
So ext4ls probably should be enabled to display these on a Unicode console.
Using -fshort-wchar globally is not necessary. Only UEFI requires 16 bit
wchar_t. We should rather not enforce the UEFI standard on the rest of the code.Quoted 6 lines
The alternative is disabling a gcc warning about mixing 32b and 16b wchar.. and really mixing 32b and 16b wchar seems like a bad idea.
We could use -fshort-wchar only if
EFI_LOADERis enabled. Technically if we are a UEFI implementation, we do not need to have ext2/ext4 (or really anything other than fat/vfat).
Quoted 5 lines
You can avoid the problem of variable width wchar by using constants starting with u (e.g. u"Hello world") which are
char16_t(introduced with C11, #include <uchar.h>) and converting to utf-8 for console output.This way we do not need -fshort-wchar at all.
oh, that would simplify things a *lot*.. is there a corresponding printf() modifier?
and any reason to fear requiring c11 (I have none myself)?
If not I'll switch over my patches to using u"string" and fixup efi hello too.
BR,
-R
Quoted 113 lines
Best regards
Heinrich
Quoted 108 lines
Quoted 41 lines
Quoted 10 lines
Quoted 10 lines
lib/vsprintf.c static char *string(char *buf, char *end, char *s, int field_width, · line 296
Quoted 10 lines
lib/vsprintf.c +8
-0+ + len =strnlen16 (s, precision); + +if (!(flags &LEFT )) +while (len < field_width--) +ADDCH (buf,' ' ); +for (i =0 ; i < len; ++i) +ADDCH (buf, *s++);I would prefer to see a conversion to UTF-8 here.
Conversion from 32bit Unicode (Or the capped 16bit Unicode of EFI) is quite easy. This is what I used in another project:
uint32_t u = s[i]; char c[5]; if (u < 0x80) { c[0] = u & 0x7F; c[1] = 0; str.append(c); } else if (u < 0x800) { c[1] = 0x80 | (u & 0x3F); u >>= 6; c[0] = 0xC0 | (u & 0x1F); c[2] = 0; str.append(c); } else if (u < 0x10000) { c[2] = 0x80 | (u & 0x3F); u >>= 6; c[1] = 0x80 | (u & 0x3F); u >>= 6; c[0] = 0xE0 | (u & 0x0F); c[3] = 0; str.append(c); } else if (u < 0x200000) { c[3] = 0x80 | (u & 0x3F); u >>= 6; c[2] = 0x80 | (u & 0x3F); u >>= 6;Quoted 8 lines
c[1] = 0x80 | (u & 0x3F); u >>= 6; c[0] = 0xF0 | (u & 0x07); c[4] = 0; str.append(c); } else { throw invalid; }I did add a
utf16_to_utf8()(based on code from grub) as part of the efi-variables patch, since there we are dealing with utf16 coming from outside of grub. I guess I could use that. I think that mostly matters if we end up printing strings that originate outside of u-boot, but I guess that will be the case for filenames in a device-path.BR,
-RQuoted 47 lines
Best regards
Heinrich
Quoted 42 lines
Quoted 41 lines
Quoted 9 lines
lib/vsprintf.c +5
-0+while (len < field_width--) +ADDCH (buf,' ' ); +return buf; +} +#ifdef CONFIG_CMD_NET static const char hex_asc[] ="0123456789abcdef" ;#define hex_asc_lo (x) hex_asc[((x) & 0x0f)]lib/vsprintf.c repeat: · line 560
Quoted 6 lines
lib/vsprintf.c +1
-2@@ -528,8 +557,14 @@ repeat:continue ;case 's' : - str = string(str, end, va_arg(args, char *), - field_width, precision, flags); +if (qualifier =='l' ) {According to ISO 9899:1999 %ls is used to indicate a
wchar_tstring, which may be u32 * or u16 * depending on GCC flag -fshort-wchar.Wouldn't it make sense to use some other notation, e.g. %S, to indicate that we explicitly mean u16 *?
Please, add a comment into the code indicating why we need u16 * support referring to the UEFI spec.
Best regards
Heinrich
Quoted 11 lines
lib/vsprintf.c +7
-0+ str = string16(str, end, va_arg(args, u16 *), + field_width, precision, flags); + + }else { + str = string(str, end, va_arg(args, char *), + field_width, precision, flags); + }continue ;case 'p' :
PATCH 1/1 env: add ENV_IS_ANYWHERE
In reply to Rob ClarkQuoted 6 lines · Rob Clark
Useful for devices which would otherwise have to use
ENV_IS_NOWHERE. Tries to find and load uboot.env from any block device (which may be, for example, hot-pluggable sd-card, SATA or USB disk, so the exact location is not known at the time u-boot is compiled).Signed-off-by Rob Clark <[email protected]>
I can see where this concept is useful. What I would like to see is updating the ENV_IS_IN_FAT / ENV_IS_IN_EXT4 / ENV_IS_ANYWHERE so that we end up with:
- ENV_IS_IN_FILESYSTEM
- Configured device, part, file.
- Optional specify device, otherwise help for the option describes the logic behind how U-Boot will iterate until it finds something.
Signature · 8 lines
Tom -------------- next part -------------- A non-text attachment was scrubbed... Name: signature.asc Type: application/pgp-signature Size: 819 bytes Desc: Digital signature URL: <http://lists.denx.de/pipermail/u-boot/attachments/20170802/b5d8b565/attachment.sig>