[PATCH v2 5/5] arm: apple: Do not list bootflows on boot

2024-04-18 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The bootflow list is only seen briefly and is probably more confusing
than helpful.

Signed-off-by: Janne Grunau 
---
 configs/apple_m1_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
index c30aec7c55..4eac1a9e2d 100644
--- a/configs/apple_m1_defconfig
+++ b/configs/apple_m1_defconfig
@@ -8,6 +8,7 @@ CONFIG_SYS_CBSIZE=256
 CONFIG_SYS_PBSIZE=276
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
+CONFIG_BOOTCOMMAND="bootflow scan -b"
 CONFIG_BOARD_LATE_INIT=y
 CONFIG_CMD_SELECT_FONT=y
 # CONFIG_NET is not set

-- 
2.44.0




[PATCH v2 1/5] apple_m1_defconfig: Turn on CONFIG_SYS_64BIT_LBA

2024-04-18 Thread Janne Grunau via B4 Relay
From: Hector Martin 

This makes USB HDDs >2TiB work. The only reason this hasn't bitten us
for the internal NVMe yet is the 4K sector size, because the largest SSD
Apple sells is 8TB and we can handle up to 16TiB with that sector size.
Close call.

Signed-off-by: Hector Martin 
Reviewed-by: Mark Kettenis 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 configs/apple_m1_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
index e00d72e8be..31d966f0ab 100644
--- a/configs/apple_m1_defconfig
+++ b/configs/apple_m1_defconfig
@@ -10,6 +10,7 @@ CONFIG_SYS_PBSIZE=276
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_LATE_INIT=y
 # CONFIG_NET is not set
+CONFIG_SYS_64BIT_LBA=y
 CONFIG_APPLE_SPI_KEYB=y
 # CONFIG_MMC is not set
 CONFIG_NVME_APPLE=y

-- 
2.44.0




[PATCH v2 3/5] configs: apple: Enable CMD_SELECT_FONT and FONT_16X32

2024-04-18 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Apple devices have high DPI displays so the larger fonts are preferable
for improved readability. This does not yet change the used font based
on the display's pixel density so the standard 8x16 font is still used
by default.

Reviewed-by: Mark Kettenis 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 configs/apple_m1_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
index 31d966f0ab..c30aec7c55 100644
--- a/configs/apple_m1_defconfig
+++ b/configs/apple_m1_defconfig
@@ -9,6 +9,7 @@ CONFIG_SYS_PBSIZE=276
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_LATE_INIT=y
+CONFIG_CMD_SELECT_FONT=y
 # CONFIG_NET is not set
 CONFIG_SYS_64BIT_LBA=y
 CONFIG_APPLE_SPI_KEYB=y
@@ -19,6 +20,7 @@ CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_XHCI_PCI=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_FONT_16X32=y
 CONFIG_SYS_WHITE_ON_BLACK=y
 CONFIG_NO_FB_CLEAR=y
 CONFIG_VIDEO_SIMPLE=y

-- 
2.44.0




[PATCH v2 0/5] configs: apple: Switch to standard boot + small adjustments

2024-04-18 Thread Janne Grunau via B4 Relay
This series contains a few misc config changes for Apple silicon
systems:
- switch from the deprecated distro boot scripts to standard boot
- allows EFI console resizing based on the video console size
- enables 16x32 bitmap fonts as Apple devices come with high DPI
  displays
- enables 64-bit LBA addressing

Signed-off-by: Janne Grunau 
---
Changes in v2:
- added Reviewed-by: tags
- switched to BOOTSTD_FULL to enable efi_bootmgr and make interactive
  use easier
- override BOOTCOMMAND to not list the bootflows
- rebased onto v2024.04
- Link to v1: 
https://lore.kernel.org/r/20240317-apple_config-v1-0-1b862bc14...@jannau.net

---
Hector Martin (1):
  apple_m1_defconfig: Turn on CONFIG_SYS_64BIT_LBA

Janne Grunau (4):
  configs: apple: Use "vidconsole,serial" as stdout/stderr
  configs: apple: Enable CMD_SELECT_FONT and FONT_16X32
  arm: apple: Switch to standard boot
  arm: apple: Do not list bootflows on boot

 arch/arm/Kconfig   |  2 +-
 configs/apple_m1_defconfig |  4 
 include/configs/apple.h| 24 
 3 files changed, 9 insertions(+), 21 deletions(-)
---
base-commit: 25049ad560826f7dc1c4740883b0016014a59789
change-id: 20240317-apple_config-981fcd9028b9

Best regards,
-- 
Janne Grunau 




[PATCH v2 2/5] configs: apple: Use "vidconsole,serial" as stdout/stderr

2024-04-18 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The display size querying in efi_console relies on this order. The
display should be the primary output device and should be used to
display more than 80x25 chars.

Reviewed-by: Mark Kettenis 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 include/configs/apple.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/configs/apple.h b/include/configs/apple.h
index 0576bc04c9..a70440b3ad 100644
--- a/include/configs/apple.h
+++ b/include/configs/apple.h
@@ -6,8 +6,8 @@
 /* Environment */
 #define ENV_DEVICE_SETTINGS \
"stdin=serial,usbkbd,spikbd\0" \
-   "stdout=serial,vidconsole\0" \
-   "stderr=serial,vidconsole\0"
+   "stdout=vidconsole,serial\0" \
+   "stderr=vidconsole,serial\0"
 
 #if IS_ENABLED(CONFIG_CMD_NVME)
#define BOOT_TARGET_NVME(func) func(NVME, nvme, 0)

-- 
2.44.0




[PATCH v2 4/5] arm: apple: Switch to standard boot

2024-04-18 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Use standard boot instead of the distro boot scripts. Use
BOOTSTD_FULL instead of BOOTSTD_DEFAULTS for easier interactive use.

Signed-off-by: Janne Grunau 
---
 arch/arm/Kconfig|  2 +-
 include/configs/apple.h | 20 ++--
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 01d6556c42..9b83b2e6f8 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1034,7 +1034,7 @@ config ARCH_APPLE
select USB
imply CMD_DM
imply CMD_GPT
-   imply DISTRO_DEFAULTS
+   imply BOOTSTD_FULL
imply OF_HAS_PRIOR_STAGE
 
 config ARCH_OWL
diff --git a/include/configs/apple.h b/include/configs/apple.h
index a70440b3ad..1e08b11448 100644
--- a/include/configs/apple.h
+++ b/include/configs/apple.h
@@ -9,26 +9,10 @@
"stdout=vidconsole,serial\0" \
"stderr=vidconsole,serial\0"
 
-#if IS_ENABLED(CONFIG_CMD_NVME)
-   #define BOOT_TARGET_NVME(func) func(NVME, nvme, 0)
-#else
-   #define BOOT_TARGET_NVME(func)
-#endif
-
-#if IS_ENABLED(CONFIG_CMD_USB)
-   #define BOOT_TARGET_USB(func) func(USB, usb, 0)
-#else
-   #define BOOT_TARGET_USB(func)
-#endif
-
-#define BOOT_TARGET_DEVICES(func) \
-   BOOT_TARGET_NVME(func) \
-   BOOT_TARGET_USB(func)
-
-#include 
+#define BOOT_TARGETS   "nvme usb"
 
 #define CFG_EXTRA_ENV_SETTINGS \
ENV_DEVICE_SETTINGS \
-   BOOTENV
+   "boot_targets=" BOOT_TARGETS "\0"
 
 #endif

-- 
2.44.0




[PATCH v4 1/6] usb: xhci: refactor xhci_set_configuration

2024-04-04 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

In the next step endpoints for multiple interfaces are set up. Move most
of the per endpoint initialization to separate function to avoid another
identation level.

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci.c | 119 +---
 1 file changed, 73 insertions(+), 46 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d13cbff9b3..534c4b973f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -475,67 +475,34 @@ static int xhci_configure_endpoints(struct usb_device 
*udev, bool ctx_change)
 }
 
 /**
- * Configure the endpoint, programming the device contexts.
+ * Fill endpoint contexts for interface descriptor ifdesc.
  *
- * @param udev pointer to the USB device structure
- * Return: returns the status of the xhci_configure_endpoints
+ * @param udev pointer to the USB device structure
+ * @param ctrl pointer to the xhci pravte device structure
+ * @param virt_dev pointer to the xhci virtual device structure
+ * @param ifdesc   pointer to the USB interface config descriptor
+ * Return: returns the status of xhci_init_ep_contexts_if
  */
-static int xhci_set_configuration(struct usb_device *udev)
+static int xhci_init_ep_contexts_if(struct usb_device *udev,
+   struct xhci_ctrl *ctrl,
+   struct xhci_virt_device *virt_dev,
+   struct usb_interface *ifdesc
+   )
 {
-   struct xhci_container_ctx *in_ctx;
-   struct xhci_container_ctx *out_ctx;
-   struct xhci_input_control_ctx *ctrl_ctx;
-   struct xhci_slot_ctx *slot_ctx;
struct xhci_ep_ctx *ep_ctx[MAX_EP_CTX_NUM];
int cur_ep;
-   int max_ep_flag = 0;
int ep_index;
unsigned int dir;
unsigned int ep_type;
-   struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
-   int num_of_ep;
-   int ep_flag = 0;
u64 trb_64 = 0;
-   int slot_id = udev->slot_id;
-   struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
-   struct usb_interface *ifdesc;
u32 max_esit_payload;
unsigned int interval;
unsigned int mult;
unsigned int max_burst;
unsigned int avg_trb_len;
unsigned int err_count = 0;
+   int num_of_ep = ifdesc->no_of_ep;
 
-   out_ctx = virt_dev->out_ctx;
-   in_ctx = virt_dev->in_ctx;
-
-   num_of_ep = udev->config.if_desc[0].no_of_ep;
-   ifdesc = >config.if_desc[0];
-
-   ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
-   /* Initialize the input context control */
-   ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
-   ctrl_ctx->drop_flags = 0;
-
-   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
-   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
-   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
-   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
-   if (max_ep_flag < ep_flag)
-   max_ep_flag = ep_flag;
-   }
-
-   xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
-
-   /* slot context */
-   xhci_slot_copy(ctrl, in_ctx, out_ctx);
-   slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
-   slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
-   slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
-
-   xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
-
-   /* filling up ep contexts */
for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
struct usb_endpoint_descriptor *endpt_desc = NULL;
struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc = NULL;
@@ -561,7 +528,8 @@ static int xhci_set_configuration(struct usb_device *udev)
avg_trb_len = max_esit_payload;
 
ep_index = xhci_get_ep_index(endpt_desc);
-   ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
+   ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx,
+  ep_index);
 
/* Allocate the ep rings */
virt_dev->eps[ep_index].ring = xhci_ring_alloc(ctrl, 1, true);
@@ -614,6 +582,65 @@ static int xhci_set_configuration(struct usb_device *udev)
}
}
 
+   return 0;
+}
+
+/**
+ * Configure the endpoint, programming the device contexts.
+ *
+ * @param udev pointer to the USB device structure
+ * Return: returns the status of the xhci_configure_endpoints
+ */
+static int xhci_set_configuration(struct usb_device *udev)
+{
+   struct xhci_container_ctx *out_ctx;
+   struct xhci_container_ctx *in_ctx;
+   struct xhci_input_control_ctx *ctrl_ctx;
+   struct xhci_slot_ctx *slot_ctx;
+   int err;
+   int cur_ep;
+   int max_ep_flag = 0;
+   struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
+   int 

[PATCH v4 2/6] usb: xhci: Set up endpoints for the first 2 interfaces

2024-04-04 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The xhci driver currently only does the necessary initialization for
endpoints found in the first interface descriptor. Apple USB keyboards
(released 2021) use the second interface descriptor for the HID keyboard
boot protocol. To allow USB drivers to use endpoints from other
interface descriptors the xhci driver needs to ensure these endpoints
are initialized as well.
Use USB_MAX_ACTIVE_INTERFACES to control how many interface descriptors
are considered during endpoint initialisation.
For now define it to 2 as that is sufficient for supporting the Apple
keyboards.

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci.c | 31 +++
 include/usb.h   |  6 ++
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 534c4b973f..741e186ee0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -606,24 +606,28 @@ static int xhci_set_configuration(struct usb_device *udev)
int slot_id = udev->slot_id;
struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
struct usb_interface *ifdesc;
+   unsigned int ifnum;
+   unsigned int max_ifnum = min((unsigned int)USB_MAX_ACTIVE_INTERFACES,
+(unsigned int)udev->config.no_of_if);
 
out_ctx = virt_dev->out_ctx;
in_ctx = virt_dev->in_ctx;
 
-   num_of_ep = udev->config.if_desc[0].no_of_ep;
-   ifdesc = >config.if_desc[0];
-
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
/* Initialize the input context control */
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
ctrl_ctx->drop_flags = 0;
 
-   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
-   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
-   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
-   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
-   if (max_ep_flag < ep_flag)
-   max_ep_flag = ep_flag;
+   for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+   ifdesc = >config.if_desc[ifnum];
+   num_of_ep = ifdesc->no_of_ep;
+   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
+   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
+   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
+   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
+   if (max_ep_flag < ep_flag)
+   max_ep_flag = ep_flag;
+   }
}
 
xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
@@ -637,9 +641,12 @@ static int xhci_set_configuration(struct usb_device *udev)
xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
 
/* filling up ep contexts */
-   err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
-   if (err < 0)
-   return err;
+   for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+   ifdesc = >config.if_desc[ifnum];
+   err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
+   if (err < 0)
+   return err;
+   }
 
return xhci_configure_endpoints(udev, false);
 }
diff --git a/include/usb.h b/include/usb.h
index 09e3f0cb30..3aafdc8bfd 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -49,6 +49,12 @@ extern bool usb_started; /* flag for the started/stopped USB 
status */
  */
 #define USB_TIMEOUT_MS(pipe) (usb_pipebulk(pipe) ? 5000 : 1000)
 
+/*
+ * The xhcd hcd driver prepares only a limited number interfaces / endpoints.
+ * Define this limit so that drivers do not exceed it.
+ */
+#define USB_MAX_ACTIVE_INTERFACES  2
+
 /* device request (setup) */
 struct devrequest {
__u8requesttype;

-- 
2.44.0




[PATCH v4 4/6] usb: Add environment based device ignorelist

2024-04-04 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Add the environment variable "usb_ignorelist" to prevent USB devices
listed in it from being bound to drivers. This allows to ignore devices
which are undesirable or trigger bugs in u-boot's USB stack.
Devices emulating keyboards are one example of undesirable devices as
u-boot currently supports only a single USB keyboard device. Most
commonly, people run into this with Yubikeys, so let's ignore those in
the default environment.

Based on previous USB keyboard specific patches for the same purpose.

Link: 
https://lore.kernel.org/u-boot/7ab604fb-0fec-4f5e-8708-7a3a7e2cb...@denx.de/
Reviewed-by: Neal Gompa 
Reviewed-by: Marek Vasut 
Signed-off-by: Janne Grunau 
---
 common/usb.c  | 64 +++
 doc/usage/environment.rst | 13 ++
 include/env_default.h | 11 
 3 files changed, 88 insertions(+)

diff --git a/common/usb.c b/common/usb.c
index 836506dcd9..44db07742e 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1084,6 +1085,48 @@ static int usb_prepare_device(struct usb_device *dev, 
int addr, bool do_read,
return 0;
 }
 
+static int usb_device_is_ignored(u16 id_vendor, u16 id_product)
+{
+   ulong vid, pid;
+   char *end;
+   const char *cur = env_get("usb_ignorelist");
+
+   /* parse "usb_ignorelist" strictly */
+   while (cur && cur[0] != '\0') {
+   vid = simple_strtoul(cur, , 0);
+   /*
+* If strtoul did not parse a single digit or the next char is
+* not ':' the ignore list is malformed.
+*/
+   if (cur == end || end[0] != ':')
+   return -EINVAL;
+
+   cur = end + 1;
+   pid = simple_strtoul(cur, , 0);
+   /* Consider '*' as wildcard for the product ID */
+   if (cur == end && end[0] == '*') {
+   pid = U16_MAX + 1;
+   end++;
+   }
+   /*
+* The ignore list is malformed if no product ID / wildcard was
+* parsed or entries are not separated by ',' or terminated with
+* '\0'.
+*/
+   if (cur == end || (end[0] != ',' && end[0] != '\0'))
+   return -EINVAL;
+
+   if (id_vendor == vid && (pid > U16_MAX || id_product == pid))
+   return -ENODEV;
+
+   if (end[0] == '\0')
+   break;
+   cur = end + 1;
+   }
+
+   return 0;
+}
+
 int usb_select_config(struct usb_device *dev)
 {
unsigned char *tmpbuf = NULL;
@@ -1099,6 +1142,27 @@ int usb_select_config(struct usb_device *dev)
le16_to_cpus(>descriptor.idProduct);
le16_to_cpus(>descriptor.bcdDevice);
 
+   /* ignore devices from usb_ignorelist */
+   err = usb_device_is_ignored(dev->descriptor.idVendor,
+   dev->descriptor.idProduct);
+   if (err == -ENODEV) {
+   dev_dbg(dev->dev, "Ignoring USB device 0x%x:0x%x\n",
+   dev->descriptor.idVendor, dev->descriptor.idProduct);
+   return err;
+   } else if (err == -EINVAL) {
+   /*
+* Continue on "usb_ignorelist" parsing errors. The list is
+* parsed for each device returning the error would result in
+* ignoring all USB devices.
+* Since the parsing error is independent of the probed device
+* report errors with printf instead of dev_err.
+*/
+   printf("usb_ignorelist parse error in \"%s\"\n",
+  env_get("usb_ignorelist"));
+   } else if (err < 0) {
+   return err;
+   }
+
/*
 * Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive
 * about this first Get Descriptor request. If there are any other
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst
index ebf75fa948..7d4b448cb3 100644
--- a/doc/usage/environment.rst
+++ b/doc/usage/environment.rst
@@ -366,6 +366,19 @@ tftpwindowsize
 This means the count of blocks we can receive before
 sending ack to server.
 
+usb_ignorelist
+Ignore USB devices to prevent binding them to an USB device driver. This 
can
+be used to ignore devices are for some reason undesirable or causes crashes
+u-boot's USB stack.
+An example for undesired behavior is the keyboard emulation of security 
keys
+like Yubikeys. U-boot currently supports only a single USB keyboard device
+so try to probe an useful keyboard device. The default environment blocks
+Yubico devices as common devices emulating keyboards.
+Devices are matched by idVendor and idProduct. The variable contains a 
comma
+separated list of idVendor:idProduct pairs 

[PATCH v4 0/6] USB keyboard improvements for asahi / desktop systems

2024-04-04 Thread Janne Grunau via B4 Relay
Apple USB Keyboards from 2021 need quirks to be useable. The boot HID
keyboard protocol is unfortunately not described in the first interface
descriptor but the second. This needs several changes. The USB keyboard
driver has to look at all (2) interface descriptors during probing.
Since I didn't want to rebuild the USB driver probe code the Apple
keyboards are bound to the keyboard driver via USB vendor and product
IDs.
To make the keyboards useable on Apple silicon devices the xhci driver
needs to initializes rings for the endpoints of the first two interface
descriptors. If this is causes concerns regarding regressions or memory
use the USB_MAX_ACTIVE_INTERFACES define could be turned into a CONFIG
option.
Even after this changes the keyboards still do not probe successfully
since they apparently do not behave HID standard compliant. They only
generate reports on key events. This leads the final check whether the
keyboard is operational to fail unless the user presses keys during the
probe. Skip this check for known keyboards.
Keychron seems to emulate Apple keyboards (some models even "re-use"
Apple's USB vendor ID) so apply this quirk as well.

Some devices like Yubikeys emulate a keyboard. since u-boot only binds a
single keyboard block this kind of devices from the USB keyboard driver.

Signed-off-by: Janne Grunau 
---
Changes in v4:
- collects "Reviewed-by:" tagDITME: describe what is new in this series 
revision.
- adds comment about usb_ignorelist parse errors
- Link to v3: 
https://lore.kernel.org/r/20240322-asahi-keyboards-v3-0-3106dd4c4...@jannau.net

Changes in v3:
- collected "Reviewed-by:" tags
- rename usb_blocklist to usb_ignorelist
- use BIT macro for USB KBD quirk bit
- refactor usb_device_is_blocked() to use 0 / negated errors as return
  value, sed -e 's/block/ignore/', simplify it and add comments
- rewritten usb_ignorelist documentation
- Link to v2: 
https://lore.kernel.org/r/20240317-asahi-keyboards-v2-0-d3f4b8384...@jannau.net

Changes in v2:
- rewritten commit message for "[PATCH 2/6] usb: xhci: Set up endpoints for the 
first 2 interfaces"
- Replaced the usb keyboard Yubikey block with an env based USB device blocklist
- Use "-EINVAL" as return value in "[PATCH 3/6] usb: xhci: Abort transfers with 
unallocated rings"
- added "Reviewed-by:" tags
- Link to v1: 
https://lore.kernel.org/r/20240221-asahi-keyboards-v1-0-814b2e741...@jannau.net

---
Janne Grunau (6):
  usb: xhci: refactor xhci_set_configuration
  usb: xhci: Set up endpoints for the first 2 interfaces
  usb: xhci: Abort transfers with unallocated rings
  usb: Add environment based device ignorelist
  usb: kbd: support Apple Magic Keyboards (2021)
  usb: kbd: Add probe quirk for Apple and Keychron keyboards

 common/usb.c |  64 ++
 common/usb_kbd.c |  59 ++--
 doc/usage/environment.rst|  13 +
 drivers/usb/host/xhci-ring.c |   5 ++
 drivers/usb/host/xhci.c  | 126 +++
 include/env_default.h|  11 
 include/usb.h|   6 +++
 7 files changed, 235 insertions(+), 49 deletions(-)
---
base-commit: 37345abb97ef0dd9c50a03b2a72617612dcae585
change-id: 20240218-asahi-keyboards-f2ddaf0022b2

Best regards,
-- 
Janne Grunau 




[PATCH v4 5/6] usb: kbd: support Apple Magic Keyboards (2021)

2024-04-04 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Apple USB keyboards (Magic Keyboard from 2021 (product id 0x029c)) carry
the HID keyboard boot protocol on the second interface descriptor.
Probe via vendor and product IDs since the class/subclass/protocol match
uses the first interface descriptor.
Probe the two first interface descriptors for the HID keyboard boot
protocol.

USB configuration descriptor for reference:

| Bus 003 Device 002: ID 05ac:029c Apple, Inc. Magic Keyboard
| Device Descriptor:
|   bLength18
|   bDescriptorType 1
|   bcdUSB   2.00
|   bDeviceClass0 [unknown]
|   bDeviceSubClass 0 [unknown]
|   bDeviceProtocol 0
|   bMaxPacketSize064
|   idVendor   0x05ac Apple, Inc.
|   idProduct  0x029c Magic Keyboard
|   bcdDevice3.90
|   iManufacturer   1 Apple Inc.
|   iProduct2 Magic Keyboard
|   iSerial 3 ...
|   bNumConfigurations  1
|   Configuration Descriptor:
| bLength 9
| bDescriptorType 2
| wTotalLength   0x003b
| bNumInterfaces  2
| bConfigurationValue 1
| iConfiguration  4 Keyboard
| bmAttributes 0xa0
|   (Bus Powered)
|   Remote Wakeup
| MaxPower  500mA
| Interface Descriptor:
|   bLength 9
|   bDescriptorType 4
|   bInterfaceNumber0
|   bAlternateSetting   0
|   bNumEndpoints   1
|   bInterfaceClass 3 Human Interface Device
|   bInterfaceSubClass  0 [unknown]
|   bInterfaceProtocol  0
|   iInterface  5 Device Management
| HID Device Descriptor:
|   bLength 9
|   bDescriptorType33
|   bcdHID   1.10
|   bCountryCode0 Not supported
|   bNumDescriptors 1
|   bDescriptorType34 Report
|   wDescriptorLength  83
|   Report Descriptors:
| ** UNAVAILABLE **
|   Endpoint Descriptor:
| bLength 7
| bDescriptorType 5
| bEndpointAddress 0x81  EP 1 IN
| bmAttributes3
|   Transfer TypeInterrupt
|   Synch Type   None
|   Usage Type   Data
| wMaxPacketSize 0x0010  1x 16 bytes
| bInterval   8
| Interface Descriptor:
|   bLength 9
|   bDescriptorType 4
|   bInterfaceNumber1
|   bAlternateSetting   0
|   bNumEndpoints   1
|   bInterfaceClass 3 Human Interface Device
|   bInterfaceSubClass  1 Boot Interface Subclass
|   bInterfaceProtocol  1 Keyboard
|   iInterface  6 Keyboard / Boot
| HID Device Descriptor:
|   bLength 9
|   bDescriptorType33
|   bcdHID   1.10
|   bCountryCode   13 International (ISO)
|   bNumDescriptors 1
|   bDescriptorType34 Report
|   wDescriptorLength 207
|   Report Descriptors:
| ** UNAVAILABLE **
|   Endpoint Descriptor:
| bLength 7
| bDescriptorType 5
| bEndpointAddress 0x82  EP 2 IN
| bmAttributes3
|   Transfer TypeInterrupt
|   Synch Type   None
|   Usage Type   Data
| wMaxPacketSize 0x0010  1x 16 bytes
| bInterval   8

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 common/usb_kbd.c | 37 ++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 4cbc9acb73..b2361bbf18 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -23,6 +23,14 @@
 
 #include 
 
+/*
+ * USB vendor and product IDs used for quirks.
+ */
+#define USB_VENDOR_ID_APPLE0x05ac
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_20210x029c
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_20210x029a
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
+
 /*
  * If overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -106,6 +114,8 @@ struct usb_kbd_pdata {
unsigned long   last_report;
struct int_queue *intq;
 
+   uint32_tifnum;
+
uint32_trepeat_delay;
 
uint32_tusb_in_pointer;
@@ -150,8 +160,8 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, 
u8 c)
  */
 static void usb_kbd_setled(struct usb_device *dev)
 {
-   struct usb_interface *iface = >config.if_desc[0];
struct usb_kbd_pdata *data = dev->privptr;
+   struct usb_interface 

[PATCH v4 3/6] usb: xhci: Abort transfers with unallocated rings

2024-04-04 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Discovered while trying to use the second interface in the USB keyboard
driver necessary on Apple USB keyboards.

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci-ring.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b60661fe05..910c5f3352 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -685,6 +685,9 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long 
pipe,
reset_ep(udev, ep_index);
 
ring = virt_dev->eps[ep_index].ring;
+   if (!ring)
+   return -EINVAL;
+
/*
 * How much data is (potentially) left before the 64KB boundary?
 * XHCI Spec puts restriction( TABLE 49 and 6.4.1 section of XHCI Spec)
@@ -871,6 +874,8 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long 
pipe,
ep_index = usb_pipe_ep_index(pipe);
 
ep_ring = virt_dev->eps[ep_index].ring;
+   if (!ep_ring)
+   return -EINVAL;
 
/*
 * Check to see if the max packet size for the default control

-- 
2.44.0




[PATCH v4 6/6] usb: kbd: Add probe quirk for Apple and Keychron keyboards

2024-04-04 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Those keyboards do not return the current device state. Polling will
timeout unless there are key presses. This is not a problem during
operation but the initial device state query during probing will fail.
Skip this step in usb_kbd_probe_dev() to make these devices useable.
Not all Apple keyboards behave like this. A keyboard with USB
vendor/product ID 05ac:0221 is reported to work with the current code.
Unfortunately some Keychron keyboards "re-use" Apple's vendor ID and
show the same behavior (Keychron C2, 05ac:024f for example).

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 common/usb_kbd.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index b2361bbf18..820f591fc5 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -31,6 +31,10 @@
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_20210x029a
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
 
+#define USB_VENDOR_ID_KEYCHRON 0x3434
+
+#define USB_HID_QUIRK_POLL_NO_REPORT_IDLE  BIT(0)
+
 /*
  * If overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -474,6 +478,7 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
struct usb_interface *iface;
struct usb_endpoint_descriptor *ep;
struct usb_kbd_pdata *data;
+   unsigned int quirks = 0;
int epNum;
 
if (dev->descriptor.bNumConfigurations != 1)
@@ -506,6 +511,15 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
 
debug("USB KBD: found interrupt EP: 0x%x\n", ep->bEndpointAddress);
 
+   switch (dev->descriptor.idVendor) {
+   case USB_VENDOR_ID_APPLE:
+   case USB_VENDOR_ID_KEYCHRON:
+   quirks |= USB_HID_QUIRK_POLL_NO_REPORT_IDLE;
+   break;
+   default:
+   break;
+   }
+
data = malloc(sizeof(struct usb_kbd_pdata));
if (!data) {
printf("USB KBD: Error allocating private data\n");
@@ -546,6 +560,14 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
 #endif
 
+   /*
+* Apple and Keychron keyboards do not report the device state. Reports
+* are only returned during key presses.
+*/
+   if (quirks & USB_HID_QUIRK_POLL_NO_REPORT_IDLE) {
+   debug("USB KBD: quirk: skip testing device state\n");
+   return 1;
+   }
debug("USB KBD: enable interrupt pipe...\n");
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
data->intq = create_int_queue(dev, data->intpipe, 1,

-- 
2.44.0




[PATCH v3 0/6] USB keyboard improvements for asahi / desktop systems

2024-03-22 Thread Janne Grunau via B4 Relay
Apple USB Keyboards from 2021 need quirks to be useable. The boot HID
keyboard protocol is unfortunately not described in the first interface
descriptor but the second. This needs several changes. The USB keyboard
driver has to look at all (2) interface descriptors during probing.
Since I didn't want to rebuild the USB driver probe code the Apple
keyboards are bound to the keyboard driver via USB vendor and product
IDs.
To make the keyboards useable on Apple silicon devices the xhci driver
needs to initializes rings for the endpoints of the first two interface
descriptors. If this is causes concerns regarding regressions or memory
use the USB_MAX_ACTIVE_INTERFACES define could be turned into a CONFIG
option.
Even after this changes the keyboards still do not probe successfully
since they apparently do not behave HID standard compliant. They only
generate reports on key events. This leads the final check whether the
keyboard is operational to fail unless the user presses keys during the
probe. Skip this check for known keyboards.
Keychron seems to emulate Apple keyboards (some models even "re-use"
Apple's USB vendor ID) so apply this quirk as well.

Some devices like Yubikeys emulate a keyboard. since u-boot only binds a
single keyboard block this kind of devices from the USB keyboard driver.

Signed-off-by: Janne Grunau 
---
Changes in v3:
- collected "Reviewed-by:" tags
- rename usb_blocklist to usb_ignorelist
- use BIT macro for USB KBD quirk bit
- refactor usb_device_is_blocked() to use 0 / negated errors as return
  value, sed -e 's/block/ignore/', simplify it and add comments
- rewritten usb_ignorelist documentation
- Link to v2: 
https://lore.kernel.org/r/20240317-asahi-keyboards-v2-0-d3f4b8384...@jannau.net

Changes in v2:
- rewritten commit message for "[PATCH 2/6] usb: xhci: Set up endpoints for the 
first 2 interfaces"
- Replaced the usb keyboard Yubikey block with an env based USB device blocklist
- Use "-EINVAL" as return value in "[PATCH 3/6] usb: xhci: Abort transfers with 
unallocated rings"
- added "Reviewed-by:" tags
- Link to v1: 
https://lore.kernel.org/r/20240221-asahi-keyboards-v1-0-814b2e741...@jannau.net

---
Janne Grunau (6):
  usb: xhci: refactor xhci_set_configuration
  usb: xhci: Set up endpoints for the first 2 interfaces
  usb: xhci: Abort transfers with unallocated rings
  usb: Add environment based device ignorelist
  usb: kbd: support Apple Magic Keyboards (2021)
  usb: kbd: Add probe quirk for Apple and Keychron keyboards

 common/usb.c |  57 
 common/usb_kbd.c |  59 ++--
 doc/usage/environment.rst|  13 +
 drivers/usb/host/xhci-ring.c |   5 ++
 drivers/usb/host/xhci.c  | 126 +++
 include/env_default.h|  11 
 include/usb.h|   6 +++
 7 files changed, 228 insertions(+), 49 deletions(-)
---
base-commit: 37345abb97ef0dd9c50a03b2a72617612dcae585
change-id: 20240218-asahi-keyboards-f2ddaf0022b2

Best regards,
-- 
Janne Grunau 




[PATCH v3 1/6] usb: xhci: refactor xhci_set_configuration

2024-03-22 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

In the next step endpoints for multiple interfaces are set up. Move most
of the per endpoint initialization to separate function to avoid another
identation level.

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci.c | 119 +---
 1 file changed, 73 insertions(+), 46 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d13cbff9b3..534c4b973f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -475,67 +475,34 @@ static int xhci_configure_endpoints(struct usb_device 
*udev, bool ctx_change)
 }
 
 /**
- * Configure the endpoint, programming the device contexts.
+ * Fill endpoint contexts for interface descriptor ifdesc.
  *
- * @param udev pointer to the USB device structure
- * Return: returns the status of the xhci_configure_endpoints
+ * @param udev pointer to the USB device structure
+ * @param ctrl pointer to the xhci pravte device structure
+ * @param virt_dev pointer to the xhci virtual device structure
+ * @param ifdesc   pointer to the USB interface config descriptor
+ * Return: returns the status of xhci_init_ep_contexts_if
  */
-static int xhci_set_configuration(struct usb_device *udev)
+static int xhci_init_ep_contexts_if(struct usb_device *udev,
+   struct xhci_ctrl *ctrl,
+   struct xhci_virt_device *virt_dev,
+   struct usb_interface *ifdesc
+   )
 {
-   struct xhci_container_ctx *in_ctx;
-   struct xhci_container_ctx *out_ctx;
-   struct xhci_input_control_ctx *ctrl_ctx;
-   struct xhci_slot_ctx *slot_ctx;
struct xhci_ep_ctx *ep_ctx[MAX_EP_CTX_NUM];
int cur_ep;
-   int max_ep_flag = 0;
int ep_index;
unsigned int dir;
unsigned int ep_type;
-   struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
-   int num_of_ep;
-   int ep_flag = 0;
u64 trb_64 = 0;
-   int slot_id = udev->slot_id;
-   struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
-   struct usb_interface *ifdesc;
u32 max_esit_payload;
unsigned int interval;
unsigned int mult;
unsigned int max_burst;
unsigned int avg_trb_len;
unsigned int err_count = 0;
+   int num_of_ep = ifdesc->no_of_ep;
 
-   out_ctx = virt_dev->out_ctx;
-   in_ctx = virt_dev->in_ctx;
-
-   num_of_ep = udev->config.if_desc[0].no_of_ep;
-   ifdesc = >config.if_desc[0];
-
-   ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
-   /* Initialize the input context control */
-   ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
-   ctrl_ctx->drop_flags = 0;
-
-   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
-   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
-   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
-   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
-   if (max_ep_flag < ep_flag)
-   max_ep_flag = ep_flag;
-   }
-
-   xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
-
-   /* slot context */
-   xhci_slot_copy(ctrl, in_ctx, out_ctx);
-   slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
-   slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
-   slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
-
-   xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
-
-   /* filling up ep contexts */
for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
struct usb_endpoint_descriptor *endpt_desc = NULL;
struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc = NULL;
@@ -561,7 +528,8 @@ static int xhci_set_configuration(struct usb_device *udev)
avg_trb_len = max_esit_payload;
 
ep_index = xhci_get_ep_index(endpt_desc);
-   ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
+   ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx,
+  ep_index);
 
/* Allocate the ep rings */
virt_dev->eps[ep_index].ring = xhci_ring_alloc(ctrl, 1, true);
@@ -614,6 +582,65 @@ static int xhci_set_configuration(struct usb_device *udev)
}
}
 
+   return 0;
+}
+
+/**
+ * Configure the endpoint, programming the device contexts.
+ *
+ * @param udev pointer to the USB device structure
+ * Return: returns the status of the xhci_configure_endpoints
+ */
+static int xhci_set_configuration(struct usb_device *udev)
+{
+   struct xhci_container_ctx *out_ctx;
+   struct xhci_container_ctx *in_ctx;
+   struct xhci_input_control_ctx *ctrl_ctx;
+   struct xhci_slot_ctx *slot_ctx;
+   int err;
+   int cur_ep;
+   int max_ep_flag = 0;
+   struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
+   int 

[PATCH v3 5/6] usb: kbd: support Apple Magic Keyboards (2021)

2024-03-22 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Apple USB keyboards (Magic Keyboard from 2021 (product id 0x029c)) carry
the HID keyboard boot protocol on the second interface descriptor.
Probe via vendor and product IDs since the class/subclass/protocol match
uses the first interface descriptor.
Probe the two first interface descriptors for the HID keyboard boot
protocol.

USB configuration descriptor for reference:

| Bus 003 Device 002: ID 05ac:029c Apple, Inc. Magic Keyboard
| Device Descriptor:
|   bLength18
|   bDescriptorType 1
|   bcdUSB   2.00
|   bDeviceClass0 [unknown]
|   bDeviceSubClass 0 [unknown]
|   bDeviceProtocol 0
|   bMaxPacketSize064
|   idVendor   0x05ac Apple, Inc.
|   idProduct  0x029c Magic Keyboard
|   bcdDevice3.90
|   iManufacturer   1 Apple Inc.
|   iProduct2 Magic Keyboard
|   iSerial 3 ...
|   bNumConfigurations  1
|   Configuration Descriptor:
| bLength 9
| bDescriptorType 2
| wTotalLength   0x003b
| bNumInterfaces  2
| bConfigurationValue 1
| iConfiguration  4 Keyboard
| bmAttributes 0xa0
|   (Bus Powered)
|   Remote Wakeup
| MaxPower  500mA
| Interface Descriptor:
|   bLength 9
|   bDescriptorType 4
|   bInterfaceNumber0
|   bAlternateSetting   0
|   bNumEndpoints   1
|   bInterfaceClass 3 Human Interface Device
|   bInterfaceSubClass  0 [unknown]
|   bInterfaceProtocol  0
|   iInterface  5 Device Management
| HID Device Descriptor:
|   bLength 9
|   bDescriptorType33
|   bcdHID   1.10
|   bCountryCode0 Not supported
|   bNumDescriptors 1
|   bDescriptorType34 Report
|   wDescriptorLength  83
|   Report Descriptors:
| ** UNAVAILABLE **
|   Endpoint Descriptor:
| bLength 7
| bDescriptorType 5
| bEndpointAddress 0x81  EP 1 IN
| bmAttributes3
|   Transfer TypeInterrupt
|   Synch Type   None
|   Usage Type   Data
| wMaxPacketSize 0x0010  1x 16 bytes
| bInterval   8
| Interface Descriptor:
|   bLength 9
|   bDescriptorType 4
|   bInterfaceNumber1
|   bAlternateSetting   0
|   bNumEndpoints   1
|   bInterfaceClass 3 Human Interface Device
|   bInterfaceSubClass  1 Boot Interface Subclass
|   bInterfaceProtocol  1 Keyboard
|   iInterface  6 Keyboard / Boot
| HID Device Descriptor:
|   bLength 9
|   bDescriptorType33
|   bcdHID   1.10
|   bCountryCode   13 International (ISO)
|   bNumDescriptors 1
|   bDescriptorType34 Report
|   wDescriptorLength 207
|   Report Descriptors:
| ** UNAVAILABLE **
|   Endpoint Descriptor:
| bLength 7
| bDescriptorType 5
| bEndpointAddress 0x82  EP 2 IN
| bmAttributes3
|   Transfer TypeInterrupt
|   Synch Type   None
|   Usage Type   Data
| wMaxPacketSize 0x0010  1x 16 bytes
| bInterval   8

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 common/usb_kbd.c | 37 ++---
 1 file changed, 34 insertions(+), 3 deletions(-)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 4cbc9acb73..b2361bbf18 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -23,6 +23,14 @@
 
 #include 
 
+/*
+ * USB vendor and product IDs used for quirks.
+ */
+#define USB_VENDOR_ID_APPLE0x05ac
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_20210x029c
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_20210x029a
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
+
 /*
  * If overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -106,6 +114,8 @@ struct usb_kbd_pdata {
unsigned long   last_report;
struct int_queue *intq;
 
+   uint32_tifnum;
+
uint32_trepeat_delay;
 
uint32_tusb_in_pointer;
@@ -150,8 +160,8 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, 
u8 c)
  */
 static void usb_kbd_setled(struct usb_device *dev)
 {
-   struct usb_interface *iface = >config.if_desc[0];
struct usb_kbd_pdata *data = dev->privptr;
+   struct usb_interface 

[PATCH v3 4/6] usb: Add environment based device ignorelist

2024-03-22 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Add the environment variable "usb_ignorelist" to prevent USB devices
listed in it from being bound to drivers. This allows to ignore devices
which are undesirable or trigger bugs in u-boot's USB stack.
Devices emulating keyboards are one example of undesirable devices as
u-boot currently supports only a single USB keyboard device. Most
commonly, people run into this with Yubikeys, so let's ignore those in
the default environment.

Based on previous USB keyboard specific patches for the same purpose.

Link: 
https://lore.kernel.org/u-boot/7ab604fb-0fec-4f5e-8708-7a3a7e2cb...@denx.de/
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 common/usb.c  | 57 +++
 doc/usage/environment.rst | 13 +++
 include/env_default.h | 11 +
 3 files changed, 81 insertions(+)

diff --git a/common/usb.c b/common/usb.c
index 836506dcd9..1421b1bb13 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -28,6 +28,7 @@
 #include 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -1084,6 +1085,48 @@ static int usb_prepare_device(struct usb_device *dev, 
int addr, bool do_read,
return 0;
 }
 
+static int usb_device_is_ignored(u16 id_vendor, u16 id_product)
+{
+   ulong vid, pid;
+   char *end;
+   const char *cur = env_get("usb_ignorelist");
+
+   /* parse "usb_ignorelist" strictly */
+   while (cur && cur[0] != '\0') {
+   vid = simple_strtoul(cur, , 0);
+   /*
+* If strtoul did not parse a single digit or the next char is
+* not ':' the ignore list is malformed.
+*/
+   if (cur == end || end[0] != ':')
+   return -EINVAL;
+
+   cur = end + 1;
+   pid = simple_strtoul(cur, , 0);
+   /* Consider '*' as wildcard for the product ID */
+   if (cur == end && end[0] == '*') {
+   pid = U16_MAX + 1;
+   end++;
+   }
+   /*
+* The ignore list is malformed if no product ID / wildcard was
+* parsed or entries are not separated by ',' or terminated with
+* '\0'.
+*/
+   if (cur == end || (end[0] != ',' && end[0] != '\0'))
+   return -EINVAL;
+
+   if (id_vendor == vid && (pid > U16_MAX || id_product == pid))
+   return -ENODEV;
+
+   if (end[0] == '\0')
+   break;
+   cur = end + 1;
+   }
+
+   return 0;
+}
+
 int usb_select_config(struct usb_device *dev)
 {
unsigned char *tmpbuf = NULL;
@@ -1099,6 +1142,20 @@ int usb_select_config(struct usb_device *dev)
le16_to_cpus(>descriptor.idProduct);
le16_to_cpus(>descriptor.bcdDevice);
 
+   /* ignore devices from usb_ignorelist */
+   err = usb_device_is_ignored(dev->descriptor.idVendor,
+   dev->descriptor.idProduct);
+   if (err == -ENODEV) {
+   dev_dbg(dev->dev, "Ignoring USB device 0x%x:0x%x\n",
+   dev->descriptor.idVendor, dev->descriptor.idProduct);
+   return err;
+   } else if (err == -EINVAL) {
+   printf("usb_ignorelist parse error in \"%s\"\n",
+  env_get("usb_ignorelist"));
+   } else if (err < 0) {
+   return err;
+   }
+
/*
 * Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive
 * about this first Get Descriptor request. If there are any other
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst
index ebf75fa948..7d4b448cb3 100644
--- a/doc/usage/environment.rst
+++ b/doc/usage/environment.rst
@@ -366,6 +366,19 @@ tftpwindowsize
 This means the count of blocks we can receive before
 sending ack to server.
 
+usb_ignorelist
+Ignore USB devices to prevent binding them to an USB device driver. This 
can
+be used to ignore devices are for some reason undesirable or causes crashes
+u-boot's USB stack.
+An example for undesired behavior is the keyboard emulation of security 
keys
+like Yubikeys. U-boot currently supports only a single USB keyboard device
+so try to probe an useful keyboard device. The default environment blocks
+Yubico devices as common devices emulating keyboards.
+Devices are matched by idVendor and idProduct. The variable contains a 
comma
+separated list of idVendor:idProduct pairs as hexadecimal numbers joined
+by a colon. '*' functions as a wildcard for idProduct to block all devices
+with the specified idVendor.
+
 vlan
 When set to a value < 4095 the traffic over
 Ethernet is encapsulated/received over 802.1q
diff --git a/include/env_default.h b/include/env_default.h
index 2ca4a087d3..8ee500d170 100644
--- a/include/env_default.h
+++ b/include/env_default.h
@@ 

[PATCH v3 2/6] usb: xhci: Set up endpoints for the first 2 interfaces

2024-03-22 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The xhci driver currently only does the necessary initialization for
endpoints found in the first interface descriptor. Apple USB keyboards
(released 2021) use the second interface descriptor for the HID keyboard
boot protocol. To allow USB drivers to use endpoints from other
interface descriptors the xhci driver needs to ensure these endpoints
are initialized as well.
Use USB_MAX_ACTIVE_INTERFACES to control how many interface descriptors
are considered during endpoint initialisation.
For now define it to 2 as that is sufficient for supporting the Apple
keyboards.

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci.c | 31 +++
 include/usb.h   |  6 ++
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 534c4b973f..741e186ee0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -606,24 +606,28 @@ static int xhci_set_configuration(struct usb_device *udev)
int slot_id = udev->slot_id;
struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
struct usb_interface *ifdesc;
+   unsigned int ifnum;
+   unsigned int max_ifnum = min((unsigned int)USB_MAX_ACTIVE_INTERFACES,
+(unsigned int)udev->config.no_of_if);
 
out_ctx = virt_dev->out_ctx;
in_ctx = virt_dev->in_ctx;
 
-   num_of_ep = udev->config.if_desc[0].no_of_ep;
-   ifdesc = >config.if_desc[0];
-
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
/* Initialize the input context control */
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
ctrl_ctx->drop_flags = 0;
 
-   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
-   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
-   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
-   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
-   if (max_ep_flag < ep_flag)
-   max_ep_flag = ep_flag;
+   for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+   ifdesc = >config.if_desc[ifnum];
+   num_of_ep = ifdesc->no_of_ep;
+   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
+   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
+   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
+   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
+   if (max_ep_flag < ep_flag)
+   max_ep_flag = ep_flag;
+   }
}
 
xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
@@ -637,9 +641,12 @@ static int xhci_set_configuration(struct usb_device *udev)
xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
 
/* filling up ep contexts */
-   err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
-   if (err < 0)
-   return err;
+   for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+   ifdesc = >config.if_desc[ifnum];
+   err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
+   if (err < 0)
+   return err;
+   }
 
return xhci_configure_endpoints(udev, false);
 }
diff --git a/include/usb.h b/include/usb.h
index 09e3f0cb30..3aafdc8bfd 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -49,6 +49,12 @@ extern bool usb_started; /* flag for the started/stopped USB 
status */
  */
 #define USB_TIMEOUT_MS(pipe) (usb_pipebulk(pipe) ? 5000 : 1000)
 
+/*
+ * The xhcd hcd driver prepares only a limited number interfaces / endpoints.
+ * Define this limit so that drivers do not exceed it.
+ */
+#define USB_MAX_ACTIVE_INTERFACES  2
+
 /* device request (setup) */
 struct devrequest {
__u8requesttype;

-- 
2.44.0




[PATCH v3 6/6] usb: kbd: Add probe quirk for Apple and Keychron keyboards

2024-03-22 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Those keyboards do not return the current device state. Polling will
timeout unless there are key presses. This is not a problem during
operation but the initial device state query during probing will fail.
Skip this step in usb_kbd_probe_dev() to make these devices useable.
Not all Apple keyboards behave like this. A keyboard with USB
vendor/product ID 05ac:0221 is reported to work with the current code.
Unfortunately some Keychron keyboards "re-use" Apple's vendor ID and
show the same behavior (Keychron C2, 05ac:024f for example).

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 common/usb_kbd.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index b2361bbf18..820f591fc5 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -31,6 +31,10 @@
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_20210x029a
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
 
+#define USB_VENDOR_ID_KEYCHRON 0x3434
+
+#define USB_HID_QUIRK_POLL_NO_REPORT_IDLE  BIT(0)
+
 /*
  * If overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -474,6 +478,7 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
struct usb_interface *iface;
struct usb_endpoint_descriptor *ep;
struct usb_kbd_pdata *data;
+   unsigned int quirks = 0;
int epNum;
 
if (dev->descriptor.bNumConfigurations != 1)
@@ -506,6 +511,15 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
 
debug("USB KBD: found interrupt EP: 0x%x\n", ep->bEndpointAddress);
 
+   switch (dev->descriptor.idVendor) {
+   case USB_VENDOR_ID_APPLE:
+   case USB_VENDOR_ID_KEYCHRON:
+   quirks |= USB_HID_QUIRK_POLL_NO_REPORT_IDLE;
+   break;
+   default:
+   break;
+   }
+
data = malloc(sizeof(struct usb_kbd_pdata));
if (!data) {
printf("USB KBD: Error allocating private data\n");
@@ -546,6 +560,14 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
 #endif
 
+   /*
+* Apple and Keychron keyboards do not report the device state. Reports
+* are only returned during key presses.
+*/
+   if (quirks & USB_HID_QUIRK_POLL_NO_REPORT_IDLE) {
+   debug("USB KBD: quirk: skip testing device state\n");
+   return 1;
+   }
debug("USB KBD: enable interrupt pipe...\n");
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
data->intq = create_int_queue(dev, data->intpipe, 1,

-- 
2.44.0




[PATCH v3 3/6] usb: xhci: Abort transfers with unallocated rings

2024-03-22 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Discovered while trying to use the second interface in the USB keyboard
driver necessary on Apple USB keyboards.

Reviewed-by: Marek Vasut 
Reviewed-by: Neal Gompa 
Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci-ring.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b60661fe05..910c5f3352 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -685,6 +685,9 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long 
pipe,
reset_ep(udev, ep_index);
 
ring = virt_dev->eps[ep_index].ring;
+   if (!ring)
+   return -EINVAL;
+
/*
 * How much data is (potentially) left before the 64KB boundary?
 * XHCI Spec puts restriction( TABLE 49 and 6.4.1 section of XHCI Spec)
@@ -871,6 +874,8 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long 
pipe,
ep_index = usb_pipe_ep_index(pipe);
 
ep_ring = virt_dev->eps[ep_index].ring;
+   if (!ep_ring)
+   return -EINVAL;
 
/*
 * Check to see if the max packet size for the default control

-- 
2.44.0




[PATCH 1/4] apple_m1_defconfig: Turn on CONFIG_SYS_64BIT_LBA

2024-03-17 Thread Janne Grunau via B4 Relay
From: Hector Martin 

This makes USB HDDs >2TiB work. The only reason this hasn't bitten us
for the internal NVMe yet is the 4K sector size, because the largest SSD
Apple sells is 8TB and we can handle up to 16TiB with that sector size.
Close call.

Signed-off-by: Hector Martin 
Signed-off-by: Janne Grunau 
---
 configs/apple_m1_defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
index e00d72e8be..31d966f0ab 100644
--- a/configs/apple_m1_defconfig
+++ b/configs/apple_m1_defconfig
@@ -10,6 +10,7 @@ CONFIG_SYS_PBSIZE=276
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_LATE_INIT=y
 # CONFIG_NET is not set
+CONFIG_SYS_64BIT_LBA=y
 CONFIG_APPLE_SPI_KEYB=y
 # CONFIG_MMC is not set
 CONFIG_NVME_APPLE=y

-- 
2.44.0



[PATCH 3/4] configs: apple: Enable CMD_SELECT_FONT and FONT_16X32

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Apple devices have high DPI displays so the larger fonts are preferable
for improved readability. This does not yet change the used font based
on the display's pixel density so the standard 8x16 font is still used
by default.

Signed-off-by: Janne Grunau 
---
 configs/apple_m1_defconfig | 2 ++
 1 file changed, 2 insertions(+)

diff --git a/configs/apple_m1_defconfig b/configs/apple_m1_defconfig
index 31d966f0ab..c30aec7c55 100644
--- a/configs/apple_m1_defconfig
+++ b/configs/apple_m1_defconfig
@@ -9,6 +9,7 @@ CONFIG_SYS_PBSIZE=276
 # CONFIG_DISPLAY_CPUINFO is not set
 CONFIG_DISPLAY_BOARDINFO_LATE=y
 CONFIG_BOARD_LATE_INIT=y
+CONFIG_CMD_SELECT_FONT=y
 # CONFIG_NET is not set
 CONFIG_SYS_64BIT_LBA=y
 CONFIG_APPLE_SPI_KEYB=y
@@ -19,6 +20,7 @@ CONFIG_USB_XHCI_DWC3=y
 CONFIG_USB_XHCI_PCI=y
 CONFIG_USB_DWC3=y
 CONFIG_USB_KEYBOARD=y
+CONFIG_VIDEO_FONT_16X32=y
 CONFIG_SYS_WHITE_ON_BLACK=y
 CONFIG_NO_FB_CLEAR=y
 CONFIG_VIDEO_SIMPLE=y

-- 
2.44.0



[PATCH 2/4] configs: apple: Use "vidconsole,serial" as stdout/stderr

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The display size querying in efi_console relies on this order. The
display should be the primary output device and should be used to
display more than 80x25 chars.

Signed-off-by: Janne Grunau 
---
 include/configs/apple.h | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/include/configs/apple.h b/include/configs/apple.h
index 0576bc04c9..a70440b3ad 100644
--- a/include/configs/apple.h
+++ b/include/configs/apple.h
@@ -6,8 +6,8 @@
 /* Environment */
 #define ENV_DEVICE_SETTINGS \
"stdin=serial,usbkbd,spikbd\0" \
-   "stdout=serial,vidconsole\0" \
-   "stderr=serial,vidconsole\0"
+   "stdout=vidconsole,serial\0" \
+   "stderr=vidconsole,serial\0"
 
 #if IS_ENABLED(CONFIG_CMD_NVME)
#define BOOT_TARGET_NVME(func) func(NVME, nvme, 0)

-- 
2.44.0



[PATCH 4/4] arm: apple: Switch to standard boot

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Use standard boot instead of the distro boot scripts.

Signed-off-by: Janne Grunau 
---
 arch/arm/Kconfig|  2 +-
 include/configs/apple.h | 20 ++--
 2 files changed, 3 insertions(+), 19 deletions(-)

diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 01d6556c42..ad89abde41 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1034,7 +1034,7 @@ config ARCH_APPLE
select USB
imply CMD_DM
imply CMD_GPT
-   imply DISTRO_DEFAULTS
+   imply BOOTSTD_DEFAULTS
imply OF_HAS_PRIOR_STAGE
 
 config ARCH_OWL
diff --git a/include/configs/apple.h b/include/configs/apple.h
index a70440b3ad..1e08b11448 100644
--- a/include/configs/apple.h
+++ b/include/configs/apple.h
@@ -9,26 +9,10 @@
"stdout=vidconsole,serial\0" \
"stderr=vidconsole,serial\0"
 
-#if IS_ENABLED(CONFIG_CMD_NVME)
-   #define BOOT_TARGET_NVME(func) func(NVME, nvme, 0)
-#else
-   #define BOOT_TARGET_NVME(func)
-#endif
-
-#if IS_ENABLED(CONFIG_CMD_USB)
-   #define BOOT_TARGET_USB(func) func(USB, usb, 0)
-#else
-   #define BOOT_TARGET_USB(func)
-#endif
-
-#define BOOT_TARGET_DEVICES(func) \
-   BOOT_TARGET_NVME(func) \
-   BOOT_TARGET_USB(func)
-
-#include 
+#define BOOT_TARGETS   "nvme usb"
 
 #define CFG_EXTRA_ENV_SETTINGS \
ENV_DEVICE_SETTINGS \
-   BOOTENV
+   "boot_targets=" BOOT_TARGETS "\0"
 
 #endif

-- 
2.44.0



[PATCH 0/4] configs: apple: Switch to standard boot + small adjustments

2024-03-17 Thread Janne Grunau via B4 Relay
This series contains a few misc config changes for Apple silicon
systems:
- switch from the deprecated distro boot scripts to standard boot
- allows EFI console resizing based on the video console size
- enables 16x32 bitmap fonts as Apple devices come with high DPI
  displays
- enables 64-bit LBA addressing for USB storage devices larger than 2TB

Signed-off-by: Janne Grunau 
---
Hector Martin (1):
  apple_m1_defconfig: Turn on CONFIG_SYS_64BIT_LBA

Janne Grunau (3):
  configs: apple: Use "vidconsole,serial" as stdout/stderr
  configs: apple: Enable CMD_SELECT_FONT and FONT_16X32
  arm: apple: Switch to standard boot

 arch/arm/Kconfig   |  2 +-
 configs/apple_m1_defconfig |  3 +++
 include/configs/apple.h| 24 
 3 files changed, 8 insertions(+), 21 deletions(-)
---
base-commit: f3c979dd0053c082d2df170446923e7ce5edbc2d
change-id: 20240317-apple_config-981fcd9028b9

Best regards,
-- 
Janne Grunau 



[PATCH v2 0/6] USB keyboard improvements for asahi / desktop systems

2024-03-17 Thread Janne Grunau via B4 Relay
Apple USB Keyboards from 2021 need quirks to be useable. The boot HID
keyboard protocol is unfortunately not described in the first interface
descriptor but the second. This needs several changes. The USB keyboard
driver has to look at all (2) interface descriptors during probing.
Since I didn't want to rebuild the USB driver probe code the Apple
keyboards are bound to the keyboard driver via USB vendor and product
IDs.
To make the keyboards useable on Apple silicon devices the xhci driver
needs to initializes rings for the endpoints of the first two interface
descriptors. If this is causes concerns regarding regressions or memory
use the USB_MAX_ACTIVE_INTERFACES define could be turned into a CONFIG
option.
Even after this changes the keyboards still do not probe successfully
since they apparently do not behave HID standard compliant. They only
generate reports on key events. This leads the final check whether the
keyboard is operational to fail unless the user presses keys during the
probe. Skip this check for known keyboards.
Keychron seems to emulate Apple keyboards (some models even "re-use"
Apple's USB vendor ID) so apply this quirk as well.

Some devices like Yubikeys emulate a keyboard. since u-boot only binds a
single keyboard block this kind of devices from the USB keyboard driver.

Signed-off-by: Janne Grunau 
---
Changes in v2:
- rewritten commit message for "[PATCH 2/6] usb: xhci: Set up endpoints for the 
first 2 interfaces"
- Replaced the usb keyboard Yubikey block with an env based USB device blocklist
- Use "-EINVAL" as return value in "[PATCH 3/6] usb: xhci: Abort transfers with 
unallocated rings"
- added "Reviewed-by:" tags
- Link to v1: 
https://lore.kernel.org/r/20240221-asahi-keyboards-v1-0-814b2e741...@jannau.net

---
Janne Grunau (6):
  usb: xhci: refactor xhci_set_configuration
  usb: xhci: Set up endpoints for the first 2 interfaces
  usb: xhci: Abort transfers with unallocated rings
  usb: Add environment based device blocklist
  usb: kbd: support Apple Magic Keyboards (2021)
  usb: kbd: Add probe quirk for Apple and Keychron keyboards

 common/usb.c |  56 +++
 common/usb_kbd.c |  61 +++--
 doc/usage/environment.rst|  12 +
 drivers/usb/host/xhci-ring.c |   5 ++
 drivers/usb/host/xhci.c  | 126 +++
 include/env_default.h|  11 
 include/usb.h|   6 +++
 7 files changed, 227 insertions(+), 50 deletions(-)
---
base-commit: 37345abb97ef0dd9c50a03b2a72617612dcae585
change-id: 20240218-asahi-keyboards-f2ddaf0022b2

Best regards,
-- 
Janne Grunau 



[PATCH v2 5/6] usb: kbd: support Apple Magic Keyboards (2021)

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Apple USB keyboards (Magic Keyboard from 2021 (product id 0x029c)) carry
the HID keyboard boot protocol on the second interface descriptor.
Probe via vendor and product IDs since the class/subclass/protocol match
uses the first interface descriptor.
Probe the two first interface descriptors for the HID keyboard boot
protocol.

USB configuration descriptor for reference:

| Bus 003 Device 002: ID 05ac:029c Apple, Inc. Magic Keyboard
| Device Descriptor:
|   bLength18
|   bDescriptorType 1
|   bcdUSB   2.00
|   bDeviceClass0 [unknown]
|   bDeviceSubClass 0 [unknown]
|   bDeviceProtocol 0
|   bMaxPacketSize064
|   idVendor   0x05ac Apple, Inc.
|   idProduct  0x029c Magic Keyboard
|   bcdDevice3.90
|   iManufacturer   1 Apple Inc.
|   iProduct2 Magic Keyboard
|   iSerial 3 ...
|   bNumConfigurations  1
|   Configuration Descriptor:
| bLength 9
| bDescriptorType 2
| wTotalLength   0x003b
| bNumInterfaces  2
| bConfigurationValue 1
| iConfiguration  4 Keyboard
| bmAttributes 0xa0
|   (Bus Powered)
|   Remote Wakeup
| MaxPower  500mA
| Interface Descriptor:
|   bLength 9
|   bDescriptorType 4
|   bInterfaceNumber0
|   bAlternateSetting   0
|   bNumEndpoints   1
|   bInterfaceClass 3 Human Interface Device
|   bInterfaceSubClass  0 [unknown]
|   bInterfaceProtocol  0
|   iInterface  5 Device Management
| HID Device Descriptor:
|   bLength 9
|   bDescriptorType33
|   bcdHID   1.10
|   bCountryCode0 Not supported
|   bNumDescriptors 1
|   bDescriptorType34 Report
|   wDescriptorLength  83
|   Report Descriptors:
| ** UNAVAILABLE **
|   Endpoint Descriptor:
| bLength 7
| bDescriptorType 5
| bEndpointAddress 0x81  EP 1 IN
| bmAttributes3
|   Transfer TypeInterrupt
|   Synch Type   None
|   Usage Type   Data
| wMaxPacketSize 0x0010  1x 16 bytes
| bInterval   8
| Interface Descriptor:
|   bLength 9
|   bDescriptorType 4
|   bInterfaceNumber1
|   bAlternateSetting   0
|   bNumEndpoints   1
|   bInterfaceClass 3 Human Interface Device
|   bInterfaceSubClass  1 Boot Interface Subclass
|   bInterfaceProtocol  1 Keyboard
|   iInterface  6 Keyboard / Boot
| HID Device Descriptor:
|   bLength 9
|   bDescriptorType33
|   bcdHID   1.10
|   bCountryCode   13 International (ISO)
|   bNumDescriptors 1
|   bDescriptorType34 Report
|   wDescriptorLength 207
|   Report Descriptors:
| ** UNAVAILABLE **
|   Endpoint Descriptor:
| bLength 7
| bDescriptorType 5
| bEndpointAddress 0x82  EP 2 IN
| bmAttributes3
|   Transfer TypeInterrupt
|   Synch Type   None
|   Usage Type   Data
| wMaxPacketSize 0x0010  1x 16 bytes
| bInterval   8

Signed-off-by: Janne Grunau 
---
 common/usb_kbd.c | 39 +++
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 4cbc9acb73..8cc3345075 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -23,6 +23,14 @@
 
 #include 
 
+/*
+ * USB vendor and product IDs used for quirks.
+ */
+#define USB_VENDOR_ID_APPLE0x05ac
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_20210x029c
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_20210x029a
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
+
 /*
  * If overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -106,6 +114,8 @@ struct usb_kbd_pdata {
unsigned long   last_report;
struct int_queue *intq;
 
+   uint32_tifnum;
+
uint32_trepeat_delay;
 
uint32_tusb_in_pointer;
@@ -150,8 +160,8 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, 
u8 c)
  */
 static void usb_kbd_setled(struct usb_device *dev)
 {
-   struct usb_interface *iface = >config.if_desc[0];
struct usb_kbd_pdata *data = dev->privptr;
+   struct usb_interface *iface = >config.if_desc[data->ifnum];

[PATCH v2 1/6] usb: xhci: refactor xhci_set_configuration

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

In the next step endpoints for multiple interfaces are set up. Move most
of the per endpoint initialization to separate function to avoid another
identation level.

Reviewed-by: Marek Vasut 
Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci.c | 119 +---
 1 file changed, 73 insertions(+), 46 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d13cbff9b3..534c4b973f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -475,67 +475,34 @@ static int xhci_configure_endpoints(struct usb_device 
*udev, bool ctx_change)
 }
 
 /**
- * Configure the endpoint, programming the device contexts.
+ * Fill endpoint contexts for interface descriptor ifdesc.
  *
- * @param udev pointer to the USB device structure
- * Return: returns the status of the xhci_configure_endpoints
+ * @param udev pointer to the USB device structure
+ * @param ctrl pointer to the xhci pravte device structure
+ * @param virt_dev pointer to the xhci virtual device structure
+ * @param ifdesc   pointer to the USB interface config descriptor
+ * Return: returns the status of xhci_init_ep_contexts_if
  */
-static int xhci_set_configuration(struct usb_device *udev)
+static int xhci_init_ep_contexts_if(struct usb_device *udev,
+   struct xhci_ctrl *ctrl,
+   struct xhci_virt_device *virt_dev,
+   struct usb_interface *ifdesc
+   )
 {
-   struct xhci_container_ctx *in_ctx;
-   struct xhci_container_ctx *out_ctx;
-   struct xhci_input_control_ctx *ctrl_ctx;
-   struct xhci_slot_ctx *slot_ctx;
struct xhci_ep_ctx *ep_ctx[MAX_EP_CTX_NUM];
int cur_ep;
-   int max_ep_flag = 0;
int ep_index;
unsigned int dir;
unsigned int ep_type;
-   struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
-   int num_of_ep;
-   int ep_flag = 0;
u64 trb_64 = 0;
-   int slot_id = udev->slot_id;
-   struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
-   struct usb_interface *ifdesc;
u32 max_esit_payload;
unsigned int interval;
unsigned int mult;
unsigned int max_burst;
unsigned int avg_trb_len;
unsigned int err_count = 0;
+   int num_of_ep = ifdesc->no_of_ep;
 
-   out_ctx = virt_dev->out_ctx;
-   in_ctx = virt_dev->in_ctx;
-
-   num_of_ep = udev->config.if_desc[0].no_of_ep;
-   ifdesc = >config.if_desc[0];
-
-   ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
-   /* Initialize the input context control */
-   ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
-   ctrl_ctx->drop_flags = 0;
-
-   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
-   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
-   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
-   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
-   if (max_ep_flag < ep_flag)
-   max_ep_flag = ep_flag;
-   }
-
-   xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
-
-   /* slot context */
-   xhci_slot_copy(ctrl, in_ctx, out_ctx);
-   slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
-   slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
-   slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
-
-   xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
-
-   /* filling up ep contexts */
for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
struct usb_endpoint_descriptor *endpt_desc = NULL;
struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc = NULL;
@@ -561,7 +528,8 @@ static int xhci_set_configuration(struct usb_device *udev)
avg_trb_len = max_esit_payload;
 
ep_index = xhci_get_ep_index(endpt_desc);
-   ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
+   ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx,
+  ep_index);
 
/* Allocate the ep rings */
virt_dev->eps[ep_index].ring = xhci_ring_alloc(ctrl, 1, true);
@@ -614,6 +582,65 @@ static int xhci_set_configuration(struct usb_device *udev)
}
}
 
+   return 0;
+}
+
+/**
+ * Configure the endpoint, programming the device contexts.
+ *
+ * @param udev pointer to the USB device structure
+ * Return: returns the status of the xhci_configure_endpoints
+ */
+static int xhci_set_configuration(struct usb_device *udev)
+{
+   struct xhci_container_ctx *out_ctx;
+   struct xhci_container_ctx *in_ctx;
+   struct xhci_input_control_ctx *ctrl_ctx;
+   struct xhci_slot_ctx *slot_ctx;
+   int err;
+   int cur_ep;
+   int max_ep_flag = 0;
+   struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
+   int num_of_ep;
+   int ep_flag 

[PATCH v2 6/6] usb: kbd: Add probe quirk for Apple and Keychron keyboards

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Those keyboards do not return the current device state. Polling will
timeout unless there are key presses. This is not a problem during
operation but the inital device state query during probing will fail.
Skip this step in usb_kbd_probe_dev() to make these devices useable.
Not all Apple keyboards behave like this. A keyboard with USB
vendor/product ID 05ac:0221 is reported to work with the current code.
Unfortunately some Keychron keyboards "re-use" Apple's vendor ID and
show the same behavior (Keychron C2, 05ac:024f for example).

Reviewed-by: Marek Vasut 
Signed-off-by: Janne Grunau 
---
 common/usb_kbd.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 8cc3345075..43c7668671 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -31,6 +31,10 @@
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_20210x029a
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
 
+#define USB_VENDOR_ID_KEYCHRON 0x3434
+
+#define USB_HID_QUIRK_POLL_NO_REPORT_IDLE  (1 << 0)
+
 /*
  * If overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -474,6 +478,7 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
struct usb_interface *iface;
struct usb_endpoint_descriptor *ep;
struct usb_kbd_pdata *data;
+   unsigned int quirks = 0;
int epNum;
 
if (dev->descriptor.bNumConfigurations != 1)
@@ -506,6 +511,15 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
 
debug("USB KBD: found interrupt EP: 0x%x\n", ep->bEndpointAddress);
 
+   switch (dev->descriptor.idVendor) {
+   case USB_VENDOR_ID_APPLE:
+   case USB_VENDOR_ID_KEYCHRON:
+   quirks |= USB_HID_QUIRK_POLL_NO_REPORT_IDLE;
+   break;
+   default:
+   break;
+   }
+
data = malloc(sizeof(struct usb_kbd_pdata));
if (!data) {
printf("USB KBD: Error allocating private data\n");
@@ -546,6 +560,14 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
 #endif
 
+   /*
+* Apple and Keychron keyboards do not report the device state. Reports
+* are only returned during key presses.
+*/
+   if (quirks & USB_HID_QUIRK_POLL_NO_REPORT_IDLE) {
+   debug("USB KBD: quirk: skip testing device state\n");
+   return 1;
+   }
debug("USB KBD: enable interrupt pipe...\n");
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
data->intq = create_int_queue(dev, data->intpipe, 1,

-- 
2.44.0



[PATCH v2 2/6] usb: xhci: Set up endpoints for the first 2 interfaces

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The xhci driver currently only does the necessary initialization for
endpoints found in the first interface descriptor. Apple USB keyboards
(released 2021) use the second interface descriptor for the HID keyboard
boot protocol. To allow USB drivers to use endpoints from other
interface descriptors the xhci driver needs to ensure these endpoints
are initialized as well.
Use USB_MAX_ACTIVE_INTERFACES to control how many interface descriptors
are considered during endpoint initialisation.
For now define it to 2 as that is sufficient for supporting the Apple
keyboards.

Reviewed-by: Marek Vasut 
Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci.c | 31 +++
 include/usb.h   |  6 ++
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 534c4b973f..741e186ee0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -606,24 +606,28 @@ static int xhci_set_configuration(struct usb_device *udev)
int slot_id = udev->slot_id;
struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
struct usb_interface *ifdesc;
+   unsigned int ifnum;
+   unsigned int max_ifnum = min((unsigned int)USB_MAX_ACTIVE_INTERFACES,
+(unsigned int)udev->config.no_of_if);
 
out_ctx = virt_dev->out_ctx;
in_ctx = virt_dev->in_ctx;
 
-   num_of_ep = udev->config.if_desc[0].no_of_ep;
-   ifdesc = >config.if_desc[0];
-
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
/* Initialize the input context control */
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
ctrl_ctx->drop_flags = 0;
 
-   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
-   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
-   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
-   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
-   if (max_ep_flag < ep_flag)
-   max_ep_flag = ep_flag;
+   for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+   ifdesc = >config.if_desc[ifnum];
+   num_of_ep = ifdesc->no_of_ep;
+   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
+   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
+   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
+   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
+   if (max_ep_flag < ep_flag)
+   max_ep_flag = ep_flag;
+   }
}
 
xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
@@ -637,9 +641,12 @@ static int xhci_set_configuration(struct usb_device *udev)
xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
 
/* filling up ep contexts */
-   err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
-   if (err < 0)
-   return err;
+   for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+   ifdesc = >config.if_desc[ifnum];
+   err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
+   if (err < 0)
+   return err;
+   }
 
return xhci_configure_endpoints(udev, false);
 }
diff --git a/include/usb.h b/include/usb.h
index 09e3f0cb30..3aafdc8bfd 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -49,6 +49,12 @@ extern bool usb_started; /* flag for the started/stopped USB 
status */
  */
 #define USB_TIMEOUT_MS(pipe) (usb_pipebulk(pipe) ? 5000 : 1000)
 
+/*
+ * The xhcd hcd driver prepares only a limited number interfaces / endpoints.
+ * Define this limit so that drivers do not exceed it.
+ */
+#define USB_MAX_ACTIVE_INTERFACES  2
+
 /* device request (setup) */
 struct devrequest {
__u8requesttype;

-- 
2.44.0



[PATCH v2 4/6] usb: Add environment based device blocklist

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Add the environment variable "usb_blocklist" to prevent USB devices
listed in it from being used. This allows to ignore devices which
trigger bugs in u-boot's USB stack or are undesirable for other reasons.
Devices emulating keyboards are one example. U-boot currently supports
only one USB keyboard device. Most commonly, people run into this with
Yubikeys, so let's ignore those in the default environment.

Based on previous USB keyboard specific patches for the same purpose.

Link: 
https://lore.kernel.org/u-boot/7ab604fb-0fec-4f5e-8708-7a3a7e2cb...@denx.de/
Signed-off-by: Janne Grunau 
---
 common/usb.c  | 56 +++
 doc/usage/environment.rst | 12 ++
 include/env_default.h | 11 ++
 3 files changed, 79 insertions(+)

diff --git a/common/usb.c b/common/usb.c
index 836506dcd9..73af5be066 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -1084,6 +1084,57 @@ static int usb_prepare_device(struct usb_device *dev, 
int addr, bool do_read,
return 0;
 }
 
+static int usb_blocklist_parse_error(const char *blocklist, size_t pos)
+{
+   printf("usb_blocklist parse error at char %zu in \"%s\"\n", pos,
+  blocklist);
+   return 0;
+}
+
+static int usb_device_is_blocked(u16 id_vendor, u16 id_product)
+{
+   ulong vid, pid;
+   char *end;
+   const char *block_str = env_get("usb_blocklist");
+   const char *cur = block_str;
+
+   /* parse "usb_blocklist" strictly */
+   while (cur && cur[0] != '\0') {
+   vid = simple_strtoul(cur, , 0);
+   if (cur == end || end[0] != ':')
+   return usb_blocklist_parse_error(block_str,
+cur - block_str);
+
+   cur = end + 1;
+   pid = simple_strtoul(cur, , 0);
+   if (cur == end && end[0] != '*')
+   return usb_blocklist_parse_error(block_str,
+cur - block_str);
+
+   if (end[0] == '*') {
+   /* use out of range idProduct as wildcard indication */
+   pid = U16_MAX + 1;
+   end++;
+   }
+   if (end[0] != ',' && end[0] != '\0')
+   return usb_blocklist_parse_error(block_str,
+cur - block_str);
+
+   if (id_vendor == vid && (pid > U16_MAX || id_product == pid)) {
+   printf("Ignoring USB device 0x%x:0x%x\n",id_vendor,
+ id_product);
+   debug("Ignoring USB device 0x%x:0x%x\n",id_vendor,
+ id_product);
+   return 1;
+   }
+   if (end[0] == '\0')
+   break;
+   cur = end + 1;
+   }
+
+   return 0;
+}
+
 int usb_select_config(struct usb_device *dev)
 {
unsigned char *tmpbuf = NULL;
@@ -1099,6 +1150,11 @@ int usb_select_config(struct usb_device *dev)
le16_to_cpus(>descriptor.idProduct);
le16_to_cpus(>descriptor.bcdDevice);
 
+   /* ignore devices from usb_blocklist */
+   if (usb_device_is_blocked(dev->descriptor.idVendor,
+ dev->descriptor.idProduct))
+   return -ENODEV;
+
/*
 * Kingston DT Ultimate 32GB USB 3.0 seems to be extremely sensitive
 * about this first Get Descriptor request. If there are any other
diff --git a/doc/usage/environment.rst b/doc/usage/environment.rst
index ebf75fa948..e42702adb2 100644
--- a/doc/usage/environment.rst
+++ b/doc/usage/environment.rst
@@ -366,6 +366,18 @@ tftpwindowsize
 This means the count of blocks we can receive before
 sending ack to server.
 
+usb_blocklist
+Block USB devices from being bound to an USB device driver. This can be 
used
+to ignore devices which causes crashes in u-boot's USB stack or are
+undesirable for other reasons.
+The default environment blocks Yubico devices since they emulate USB
+keyboards. U-boot currently supports only a single USB keyboard device and
+it is undesirable that a Yubikey is used as keyboard.
+Devices are matched by idVendor and idProduct. The variable contains a 
comma
+separated list of idVendor:idProduct pairs as hexadecimal numbers joined
+by a colon. '*' functions as a wildcard for idProduct to block all devices
+with the specified idVendor.
+
 vlan
 When set to a value < 4095 the traffic over
 Ethernet is encapsulated/received over 802.1q
diff --git a/include/env_default.h b/include/env_default.h
index 2ca4a087d3..ba4c7516b4 100644
--- a/include/env_default.h
+++ b/include/env_default.h
@@ -99,6 +99,17 @@ const char default_environment[] = {
 #ifdef CONFIG_SYS_SOC
"soc="  CONFIG_SYS_SOC  "\0"
 #endif
+#ifdef 

[PATCH v2 3/6] usb: xhci: Abort transfers with unallocated rings

2024-03-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Discovered while trying to use the second interface in the USB keyboard
driver necessary on Apple USB keyboards.

Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci-ring.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b60661fe05..910c5f3352 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -685,6 +685,9 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long 
pipe,
reset_ep(udev, ep_index);
 
ring = virt_dev->eps[ep_index].ring;
+   if (!ring)
+   return -EINVAL;
+
/*
 * How much data is (potentially) left before the 64KB boundary?
 * XHCI Spec puts restriction( TABLE 49 and 6.4.1 section of XHCI Spec)
@@ -871,6 +874,8 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long 
pipe,
ep_index = usb_pipe_ep_index(pipe);
 
ep_ring = virt_dev->eps[ep_index].ring;
+   if (!ep_ring)
+   return -EINVAL;
 
/*
 * Check to see if the max packet size for the default control

-- 
2.44.0



[PATCH v3 7/7] efi_selftest: Update StrToFat() unit test after CP473 map extension

2024-03-16 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Test that Unicode code points which map to CP437 code points 1-31 are
converted to '_'. This ensures no FAT file names do not contain chars
which are control characters in other code pages (CP 1250 for example).

Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_unicode_collation.c | 12 
 1 file changed, 12 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_unicode_collation.c 
b/lib/efi_selftest/efi_selftest_unicode_collation.c
index 32c99caf35..ad7dfa9fb9 100644
--- a/lib/efi_selftest/efi_selftest_unicode_collation.c
+++ b/lib/efi_selftest/efi_selftest_unicode_collation.c
@@ -220,6 +220,18 @@ static int test_str_to_fat(void)
return EFI_ST_FAILURE;
}
 
+   /*
+* Test unicode code points which map to CP 437 0x01 - 0x1f are
+* converted to '_'.
+*/
+   boottime->set_mem(fat, 16, 0);
+   ret = unicode_collation_protocol->str_to_fat(unicode_collation_protocol,
+   u"\u263a\u2666\u2022\u25d8\u2642\u2194\u00b6\u203c", 8, fat);
+   if (!ret || efi_st_strcmp_16_8(u"", fat)) {
+   efi_st_error("str_to_fat returned %u, \"%s\"\n", ret, fat);
+   return EFI_ST_FAILURE;
+   }
+
return EFI_ST_SUCCESS;
 }
 

-- 
2.44.0



[PATCH v3 2/7] video: console: Parse UTF-8 character sequences

2024-03-16 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

efi_console / UEFI applications (grub2, sd-boot, ...) pass UTF-8
character sequences to vidconsole which results in wrong glyphs for code
points outside of ASCII. The truetype console expects Unicode code
points and bitmap font based consoles expect code page 437 code points.
To support both convert UTF-8 to UTF-32 and pass Unicode code points in
vidconsole_ops.putc_xy(). These can be used directly in console_truetype
and after conversion to code page 437 in console_{normal,rotate}.

This fixes rendering of international, symbol and box drawing characters
used by UEFI applications.

Signed-off-by: Janne Grunau 
---
 drivers/video/console_normal.c  |  6 --
 drivers/video/console_rotate.c  | 16 ++--
 drivers/video/console_truetype.c|  8 
 drivers/video/vidconsole-uclass.c   | 18 +-
 drivers/video/vidconsole_internal.h | 19 +++
 include/video_console.h | 10 ++
 6 files changed, 56 insertions(+), 21 deletions(-)

diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index a0231293f3..34ef5a5229 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -63,7 +64,7 @@ static int console_move_rows(struct udevice *dev, uint rowdst,
return 0;
 }
 
-static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -73,8 +74,9 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, 
uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int x, linenum, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index 65358a1c6e..e4303dfb36 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -67,7 +68,7 @@ static int console_move_rows_1(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -77,8 +78,9 @@ static int console_putc_xy_1(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int x, linenum, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -145,7 +147,7 @@ static int console_move_rows_2(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -155,8 +157,9 @@ static int console_putc_xy_2(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int linenum, x, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -227,7 +230,7 @@ static int console_move_rows_3(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -237,8 +240,9 @@ static int console_putc_xy_3(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int linenum, x, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-  

[PATCH v3 1/7] lib: charset: Fix and extend utf8_to_utf32_stream() documentation

2024-03-16 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Suggested-by: Heinrich Schuchardt 
Reviewed-by: Heinrich Schuchardt 
Signed-off-by: Janne Grunau 
---
 include/charset.h | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/charset.h b/include/charset.h
index 44034c71d3..f1050c903d 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -324,11 +324,21 @@ int utf_to_cp(s32 *c, const u16 *codepage);
 int utf8_to_cp437_stream(u8 c, char *buffer);
 
 /**
- * utf8_to_utf32_stream() - convert UTF-8 stream to UTF-32
+ * utf8_to_utf32_stream() - convert UTF-8 byte stream to Unicode code points
+ *
+ * The function is called for each byte @c in a UTF-8 stream. The byte is
+ * appended to the temporary storage @buffer until the UTF-8 stream in
+ * @buffer describes a Unicode code point.
+ *
+ * When a new code point has been decoded it is returned and buffer[0] is
+ * set to '\0', otherwise the return value is 0.
+ *
+ * The buffer must be at least 5 characters long. Before the first function
+ * invocation buffer[0] must be set to '\0'."
  *
  * @c: next UTF-8 character to convert
  * @buffer:buffer, at least 5 characters
- * Return: next codepage 437 character or 0
+ * Return: Unicode code point or 0
  */
 int utf8_to_utf32_stream(u8 c, char *buffer);
 

-- 
2.44.0



[PATCH v3 6/7] efi_selftest: Add geometric shapes character selftest

2024-03-16 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Draw symbols from Unicode's "Geometric shapes" page which translate to
code page 437 code points 1-31. These are used by UEFI applications to
draw user interfaces using EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.
The output has to be checked manually on the screen for correctness.

Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 13 +
 1 file changed, 13 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index b56fd2ab76..2208a9877a 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -60,6 +60,13 @@ 
u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534"
 u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
 u"\u2500\u2500\u2500\u2500\u2518\n";
 
+   const u16 shapes[] =
+u"Geometric shapes as described\n"
+u"U+25B2 \u25B2 - Black up-pointing triangle\n"
+u"U+25BA \u25BA - Black right-pointing pointer\n"
+u"U+25BC \u25BC - Black down-pointing triangle\n"
+u"U+25C4 \u25C4 - Black left-pointing pointer\n";
+
/* SetAttribute */
efi_st_printf("\nColor palette\n");
for (foreground = 0; foreground < 0x10; ++foreground) {
@@ -160,6 +167,12 @@ u"\u2500\u2500\u2500\u2500\u2518\n";
return EFI_ST_FAILURE;
}
efi_st_printf("\n");
+   ret = con_out->output_string(con_out, shapes);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for geometric shapes\n");
+   return EFI_ST_FAILURE;
+   }
+   efi_st_printf("\n");
 
return EFI_ST_SUCCESS;
 }

-- 
2.44.0



[PATCH v3 5/7] efi_selftest: Add box drawing character selftest

2024-03-16 Thread Janne Grunau via B4 Relay
From: Andre Przywara 

UEFI applications rely on Unicode output capability, and might use that
for drawing pseudo-graphical interfaces using Unicode defined box
drawing characters.

Add a simple test to display the most basic box characters, which would
need to be checked manually on the screen for correctness.

Signed-off-by: Andre Przywara 
Suggested-by: Heinrich Schuchardt 
Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index 917903473d..b56fd2ab76 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -46,6 +46,20 @@ u"U+03BB \u03BB - Greek small letter lambda\n"
 u"U+03C2 \u03C2 - Greek small letter final sigma\n"
 u"U+1F19 \u1F19 - Greek capital letter epsilon with dasia\n";
 
+   const u16 boxes[] =
+u"This should render as four boxes with text\n"
+u"\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502"
+u" left top\u2502 right top \u2502\n\u251c\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 "
+u"left bottom \u2502 right bottom  \u2502\n\u2514\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2518\n";
+
/* SetAttribute */
efi_st_printf("\nColor palette\n");
for (foreground = 0; foreground < 0x10; ++foreground) {
@@ -140,6 +154,12 @@ u"U+1F19 \u1F19 - Greek capital letter epsilon with 
dasia\n";
return EFI_ST_FAILURE;
}
efi_st_printf("\n");
+   ret = con_out->output_string(con_out, boxes);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for box drawing chars\n");
+   return EFI_ST_FAILURE;
+   }
+   efi_st_printf("\n");
 
return EFI_ST_SUCCESS;
 }

-- 
2.44.0



[PATCH v3 4/7] efi_selftest: Add international characters test

2024-03-16 Thread Janne Grunau via B4 Relay
From: Andre Przywara 

UEFI relies entirely on unicode output, which actual fonts displayed on
the screen might not be ready for.

Add a test displaying some international characters, to reveal missing
glyphs, especially in our builtin fonts.
This would be needed to be manually checked on the screen for
correctness.

Signed-off-by: Andre Przywara 
Suggested-by: Heinrich Schuchardt 
Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 21 +
 1 file changed, 21 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index cc44b38bc2..917903473d 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -31,6 +31,21 @@ static int execute(void)
0xD804, 0xDC22,
0};
 
+   const u16 text[] =
+u"This should render international characters as described\n"
+u"U+00D6 \u00D6 - Latin capital letter O with diaresis\n"
+u"U+00DF \u00DF - Latin small letter sharp s\n"
+u"U+00E5 \u00E5 - Latin small letter a with ring above\n"
+u"U+00E9 \u00E9 - Latin small letter e with acute\n"
+u"U+00F1 \u00F1 - Latin small letter n with tilde\n"
+u"U+00F6 \u00F6 - Latin small letter o with diaresis\n"
+u"The following characters will render as '?' with bitmap fonts\n"
+u"U+00F8 \u00F8 - Latin small letter o with stroke\n"
+u"U+03AC \u03AC - Greek small letter alpha with tonus\n"
+u"U+03BB \u03BB - Greek small letter lambda\n"
+u"U+03C2 \u03C2 - Greek small letter final sigma\n"
+u"U+1F19 \u1F19 - Greek capital letter epsilon with dasia\n";
+
/* SetAttribute */
efi_st_printf("\nColor palette\n");
for (foreground = 0; foreground < 0x10; ++foreground) {
@@ -119,6 +134,12 @@ static int execute(void)
return EFI_ST_FAILURE;
}
efi_st_printf("\n");
+   ret = con_out->output_string(con_out, text);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for international chars\n");
+   return EFI_ST_FAILURE;
+   }
+   efi_st_printf("\n");
 
return EFI_ST_SUCCESS;
 }

-- 
2.44.0



[PATCH v3 0/7] video: Add UTF-8 support for UEFI applications

2024-03-16 Thread Janne Grunau via B4 Relay
Andre submitted 2 years ago DM_VIDEO improvements for UEFI applications
using UEFI's EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL but did not follow with
suggested changes. This series takes care of the UTF-8 support which
required to draw symbol and box drawing characters used by UEFI
applications like grub2 and sd-boot correctly.

Compared to Andre's version this version has the following changes:
- use and extend existing conversion functions from lib/charset.c
- convert to Unicode code points for truetype console support
- conversion is conditional on CONFIG_CHARSET
- use escape sequences in tests as proposed by Heinrich

Link: 
https://lore.kernel.org/u-boot/20220110005638.21599-1-andre.przyw...@arm.com/
Signed-off-by: Janne Grunau 
---
Changes in v3:
- added Reviewed-by tag
- removed unnecessary u8 casts
- limited utf-8 conversion buffer to 5 bytes as documented
- added missing console_utf_to_cp437() documentation
- adapted EFI text output self-tests according to review comments
- dropped wait after EFI text output self tests
- added StrToFat EFI self test to ensure Unicode code points which map
  to code page 437 code points 1-31 are converted to '_'
- Link to v2: 
https://lore.kernel.org/r/20240210-vidconsole-utf8-uefi-v2-0-88c03db60...@jannau.net

Changes in v2:
- use "CONFIG_IS_ENABLED(CHARSET)" instead of EFI_LOADER
- rewritten commit message for mapping CP437 cp 1-31
- extended utf8_to_utf32_stream() documentation as suggested by
  Heinrich
- Link to RFC: 
https://lore.kernel.org/r/20240117-vidconsole-utf8-uefi-v1-0-539f7ce74...@jannau.net

---
Andre Przywara (2):
  efi_selftest: Add international characters test
  efi_selftest: Add box drawing character selftest

Janne Grunau (5):
  lib: charset: Fix and extend utf8_to_utf32_stream() documentation
  video: console: Parse UTF-8 character sequences
  lib/charset: Map Unicode code points to CP437 code points 1-31
  efi_selftest: Add geometric shapes character selftest
  efi_selftest: Update StrToFat() unit test after CP473 map extension

 drivers/video/console_normal.c|  6 ++-
 drivers/video/console_rotate.c| 16 ---
 drivers/video/console_truetype.c  |  8 ++--
 drivers/video/vidconsole-uclass.c | 18 +---
 drivers/video/vidconsole_internal.h   | 19 
 include/charset.h | 16 +--
 include/cp1250.h  | 12 -
 include/cp437.h   | 12 -
 include/video_console.h   | 10 +++--
 lib/charset.c |  9 ++--
 lib/efi_loader/efi_unicode_collation.c|  2 +-
 lib/efi_selftest/efi_selftest_textoutput.c| 54 +++
 lib/efi_selftest/efi_selftest_unicode_collation.c | 12 +
 13 files changed, 162 insertions(+), 32 deletions(-)
---
base-commit: 866ca972d6c3cabeaf6dbac431e8e08bb30b3c8e
change-id: 20240117-vidconsole-utf8-uefi-fa23b4ac65d6

Best regards,
-- 
Janne Grunau 



[PATCH v3 3/7] lib/charset: Map Unicode code points to CP437 code points 1-31

2024-03-16 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Code page 437 uses code points 1-31 for glyphs instead of control
characters. Map the appropriate Unicode code points to this code points.
Fixes rendering of grub2's menu as EFI application using the
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on a console with bitmap fonts.

Signed-off-by: Janne Grunau 
---
 include/charset.h  |  2 +-
 include/cp1250.h   | 12 ++--
 include/cp437.h| 12 ++--
 lib/charset.c  |  9 ++---
 lib/efi_loader/efi_unicode_collation.c |  2 +-
 5 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/include/charset.h b/include/charset.h
index f1050c903d..348bad5883 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -16,7 +16,7 @@
 /*
  * codepage_437 - Unicode to codepage 437 translation table
  */
-extern const u16 codepage_437[128];
+extern const u16 codepage_437[160];
 
 /**
  * console_read_unicode() - read Unicode code point from console
diff --git a/include/cp1250.h b/include/cp1250.h
index adacf8a958..b762c78d9f 100644
--- a/include/cp1250.h
+++ b/include/cp1250.h
@@ -1,10 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 
 /*
- * Constant CP1250 contains the Unicode code points for characters 0x80 - 0xff
- * of the code page 1250.
+ * Constant CP1250 contains the Unicode code points for characters 0x00 - 0x1f
+ * and 0x80 - 0xff of the code page 1250.
  */
 #define CP1250 { \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
0x20ac, 0x, 0x201a, 0x, \
0x201e, 0x2026, 0x2020, 0x2021, \
0x, 0x2030, 0x0160, 0x2039, \
diff --git a/include/cp437.h b/include/cp437.h
index 0b2b97132e..5093130f5e 100644
--- a/include/cp437.h
+++ b/include/cp437.h
@@ -1,10 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 
 /*
- * Constant CP437 contains the Unicode code points for characters 0x80 - 0xff
- * of the code page 437.
+ * Constant CP437 contains the Unicode code points for characters 0x00 - 0x1f
+ * and 0x80 - 0xff of the code page 437.
  */
 #define CP437 { \
+   0x, 0x263a, 0x263b, 0x2665, \
+   0x2666, 0x2663, 0x2660, 0x2022, \
+   0x25d8, 0x25cb, 0x25d9, 0x2642, \
+   0x2640, 0x266a, 0x266b, 0x263c, \
+   0x25ba, 0x25c4, 0x2195, 0x203c, \
+   0x00b6, 0x00a7, 0x25ac, 0x21a8, \
+   0x2191, 0x2193, 0x2192, 0x2190, \
+   0x221f, 0x2194, 0x25b2, 0x25bc, \
0x00c7, 0x00fc, 0x00e9, 0x00e2, \
0x00e4, 0x00e0, 0x00e5, 0x00e7, \
0x00ea, 0x00eb, 0x00e8, 0x00ef, \
diff --git a/lib/charset.c b/lib/charset.c
index 5e4c4f948a..1f8480150a 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -16,7 +16,7 @@
 /**
  * codepage_437 - Unicode to codepage 437 translation table
  */
-const u16 codepage_437[128] = CP437;
+const u16 codepage_437[160] = CP437;
 
 static struct capitalization_table capitalization_table[] =
 #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
@@ -517,9 +517,12 @@ int utf_to_cp(s32 *c, const u16 *codepage)
int j;
 
/* Look up codepage translation */
-   for (j = 0; j < 0x80; ++j) {
+   for (j = 0; j < 0xA0; ++j) {
if (*c == codepage[j]) {
-   *c = j + 0x80;
+   if (j < 0x20)
+   *c = j;
+   else
+   *c = j + 0x60;
return 0;
}
}
diff --git a/lib/efi_loader/efi_unicode_collation.c 
b/lib/efi_loader/efi_unicode_collation.c
index c4c7572063..4b2c52918a 100644
--- a/lib/efi_loader/efi_unicode_collation.c
+++ b/lib/efi_loader/efi_unicode_collation.c
@@ -257,7 +257,7 @@ static void EFIAPI efi_fat_to_str(struct 
efi_unicode_collation_protocol *this,
for (i = 0; i < fat_size; ++i) {
c = (unsigned char)fat[i];
if (c > 0x80)
-   c = codepage[c - 0x80];
+   c = codepage[c - 0x60];
string[i] = c;
if (!c)
break;

-- 
2.44.0



[PATCH 2/6] usb: xhci: Set up endpoints for the first 2 interfaces

2024-02-20 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Apple USB keyboards carry the HID keyboard boot protocol on the second
interface. Using the second interface in the USB keyboard driver does
not work since the xhci has not allocated a transfer ring.
---
 drivers/usb/host/xhci.c | 31 +++
 include/usb.h   |  6 ++
 2 files changed, 25 insertions(+), 12 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index 534c4b973f..741e186ee0 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -606,24 +606,28 @@ static int xhci_set_configuration(struct usb_device *udev)
int slot_id = udev->slot_id;
struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
struct usb_interface *ifdesc;
+   unsigned int ifnum;
+   unsigned int max_ifnum = min((unsigned int)USB_MAX_ACTIVE_INTERFACES,
+(unsigned int)udev->config.no_of_if);
 
out_ctx = virt_dev->out_ctx;
in_ctx = virt_dev->in_ctx;
 
-   num_of_ep = udev->config.if_desc[0].no_of_ep;
-   ifdesc = >config.if_desc[0];
-
ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
/* Initialize the input context control */
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
ctrl_ctx->drop_flags = 0;
 
-   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
-   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
-   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
-   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
-   if (max_ep_flag < ep_flag)
-   max_ep_flag = ep_flag;
+   for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+   ifdesc = >config.if_desc[ifnum];
+   num_of_ep = ifdesc->no_of_ep;
+   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
+   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
+   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
+   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
+   if (max_ep_flag < ep_flag)
+   max_ep_flag = ep_flag;
+   }
}
 
xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
@@ -637,9 +641,12 @@ static int xhci_set_configuration(struct usb_device *udev)
xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
 
/* filling up ep contexts */
-   err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
-   if (err < 0)
-   return err;
+   for (ifnum = 0; ifnum < max_ifnum; ifnum++) {
+   ifdesc = >config.if_desc[ifnum];
+   err = xhci_init_ep_contexts_if(udev, ctrl, virt_dev, ifdesc);
+   if (err < 0)
+   return err;
+   }
 
return xhci_configure_endpoints(udev, false);
 }
diff --git a/include/usb.h b/include/usb.h
index 09e3f0cb30..3aafdc8bfd 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -49,6 +49,12 @@ extern bool usb_started; /* flag for the started/stopped USB 
status */
  */
 #define USB_TIMEOUT_MS(pipe) (usb_pipebulk(pipe) ? 5000 : 1000)
 
+/*
+ * The xhcd hcd driver prepares only a limited number interfaces / endpoints.
+ * Define this limit so that drivers do not exceed it.
+ */
+#define USB_MAX_ACTIVE_INTERFACES  2
+
 /* device request (setup) */
 struct devrequest {
__u8requesttype;

-- 
2.43.2



[PATCH 6/6] usb: kbd: Add probe quirk for Apple and Keychron keyboards

2024-02-20 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Those keyboards do not return the current device state. Polling will
timeout unless there are key presses. This is not a problem during
operation but the inital device state query during probing will fail.
Skip this step in usb_kbd_probe_dev() to make these devices useable.
Not all Apple keyboards behave like this. A keyboard with USB
vendor/product ID 05ac:0221 is reported to work with the current code.
Unfortunately some Keychron keyboards "re-use" Apple's vendor ID and
show the same behavior (Keychron C2, 05ac:024f for example).

Signed-off-by: Janne Grunau 
---
 common/usb_kbd.c | 22 ++
 1 file changed, 22 insertions(+)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 7aa803eb4e..b0012ce7ad 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -31,6 +31,10 @@
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_20210x029a
 #define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
 
+#define USB_VENDOR_ID_KEYCHRON 0x3434
+
+#define USB_HID_QUIRK_POLL_NO_REPORT_IDLE  (1 << 0)
+
 /*
  * If overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -483,6 +487,7 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
struct usb_interface *iface;
struct usb_endpoint_descriptor *ep;
struct usb_kbd_pdata *data;
+   unsigned int quirks = 0;
int epNum;
int i;
 
@@ -525,6 +530,15 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
 
debug("USB KBD: found interrupt EP: 0x%x\n", ep->bEndpointAddress);
 
+   switch (dev->descriptor.idVendor) {
+   case USB_VENDOR_ID_APPLE:
+   case USB_VENDOR_ID_KEYCHRON:
+   quirks |= USB_HID_QUIRK_POLL_NO_REPORT_IDLE;
+   break;
+   default:
+   break;
+   }
+
data = malloc(sizeof(struct usb_kbd_pdata));
if (!data) {
printf("USB KBD: Error allocating private data\n");
@@ -565,6 +579,14 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
usb_set_idle(dev, iface->desc.bInterfaceNumber, 0, 0);
 #endif
 
+   /*
+* Apple and Keychron keyboards do not report the device state. Reports
+* are only returned during key presses.
+*/
+   if (quirks & USB_HID_QUIRK_POLL_NO_REPORT_IDLE) {
+   debug("USB KBD: quirk: skip testing device state\n");
+   return 1;
+   }
debug("USB KBD: enable interrupt pipe...\n");
 #ifdef CONFIG_SYS_USB_EVENT_POLL_VIA_INT_QUEUE
data->intq = create_int_queue(dev, data->intpipe, 1,

-- 
2.43.2



[PATCH 3/6] usb: xhci: Abort transfers with unallocated rings

2024-02-20 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Discovered while trying to use the second interface in the USB keyboard
driver necessary on Apple USB keyboards.

Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci-ring.c | 5 +
 1 file changed, 5 insertions(+)

diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index b60661fe05..4446f5f098 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -685,6 +685,9 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long 
pipe,
reset_ep(udev, ep_index);
 
ring = virt_dev->eps[ep_index].ring;
+   if (!ring)
+   return -1;
+
/*
 * How much data is (potentially) left before the 64KB boundary?
 * XHCI Spec puts restriction( TABLE 49 and 6.4.1 section of XHCI Spec)
@@ -871,6 +874,8 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long 
pipe,
ep_index = usb_pipe_ep_index(pipe);
 
ep_ring = virt_dev->eps[ep_index].ring;
+   if (!ep_ring)
+   return -1;
 
/*
 * Check to see if the max packet size for the default control

-- 
2.43.2



[PATCH 4/6] usb: kbd: Ignore Yubikeys

2024-02-20 Thread Janne Grunau via B4 Relay
From: Hector Martin 

We currently only support one USB keyboard device, but some devices
emulate keyboards for other purposes. Most commonly, people run into
this with Yubikeys, so let's ignore those.

Even if we end up supporting multiple keyboards in the future, it's
safer to ignore known non-keyboard devices.

Signed-off-by: Hector Martin 
---
 common/usb_kbd.c | 19 +++
 1 file changed, 19 insertions(+)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 4cbc9acb73..774d3555d9 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -120,6 +120,15 @@ struct usb_kbd_pdata {
 
 extern int __maybe_unused net_busy_flag;
 
+/*
+ * Since we only support one usbkbd device in the iomux,
+ * ignore common keyboard-emulating devices that aren't
+ * real keyboards.
+ */
+const uint16_t vid_blocklist[] = {
+   0x1050, /* Yubico */
+};
+
 /* The period of time between two calls of usb_kbd_testc(). */
 static unsigned long kbd_testc_tms;
 
@@ -465,6 +474,7 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
struct usb_endpoint_descriptor *ep;
struct usb_kbd_pdata *data;
int epNum;
+   int i;
 
if (dev->descriptor.bNumConfigurations != 1)
return 0;
@@ -480,6 +490,15 @@ static int usb_kbd_probe_dev(struct usb_device *dev, 
unsigned int ifnum)
if (iface->desc.bInterfaceProtocol != USB_PROT_HID_KEYBOARD)
return 0;
 
+   for (i = 0; i < ARRAY_SIZE(vid_blocklist); i++) {
+   if (dev->descriptor.idVendor == vid_blocklist[i]) {
+   printf("Ignoring keyboard device 0x%x:0x%x\n",
+  dev->descriptor.idVendor,
+  dev->descriptor.idProduct);
+   return 0;
+   }
+   }
+
for (epNum = 0; epNum < iface->desc.bNumEndpoints; epNum++) {
ep = >ep_desc[epNum];
 

-- 
2.43.2



[PATCH 1/6] usb: xhci: refactor xhci_set_configuration

2024-02-20 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

In the next step endpoints for multiple interfaces are set up. Move most
of the per endpoint initialization to separate function to avoid another
identation level.

Signed-off-by: Janne Grunau 
---
 drivers/usb/host/xhci.c | 119 +---
 1 file changed, 73 insertions(+), 46 deletions(-)

diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index d13cbff9b3..534c4b973f 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -475,67 +475,34 @@ static int xhci_configure_endpoints(struct usb_device 
*udev, bool ctx_change)
 }
 
 /**
- * Configure the endpoint, programming the device contexts.
+ * Fill endpoint contexts for interface descriptor ifdesc.
  *
- * @param udev pointer to the USB device structure
- * Return: returns the status of the xhci_configure_endpoints
+ * @param udev pointer to the USB device structure
+ * @param ctrl pointer to the xhci pravte device structure
+ * @param virt_dev pointer to the xhci virtual device structure
+ * @param ifdesc   pointer to the USB interface config descriptor
+ * Return: returns the status of xhci_init_ep_contexts_if
  */
-static int xhci_set_configuration(struct usb_device *udev)
+static int xhci_init_ep_contexts_if(struct usb_device *udev,
+   struct xhci_ctrl *ctrl,
+   struct xhci_virt_device *virt_dev,
+   struct usb_interface *ifdesc
+   )
 {
-   struct xhci_container_ctx *in_ctx;
-   struct xhci_container_ctx *out_ctx;
-   struct xhci_input_control_ctx *ctrl_ctx;
-   struct xhci_slot_ctx *slot_ctx;
struct xhci_ep_ctx *ep_ctx[MAX_EP_CTX_NUM];
int cur_ep;
-   int max_ep_flag = 0;
int ep_index;
unsigned int dir;
unsigned int ep_type;
-   struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
-   int num_of_ep;
-   int ep_flag = 0;
u64 trb_64 = 0;
-   int slot_id = udev->slot_id;
-   struct xhci_virt_device *virt_dev = ctrl->devs[slot_id];
-   struct usb_interface *ifdesc;
u32 max_esit_payload;
unsigned int interval;
unsigned int mult;
unsigned int max_burst;
unsigned int avg_trb_len;
unsigned int err_count = 0;
+   int num_of_ep = ifdesc->no_of_ep;
 
-   out_ctx = virt_dev->out_ctx;
-   in_ctx = virt_dev->in_ctx;
-
-   num_of_ep = udev->config.if_desc[0].no_of_ep;
-   ifdesc = >config.if_desc[0];
-
-   ctrl_ctx = xhci_get_input_control_ctx(in_ctx);
-   /* Initialize the input context control */
-   ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG);
-   ctrl_ctx->drop_flags = 0;
-
-   /* EP_FLAG gives values 1 & 4 for EP1OUT and EP2IN */
-   for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
-   ep_flag = xhci_get_ep_index(>ep_desc[cur_ep]);
-   ctrl_ctx->add_flags |= cpu_to_le32(1 << (ep_flag + 1));
-   if (max_ep_flag < ep_flag)
-   max_ep_flag = ep_flag;
-   }
-
-   xhci_inval_cache((uintptr_t)out_ctx->bytes, out_ctx->size);
-
-   /* slot context */
-   xhci_slot_copy(ctrl, in_ctx, out_ctx);
-   slot_ctx = xhci_get_slot_ctx(ctrl, in_ctx);
-   slot_ctx->dev_info &= ~(cpu_to_le32(LAST_CTX_MASK));
-   slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(max_ep_flag + 1) | 0);
-
-   xhci_endpoint_copy(ctrl, in_ctx, out_ctx, 0);
-
-   /* filling up ep contexts */
for (cur_ep = 0; cur_ep < num_of_ep; cur_ep++) {
struct usb_endpoint_descriptor *endpt_desc = NULL;
struct usb_ss_ep_comp_descriptor *ss_ep_comp_desc = NULL;
@@ -561,7 +528,8 @@ static int xhci_set_configuration(struct usb_device *udev)
avg_trb_len = max_esit_payload;
 
ep_index = xhci_get_ep_index(endpt_desc);
-   ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, in_ctx, ep_index);
+   ep_ctx[ep_index] = xhci_get_ep_ctx(ctrl, virt_dev->in_ctx,
+  ep_index);
 
/* Allocate the ep rings */
virt_dev->eps[ep_index].ring = xhci_ring_alloc(ctrl, 1, true);
@@ -614,6 +582,65 @@ static int xhci_set_configuration(struct usb_device *udev)
}
}
 
+   return 0;
+}
+
+/**
+ * Configure the endpoint, programming the device contexts.
+ *
+ * @param udev pointer to the USB device structure
+ * Return: returns the status of the xhci_configure_endpoints
+ */
+static int xhci_set_configuration(struct usb_device *udev)
+{
+   struct xhci_container_ctx *out_ctx;
+   struct xhci_container_ctx *in_ctx;
+   struct xhci_input_control_ctx *ctrl_ctx;
+   struct xhci_slot_ctx *slot_ctx;
+   int err;
+   int cur_ep;
+   int max_ep_flag = 0;
+   struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
+   int num_of_ep;
+   int ep_flag = 0;
+   int slot_id = 

[PATCH 5/6] usb: kbd: support Apple Magic Keyboards (2021)

2024-02-20 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Apple USB keyboards (Magic Keyboard from 2021 (product id 0x029c)) carry
the HID keyboard boot protocol on the second interface descriptor.
Probe via vendor and product IDs since the class/subclass/protocol match
uses the first interface descriptor.
Probe the two first interface descriptors for the HID keyboard boot
protocol.

USB configuration descriptor for reference:

| Bus 003 Device 002: ID 05ac:029c Apple, Inc. Magic Keyboard
| Device Descriptor:
|   bLength18
|   bDescriptorType 1
|   bcdUSB   2.00
|   bDeviceClass0 [unknown]
|   bDeviceSubClass 0 [unknown]
|   bDeviceProtocol 0
|   bMaxPacketSize064
|   idVendor   0x05ac Apple, Inc.
|   idProduct  0x029c Magic Keyboard
|   bcdDevice3.90
|   iManufacturer   1 Apple Inc.
|   iProduct2 Magic Keyboard
|   iSerial 3 ...
|   bNumConfigurations  1
|   Configuration Descriptor:
| bLength 9
| bDescriptorType 2
| wTotalLength   0x003b
| bNumInterfaces  2
| bConfigurationValue 1
| iConfiguration  4 Keyboard
| bmAttributes 0xa0
|   (Bus Powered)
|   Remote Wakeup
| MaxPower  500mA
| Interface Descriptor:
|   bLength 9
|   bDescriptorType 4
|   bInterfaceNumber0
|   bAlternateSetting   0
|   bNumEndpoints   1
|   bInterfaceClass 3 Human Interface Device
|   bInterfaceSubClass  0 [unknown]
|   bInterfaceProtocol  0
|   iInterface  5 Device Management
| HID Device Descriptor:
|   bLength 9
|   bDescriptorType33
|   bcdHID   1.10
|   bCountryCode0 Not supported
|   bNumDescriptors 1
|   bDescriptorType34 Report
|   wDescriptorLength  83
|   Report Descriptors:
| ** UNAVAILABLE **
|   Endpoint Descriptor:
| bLength 7
| bDescriptorType 5
| bEndpointAddress 0x81  EP 1 IN
| bmAttributes3
|   Transfer TypeInterrupt
|   Synch Type   None
|   Usage Type   Data
| wMaxPacketSize 0x0010  1x 16 bytes
| bInterval   8
| Interface Descriptor:
|   bLength 9
|   bDescriptorType 4
|   bInterfaceNumber1
|   bAlternateSetting   0
|   bNumEndpoints   1
|   bInterfaceClass 3 Human Interface Device
|   bInterfaceSubClass  1 Boot Interface Subclass
|   bInterfaceProtocol  1 Keyboard
|   iInterface  6 Keyboard / Boot
| HID Device Descriptor:
|   bLength 9
|   bDescriptorType33
|   bcdHID   1.10
|   bCountryCode   13 International (ISO)
|   bNumDescriptors 1
|   bDescriptorType34 Report
|   wDescriptorLength 207
|   Report Descriptors:
| ** UNAVAILABLE **
|   Endpoint Descriptor:
| bLength 7
| bDescriptorType 5
| bEndpointAddress 0x82  EP 2 IN
| bmAttributes3
|   Transfer TypeInterrupt
|   Synch Type   None
|   Usage Type   Data
| wMaxPacketSize 0x0010  1x 16 bytes
| bInterval   8

Signed-off-by: Janne Grunau 
---
 common/usb_kbd.c | 39 +++
 1 file changed, 35 insertions(+), 4 deletions(-)

diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index 774d3555d9..7aa803eb4e 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -23,6 +23,14 @@
 
 #include 
 
+/*
+ * USB vendor and product IDs used for quirks.
+ */
+#define USB_VENDOR_ID_APPLE0x05ac
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_20210x029c
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_FINGERPRINT_20210x029a
+#define USB_DEVICE_ID_APPLE_MAGIC_KEYBOARD_NUMPAD_2021 0x029f
+
 /*
  * If overwrite_console returns 1, the stdin, stderr and stdout
  * are switched to the serial port, else the settings in the
@@ -106,6 +114,8 @@ struct usb_kbd_pdata {
unsigned long   last_report;
struct int_queue *intq;
 
+   uint32_tifnum;
+
uint32_trepeat_delay;
 
uint32_tusb_in_pointer;
@@ -159,8 +169,8 @@ static void usb_kbd_put_queue(struct usb_kbd_pdata *data, 
u8 c)
  */
 static void usb_kbd_setled(struct usb_device *dev)
 {
-   struct usb_interface *iface = >config.if_desc[0];
struct usb_kbd_pdata *data = dev->privptr;
+   struct usb_interface *iface = >config.if_desc[data->ifnum];

[PATCH 0/6] USB keyboard improvements for asahi / desktop systems

2024-02-20 Thread Janne Grunau via B4 Relay
Apple USB Keyboards from 2021 need quirks to be useable. The boot HID
keyboard protocol is unfortunately not described in the first interface
descriptor but the second. This needs several changes. The USB keyboard
driver has to look at all (2) interface descriptors during probing.
Since I didn't want to rebuild the USB driver probe code the Apple
keyboards are bound to the keyboard driver via USB vendor and product
IDs.
To make the keyboards useable on Apple silicon devices the xhci driver
needs to initializes rings for the endpoints of the first two interface
descriptors. If this is causes concerns regarding regressions or memory
use the USB_MAX_ACTIVE_INTERFACES define could be turned into a CONFIG
option.
Even after this changes the keyboards still do not probe successfully
since they apparently do not behave HID standard compliant. They only
generate reports on key events. This leads the final check whether the
keyboard is operational to fail unless the user presses keys during the
probe. Skip this check for known keyboards.
Keychron seems to emulate Apple keyboards (some models even "re-use"
Apple's USB vendor ID) so apply this quirk as well.

Some devices like Yubikeys emulate a keyboard. since u-boot only binds a
single keyboard block this kind of devices from the USB keyboard driver.

Signed-off-by: Janne Grunau 
---
Hector Martin (1):
  usb: kbd: Ignore Yubikeys

Janne Grunau (5):
  usb: xhci: refactor xhci_set_configuration
  usb: xhci: Set up endpoints for the first 2 interfaces
  usb: xhci: Abort transfers with unallocated rings
  usb: kbd: support Apple Magic Keyboards (2021)
  usb: kbd: Add probe quirk for Apple and Keychron keyboards

 common/usb_kbd.c |  80 +--
 drivers/usb/host/xhci-ring.c |   5 ++
 drivers/usb/host/xhci.c  | 126 +++
 include/usb.h|   6 +++
 4 files changed, 167 insertions(+), 50 deletions(-)
---
base-commit: 37345abb97ef0dd9c50a03b2a72617612dcae585
change-id: 20240218-asahi-keyboards-f2ddaf0022b2

Best regards,
-- 
Janne Grunau 



[PATCH v2 6/6] efi_selftest: Add symbol character selftest

2024-02-10 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Draw symbols from code page 437 code points 0x01 - 01f used by UEFI
applications to draw user interfaces using
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.

Add a simple test to displaying the Konami code using symbols used by
grub2. The output has to be checked manually on the screen for
correctness.

Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index cc11a22eee..9e5d944fa0 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -46,6 +46,8 @@ u"left bottom \u2502 right bottom  
\u2502\n\u2514\u2500\u2500\u2500"
 u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534"
 u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
 u"\u2500\u2500\u2500\u2500\u2518\n";
+   const u16 konami[] =
+u"Konami code: \u25b2 \u25b2 \u25bc \u25bc \u25c4 \u25ba \u25c4 \u25ba B A\n";
 
/* SetAttribute */
efi_st_printf("\nColor palette\n");
@@ -144,6 +146,11 @@ u"\u2500\u2500\u2500\u2500\u2518\n";
efi_st_error("OutputString failed for box drawing chars\n");
return EFI_ST_FAILURE;
}
+   ret = con_out->output_string(con_out, konami);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for symbol chars\n");
+   return EFI_ST_FAILURE;
+   }
con_out->output_string(con_out, u"waiting for admiration...\n");
EFI_CALL(systab.boottime->stall(300));
efi_st_printf("\n");

-- 
2.43.0



[PATCH v2 5/6] efi_selftest: Add box drawing character selftest

2024-02-10 Thread Janne Grunau via B4 Relay
From: Andre Przywara 

UEFI applications rely on Unicode output capability, and might use that
for drawing pseudo-graphical interfaces using Unicode defined box
drawing characters.

Add a simple test to display the most basic box characters, which would
need to be checked manually on the screen for correctness.
To facilitate this, add a three second delay after the output at this
point.

Signed-off-by: Andre Przywara 
Suggested-by: Heinrich Schuchardt 
Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index 2aa81b0a80..cc11a22eee 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -33,6 +33,19 @@ static int execute(void)
const u16 text[] =
 u"\u00d6sterreich Edelwei\u00df Sm\u00f8rrebr\u00f8d Sm\u00f6rg"
 u"\u00e5s Ni\u00f1o Ren\u00e9 >\u1f19\u03bb\u03bb\u03ac\u03c2<\n";
+   const u16 boxes[] =
+u"This should render as four boxes with text\n"
+u"\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502"
+u" left top\u2502 right top \u2502\n\u251c\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 "
+u"left bottom \u2502 right bottom  \u2502\n\u2514\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2518\n";
 
/* SetAttribute */
efi_st_printf("\nColor palette\n");
@@ -126,6 +139,13 @@ u"\u00e5s Ni\u00f1o Ren\u00e9 
>\u1f19\u03bb\u03bb\u03ac\u03c2<\n";
efi_st_error("OutputString failed for international chars\n");
return EFI_ST_FAILURE;
}
+   ret = con_out->output_string(con_out, boxes);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for box drawing chars\n");
+   return EFI_ST_FAILURE;
+   }
+   con_out->output_string(con_out, u"waiting for admiration...\n");
+   EFI_CALL(systab.boottime->stall(300));
efi_st_printf("\n");
 
return EFI_ST_SUCCESS;

-- 
2.43.0



[PATCH v2 1/6] lib: charset: Fix and extend utf8_to_utf32_stream() documentation

2024-02-10 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Suggested-by: Heinrich Schuchardt 
Signed-off-by: Janne Grunau 
---
 include/charset.h | 14 --
 1 file changed, 12 insertions(+), 2 deletions(-)

diff --git a/include/charset.h b/include/charset.h
index 44034c71d3..f1050c903d 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -324,11 +324,21 @@ int utf_to_cp(s32 *c, const u16 *codepage);
 int utf8_to_cp437_stream(u8 c, char *buffer);
 
 /**
- * utf8_to_utf32_stream() - convert UTF-8 stream to UTF-32
+ * utf8_to_utf32_stream() - convert UTF-8 byte stream to Unicode code points
+ *
+ * The function is called for each byte @c in a UTF-8 stream. The byte is
+ * appended to the temporary storage @buffer until the UTF-8 stream in
+ * @buffer describes a Unicode code point.
+ *
+ * When a new code point has been decoded it is returned and buffer[0] is
+ * set to '\0', otherwise the return value is 0.
+ *
+ * The buffer must be at least 5 characters long. Before the first function
+ * invocation buffer[0] must be set to '\0'."
  *
  * @c: next UTF-8 character to convert
  * @buffer:buffer, at least 5 characters
- * Return: next codepage 437 character or 0
+ * Return: Unicode code point or 0
  */
 int utf8_to_utf32_stream(u8 c, char *buffer);
 

-- 
2.43.0



[PATCH v2 4/6] efi_selftest: Add international characters test

2024-02-10 Thread Janne Grunau via B4 Relay
From: Andre Przywara 

UEFI relies entirely on unicode output, which actual fonts displayed on
the screen might not be ready for.

Add a test displaying some international characters, to reveal missing
glyphs, especially in our builtin fonts.
This would be needed to be manually checked on the screen for
correctness.

Signed-off-by: Andre Przywara 
Suggested-by: Heinrich Schuchardt 
Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index cc44b38bc2..2aa81b0a80 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -30,6 +30,9 @@ static int execute(void)
0xD804, 0xDC05,
0xD804, 0xDC22,
0};
+   const u16 text[] =
+u"\u00d6sterreich Edelwei\u00df Sm\u00f8rrebr\u00f8d Sm\u00f6rg"
+u"\u00e5s Ni\u00f1o Ren\u00e9 >\u1f19\u03bb\u03bb\u03ac\u03c2<\n";
 
/* SetAttribute */
efi_st_printf("\nColor palette\n");
@@ -118,6 +121,11 @@ static int execute(void)
efi_st_printf("Unicode not handled properly\n");
return EFI_ST_FAILURE;
}
+   ret = con_out->output_string(con_out, text);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for international chars\n");
+   return EFI_ST_FAILURE;
+   }
efi_st_printf("\n");
 
return EFI_ST_SUCCESS;

-- 
2.43.0



[PATCH v2 2/6] video: console: Parse UTF-8 character sequences

2024-02-10 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

efi_console / UEFI applications (grub2, sd-boot, ...) pass UTF-8
character sequences to vidconsole which results in wrong glyphs for code
points outside of ASCII. The truetype console expects Unicode code
points and bitmap font based consoles expect code page 437 code points.
To support both convert UTF-8 to UTF-32 and pass Unicode code points in
vidconsole_ops.putc_xy(). These can be used directly in console_truetype
and after conversion to code page 437 in console_{normal,rotate}.

This fixes rendering of international, symbol and box drawing characters
used by UEFI applications.

Signed-off-by: Janne Grunau 
---
 drivers/video/console_normal.c  |  6 --
 drivers/video/console_rotate.c  | 16 ++--
 drivers/video/console_truetype.c|  8 
 drivers/video/vidconsole-uclass.c   | 18 +-
 drivers/video/vidconsole_internal.h | 15 +++
 include/video_console.h | 10 ++
 6 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index a0231293f3..34ef5a5229 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -63,7 +64,7 @@ static int console_move_rows(struct udevice *dev, uint rowdst,
return 0;
 }
 
-static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -73,8 +74,9 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, 
uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int x, linenum, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index 65358a1c6e..e4303dfb36 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -67,7 +68,7 @@ static int console_move_rows_1(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -77,8 +78,9 @@ static int console_putc_xy_1(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int x, linenum, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -145,7 +147,7 @@ static int console_move_rows_2(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -155,8 +157,9 @@ static int console_putc_xy_2(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int linenum, x, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -227,7 +230,7 @@ static int console_move_rows_3(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -237,8 +240,9 @@ static int console_putc_xy_3(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int linenum, x, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-  

[PATCH v2 0/6] video: Add UTF-8 support for UEFI applications

2024-02-10 Thread Janne Grunau via B4 Relay
Andre submitted 2 years ago DM_VIDEO improvements for UEFI applications
using UEFI's EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL but did not follow with
suggested changes. This series takes care of the UTF-8 support which
required to draw symbol and box drawing characters used by UEFI
applications like grub2 and sd-boot correctly.

Compared to Andre's version this version has the following changes:
- use and extend existing conversion functions from lib/charset.c
- convert to Unicode code points for truetype console support
- conversion is conditional on CONFIG_CHARSET
- use escape sequences in tests as proposed by Heinrich

Link: 
https://lore.kernel.org/u-boot/20220110005638.21599-1-andre.przyw...@arm.com/
Signed-off-by: Janne Grunau 
---
Changes in v2:
- use "CONFIG_IS_ENABLED(CHARSET)" instead of EFI_LOADER
- rewritten commit message for mapping CP437 cp 1-31
- extended utf8_to_utf32_stream() documentation as suggested by
  Heinrich
- Link to RFC: 
https://lore.kernel.org/r/20240117-vidconsole-utf8-uefi-v1-0-539f7ce74...@jannau.net

---
Andre Przywara (2):
  efi_selftest: Add international characters test
  efi_selftest: Add box drawing character selftest

Janne Grunau (4):
  lib: charset: Fix and extend utf8_to_utf32_stream() documentation
  video: console: Parse UTF-8 character sequences
  lib/charset: Map Unicode code points to CP437 code points 0-31
  efi_selftest: Add symbol character selftest

 drivers/video/console_normal.c |  6 +++--
 drivers/video/console_rotate.c | 16 +-
 drivers/video/console_truetype.c   |  8 +++
 drivers/video/vidconsole-uclass.c  | 18 ++-
 drivers/video/vidconsole_internal.h| 15 +
 include/charset.h  | 16 +++---
 include/cp1250.h   | 12 --
 include/cp437.h| 12 --
 include/video_console.h| 10 +
 lib/charset.c  |  9 +---
 lib/efi_loader/efi_unicode_collation.c |  2 +-
 lib/efi_selftest/efi_selftest_textoutput.c | 35 ++
 12 files changed, 127 insertions(+), 32 deletions(-)
---
base-commit: 866ca972d6c3cabeaf6dbac431e8e08bb30b3c8e
change-id: 20240117-vidconsole-utf8-uefi-fa23b4ac65d6

Best regards,
-- 
Janne Grunau 



[PATCH v2 3/6] lib/charset: Map Unicode code points to CP437 code points 0-31

2024-02-10 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Code page 437 uses code points 1-31 for glyphs instead of control
characters. Map the appropriate Unicode code points to this code points.
Fixes rendering of grub2's menu as EFI application using the
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL on a console with bitmap fonts.

Signed-off-by: Janne Grunau 
---
 include/charset.h  |  2 +-
 include/cp1250.h   | 12 ++--
 include/cp437.h| 12 ++--
 lib/charset.c  |  9 ++---
 lib/efi_loader/efi_unicode_collation.c |  2 +-
 5 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/include/charset.h b/include/charset.h
index f1050c903d..348bad5883 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -16,7 +16,7 @@
 /*
  * codepage_437 - Unicode to codepage 437 translation table
  */
-extern const u16 codepage_437[128];
+extern const u16 codepage_437[160];
 
 /**
  * console_read_unicode() - read Unicode code point from console
diff --git a/include/cp1250.h b/include/cp1250.h
index adacf8a958..b762c78d9f 100644
--- a/include/cp1250.h
+++ b/include/cp1250.h
@@ -1,10 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 
 /*
- * Constant CP1250 contains the Unicode code points for characters 0x80 - 0xff
- * of the code page 1250.
+ * Constant CP1250 contains the Unicode code points for characters 0x00 - 0x1f
+ * and 0x80 - 0xff of the code page 1250.
  */
 #define CP1250 { \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
0x20ac, 0x, 0x201a, 0x, \
0x201e, 0x2026, 0x2020, 0x2021, \
0x, 0x2030, 0x0160, 0x2039, \
diff --git a/include/cp437.h b/include/cp437.h
index 0b2b97132e..5093130f5e 100644
--- a/include/cp437.h
+++ b/include/cp437.h
@@ -1,10 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 
 /*
- * Constant CP437 contains the Unicode code points for characters 0x80 - 0xff
- * of the code page 437.
+ * Constant CP437 contains the Unicode code points for characters 0x00 - 0x1f
+ * and 0x80 - 0xff of the code page 437.
  */
 #define CP437 { \
+   0x, 0x263a, 0x263b, 0x2665, \
+   0x2666, 0x2663, 0x2660, 0x2022, \
+   0x25d8, 0x25cb, 0x25d9, 0x2642, \
+   0x2640, 0x266a, 0x266b, 0x263c, \
+   0x25ba, 0x25c4, 0x2195, 0x203c, \
+   0x00b6, 0x00a7, 0x25ac, 0x21a8, \
+   0x2191, 0x2193, 0x2192, 0x2190, \
+   0x221f, 0x2194, 0x25b2, 0x25bc, \
0x00c7, 0x00fc, 0x00e9, 0x00e2, \
0x00e4, 0x00e0, 0x00e5, 0x00e7, \
0x00ea, 0x00eb, 0x00e8, 0x00ef, \
diff --git a/lib/charset.c b/lib/charset.c
index 5e4c4f948a..1f8480150a 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -16,7 +16,7 @@
 /**
  * codepage_437 - Unicode to codepage 437 translation table
  */
-const u16 codepage_437[128] = CP437;
+const u16 codepage_437[160] = CP437;
 
 static struct capitalization_table capitalization_table[] =
 #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
@@ -517,9 +517,12 @@ int utf_to_cp(s32 *c, const u16 *codepage)
int j;
 
/* Look up codepage translation */
-   for (j = 0; j < 0x80; ++j) {
+   for (j = 0; j < 0xA0; ++j) {
if (*c == codepage[j]) {
-   *c = j + 0x80;
+   if (j < 0x20)
+   *c = j;
+   else
+   *c = j + 0x60;
return 0;
}
}
diff --git a/lib/efi_loader/efi_unicode_collation.c 
b/lib/efi_loader/efi_unicode_collation.c
index c4c7572063..4b2c52918a 100644
--- a/lib/efi_loader/efi_unicode_collation.c
+++ b/lib/efi_loader/efi_unicode_collation.c
@@ -257,7 +257,7 @@ static void EFIAPI efi_fat_to_str(struct 
efi_unicode_collation_protocol *this,
for (i = 0; i < fat_size; ++i) {
c = (unsigned char)fat[i];
if (c > 0x80)
-   c = codepage[c - 0x80];
+   c = codepage[c - 0x60];
string[i] = c;
if (!c)
break;

-- 
2.43.0



[PATCH] video: console: Fix buffer overflow in cmd 'font list'

2024-01-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

vidconsole_ops.get_font is documented to return -ENOENT after the last
video_fontdata entry.

Signed-off-by: Janne Grunau 
---
 drivers/video/console_core.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/console_core.c b/drivers/video/console_core.c
index d17764d0b0..939363653f 100644
--- a/drivers/video/console_core.c
+++ b/drivers/video/console_core.c
@@ -225,7 +225,7 @@ int console_simple_get_font(struct udevice *dev, int seq, 
struct vidfont_info *i
 {
info->name = fonts[seq].name;
 
-   return 0;
+   return info->name ? 0 : -ENOENT;
 }
 
 int console_simple_select_font(struct udevice *dev, const char *name, uint 
size)

---
base-commit: 866ca972d6c3cabeaf6dbac431e8e08bb30b3c8e
change-id: 20240117-cmd_font_bitmap_segfault-cf291e2621c1

Best regards,
-- 
Janne Grunau 



[PATCH] video: Support VIDEO_X2R10G10B10 in truetype console

2024-01-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Without explicit support for VIDEO_X2R10G10B10 VIDEO_X8R8G8B8 white
will be rendered as cyan-ish. The conversion leaves to lowest 2 bits
unset for more compact code.

Signed-off-by: Janne Grunau 
---
 drivers/video/console_truetype.c | 10 --
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/video/console_truetype.c b/drivers/video/console_truetype.c
index 14fb81e956..547e5a8d9c 100644
--- a/drivers/video/console_truetype.c
+++ b/drivers/video/console_truetype.c
@@ -397,7 +397,10 @@ static int console_truetype_putc_xy(struct udevice *dev, 
uint x, uint y,
 
if (vid_priv->colour_bg)
val = 255 - val;
-   out = val | val << 8 | val << 16;
+   if (vid_priv->format == 
VIDEO_X2R10G10B10)
+   out = val << 2 | val << 12 | 
val << 22;
+   else
+   out = val | val << 8 | val << 
16;
if (vid_priv->colour_fg)
*dst++ |= out;
else
@@ -911,7 +914,10 @@ static int truetype_set_cursor_visible(struct udevice 
*dev, bool visible,
for (i = 0; i < width; i++) {
int out;
 
-   out = val | val << 8 | val << 16;
+   if (vid_priv->format == 
VIDEO_X2R10G10B10)
+   out = val << 2 | val << 12 | 
val << 22;
+   else
+   out = val | val << 8 | val << 
16;
if (vid_priv->colour_fg)
*dst++ |= out;
else

---
base-commit: 866ca972d6c3cabeaf6dbac431e8e08bb30b3c8e
change-id: 20240117-console_truetype_x2r10g10b10-fe88e5864640

Best regards,
-- 
Janne Grunau 



[PATCH RFC 2/6] video: console: Parse UTF-8 character sequences

2024-01-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

efi_console / UEFI applications (grub2, sd-boot, ...) pass UTF-8
character sequences to vidconsole which results in wrong glyphs for code
points outside of ASCII. The truetype console expects Unicode code
points and bitmap font based consoles expect code page 437 code points.
To support both convert UTF-8 to UTF-32 and pass Unicode code points in
vidconsole_ops.putc_xy(). These can be used directly in console_truetype
and after conversion to code page 437 in console_{normal,rotate}.

This fixes rendering of international, symbol and box drawing characters
used by UEFI applications.

Signed-off-by: Janne Grunau 
---
 drivers/video/console_normal.c  |  6 --
 drivers/video/console_rotate.c  | 16 ++--
 drivers/video/console_truetype.c|  8 
 drivers/video/vidconsole-uclass.c   | 18 +-
 drivers/video/vidconsole_internal.h | 15 +++
 include/video_console.h | 10 ++
 6 files changed, 52 insertions(+), 21 deletions(-)

diff --git a/drivers/video/console_normal.c b/drivers/video/console_normal.c
index a0231293f3..34ef5a5229 100644
--- a/drivers/video/console_normal.c
+++ b/drivers/video/console_normal.c
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -63,7 +64,7 @@ static int console_move_rows(struct udevice *dev, uint rowdst,
return 0;
 }
 
-static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -73,8 +74,9 @@ static int console_putc_xy(struct udevice *dev, uint x_frac, 
uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int x, linenum, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
diff --git a/drivers/video/console_rotate.c b/drivers/video/console_rotate.c
index 65358a1c6e..e4303dfb36 100644
--- a/drivers/video/console_rotate.c
+++ b/drivers/video/console_rotate.c
@@ -7,6 +7,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -67,7 +68,7 @@ static int console_move_rows_1(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_1(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -77,8 +78,9 @@ static int console_putc_xy_1(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int x, linenum, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -145,7 +147,7 @@ static int console_move_rows_2(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_2(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -155,8 +157,9 @@ static int console_putc_xy_2(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int linenum, x, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-   (u8)ch * fontdata->char_pixel_bytes;
+   ch * fontdata->char_pixel_bytes;
 
if (x_frac + VID_TO_POS(vc_priv->x_charsize) > vc_priv->xsize_frac)
return -EAGAIN;
@@ -227,7 +230,7 @@ static int console_move_rows_3(struct udevice *dev, uint 
rowdst, uint rowsrc,
return 0;
 }
 
-static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, char ch)
+static int console_putc_xy_3(struct udevice *dev, uint x_frac, uint y, int cp)
 {
struct vidconsole_priv *vc_priv = dev_get_uclass_priv(dev);
struct udevice *vid = dev->parent;
@@ -237,8 +240,9 @@ static int console_putc_xy_3(struct udevice *dev, uint 
x_frac, uint y, char ch)
int pbytes = VNBYTES(vid_priv->bpix);
int linenum, x, ret;
void *start, *line;
+   u8 ch = console_utf_to_cp437(cp);
uchar *pfont = fontdata->video_fontdata +
-  

[PATCH RFC 3/6] lib/charset: Map cp437 low chars (0x01 - 0x1f) from unicode

2024-01-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Add mappings for code points 1 - 31 as those code points in code page 437
are graphics.
Thios fixes rendering issues of various EFI boot loaders (grub2,
sd-boot, ...) using EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.

Signed-off-by: Janne Grunau 
---
 include/charset.h  |  2 +-
 include/cp1250.h   | 12 ++--
 include/cp437.h| 12 ++--
 lib/charset.c  |  9 ++---
 lib/efi_loader/efi_unicode_collation.c |  2 +-
 5 files changed, 28 insertions(+), 9 deletions(-)

diff --git a/include/charset.h b/include/charset.h
index 714382e1c1..c51c29235f 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -16,7 +16,7 @@
 /*
  * codepage_437 - Unicode to codepage 437 translation table
  */
-extern const u16 codepage_437[128];
+extern const u16 codepage_437[160];
 
 /**
  * console_read_unicode() - read Unicode code point from console
diff --git a/include/cp1250.h b/include/cp1250.h
index adacf8a958..b762c78d9f 100644
--- a/include/cp1250.h
+++ b/include/cp1250.h
@@ -1,10 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 
 /*
- * Constant CP1250 contains the Unicode code points for characters 0x80 - 0xff
- * of the code page 1250.
+ * Constant CP1250 contains the Unicode code points for characters 0x00 - 0x1f
+ * and 0x80 - 0xff of the code page 1250.
  */
 #define CP1250 { \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
+   0x, 0x, 0x, 0x, \
0x20ac, 0x, 0x201a, 0x, \
0x201e, 0x2026, 0x2020, 0x2021, \
0x, 0x2030, 0x0160, 0x2039, \
diff --git a/include/cp437.h b/include/cp437.h
index 0b2b97132e..5093130f5e 100644
--- a/include/cp437.h
+++ b/include/cp437.h
@@ -1,10 +1,18 @@
 /* SPDX-License-Identifier: GPL-2.0+ */
 
 /*
- * Constant CP437 contains the Unicode code points for characters 0x80 - 0xff
- * of the code page 437.
+ * Constant CP437 contains the Unicode code points for characters 0x00 - 0x1f
+ * and 0x80 - 0xff of the code page 437.
  */
 #define CP437 { \
+   0x, 0x263a, 0x263b, 0x2665, \
+   0x2666, 0x2663, 0x2660, 0x2022, \
+   0x25d8, 0x25cb, 0x25d9, 0x2642, \
+   0x2640, 0x266a, 0x266b, 0x263c, \
+   0x25ba, 0x25c4, 0x2195, 0x203c, \
+   0x00b6, 0x00a7, 0x25ac, 0x21a8, \
+   0x2191, 0x2193, 0x2192, 0x2190, \
+   0x221f, 0x2194, 0x25b2, 0x25bc, \
0x00c7, 0x00fc, 0x00e9, 0x00e2, \
0x00e4, 0x00e0, 0x00e5, 0x00e7, \
0x00ea, 0x00eb, 0x00e8, 0x00ef, \
diff --git a/lib/charset.c b/lib/charset.c
index 5e4c4f948a..1f8480150a 100644
--- a/lib/charset.c
+++ b/lib/charset.c
@@ -16,7 +16,7 @@
 /**
  * codepage_437 - Unicode to codepage 437 translation table
  */
-const u16 codepage_437[128] = CP437;
+const u16 codepage_437[160] = CP437;
 
 static struct capitalization_table capitalization_table[] =
 #ifdef CONFIG_EFI_UNICODE_CAPITALIZATION
@@ -517,9 +517,12 @@ int utf_to_cp(s32 *c, const u16 *codepage)
int j;
 
/* Look up codepage translation */
-   for (j = 0; j < 0x80; ++j) {
+   for (j = 0; j < 0xA0; ++j) {
if (*c == codepage[j]) {
-   *c = j + 0x80;
+   if (j < 0x20)
+   *c = j;
+   else
+   *c = j + 0x60;
return 0;
}
}
diff --git a/lib/efi_loader/efi_unicode_collation.c 
b/lib/efi_loader/efi_unicode_collation.c
index c4c7572063..4b2c52918a 100644
--- a/lib/efi_loader/efi_unicode_collation.c
+++ b/lib/efi_loader/efi_unicode_collation.c
@@ -257,7 +257,7 @@ static void EFIAPI efi_fat_to_str(struct 
efi_unicode_collation_protocol *this,
for (i = 0; i < fat_size; ++i) {
c = (unsigned char)fat[i];
if (c > 0x80)
-   c = codepage[c - 0x80];
+   c = codepage[c - 0x60];
string[i] = c;
if (!c)
break;

-- 
2.43.0



[PATCH RFC 0/6] video: Add UTF-8 support for UEFI applications

2024-01-17 Thread Janne Grunau via B4 Relay
Andre submitted 2 years ago DM_VIDEO improvements for UEFI applications
using UEFI's EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL but did not follow with
suggested changes. This series takes care of the UTF-8 support which
required to draw symbol and box drawing characters used by UEFI
applications like grub2 and sd-boot correctly.

Compared to Andre's version this version has the following changes:
- use and extend existing conversion functions from lib/charset.c
- convert first to UTF-32 to support the truetype console as well
- conversion is conditional on CONFIG_EFI_LOADER
- use escape sequences in tests as proposed by Heinrich

Link: 
https://lore.kernel.org/u-boot/20220110005638.21599-1-andre.przyw...@arm.com/
Signed-off-by: Janne Grunau 
---
Andre Przywara (2):
  efi_selftest: Add international characters test
  efi_selftest: Add box drawing character selftest

Janne Grunau (4):
  lib: charset: Fix utf8_to_utf32_stream() return value doc string
  video: console: Parse UTF-8 character sequences
  lib/charset: Map cp437 low chars (0x01 - 0x1f) from unicode
  efi_selftest: Add symbol character selftest

 drivers/video/console_normal.c |  6 +++--
 drivers/video/console_rotate.c | 16 +-
 drivers/video/console_truetype.c   |  8 +++
 drivers/video/vidconsole-uclass.c  | 18 ++-
 drivers/video/vidconsole_internal.h| 15 +
 include/charset.h  |  4 ++--
 include/cp1250.h   | 12 --
 include/cp437.h| 12 --
 include/video_console.h| 10 +
 lib/charset.c  |  9 +---
 lib/efi_loader/efi_unicode_collation.c |  2 +-
 lib/efi_selftest/efi_selftest_textoutput.c | 35 ++
 12 files changed, 116 insertions(+), 31 deletions(-)
---
base-commit: 866ca972d6c3cabeaf6dbac431e8e08bb30b3c8e
change-id: 20240117-vidconsole-utf8-uefi-fa23b4ac65d6

Best regards,
-- 
Janne Grunau 



[PATCH RFC 6/6] efi_selftest: Add symbol character selftest

2024-01-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

Draw symbols from code page 437 code points 0x01 - 01f used by UEFI
applications to draw user interfaces using
EFI_SIMPLE_TEXT_OUTPUT_PROTOCOL.

Add a simple test to displaying the Konami code using symbols used by
grub2. The output has to be checked manually on the screen for
correctness.

Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 7 +++
 1 file changed, 7 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index cc11a22eee..9e5d944fa0 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -46,6 +46,8 @@ u"left bottom \u2502 right bottom  
\u2502\n\u2514\u2500\u2500\u2500"
 u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534"
 u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
 u"\u2500\u2500\u2500\u2500\u2518\n";
+   const u16 konami[] =
+u"Konami code: \u25b2 \u25b2 \u25bc \u25bc \u25c4 \u25ba \u25c4 \u25ba B A\n";
 
/* SetAttribute */
efi_st_printf("\nColor palette\n");
@@ -144,6 +146,11 @@ u"\u2500\u2500\u2500\u2500\u2518\n";
efi_st_error("OutputString failed for box drawing chars\n");
return EFI_ST_FAILURE;
}
+   ret = con_out->output_string(con_out, konami);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for symbol chars\n");
+   return EFI_ST_FAILURE;
+   }
con_out->output_string(con_out, u"waiting for admiration...\n");
EFI_CALL(systab.boottime->stall(300));
efi_st_printf("\n");

-- 
2.43.0



[PATCH RFC 5/6] efi_selftest: Add box drawing character selftest

2024-01-17 Thread Janne Grunau via B4 Relay
From: Andre Przywara 

UEFI applications rely on Unicode output capability, and might use that
for drawing pseudo-graphical interfaces using Unicode defined box
drawing characters.

Add a simple test to display the most basic box characters, which would
need to be checked manually on the screen for correctness.
To facilitate this, add a three second delay after the output at this
point.

Signed-off-by: Andre Przywara 
Suggested-by: Heinrich Schuchardt 
Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 20 
 1 file changed, 20 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index 2aa81b0a80..cc11a22eee 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -33,6 +33,19 @@ static int execute(void)
const u16 text[] =
 u"\u00d6sterreich Edelwei\u00df Sm\u00f8rrebr\u00f8d Sm\u00f6rg"
 u"\u00e5s Ni\u00f1o Ren\u00e9 >\u1f19\u03bb\u03bb\u03ac\u03c2<\n";
+   const u16 boxes[] =
+u"This should render as four boxes with text\n"
+u"\u250c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u252c\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2510\n\u2502"
+u" left top\u2502 right top \u2502\n\u251c\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u253c\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2524\n\u2502 "
+u"left bottom \u2502 right bottom  \u2502\n\u2514\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2534"
+u"\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500"
+u"\u2500\u2500\u2500\u2500\u2518\n";
 
/* SetAttribute */
efi_st_printf("\nColor palette\n");
@@ -126,6 +139,13 @@ u"\u00e5s Ni\u00f1o Ren\u00e9 
>\u1f19\u03bb\u03bb\u03ac\u03c2<\n";
efi_st_error("OutputString failed for international chars\n");
return EFI_ST_FAILURE;
}
+   ret = con_out->output_string(con_out, boxes);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for box drawing chars\n");
+   return EFI_ST_FAILURE;
+   }
+   con_out->output_string(con_out, u"waiting for admiration...\n");
+   EFI_CALL(systab.boottime->stall(300));
efi_st_printf("\n");
 
return EFI_ST_SUCCESS;

-- 
2.43.0



[PATCH RFC 1/6] lib: charset: Fix utf8_to_utf32_stream() return value doc string

2024-01-17 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The comment appears to be copied from utf8_to_cp437_stream() but was not
updated.

Signed-off-by: Janne Grunau 
---
 include/charset.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/include/charset.h b/include/charset.h
index 44034c71d3..714382e1c1 100644
--- a/include/charset.h
+++ b/include/charset.h
@@ -328,7 +328,7 @@ int utf8_to_cp437_stream(u8 c, char *buffer);
  *
  * @c: next UTF-8 character to convert
  * @buffer:buffer, at least 5 characters
- * Return: next codepage 437 character or 0
+ * Return: next Unicode code point or 0
  */
 int utf8_to_utf32_stream(u8 c, char *buffer);
 

-- 
2.43.0



[PATCH RFC 4/6] efi_selftest: Add international characters test

2024-01-17 Thread Janne Grunau via B4 Relay
From: Andre Przywara 

UEFI relies entirely on unicode output, which actual fonts displayed on
the screen might not be ready for.

Add a test displaying some international characters, to reveal missing
glyphs, especially in our builtin fonts.
This would be needed to be manually checked on the screen for
correctness.

Signed-off-by: Andre Przywara 
Suggested-by: Heinrich Schuchardt 
Signed-off-by: Janne Grunau 
---
 lib/efi_selftest/efi_selftest_textoutput.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/lib/efi_selftest/efi_selftest_textoutput.c 
b/lib/efi_selftest/efi_selftest_textoutput.c
index cc44b38bc2..2aa81b0a80 100644
--- a/lib/efi_selftest/efi_selftest_textoutput.c
+++ b/lib/efi_selftest/efi_selftest_textoutput.c
@@ -30,6 +30,9 @@ static int execute(void)
0xD804, 0xDC05,
0xD804, 0xDC22,
0};
+   const u16 text[] =
+u"\u00d6sterreich Edelwei\u00df Sm\u00f8rrebr\u00f8d Sm\u00f6rg"
+u"\u00e5s Ni\u00f1o Ren\u00e9 >\u1f19\u03bb\u03bb\u03ac\u03c2<\n";
 
/* SetAttribute */
efi_st_printf("\nColor palette\n");
@@ -118,6 +121,11 @@ static int execute(void)
efi_st_printf("Unicode not handled properly\n");
return EFI_ST_FAILURE;
}
+   ret = con_out->output_string(con_out, text);
+   if (ret != EFI_ST_SUCCESS) {
+   efi_st_error("OutputString failed for international chars\n");
+   return EFI_ST_FAILURE;
+   }
efi_st_printf("\n");
 
return EFI_ST_SUCCESS;

-- 
2.43.0



[PATCH v2] arm: apple: t602x: Add missing MMIO regions to memmap

2023-11-30 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The memory maps for Apple's M2 Pro/Max/Ultra left MMIO space out which
was not used by any driver at the time. The display out exposed as
simple-framebuffer use a power-domain controlled by a device in an
unmapped region.
Add a map covering this region as well as another MMIO region in the
range 0x4'' - 0x5''. The added regions cover all MMIO
annotated in Apple's device tree in this range.

Signed-off-by: Janne Grunau 
---
Changes in v2:
- use SZ_1G as block size
- Link to v1: 
https://lore.kernel.org/r/20231130-apple_t602x_extend_memmap-v1-1-cd96b251d...@jannau.net
---
 arch/arm/mach-apple/board.c | 48 +
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
index 47393babbc..7a6151a972 100644
--- a/arch/arm/mach-apple/board.c
+++ b/arch/arm/mach-apple/board.c
@@ -370,6 +370,22 @@ static struct mm_region t6020_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 PTE_BLOCK_NON_SHARE |
 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x4,
+   .phys = 0x4,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x48000,
+   .phys = 0x48000,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* I/O */
.virt = 0x58000,
@@ -471,6 +487,22 @@ static struct mm_region t6022_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 PTE_BLOCK_NON_SHARE |
 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x4,
+   .phys = 0x4,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x48000,
+   .phys = 0x48000,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* I/O */
.virt = 0x58000,
@@ -551,6 +583,22 @@ static struct mm_region t6022_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 PTE_BLOCK_NON_SHARE |
 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x24,
+   .phys = 0x24,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x248000,
+   .phys = 0x248000,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* I/O */
.virt = 0x258000,

---
base-commit: 43f2873fa98b1da6eb56d756315c7bd7db63db27
change-id: 20231130-apple_t602x_extend_memmap-c82c522ca8c0

Best regards,
-- 
Janne Grunau 



[PATCH] arm: apple: t602x: Add missing MMIO regions to memmap

2023-11-30 Thread Janne Grunau via B4 Relay
From: Janne Grunau 

The memory maps for Apple's M2 Pro/Max/Ultra left MMIO space out which
was not used by any driver at the time. The display out exposed as
simple-framebuffer use a power-domain controlled by a device in an
unmapped region.
Add a map covering this region as well as another MMIO region in the
range 0x4'' - 0x5''. The added regions cover all MMIO
annotated in Apple's device tree in this range.

Signed-off-by: Janne Grunau 
---
 arch/arm/mach-apple/board.c | 48 +
 1 file changed, 48 insertions(+)

diff --git a/arch/arm/mach-apple/board.c b/arch/arm/mach-apple/board.c
index 47393babbc..e05ec431bc 100644
--- a/arch/arm/mach-apple/board.c
+++ b/arch/arm/mach-apple/board.c
@@ -370,6 +370,22 @@ static struct mm_region t6020_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 PTE_BLOCK_NON_SHARE |
 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x4,
+   .phys = 0x4,
+   .size = SZ_512M,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x48000,
+   .phys = 0x48000,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* I/O */
.virt = 0x58000,
@@ -471,6 +487,22 @@ static struct mm_region t6022_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 PTE_BLOCK_NON_SHARE |
 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x4,
+   .phys = 0x4,
+   .size = SZ_512M,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x48000,
+   .phys = 0x48000,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* I/O */
.virt = 0x58000,
@@ -551,6 +583,22 @@ static struct mm_region t6022_mem_map[] = {
.attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
 PTE_BLOCK_NON_SHARE |
 PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x24,
+   .phys = 0x24,
+   .size = SZ_512M,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
+   }, {
+   /* I/O */
+   .virt = 0x248000,
+   .phys = 0x248000,
+   .size = SZ_1G,
+   .attrs = PTE_BLOCK_MEMTYPE(MT_DEVICE_NGNRNE) |
+   PTE_BLOCK_NON_SHARE |
+   PTE_BLOCK_PXN | PTE_BLOCK_UXN
}, {
/* I/O */
.virt = 0x258000,

---
base-commit: 43f2873fa98b1da6eb56d756315c7bd7db63db27
change-id: 20231130-apple_t602x_extend_memmap-c82c522ca8c0

Best regards,
-- 
Janne Grunau