summaryrefslogtreecommitdiff
path: root/config/grub
diff options
context:
space:
mode:
authorLeah Rowe <leah@libreboot.org>2026-09-18 21:04:00 +0100
committerLeah Rowe <leah@libreboot.org>2026-09-20 13:53:33 +0100
commit076c87ccf68f7fe5a3998e8cd8edd2033a2f2ef0 (patch)
tree9aaf04cfa16565227f733b917af3e3c485505544 /config/grub
parent387e6dd771588b7f8426c8d0934e610626730d51 (diff)
xbmk: make all projects multi-tree
we currently distinguish, by virtue of logic, multi- and single-tree projects. this introduces a lot of complexity, so the following patch has removed this distinction. all single-tree projects are now multi tree, but with only one tree. other design changes: config/git removed. rev/tree now handled with mkhelper and target configs. this allows per-tree remote handling, so we could (for example) add the mrchromebox coreboot fork easily, for specific chromebook models. config/project is now config/module/project. this cleans up the main config/ directory. cfgname variable: .config no longer hardcoded when doing configs in projects. it is configurable with this variable. if unset, the previous .cfg is used noconfig variable: set this in target/mkhelper configs, and config/module/project/tree/config/ is unused; instead, make is called without config copying. a "noconfig" placeholder is used. this enables cleaner usage of previously single-tree projects in the new multi-tree-only structure. cfgvars: variables reinitialised in project config are cleaned more reliably. in particular, several variables e.g. autogenargs were not being reset between projects, although the autogenargs variable is currently unused. general cleanup has been conducted across the build system, as part of this redesign. several parts of the build system more over-engineered as a result of the previous design, and the new design enabled a severe reduction in sloccount (75 lines reduced in lbmk). yes, this change *adds features* but there are fewer lines of code than before. this is the best kind of change. way better than the 3-line-diff. yes. rev= and tree= are set more centrally in configs. the mkhelper config can be used to set url/url_bkup, but individual trees can override them. configs have been cleaned up, with several variables now much more heavily centralised. config/git/ was used before to first download the bare repository, and then the real clone was made with patches. this allows git repositories to be cached for future re-builds. with config/git/ gone, the download logic for projects is more centrally implemented. a separate call to ./mk -f is no longer performed, and in fact ./mk -f never needs to be used anymore as a result. ./mk -f now is basically the same thing as -b, just without any action performed. this change will allow rapid expansion of the libreboot project. i want to add hundreds of chromebooks to the project, using mrchromebox, but the previous design did not permit this. this change means that i can easily have unlimited upstreams per project. coreboot will, in some follow-up changes, have the following upstreams: coreboot/default: coreboot.org coreboot/fam15h: 15h.org fork coreboot/chromebook: mrchromebox fork this can now be done freely without massive changes to the build system. under the previous design, i worked on a now-abandoned patch to do N remotes per project, reading repo links from a file. this meant that i'd have coreboot.org first (main and backup), then mrchromebox. this meant that lbmk would failover through to mrchromebox, wasting time for the user. this new design is much cleaner, and will enable the project to be maintained much more easily. Signed-off-by: Leah Rowe <leah@libreboot.org>
Diffstat (limited to 'config/grub')
-rw-r--r--config/grub/default/config/payload305
-rw-r--r--config/grub/default/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch90
-rw-r--r--config/grub/default/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch25
-rw-r--r--config/grub/default/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch107
-rw-r--r--config/grub/default/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch38
-rw-r--r--config/grub/default/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch102
-rw-r--r--config/grub/default/patches/0006-don-t-print-error-if-module-not-found.patch34
-rw-r--r--config/grub/default/patches/0007-don-t-print-empty-error-messages.patch31
-rw-r--r--config/grub/default/patches/0008-kern-coreboot-mmap-Map-to-reserved.patch37
-rw-r--r--config/grub/default/patches/0009-Revert-configure-Check-linker-for-image-base-support.patch70
-rw-r--r--config/grub/default/patches/0010-Revert-configure-Print-a-more-helpful-error-if-autoc.patch30
-rw-r--r--config/grub/default/patches/0011-bootstrap-Don-t-download-po-files.patch91
-rw-r--r--config/grub/default/target.cfg4
-rw-r--r--config/grub/nvme/config/payload320
-rw-r--r--config/grub/nvme/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch90
-rw-r--r--config/grub/nvme/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch25
-rw-r--r--config/grub/nvme/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch107
-rw-r--r--config/grub/nvme/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch38
-rw-r--r--config/grub/nvme/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch102
-rw-r--r--config/grub/nvme/patches/0006-don-t-print-error-if-module-not-found.patch34
-rw-r--r--config/grub/nvme/patches/0007-don-t-print-empty-error-messages.patch31
-rw-r--r--config/grub/nvme/patches/0008-Add-native-NVMe-driver-based-on-SeaBIOS.patch1074
-rw-r--r--config/grub/nvme/patches/0009-kern-coreboot-mmap-Map-to-reserved.patch37
-rw-r--r--config/grub/nvme/patches/0010-Revert-configure-Check-linker-for-image-base-support.patch70
-rw-r--r--config/grub/nvme/patches/0011-Revert-configure-Print-a-more-helpful-error-if-autoc.patch30
-rw-r--r--config/grub/nvme/patches/0012-bootstrap-Don-t-download-po-files.patch91
-rw-r--r--config/grub/nvme/target.cfg4
-rw-r--r--config/grub/xhci_nvme/config/payload321
-rw-r--r--config/grub/xhci_nvme/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch90
-rw-r--r--config/grub/xhci_nvme/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch25
-rw-r--r--config/grub/xhci_nvme/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch107
-rw-r--r--config/grub/xhci_nvme/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch38
-rw-r--r--config/grub/xhci_nvme/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch102
-rw-r--r--config/grub/xhci_nvme/patches/0006-don-t-print-error-if-module-not-found.patch34
-rw-r--r--config/grub/xhci_nvme/patches/0007-don-t-print-empty-error-messages.patch31
-rw-r--r--config/grub/xhci_nvme/patches/0008-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch246
-rw-r--r--config/grub/xhci_nvme/patches/0009-usb-Add-enum-for-xHCI.patch29
-rw-r--r--config/grub/xhci_nvme/patches/0010-usbtrans-Set-default-maximum-packet-size.patch33
-rw-r--r--config/grub/xhci_nvme/patches/0011-grub-core-bus-usb-Add-function-pointer-for-attach-de.patch121
-rw-r--r--config/grub/xhci_nvme/patches/0012-grub-core-bus-usb-usbhub-Add-new-private-fields-for-.patch77
-rw-r--r--config/grub/xhci_nvme/patches/0013-grub-core-bus-usb-Add-xhci-support.patch2807
-rw-r--r--config/grub/xhci_nvme/patches/0014-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch127
-rw-r--r--config/grub/xhci_nvme/patches/0015-xHCI-also-accept-SBRN-0x31-and-0x32.patch26
-rw-r--r--config/grub/xhci_nvme/patches/0016-xhci-fix-port-indexing.patch43
-rw-r--r--config/grub/xhci_nvme/patches/0017-xhci-configure-TT-for-non-root-hubs.patch98
-rw-r--r--config/grub/xhci_nvme/patches/0018-Fix-compilation-on-x86_64.patch90
-rw-r--r--config/grub/xhci_nvme/patches/0019-Add-native-NVMe-driver-based-on-SeaBIOS.patch1074
-rw-r--r--config/grub/xhci_nvme/patches/0020-kern-coreboot-mmap-Map-to-reserved.patch37
-rw-r--r--config/grub/xhci_nvme/patches/0021-Revert-configure-Check-linker-for-image-base-support.patch70
-rw-r--r--config/grub/xhci_nvme/patches/0022-Revert-configure-Print-a-more-helpful-error-if-autoc.patch30
-rw-r--r--config/grub/xhci_nvme/patches/0023-bootstrap-Don-t-download-po-files.patch91
-rw-r--r--config/grub/xhci_nvme/target.cfg4
52 files changed, 0 insertions, 8768 deletions
diff --git a/config/grub/default/config/payload b/config/grub/default/config/payload
deleted file mode 100644
index 3d84413e..00000000
--- a/config/grub/default/config/payload
+++ /dev/null
@@ -1,305 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2014-2016,2020-2021,2023-2025 Leah Rowe <leah@libreboot.org>
-# Copyright (C) 2015 Klemens Nanni <contact@autoboot.org>
-
-set prefix=(memdisk)/boot/grub
-
-insmod at_keyboard
-insmod usb_keyboard
-insmod nativedisk
-insmod ehci
-insmod ohci
-insmod uhci
-insmod usb
-insmod usbms
-insmod regexp
-
-terminal_input --append at_keyboard
-terminal_input --append usb_keyboard
-terminal_output --append cbmemc
-
-# User interface overrides wherever "keystatus" is supported
-# Keep SHIFT key pressed before powering on to disable graphics
-if keystatus --shift; then
- terminal_output --append vga_text
-else
- gfxpayload=keep
- terminal_output --append gfxterm
-
- for dt in cbfsdisk memdisk; do
- for it in png jpg; do
- if [ -f (${dt})/background.${it} ]; then
- insmod ${it}
- background_image (${dt})/background.${it}
- fi
- done
- done
-fi
-
-# Keep CTRL pressed to enable default serial terminal (COM1 or the like)
-if keystatus --ctrl; then
- serial
- terminal_input --append serial
- terminal_output --append serial
-fi
-
-# Keep ALT pressed to enable spkmodem
-if keystatus --alt; then
- terminal_output --append spkmodem
-fi
-
-
-set default="0"
-if [ -f (cbfsdisk)/timeout.cfg ]; then
- source (cbfsdisk)/timeout.cfg
-else
- set timeout=8
-fi
-set grub_scan_disk="ahci ata"
-if [ -f (cbfsdisk)/scan.cfg ]; then
- source (cbfsdisk)/scan.cfg
-fi
-
-if [ -f (cbfsdisk)/keymap.gkb ]; then
- keymap (cbfsdisk)/keymap.gkb
-fi
-
-function really_try_user_config {
- set root="${1}"
-
- if [ -f /"${2}"/grub.cfg ]; then
- unset superusers
- configfile /"${2}"/grub.cfg
- fi
-}
-
-function try_user_config {
- # The @/... entries are for cases where the BTRFS filesystem is being used
- for dir in grub boot/grub @/grub @/boot/grub grub2 boot/grub2 @/grub2 @/boot/grub2 boot @/boot; do
- really_try_user_config "${1}" "${dir}"
- done
- for dir in ubuntu debian redhat; do
- really_try_user_config "${1}" "EFI/${dir}"
- done
-}
-function search_grub {
- echo -n "Attempting to load grub.cfg from '${1}' devices"
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${1}" != "nvme" ]; then
- try_user_config "(${1}${i},${part})"
- fi
- done
- if [ "${1}" != "nvme" ]; then
- # raw devices e.g. (ahci0) instead of (ahci0,1)
- try_user_config "(${1}${i})"
- fi
- done
- echo # Insert newline
-}
-
-function try_isolinux_config {
- set root="${1}"
- for dir in '' /boot /EFI /@ /@/boot; do
- if [ -f "${dir}"/isolinux/isolinux.cfg ]; then
- syslinux_configfile -i "${dir}"/isolinux/isolinux.cfg
- elif [ -f "${dir}"/syslinux/syslinux.cfg ]; then
- syslinux_configfile -s "${dir}"/syslinux/syslinux.cfg
- elif [ -f "${dir}"/syslinux/extlinux.conf ]; then
- syslinux_configfile -s "${dir}"/syslinux/extlinux.conf
- elif [ -f "${dir}"/extlinux/extlinux.conf ]; then
- syslinux_configfile -s "${dir}"/extlinux/extlinux.conf
- fi
- done
-}
-function search_isolinux {
- echo "\nAttempting to parse iso/sys/extlinux config from '${1}' devices"
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${1}" != "nvme" ]; then
- try_isolinux_config "(${1}${i},${part})"
- fi
- done
- if [ "${1}" != "nvme" ]; then
- # raw devices e.g. (usb0) instead of (usb0,1)
- try_isolinux_config "(${1}${i})"
- fi
- done
- echo # Insert newline
-}
-function try_bootcfg {
- try_user_config "${1}"
- try_isolinux_config "${1}"
-}
-function search_bootcfg {
- search_grub "${1}"
- search_isolinux "${1}"
-}
-menuentry 'Load Operating System (incl. fully encrypted disks) [o]' --hotkey='o' {
-
- for grub_disk in ${grub_scan_disk}; do
- search_bootcfg ${grub_disk}
- done
-
- # grub device enumeration is very slow, so checks are hardcoded
-
- raidvol="md/0 md/1 md/2 md/3 md/4 md/5 md/6 md/7 md/8 md/9"
-
- # in practise, doing multiple redundant checks is perfectly fast
- # TODO: optimize grub itself, and use */? here for everything
-
- for vol in ${raidvol} ; do
- try_bootcfg "${vol}"
- done
-
- unset bootdev
- for grub_disk in ${grub_scan_disk}; do
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${grub_disk}" = "ahci" ]; then
- bootdev="${bootdev} (ahci${i},${part})"
- elif [ "${grub_disk}" = "ata" ]; then
- bootdev="${bootdev} (ata${i},${part})"
- elif [ "${grub_disk}" = "nvme" ]; then
- # TODO: do we care about other namesapces
- bootdev="${bootdev} (nvme${i}n1,${part})"
- fi
- done
- done
- done
-
- set pager=0
- echo -n "Attempting to unlock encrypted volumes"
- for dev in ${bootdev} ${raidvol}; do
- if cryptomount "${dev}" ; then break ; fi
- done
- set pager=1
- echo
-
- search_bootcfg crypto
-
- lvmvol=""
-
- # after cryptomount, lvm volumes might be available
- # using * is slow on some machines, but we use it here,
- # just once. in so doing, we find every lvm volume
- for vol in (*); do
- if regexp ^\\(lvm/ $vol; then
- lvmvol="${lvmvol} ${vol}"
- try_bootcfg "${vol}"
- fi
- done
-
- # user might have put luks inside lvm
- set pager=0
- echo "Attempting to unlock encrypted LVMs"
- for vol in ${lvmvol}; do
- cryptomount "$vol"
- done
- set pager=1
- echo
-
- search_bootcfg crypto
-
- true # Prevent pager requiring to accept each line instead of whole screen
-}
-
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on USB [s]' --hotkey='s' {
- search_bootcfg usb
-}
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on AHCI [a]' --hotkey='a' {
- search_bootcfg ahci
-}
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on ATA/IDE [d]' --hotkey='d' {
- search_bootcfg ata
-}
-if [ -f (cbfsdisk)/grub.cfg ]; then
-menuentry 'Load configuration (grub.cfg) in CBFS [t]' --hotkey='t' {
- set root='(cbfsdisk)'
- if [ -f /grub.cfg ]; then
- configfile /grub.cfg
- fi
-}
-fi
-if [ -f (cbfsdisk)/grubtest.cfg ]; then
-menuentry 'Load test configuration (grubtest.cfg) inside of CBFS [t]' --hotkey='t' {
- set root='(cbfsdisk)'
- if [ -f /grubtest.cfg ]; then
- configfile /grubtest.cfg
- fi
-}
-fi
-if [ -f (cbfsdisk)/u-boot ]; then
-menuentry 'U-Boot i386 payload (experimental) [u]' --hotkey='u' {
- set root='cbfsdisk'
- chainloader /u-boot
-}
-fi
-if [ -f (cbfsdisk)/seabios.elf ]; then
-if [ -f (cbfsdisk)/img/u-boot ]; then
-menuentry 'Load SeaBIOS (U-Boot UEFI available in the ESC menu) [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /seabios.elf
-}
-else
-menuentry 'Load SeaBIOS [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /seabios.elf
-}
-fi
-fi
-if [ -f (cbfsdisk)/img/grub2 ]; then
-if [ -f (cbfsdisk)/img/u-boot ]; then
-menuentry 'Return to SeaBIOS (U-Boot UEFI available in the ESC menu) [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /fallback/payload
-}
-else
-menuentry 'Return to SeaBIOS [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /fallback/payload
-}
-fi
-fi
-menuentry 'Poweroff [p]' --hotkey='p' {
- halt
-}
-menuentry 'Reboot [r]' --hotkey='r' {
- reboot
-}
-if [ -f (cbfsdisk)/img/memtest ]; then
-menuentry 'Load MemTest86+ [m]' --hotkey='m' {
- set root='cbfsdisk'
- chainloader /img/memtest
-}
-fi
-
-submenu 'Other [z]' --hotkey='z' {
- menuentry 'Enable default serial terminal [s]' --hotkey='s' {
- serial
- terminal_input --append serial
- terminal_output --append serial
- }
-
- menuentry 'Disable default serial terminal' {
- terminal_input --remove serial
- terminal_output --remove serial
- }
-
- menuentry 'Enable gfxterm' {
- terminal_output --append gfxterm
- terminal_output --remove vga_text
- }
- menuentry 'Disable gfxterm [g]' --hotkey='g' {
- terminal_output --remove gfxterm
- terminal_output --append vga_text
- }
-
- menuentry 'Enable spkmodem [a]' --hotkey='a' {
- terminal_output --append spkmodem
- }
-
- menuentry 'Disable spkmodem [z]' --hotkey='z' {
- terminal_output --remove spkmodem
- }
-}
diff --git a/config/grub/default/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch b/config/grub/default/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch
deleted file mode 100644
index 7112b0aa..00000000
--- a/config/grub/default/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 5a2c887181e7cdbd6b38d544e460d02623c902e6 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 31 Oct 2021 03:47:05 +0000
-Subject: [PATCH 01/10] mitigate grub's missing characters for borders/arrow
- characters
-
-This cleans up the display on the main screen in GRUB.
-
-Just don't draw a border, at all.
----
- grub-core/normal/menu_text.c | 49 ++----------------------------------
- 1 file changed, 2 insertions(+), 47 deletions(-)
-
-diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
-index 9c383e64a..8ec1dd1e8 100644
---- a/grub-core/normal/menu_text.c
-+++ b/grub-core/normal/menu_text.c
-@@ -108,47 +108,6 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right,
- grub_print_message_indented_real (msg, margin_left, margin_right, term, 0);
- }
-
--static void
--draw_border (struct grub_term_output *term, const struct grub_term_screen_geometry *geo)
--{
-- int i;
--
-- grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
--
-- grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y - 1 });
-- grub_putcode (GRUB_UNICODE_CORNER_UL, term);
-- for (i = 0; i < geo->entry_width + 1; i++)
-- grub_putcode (GRUB_UNICODE_HLINE, term);
-- grub_putcode (GRUB_UNICODE_CORNER_UR, term);
--
-- for (i = 0; i < geo->num_entries; i++)
-- {
-- grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y + i });
-- grub_putcode (GRUB_UNICODE_VLINE, term);
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x + geo->entry_width + 1,
-- geo->first_entry_y + i });
-- grub_putcode (GRUB_UNICODE_VLINE, term);
-- }
--
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y - 1 + geo->num_entries + 1 });
-- grub_putcode (GRUB_UNICODE_CORNER_LL, term);
-- for (i = 0; i < geo->entry_width + 1; i++)
-- grub_putcode (GRUB_UNICODE_HLINE, term);
-- grub_putcode (GRUB_UNICODE_CORNER_LR, term);
--
-- grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
--
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- (geo->first_entry_y - 1 + geo->num_entries
-- + GRUB_TERM_MARGIN + 1) });
--}
--
- static int
- print_message (int nested, int edit, struct grub_term_output *term, int dry_run)
- {
-@@ -167,10 +126,8 @@ command-line or ESC to discard edits and return to the GRUB menu."),
- {
- char *msg_translated;
-
-- msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which "
-- "entry is highlighted."),
-- GRUB_UNICODE_UPARROW,
-- GRUB_UNICODE_DOWNARROW);
-+ msg_translated = grub_xasprintf (_("Use the arrow keys to select which "
-+ "entry is highlighted."));
- if (!msg_translated)
- return 0;
- ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN,
-@@ -413,8 +370,6 @@ grub_menu_init_page (int nested, int edit,
-
- grub_term_normal_color = grub_color_menu_normal;
- grub_term_highlight_color = grub_color_menu_highlight;
-- if (geo->border)
-- draw_border (term, geo);
- grub_term_normal_color = old_color_normal;
- grub_term_highlight_color = old_color_highlight;
- geo->timeout_y = geo->first_entry_y + geo->num_entries
---
-2.47.3
-
diff --git a/config/grub/default/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch b/config/grub/default/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch
deleted file mode 100644
index af139ffc..00000000
--- a/config/grub/default/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 25d7d35e0af74361a5510c3e6313b8ce5e00cd6a Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sat, 19 Nov 2022 16:30:24 +0000
-Subject: [PATCH 02/10] say the name libreboot, in the grub menu
-
----
- grub-core/normal/main.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
-index de9a3f961..bed502cde 100644
---- a/grub-core/normal/main.c
-+++ b/grub-core/normal/main.c
-@@ -215,7 +215,7 @@ grub_normal_init_page (struct grub_term_output *term,
-
- grub_term_cls (term);
-
-- msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION);
-+ msg_formatted = grub_xasprintf (_("Libreboot 26.01 Magnanimous Max (GRUB menu): https://libreboot.org/"));
- if (!msg_formatted)
- return;
-
---
-2.47.3
-
diff --git a/config/grub/default/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch b/config/grub/default/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch
deleted file mode 100644
index bb07abd6..00000000
--- a/config/grub/default/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From acff2df937bb4172f9bdb46d12e82edbbcad7996 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Mon, 30 Oct 2023 22:19:21 +0000
-Subject: [PATCH 03/10] at_keyboard coreboot: force scancodes2+translate
-
-Scan code set 2 with translation should be assumed in
-every case, as the default starting position.
-
-However, GRUB is trying to detect and use other modes
-such as set 2 without translation, or set 1 without
-translation from set 2; it also detects no-mode and
-assumes mode 1, on really old keyboards.
-
-The current behaviour has been retained, for everything
-except GRUB_MACHINE_COREBOOT; for the latter, scan code
-set 2 with translation is hardcoded, and forced in code.
-
-This is required to make keyboard initialisation work on
-the MEC5035 EC used by the Dell Latitude E6400, when
-running GRUB as a coreboot payload on that laptop. The
-EC reports scancode set 2 with translation when probed,
-but actually only outputs scancode set 1.
-
-Since GRUB is attempting to use it without translation,
-and since the machine reports set 2 with translation,
-but only ever outputs set 1 scancodes, this results in
-wrong keypresses for every key.
-
-This fix fixed that, by forcing set 2 with translation,
-treating it as set 1, but only on coreboot. This is the
-same behaviour used in GNU+Linux systems and SeaBIOS.
-With this change, GRUB keyboard initialisation now works
-just fine on those machines.
-
-This has *also* been tested on other coreboot machines
-running GRUB; several HP EliteBooks, ThinkPads and
-Dell Precision T1650. All seems to work just fine.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/term/at_keyboard.c | 20 ++++++++++++++++++--
- 1 file changed, 18 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c
-index f8a129eb7..8207225c2 100644
---- a/grub-core/term/at_keyboard.c
-+++ b/grub-core/term/at_keyboard.c
-@@ -138,6 +138,7 @@ write_mode (int mode)
- return (i != GRUB_AT_TRIES);
- }
-
-+#if !defined (GRUB_MACHINE_COREBOOT)
- static int
- query_mode (void)
- {
-@@ -161,10 +162,12 @@ query_mode (void)
- return 3;
- return 0;
- }
-+#endif
-
- static void
- set_scancodes (void)
- {
-+#if !defined (GRUB_MACHINE_COREBOOT)
- /* You must have visited computer museum. Keyboard without scancode set
- knowledge. Assume XT. */
- if (!grub_keyboard_orig_set)
-@@ -173,20 +176,33 @@ set_scancodes (void)
- ps2_state.current_set = 1;
- return;
- }
-+#endif
-
- #if !USE_SCANCODE_SET
- ps2_state.current_set = 1;
- return;
--#else
-+#endif
-
-+#if defined (GRUB_MACHINE_COREBOOT)
-+ /* enable translation */
-+ grub_keyboard_controller_write (grub_keyboard_controller_orig
-+ & ~KEYBOARD_AT_DISABLE);
-+#else
-+ /* if not coreboot, disable translation and try mode 2 first, before 1 */
- grub_keyboard_controller_write (grub_keyboard_controller_orig
- & ~KEYBOARD_AT_TRANSLATE
- & ~KEYBOARD_AT_DISABLE);
-+#endif
-
- keyboard_controller_wait_until_ready ();
- grub_outb (KEYBOARD_COMMAND_ENABLE, KEYBOARD_REG_DATA);
--
- write_mode (2);
-+
-+#if defined (GRUB_MACHINE_COREBOOT)
-+ /* mode 2 with translation, so make grub treat as set 1 */
-+ ps2_state.current_set = 1;
-+#else
-+ /* if not coreboot, translation isn't set; test 2 and fall back to 1 */
- ps2_state.current_set = query_mode ();
- grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set);
- if (ps2_state.current_set == 2)
---
-2.47.3
-
diff --git a/config/grub/default/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch b/config/grub/default/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch
deleted file mode 100644
index fbcbb2c3..00000000
--- a/config/grub/default/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 247133e1f9820bcb81f7d27fc1395d64dc7b0a89 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Tue, 31 Oct 2023 10:33:28 +0000
-Subject: [PATCH 04/10] keylayouts: don't print "Unknown key" message
-
-on keyboards with stuck keys, this results in GRUB just
-spewing it repeatedly, preventing use of GRUB.
-
-in such cases, it's still possible to use the keyboard,
-and we should let the user at least boot.
-
-it often appears when people plug in faulty usb keyboards,
-but can appear for laptop keyboards too; one of my e6400
-has stuck keys.
-
-with this patch, grub should be a bit more reliable in
-terms of user experience, when the keyboard is faulty.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/commands/keylayouts.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c
-index aa3ba34f2..445fa0601 100644
---- a/grub-core/commands/keylayouts.c
-+++ b/grub-core/commands/keylayouts.c
-@@ -174,7 +174,6 @@ grub_term_map_key (grub_keyboard_key_t code, int status)
- key = map_key_core (code, status, &alt_gr_consumed);
-
- if (key == 0 || key == GRUB_TERM_SHIFT) {
-- grub_printf ("Unknown key 0x%x detected\n", code);
- return GRUB_TERM_NO_KEY;
- }
-
---
-2.47.3
-
diff --git a/config/grub/default/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch b/config/grub/default/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch
deleted file mode 100644
index 93b0c505..00000000
--- a/config/grub/default/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From c5ad46b7ba93136764fd1eae1bd0c0c32ce1c5b2 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 16:14:58 +0000
-Subject: [PATCH 05/10] don't print missing prefix errors on the screen
-
-we do actually set the prefix. this patch modifies
-grub to still set grub_errno and return accordingly,
-so the behaviour is otherwise identical, but it will
-no longer print a warning message on the screen.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/commands/keylayouts.c | 2 +-
- grub-core/commands/loadenv.c | 2 +-
- grub-core/commands/nativedisk.c | 2 +-
- grub-core/efiemu/main.c | 3 +--
- grub-core/font/font.c | 2 +-
- grub-core/kern/dl.c | 2 +-
- 6 files changed, 6 insertions(+), 7 deletions(-)
-
-diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c
-index 445fa0601..00bcf7025 100644
---- a/grub-core/commands/keylayouts.c
-+++ b/grub-core/commands/keylayouts.c
-@@ -211,7 +211,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
- {
- const char *prefix = grub_env_get ("prefix");
- if (!prefix)
-- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_BAD_ARGUMENT);
- filename = grub_xasprintf ("%s/layouts/%s.gkb", prefix, argv[0]);
- if (!filename)
- return grub_errno;
-diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c
-index 166445849..699b39bfa 100644
---- a/grub-core/commands/loadenv.c
-+++ b/grub-core/commands/loadenv.c
-@@ -58,7 +58,7 @@ open_envblk_file (char *filename,
- prefix = grub_env_get ("prefix");
- if (! prefix)
- {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- return 0;
- }
-
-diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
-index 580c8d3b0..6806bff9c 100644
---- a/grub-core/commands/nativedisk.c
-+++ b/grub-core/commands/nativedisk.c
-@@ -186,7 +186,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
- prefix = grub_env_get ("prefix");
-
- if (! prefix)
-- return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_FILE_NOT_FOUND);
-
- if (prefix)
- path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL;
-diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c
-index e7037f4ed..e5d4dbff1 100644
---- a/grub-core/efiemu/main.c
-+++ b/grub-core/efiemu/main.c
-@@ -231,8 +231,7 @@ grub_efiemu_autocore (void)
- prefix = grub_env_get ("prefix");
-
- if (! prefix)
-- return grub_error (GRUB_ERR_FILE_NOT_FOUND,
-- N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_FILE_NOT_FOUND);
-
- suffix = grub_efiemu_get_default_core_name ();
-
-diff --git a/grub-core/font/font.c b/grub-core/font/font.c
-index 18de52562..2a0fea6c8 100644
---- a/grub-core/font/font.c
-+++ b/grub-core/font/font.c
-@@ -461,7 +461,7 @@ grub_font_load (const char *filename)
-
- if (!prefix)
- {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- goto fail;
- }
- file = try_open_from_prefix (prefix, filename);
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index de8c3aa8d..eac3ea48d 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -880,7 +880,7 @@ grub_dl_load (const char *name)
- return 0;
-
- if (! grub_dl_dir) {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- return 0;
- }
-
---
-2.47.3
-
diff --git a/config/grub/default/patches/0006-don-t-print-error-if-module-not-found.patch b/config/grub/default/patches/0006-don-t-print-error-if-module-not-found.patch
deleted file mode 100644
index 2dbf6d87..00000000
--- a/config/grub/default/patches/0006-don-t-print-error-if-module-not-found.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 6522ceca8949105b2e1575ada2f05b3061bfe8f3 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 16:36:22 +0000
-Subject: [PATCH 06/10] don't print error if module not found
-
-still set grub_errno accordingly, and otherwise
-behave the same. in libreboot, we remove a lot of
-modules but then rely on loading a grub.cfg
-provided by a distro; in almost all cases that works,
-but also in almost all cases, that will try to load
-a module we don't actually need, but then it prints
-a message. this can annoy some users, so silence it.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/kern/dl.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index eac3ea48d..6d67ba54f 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -510,7 +510,7 @@ grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e)
-
- s = grub_dl_find_section (e, ".modname");
- if (!s)
-- return grub_error (GRUB_ERR_BAD_MODULE, "no module name found");
-+ return (grub_errno = GRUB_ERR_BAD_MODULE);
-
- mod->name = grub_strdup ((char *) e + s->sh_offset);
- if (! mod->name)
---
-2.47.3
-
diff --git a/config/grub/default/patches/0007-don-t-print-empty-error-messages.patch b/config/grub/default/patches/0007-don-t-print-empty-error-messages.patch
deleted file mode 100644
index 67ae7d66..00000000
--- a/config/grub/default/patches/0007-don-t-print-empty-error-messages.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 557d3e583e6aaa887d7b3876c6980ba0e0e671a3 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 17:25:20 +0000
-Subject: [PATCH 07/10] don't print empty error messages
-
-this is part two of the quest to kill the prefix
-error message. after i disabled prefix-related
-messages, it still printed "error: ." on screen.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/kern/err.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
-index ba04b57fb..dab62646d 100644
---- a/grub-core/kern/err.c
-+++ b/grub-core/kern/err.c
-@@ -116,7 +116,8 @@ grub_print_error (void)
- {
- if (grub_errno != GRUB_ERR_NONE)
- {
-- grub_err_printf (_("error: %s.\n"), grub_errmsg);
-+ if (grub_strlen(grub_errmsg) > 0)
-+ grub_err_printf (_("error: %s.\n"), grub_errmsg);
- grub_err_printed_errors++;
- }
- }
---
-2.47.3
-
diff --git a/config/grub/default/patches/0008-kern-coreboot-mmap-Map-to-reserved.patch b/config/grub/default/patches/0008-kern-coreboot-mmap-Map-to-reserved.patch
deleted file mode 100644
index 7ce1bf09..00000000
--- a/config/grub/default/patches/0008-kern-coreboot-mmap-Map-to-reserved.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 101ea5afcfbe459e624df27c422f59b4ded07000 Mon Sep 17 00:00:00 2001
-From: Paul Menzel <pmenzel@molgen.mpg.de>
-Date: Mon, 17 May 2021 10:24:36 +0200
-Subject: [PATCH 08/10] kern/coreboot/mmap: Map to reserved
-
-https://git.savannah.gnu.org/cgit/grub.git/commit/?id=6de9ee86bf9ae50967413e6a73b5dfd13e5ffb50
-
-Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
----
- grub-core/kern/coreboot/mmap.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/kern/coreboot/mmap.c b/grub-core/kern/coreboot/mmap.c
-index caf8f7cef..2fc316e8d 100644
---- a/grub-core/kern/coreboot/mmap.c
-+++ b/grub-core/kern/coreboot/mmap.c
-@@ -59,7 +59,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
- /* Multiboot mmaps match with the coreboot mmap
- definition. Therefore, we can just pass type
- through. */
-- mem_region->type,
-+ (mem_region->type >= 13) ? 2 : mem_region->type,
- ctx->hook_data))
- return 1;
- if (start < 0xa0000)
-@@ -81,7 +81,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
- /* Multiboot mmaps match with the coreboot mmap
- definition. Therefore, we can just pass type
- through. */
-- mem_region->type,
-+ (mem_region->type >= 13) ? 2 : mem_region->type,
- ctx->hook_data))
- return 1;
- }
---
-2.47.3
-
diff --git a/config/grub/default/patches/0009-Revert-configure-Check-linker-for-image-base-support.patch b/config/grub/default/patches/0009-Revert-configure-Check-linker-for-image-base-support.patch
deleted file mode 100644
index 9bb2563d..00000000
--- a/config/grub/default/patches/0009-Revert-configure-Check-linker-for-image-base-support.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From a56ceedd60bd6515ad3c84ec6aa4c3d66a8bac87 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Wed, 24 Dec 2025 01:42:17 +0100
-Subject: [PATCH 09/10] Revert "configure: Check linker for --image-base
- support"
-
-This reverts commit 1a5417f39a0ccefcdd5440f2a67f84d2d2e26960.
----
- acinclude.m4 | 5 -----
- configure.ac | 14 ++------------
- 2 files changed, 2 insertions(+), 17 deletions(-)
-
-diff --git a/acinclude.m4 b/acinclude.m4
-index 70c1912f8..fa7840f09 100644
---- a/acinclude.m4
-+++ b/acinclude.m4
-@@ -79,11 +79,6 @@ AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
- [AC_MSG_CHECKING([whether ${TARGET_OBJCOPY} works for absolute addresses])
- AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
- [cat > conftest.c <<\EOF
--asm (
-- ".globl start, _start, __start\n"
-- ".ifdef cmain; .set start = _start = __start = cmain\n.endif\n"
-- ".ifdef _cmain; .set start = _start = __start = _cmain\n.endif\n"
--);
- void cmain (void);
- void
- cmain (void)
-diff --git a/configure.ac b/configure.ac
-index d8ca1b7c1..041cfbab4 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1461,6 +1461,7 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
- TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc"
- TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
- TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc"
-+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
- TARGET_IMG_CFLAGS=
- else
- TARGET_APPLE_LINKER=0
-@@ -1468,6 +1469,7 @@ else
- TARGET_IMG_LDSCRIPT=
- TARGET_IMG_LDFLAGS='-Wl,-N'
- TARGET_IMG_LDFLAGS_AC='-Wl,-N'
-+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
- TARGET_IMG_CFLAGS=
- fi
-
-@@ -1798,18 +1800,6 @@ grub_PROG_TARGET_CC
- m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
-
- if test "x$TARGET_APPLE_LINKER" != x1 ; then
--AX_CHECK_LINK_FLAG([-Wl,--image-base,0x400000],
-- [TARGET_IMG_BASE_LDOPT="-Wl,--image-base"],
-- [TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"],
-- [],
-- [AC_LANG_SOURCE([
--asm (".globl start; start:");
--asm (".globl _start; _start:");
--asm (".globl __start; __start:");
--void __main (void);
--void __main (void) {}
--int main (void);
-- ])])
- grub_PROG_OBJCOPY_ABSOLUTE
- fi
- grub_PROG_LD_BUILD_ID_NONE
---
-2.47.3
-
diff --git a/config/grub/default/patches/0010-Revert-configure-Print-a-more-helpful-error-if-autoc.patch b/config/grub/default/patches/0010-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
deleted file mode 100644
index 0c968993..00000000
--- a/config/grub/default/patches/0010-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From 66028b6bc149a25894fe5ca395b22804f389a18e Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Mon, 19 Jan 2026 15:27:23 +0000
-Subject: [PATCH 10/10] Revert "configure: Print a more helpful error if
- autoconf-archive is not installed"
-
-This reverts commit ac042f3f58d33ce9cd5ff61750f06da1a1d7b0eb.
----
- configure.ac | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 041cfbab4..209c0fb11 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1794,11 +1794,6 @@ LIBS=""
- # Defined in acinclude.m4.
- grub_ASM_USCORE
- grub_PROG_TARGET_CC
--
--# The error message produced by autoconf if autoconf-archive is not installed is
--# quite misleading and not very helpful. So, try point people in the right direction.
--m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
--
- if test "x$TARGET_APPLE_LINKER" != x1 ; then
- grub_PROG_OBJCOPY_ABSOLUTE
- fi
---
-2.47.3
-
diff --git a/config/grub/default/patches/0011-bootstrap-Don-t-download-po-files.patch b/config/grub/default/patches/0011-bootstrap-Don-t-download-po-files.patch
deleted file mode 100644
index cfb66047..00000000
--- a/config/grub/default/patches/0011-bootstrap-Don-t-download-po-files.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 5d18c96a22d98d137ea40bfc6aabadce933c2d45 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 1 Feb 2026 20:30:55 +0100
-Subject: [PATCH 1/1] bootstrap: Don't download po files
-
-GRUB doesn't verify checksums at all, and it pulls from
-this URL recursively:
-
-https://translationproject.org/latest/grub/
-
-These files can change at any time, and GRUB is just
-downloading them trustingly. Even if the upstream is
-totally benevolent, what if they got hacked?
-
-I downloaded them, hashed them and decided to mirror
-them on my RSYNC mirror. In this way, Libreboot can now
-use them in a deterministic fashion.
-
-Simply adding them to the GRUB source code would mean
-patching GRUB, which would add 8MB to lbmk. I won't do
-it.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- bootstrap | 31 +++++++++++++------------------
- 1 file changed, 13 insertions(+), 18 deletions(-)
-
-diff --git a/bootstrap b/bootstrap
-index dc9fb4383..9fc5a5c36 100755
---- a/bootstrap
-+++ b/bootstrap
-@@ -1,5 +1,16 @@
- #! /bin/sh
--# DO NOT EDIT! GENERATED AUTOMATICALLY!
-+# THIS FILE WAS EDITED BY LIBREBOOT TO REMOVE
-+# HACKY GRUB BEHAVIOUR; po files now downloaded
-+# by lbmk, via config/submodule/grub/ - so that
-+# versioned files are possible, with proper checksum
-+# verification, and mirrors are used.
-+
-+# Yes. This file has been modified. I intend to
-+# eventually remove this hacky script. Probably
-+# replace the entire GRUB build system.
-+
-+# Please do fix/edit or (when possible) remove
-+# this file. Thank you.
-
- # Bootstrap this package from checked-out sources.
-
-@@ -145,13 +156,6 @@ bootstrap_post_import_hook() { :; }
- # Override it via your own definition in bootstrap.conf.
- bootstrap_epilogue() { :; }
-
--# The command to download all .po files for a specified domain into a
--# specified directory. Fill in the first %s with the destination
--# directory and the second with the domain name.
--po_download_command_format=\
--"wget --mirror --level=1 -nd -nv -A.po -P '%s' \
-- https://translationproject.org/latest/%s/"
--
- # When extracting the package name from an AC_INIT invocation,
- # prefer a non-empty tarname (4th argument of AC_INIT if given), else
- # fall back to the package name (1st argument with munging).
-@@ -909,14 +913,6 @@ autopull()
-
- # ----------------------------- Get translations. -----------------------------
-
--download_po_files() {
-- subdir=$1
-- domain=$2
-- echo "$me: getting translations into $subdir for $domain..."
-- cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
-- eval "$cmd"
--}
--
- # Mirror .po files to $po_dir/.reference and copy only the new
- # or modified ones into $po_dir. Also update $po_dir/LINGUAS.
- # Note po files that exist locally only are left in $po_dir but will
-@@ -932,8 +928,7 @@ update_po_files() {
- ref_po_dir="$po_dir/.reference"
-
- test -d $ref_po_dir || mkdir $ref_po_dir || return
-- download_po_files $ref_po_dir $domain \
-- && ls "$ref_po_dir"/*.po 2>/dev/null |
-+ ls "$ref_po_dir"/*.po 2>/dev/null |
- sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
-
- for po in x $(ls $ref_po_dir | sed -n 's/\.po$//p'); do
---
-2.47.3
-
diff --git a/config/grub/default/target.cfg b/config/grub/default/target.cfg
deleted file mode 100644
index 2ce61fff..00000000
--- a/config/grub/default/target.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-tree="default"
-rev="eaa3b8f0f90605a82c6bfda4c5c4b73c58eb81ac"
diff --git a/config/grub/nvme/config/payload b/config/grub/nvme/config/payload
deleted file mode 100644
index 4f3de36e..00000000
--- a/config/grub/nvme/config/payload
+++ /dev/null
@@ -1,320 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2014-2016,2020-2021,2023-2025 Leah Rowe <leah@libreboot.org>
-# Copyright (C) 2015 Klemens Nanni <contact@autoboot.org>
-
-set prefix=(memdisk)/boot/grub
-
-insmod at_keyboard
-insmod usb_keyboard
-insmod nativedisk
-insmod ehci
-insmod ohci
-insmod uhci
-insmod usb
-insmod usbms
-insmod regexp
-
-terminal_input --append at_keyboard
-terminal_input --append usb_keyboard
-terminal_output --append cbmemc
-
-# User interface overrides wherever "keystatus" is supported
-# Keep SHIFT key pressed before powering on to disable graphics
-if keystatus --shift; then
- terminal_output --append vga_text
-else
- gfxpayload=keep
- terminal_output --append gfxterm
-
- for dt in cbfsdisk memdisk; do
- for it in png jpg; do
- if [ -f (${dt})/background.${it} ]; then
- insmod ${it}
- background_image (${dt})/background.${it}
- fi
- done
- done
-fi
-
-# Keep CTRL pressed to enable default serial terminal (COM1 or the like)
-if keystatus --ctrl; then
- serial
- terminal_input --append serial
- terminal_output --append serial
-fi
-
-# Keep ALT pressed to enable spkmodem
-if keystatus --alt; then
- terminal_output --append spkmodem
-fi
-
-
-set default="0"
-if [ -f (cbfsdisk)/timeout.cfg ]; then
- source (cbfsdisk)/timeout.cfg
-else
- set timeout=8
-fi
-set grub_scan_disk="nvme ahci ata"
-if [ -f (cbfsdisk)/scan.cfg ]; then
- source (cbfsdisk)/scan.cfg
-fi
-
-if [ -f (cbfsdisk)/keymap.gkb ]; then
- keymap (cbfsdisk)/keymap.gkb
-fi
-
-function really_try_user_config {
- set root="${1}"
-
- if [ -f /"${2}"/grub.cfg ]; then
- unset superusers
- configfile /"${2}"/grub.cfg
- fi
-}
-
-function try_user_config {
- # The @/... entries are for cases where the BTRFS filesystem is being used
- for dir in grub boot/grub @/grub @/boot/grub grub2 boot/grub2 @/grub2 @/boot/grub2 boot @/boot; do
- really_try_user_config "${1}" "${dir}"
- done
- for dir in ubuntu debian redhat; do
- really_try_user_config "${1}" "EFI/${dir}"
- done
-}
-function search_grub {
- echo -n "Attempting to load grub.cfg from '${1}' devices"
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${1}" != "nvme" ]; then
- try_user_config "(${1}${i},${part})"
- else
- # TODO: do we care about other namesapces
- try_user_config "(nvme${i}n1,${part})"
- fi
- done
- if [ "${1}" != "nvme" ]; then
- # raw devices e.g. (ahci0) instead of (ahci0,1)
- try_user_config "(${1}${i})"
- else
- # TODO: do we care about other namesapces
- try_user_config "(nvme${i}n1)"
- fi
- done
- echo # Insert newline
-}
-
-function try_isolinux_config {
- set root="${1}"
- for dir in '' /boot /EFI /@ /@/boot; do
- if [ -f "${dir}"/isolinux/isolinux.cfg ]; then
- syslinux_configfile -i "${dir}"/isolinux/isolinux.cfg
- elif [ -f "${dir}"/syslinux/syslinux.cfg ]; then
- syslinux_configfile -s "${dir}"/syslinux/syslinux.cfg
- elif [ -f "${dir}"/syslinux/extlinux.conf ]; then
- syslinux_configfile -s "${dir}"/syslinux/extlinux.conf
- elif [ -f "${dir}"/extlinux/extlinux.conf ]; then
- syslinux_configfile -s "${dir}"/extlinux/extlinux.conf
- fi
- done
-}
-function search_isolinux {
- echo "\nAttempting to parse iso/sys/extlinux config from '${1}' devices"
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${1}" != "nvme" ]; then
- try_isolinux_config "(${1}${i},${part})"
- else
- # TODO: see above
- try_isolinux_config "(nvme${i}n1,${part})"
- fi
- done
- if [ "${1}" != "nvme" ]; then
- # raw devices e.g. (usb0) instead of (usb0,1)
- try_isolinux_config "(${1}${i})"
- else
- # TODO: do we care about other namesapces
- try_isolinux_config "(nvme${i}n1)"
- fi
- done
- echo # Insert newline
-}
-function try_bootcfg {
- try_user_config "${1}"
- try_isolinux_config "${1}"
-}
-function search_bootcfg {
- search_grub "${1}"
- search_isolinux "${1}"
-}
-menuentry 'Load Operating System (incl. fully encrypted disks) [o]' --hotkey='o' {
-
- for grub_disk in ${grub_scan_disk}; do
- search_bootcfg ${grub_disk}
- done
-
- # grub device enumeration is very slow, so checks are hardcoded
-
- raidvol="md/0 md/1 md/2 md/3 md/4 md/5 md/6 md/7 md/8 md/9"
-
- # in practise, doing multiple redundant checks is perfectly fast
- # TODO: optimize grub itself, and use */? here for everything
-
- for vol in ${raidvol} ; do
- try_bootcfg "${vol}"
- done
-
- unset bootdev
- for grub_disk in ${grub_scan_disk}; do
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${grub_disk}" = "ahci" ]; then
- bootdev="${bootdev} (ahci${i},${part})"
- elif [ "${grub_disk}" = "ata" ]; then
- bootdev="${bootdev} (ata${i},${part})"
- elif [ "${grub_disk}" = "nvme" ]; then
- # TODO: do we care about other namesapces
- bootdev="${bootdev} (nvme${i}n1,${part})"
- fi
- done
- done
- done
-
- set pager=0
- echo -n "Attempting to unlock encrypted volumes"
- for dev in ${bootdev} ${raidvol}; do
- if cryptomount "${dev}" ; then break ; fi
- done
- set pager=1
- echo
-
- search_bootcfg crypto
-
- lvmvol=""
-
- # after cryptomount, lvm volumes might be available
- # using * is slow on some machines, but we use it here,
- # just once. in so doing, we find every lvm volume
- for vol in (*); do
- if regexp ^\\(lvm/ $vol; then
- lvmvol="${lvmvol} ${vol}"
- try_bootcfg "${vol}"
- fi
- done
-
- # user might have put luks inside lvm
- set pager=0
- echo "Attempting to unlock encrypted LVMs"
- for vol in ${lvmvol}; do
- cryptomount "$vol"
- done
- set pager=1
- echo
-
- search_bootcfg crypto
-
- true # Prevent pager requiring to accept each line instead of whole screen
-}
-
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on USB [s]' --hotkey='s' {
- search_bootcfg usb
-}
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on AHCI [a]' --hotkey='a' {
- search_bootcfg ahci
-}
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on ATA/IDE [d]' --hotkey='d' {
- search_bootcfg ata
-}
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on NVMe [e]' --hotkey='e' {
- search_bootcfg nvme
-}
-if [ -f (cbfsdisk)/grub.cfg ]; then
-menuentry 'Load configuration (grub.cfg) in CBFS [t]' --hotkey='t' {
- set root='(cbfsdisk)'
- if [ -f /grub.cfg ]; then
- configfile /grub.cfg
- fi
-}
-fi
-if [ -f (cbfsdisk)/grubtest.cfg ]; then
-menuentry 'Load test configuration (grubtest.cfg) inside of CBFS [t]' --hotkey='t' {
- set root='(cbfsdisk)'
- if [ -f /grubtest.cfg ]; then
- configfile /grubtest.cfg
- fi
-}
-fi
-if [ -f (cbfsdisk)/u-boot ]; then
-menuentry 'U-Boot i386 payload (experimental) [u]' --hotkey='u' {
- set root='cbfsdisk'
- chainloader /u-boot
-}
-fi
-if [ -f (cbfsdisk)/seabios.elf ]; then
-if [ -f (cbfsdisk)/img/u-boot ]; then
-menuentry 'Load SeaBIOS (U-Boot UEFI available in the ESC menu) [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /seabios.elf
-}
-else
-menuentry 'Load SeaBIOS [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /seabios.elf
-}
-fi
-fi
-if [ -f (cbfsdisk)/img/grub2 ]; then
-if [ -f (cbfsdisk)/img/u-boot ]; then
-menuentry 'Return to SeaBIOS (U-Boot UEFI available in the ESC menu) [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /fallback/payload
-}
-else
-menuentry 'Return to SeaBIOS [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /fallback/payload
-}
-fi
-fi
-menuentry 'Poweroff [p]' --hotkey='p' {
- halt
-}
-menuentry 'Reboot [r]' --hotkey='r' {
- reboot
-}
-if [ -f (cbfsdisk)/img/memtest ]; then
-menuentry 'Load MemTest86+ [m]' --hotkey='m' {
- set root='cbfsdisk'
- chainloader /img/memtest
-}
-fi
-
-submenu 'Other [z]' --hotkey='z' {
- menuentry 'Enable default serial terminal [s]' --hotkey='s' {
- serial
- terminal_input --append serial
- terminal_output --append serial
- }
-
- menuentry 'Disable default serial terminal' {
- terminal_input --remove serial
- terminal_output --remove serial
- }
-
- menuentry 'Enable gfxterm' {
- terminal_output --append gfxterm
- terminal_output --remove vga_text
- }
- menuentry 'Disable gfxterm [g]' --hotkey='g' {
- terminal_output --remove gfxterm
- terminal_output --append vga_text
- }
-
- menuentry 'Enable spkmodem [a]' --hotkey='a' {
- terminal_output --append spkmodem
- }
-
- menuentry 'Disable spkmodem [z]' --hotkey='z' {
- terminal_output --remove spkmodem
- }
-}
diff --git a/config/grub/nvme/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch b/config/grub/nvme/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch
deleted file mode 100644
index 41194e98..00000000
--- a/config/grub/nvme/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 2c953c9160cbed357437891cf1790aeb1c2bd0f5 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 31 Oct 2021 03:47:05 +0000
-Subject: [PATCH 01/10] mitigate grub's missing characters for borders/arrow
- characters
-
-This cleans up the display on the main screen in GRUB.
-
-Just don't draw a border, at all.
----
- grub-core/normal/menu_text.c | 49 ++----------------------------------
- 1 file changed, 2 insertions(+), 47 deletions(-)
-
-diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
-index 9c383e64a..8ec1dd1e8 100644
---- a/grub-core/normal/menu_text.c
-+++ b/grub-core/normal/menu_text.c
-@@ -108,47 +108,6 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right,
- grub_print_message_indented_real (msg, margin_left, margin_right, term, 0);
- }
-
--static void
--draw_border (struct grub_term_output *term, const struct grub_term_screen_geometry *geo)
--{
-- int i;
--
-- grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
--
-- grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y - 1 });
-- grub_putcode (GRUB_UNICODE_CORNER_UL, term);
-- for (i = 0; i < geo->entry_width + 1; i++)
-- grub_putcode (GRUB_UNICODE_HLINE, term);
-- grub_putcode (GRUB_UNICODE_CORNER_UR, term);
--
-- for (i = 0; i < geo->num_entries; i++)
-- {
-- grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y + i });
-- grub_putcode (GRUB_UNICODE_VLINE, term);
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x + geo->entry_width + 1,
-- geo->first_entry_y + i });
-- grub_putcode (GRUB_UNICODE_VLINE, term);
-- }
--
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y - 1 + geo->num_entries + 1 });
-- grub_putcode (GRUB_UNICODE_CORNER_LL, term);
-- for (i = 0; i < geo->entry_width + 1; i++)
-- grub_putcode (GRUB_UNICODE_HLINE, term);
-- grub_putcode (GRUB_UNICODE_CORNER_LR, term);
--
-- grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
--
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- (geo->first_entry_y - 1 + geo->num_entries
-- + GRUB_TERM_MARGIN + 1) });
--}
--
- static int
- print_message (int nested, int edit, struct grub_term_output *term, int dry_run)
- {
-@@ -167,10 +126,8 @@ command-line or ESC to discard edits and return to the GRUB menu."),
- {
- char *msg_translated;
-
-- msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which "
-- "entry is highlighted."),
-- GRUB_UNICODE_UPARROW,
-- GRUB_UNICODE_DOWNARROW);
-+ msg_translated = grub_xasprintf (_("Use the arrow keys to select which "
-+ "entry is highlighted."));
- if (!msg_translated)
- return 0;
- ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN,
-@@ -413,8 +370,6 @@ grub_menu_init_page (int nested, int edit,
-
- grub_term_normal_color = grub_color_menu_normal;
- grub_term_highlight_color = grub_color_menu_highlight;
-- if (geo->border)
-- draw_border (term, geo);
- grub_term_normal_color = old_color_normal;
- grub_term_highlight_color = old_color_highlight;
- geo->timeout_y = geo->first_entry_y + geo->num_entries
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch b/config/grub/nvme/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch
deleted file mode 100644
index 359f31f8..00000000
--- a/config/grub/nvme/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From 71623385f90580b2138110cf00ee66b7a05abcf6 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sat, 19 Nov 2022 16:30:24 +0000
-Subject: [PATCH 02/10] say the name libreboot, in the grub menu
-
----
- grub-core/normal/main.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
-index de9a3f961..bed502cde 100644
---- a/grub-core/normal/main.c
-+++ b/grub-core/normal/main.c
-@@ -215,7 +215,7 @@ grub_normal_init_page (struct grub_term_output *term,
-
- grub_term_cls (term);
-
-- msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION);
-+ msg_formatted = grub_xasprintf (_("Libreboot 26.01 Magnanimous Max (GRUB menu): https://libreboot.org/"));
- if (!msg_formatted)
- return;
-
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch b/config/grub/nvme/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch
deleted file mode 100644
index ab26c6b2..00000000
--- a/config/grub/nvme/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From a21c5e997d6247d713717745b5f7bd380b98fce1 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Mon, 30 Oct 2023 22:19:21 +0000
-Subject: [PATCH 03/10] at_keyboard coreboot: force scancodes2+translate
-
-Scan code set 2 with translation should be assumed in
-every case, as the default starting position.
-
-However, GRUB is trying to detect and use other modes
-such as set 2 without translation, or set 1 without
-translation from set 2; it also detects no-mode and
-assumes mode 1, on really old keyboards.
-
-The current behaviour has been retained, for everything
-except GRUB_MACHINE_COREBOOT; for the latter, scan code
-set 2 with translation is hardcoded, and forced in code.
-
-This is required to make keyboard initialisation work on
-the MEC5035 EC used by the Dell Latitude E6400, when
-running GRUB as a coreboot payload on that laptop. The
-EC reports scancode set 2 with translation when probed,
-but actually only outputs scancode set 1.
-
-Since GRUB is attempting to use it without translation,
-and since the machine reports set 2 with translation,
-but only ever outputs set 1 scancodes, this results in
-wrong keypresses for every key.
-
-This fix fixed that, by forcing set 2 with translation,
-treating it as set 1, but only on coreboot. This is the
-same behaviour used in GNU+Linux systems and SeaBIOS.
-With this change, GRUB keyboard initialisation now works
-just fine on those machines.
-
-This has *also* been tested on other coreboot machines
-running GRUB; several HP EliteBooks, ThinkPads and
-Dell Precision T1650. All seems to work just fine.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/term/at_keyboard.c | 20 ++++++++++++++++++--
- 1 file changed, 18 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c
-index f8a129eb7..8207225c2 100644
---- a/grub-core/term/at_keyboard.c
-+++ b/grub-core/term/at_keyboard.c
-@@ -138,6 +138,7 @@ write_mode (int mode)
- return (i != GRUB_AT_TRIES);
- }
-
-+#if !defined (GRUB_MACHINE_COREBOOT)
- static int
- query_mode (void)
- {
-@@ -161,10 +162,12 @@ query_mode (void)
- return 3;
- return 0;
- }
-+#endif
-
- static void
- set_scancodes (void)
- {
-+#if !defined (GRUB_MACHINE_COREBOOT)
- /* You must have visited computer museum. Keyboard without scancode set
- knowledge. Assume XT. */
- if (!grub_keyboard_orig_set)
-@@ -173,20 +176,33 @@ set_scancodes (void)
- ps2_state.current_set = 1;
- return;
- }
-+#endif
-
- #if !USE_SCANCODE_SET
- ps2_state.current_set = 1;
- return;
--#else
-+#endif
-
-+#if defined (GRUB_MACHINE_COREBOOT)
-+ /* enable translation */
-+ grub_keyboard_controller_write (grub_keyboard_controller_orig
-+ & ~KEYBOARD_AT_DISABLE);
-+#else
-+ /* if not coreboot, disable translation and try mode 2 first, before 1 */
- grub_keyboard_controller_write (grub_keyboard_controller_orig
- & ~KEYBOARD_AT_TRANSLATE
- & ~KEYBOARD_AT_DISABLE);
-+#endif
-
- keyboard_controller_wait_until_ready ();
- grub_outb (KEYBOARD_COMMAND_ENABLE, KEYBOARD_REG_DATA);
--
- write_mode (2);
-+
-+#if defined (GRUB_MACHINE_COREBOOT)
-+ /* mode 2 with translation, so make grub treat as set 1 */
-+ ps2_state.current_set = 1;
-+#else
-+ /* if not coreboot, translation isn't set; test 2 and fall back to 1 */
- ps2_state.current_set = query_mode ();
- grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set);
- if (ps2_state.current_set == 2)
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch b/config/grub/nvme/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch
deleted file mode 100644
index 68dfb2f7..00000000
--- a/config/grub/nvme/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From 062379b1cd5a4f99324c625fb371c29eb00ad4a2 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Tue, 31 Oct 2023 10:33:28 +0000
-Subject: [PATCH 04/10] keylayouts: don't print "Unknown key" message
-
-on keyboards with stuck keys, this results in GRUB just
-spewing it repeatedly, preventing use of GRUB.
-
-in such cases, it's still possible to use the keyboard,
-and we should let the user at least boot.
-
-it often appears when people plug in faulty usb keyboards,
-but can appear for laptop keyboards too; one of my e6400
-has stuck keys.
-
-with this patch, grub should be a bit more reliable in
-terms of user experience, when the keyboard is faulty.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/commands/keylayouts.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c
-index aa3ba34f2..445fa0601 100644
---- a/grub-core/commands/keylayouts.c
-+++ b/grub-core/commands/keylayouts.c
-@@ -174,7 +174,6 @@ grub_term_map_key (grub_keyboard_key_t code, int status)
- key = map_key_core (code, status, &alt_gr_consumed);
-
- if (key == 0 || key == GRUB_TERM_SHIFT) {
-- grub_printf ("Unknown key 0x%x detected\n", code);
- return GRUB_TERM_NO_KEY;
- }
-
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch b/config/grub/nvme/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch
deleted file mode 100644
index 53dbdd87..00000000
--- a/config/grub/nvme/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From e77ca67985c1bef8afd93587232da3d298a8dd51 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 16:14:58 +0000
-Subject: [PATCH 05/10] don't print missing prefix errors on the screen
-
-we do actually set the prefix. this patch modifies
-grub to still set grub_errno and return accordingly,
-so the behaviour is otherwise identical, but it will
-no longer print a warning message on the screen.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/commands/keylayouts.c | 2 +-
- grub-core/commands/loadenv.c | 2 +-
- grub-core/commands/nativedisk.c | 2 +-
- grub-core/efiemu/main.c | 3 +--
- grub-core/font/font.c | 2 +-
- grub-core/kern/dl.c | 2 +-
- 6 files changed, 6 insertions(+), 7 deletions(-)
-
-diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c
-index 445fa0601..00bcf7025 100644
---- a/grub-core/commands/keylayouts.c
-+++ b/grub-core/commands/keylayouts.c
-@@ -211,7 +211,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
- {
- const char *prefix = grub_env_get ("prefix");
- if (!prefix)
-- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_BAD_ARGUMENT);
- filename = grub_xasprintf ("%s/layouts/%s.gkb", prefix, argv[0]);
- if (!filename)
- return grub_errno;
-diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c
-index 166445849..699b39bfa 100644
---- a/grub-core/commands/loadenv.c
-+++ b/grub-core/commands/loadenv.c
-@@ -58,7 +58,7 @@ open_envblk_file (char *filename,
- prefix = grub_env_get ("prefix");
- if (! prefix)
- {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- return 0;
- }
-
-diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
-index 580c8d3b0..6806bff9c 100644
---- a/grub-core/commands/nativedisk.c
-+++ b/grub-core/commands/nativedisk.c
-@@ -186,7 +186,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
- prefix = grub_env_get ("prefix");
-
- if (! prefix)
-- return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_FILE_NOT_FOUND);
-
- if (prefix)
- path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL;
-diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c
-index e7037f4ed..e5d4dbff1 100644
---- a/grub-core/efiemu/main.c
-+++ b/grub-core/efiemu/main.c
-@@ -231,8 +231,7 @@ grub_efiemu_autocore (void)
- prefix = grub_env_get ("prefix");
-
- if (! prefix)
-- return grub_error (GRUB_ERR_FILE_NOT_FOUND,
-- N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_FILE_NOT_FOUND);
-
- suffix = grub_efiemu_get_default_core_name ();
-
-diff --git a/grub-core/font/font.c b/grub-core/font/font.c
-index 18de52562..2a0fea6c8 100644
---- a/grub-core/font/font.c
-+++ b/grub-core/font/font.c
-@@ -461,7 +461,7 @@ grub_font_load (const char *filename)
-
- if (!prefix)
- {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- goto fail;
- }
- file = try_open_from_prefix (prefix, filename);
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index de8c3aa8d..eac3ea48d 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -880,7 +880,7 @@ grub_dl_load (const char *name)
- return 0;
-
- if (! grub_dl_dir) {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- return 0;
- }
-
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0006-don-t-print-error-if-module-not-found.patch b/config/grub/nvme/patches/0006-don-t-print-error-if-module-not-found.patch
deleted file mode 100644
index 3851c7fe..00000000
--- a/config/grub/nvme/patches/0006-don-t-print-error-if-module-not-found.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 9412b6be27bce2d79f154761387d35f44184c069 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 16:36:22 +0000
-Subject: [PATCH 06/10] don't print error if module not found
-
-still set grub_errno accordingly, and otherwise
-behave the same. in libreboot, we remove a lot of
-modules but then rely on loading a grub.cfg
-provided by a distro; in almost all cases that works,
-but also in almost all cases, that will try to load
-a module we don't actually need, but then it prints
-a message. this can annoy some users, so silence it.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/kern/dl.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index eac3ea48d..6d67ba54f 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -510,7 +510,7 @@ grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e)
-
- s = grub_dl_find_section (e, ".modname");
- if (!s)
-- return grub_error (GRUB_ERR_BAD_MODULE, "no module name found");
-+ return (grub_errno = GRUB_ERR_BAD_MODULE);
-
- mod->name = grub_strdup ((char *) e + s->sh_offset);
- if (! mod->name)
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0007-don-t-print-empty-error-messages.patch b/config/grub/nvme/patches/0007-don-t-print-empty-error-messages.patch
deleted file mode 100644
index aa42420f..00000000
--- a/config/grub/nvme/patches/0007-don-t-print-empty-error-messages.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 2ad50d482cae148df832ccd68f90b8111684ecde Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 17:25:20 +0000
-Subject: [PATCH 07/10] don't print empty error messages
-
-this is part two of the quest to kill the prefix
-error message. after i disabled prefix-related
-messages, it still printed "error: ." on screen.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/kern/err.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
-index ba04b57fb..dab62646d 100644
---- a/grub-core/kern/err.c
-+++ b/grub-core/kern/err.c
-@@ -116,7 +116,8 @@ grub_print_error (void)
- {
- if (grub_errno != GRUB_ERR_NONE)
- {
-- grub_err_printf (_("error: %s.\n"), grub_errmsg);
-+ if (grub_strlen(grub_errmsg) > 0)
-+ grub_err_printf (_("error: %s.\n"), grub_errmsg);
- grub_err_printed_errors++;
- }
- }
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0008-Add-native-NVMe-driver-based-on-SeaBIOS.patch b/config/grub/nvme/patches/0008-Add-native-NVMe-driver-based-on-SeaBIOS.patch
deleted file mode 100644
index e0b40f2f..00000000
--- a/config/grub/nvme/patches/0008-Add-native-NVMe-driver-based-on-SeaBIOS.patch
+++ /dev/null
@@ -1,1074 +0,0 @@
-From 202e20bef3766480aee18e679b9306387be615dc Mon Sep 17 00:00:00 2001
-From: Mate Kukri <km@mkukri.xyz>
-Date: Mon, 20 May 2024 11:43:35 +0100
-Subject: [PATCH 08/10] Add native NVMe driver based on SeaBIOS
-
-Tested to successfully boot Debian on QEMU and OptiPlex 3050.
-
-Signed-off-by: Mate Kukri <km@mkukri.xyz>
----
- Makefile.am | 2 +-
- grub-core/Makefile.core.def | 6 +
- grub-core/commands/nativedisk.c | 1 +
- grub-core/disk/nvme-int.h | 208 +++++++++
- grub-core/disk/nvme.c | 781 ++++++++++++++++++++++++++++++++
- include/grub/disk.h | 1 +
- 6 files changed, 998 insertions(+), 1 deletion(-)
- create mode 100644 grub-core/disk/nvme-int.h
- create mode 100644 grub-core/disk/nvme.c
-
-diff --git a/Makefile.am b/Makefile.am
-index 43635d5ff..2c86dbbf6 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -434,7 +434,7 @@ if COND_i386_coreboot
- FS_PAYLOAD_MODULES ?= $(shell cat grub-core/fs.lst)
- default_payload.elf: grub-mkstandalone grub-mkimage FORCE
- test -f $@ && rm $@ || true
-- pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
-+ pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata nvme ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
- endif
-
- endif
-diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
-index 0cf155128..176d35364 100644
---- a/grub-core/Makefile.core.def
-+++ b/grub-core/Makefile.core.def
-@@ -2773,3 +2773,9 @@ module = {
- cflags = '-Wno-uninitialized';
- cppflags = '-I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/tests/asn1/';
- };
-+
-+module = {
-+ name = nvme;
-+ common = disk/nvme.c;
-+ enable = pci;
-+};
-diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
-index 6806bff9c..fd68a513e 100644
---- a/grub-core/commands/nativedisk.c
-+++ b/grub-core/commands/nativedisk.c
-@@ -78,6 +78,7 @@ get_uuid (const char *name, char **uuid, int getnative)
- case GRUB_DISK_DEVICE_ATA_ID:
- case GRUB_DISK_DEVICE_SCSI_ID:
- case GRUB_DISK_DEVICE_XEN:
-+ case GRUB_DISK_DEVICE_NVME_ID:
- if (getnative)
- break;
- /* FALLTHROUGH */
-diff --git a/grub-core/disk/nvme-int.h b/grub-core/disk/nvme-int.h
-new file mode 100644
-index 000000000..1295b58aa
---- /dev/null
-+++ b/grub-core/disk/nvme-int.h
-@@ -0,0 +1,208 @@
-+// NVMe datastructures and constants
-+//
-+// Copyright 2017 Amazon.com, Inc. or its affiliates.
-+//
-+// This file may be distributed under the terms of the GNU LGPLv3 license.
-+
-+#ifndef __NVME_INT_H
-+#define __NVME_INT_H
-+
-+#include <grub/types.h>
-+
-+/* Data structures */
-+
-+/* The register file of a NVMe host controller. This struct follows the naming
-+ scheme in the NVMe specification. */
-+struct nvme_reg {
-+ grub_uint64_t cap; /* controller capabilities */
-+ grub_uint32_t vs; /* version */
-+ grub_uint32_t intms; /* interrupt mask set */
-+ grub_uint32_t intmc; /* interrupt mask clear */
-+ grub_uint32_t cc; /* controller configuration */
-+ grub_uint32_t _res0;
-+ grub_uint32_t csts; /* controller status */
-+ grub_uint32_t _res1;
-+ grub_uint32_t aqa; /* admin queue attributes */
-+ grub_uint64_t asq; /* admin submission queue base address */
-+ grub_uint64_t acq; /* admin completion queue base address */
-+};
-+
-+/* Submission queue entry */
-+struct nvme_sqe {
-+ union {
-+ grub_uint32_t dword[16];
-+ struct {
-+ grub_uint32_t cdw0; /* Command DWORD 0 */
-+ grub_uint32_t nsid; /* Namespace ID */
-+ grub_uint64_t _res0;
-+ grub_uint64_t mptr; /* metadata ptr */
-+
-+ grub_uint64_t dptr_prp1;
-+ grub_uint64_t dptr_prp2;
-+ };
-+ };
-+};
-+
-+/* Completion queue entry */
-+struct nvme_cqe {
-+ union {
-+ grub_uint32_t dword[4];
-+ struct {
-+ grub_uint32_t cdw0;
-+ grub_uint32_t _res0;
-+ grub_uint16_t sq_head;
-+ grub_uint16_t sq_id;
-+ grub_uint16_t cid;
-+ grub_uint16_t status;
-+ };
-+ };
-+};
-+
-+/* The common part of every submission or completion queue. */
-+struct nvme_queue {
-+ grub_uint32_t *dbl; /* doorbell */
-+ grub_uint16_t mask; /* length - 1 */
-+};
-+
-+struct nvme_cq {
-+ struct nvme_queue common;
-+ struct nvme_cqe *cqe;
-+
-+ /* We have read upto (but not including) this entry in the queue. */
-+ grub_uint16_t head;
-+
-+ /* The current phase bit the controller uses to indicate that it has written
-+ a new entry. This is inverted after each wrap. */
-+ unsigned phase : 1;
-+};
-+
-+struct nvme_sq {
-+ struct nvme_queue common;
-+ struct nvme_sqe *sqe;
-+
-+ /* Corresponding completion queue. We only support a single SQ per CQ. */
-+ struct nvme_cq *cq;
-+
-+ /* The last entry the controller has fetched. */
-+ grub_uint16_t head;
-+
-+ /* The last value we have written to the tail doorbell. */
-+ grub_uint16_t tail;
-+};
-+
-+struct nvme_ctrl {
-+ grub_pci_device_t pci;
-+ struct nvme_reg volatile *reg;
-+
-+ grub_uint32_t ctrlnum;
-+
-+ grub_uint32_t doorbell_stride; /* in bytes */
-+
-+ struct nvme_sq admin_sq;
-+ struct nvme_cq admin_cq;
-+
-+ grub_uint32_t ns_count;
-+
-+ struct nvme_sq io_sq;
-+ struct nvme_cq io_cq;
-+};
-+
-+struct nvme_namespace {
-+ struct nvme_namespace *next;
-+ struct nvme_namespace **prev;
-+
-+ char *devname;
-+
-+ grub_uint32_t nsnum;
-+
-+ struct nvme_ctrl *ctrl;
-+
-+ grub_uint32_t ns_id;
-+
-+ grub_uint64_t lba_count; /* The total amount of sectors. */
-+
-+ grub_uint32_t block_size;
-+ grub_uint32_t metadata_size;
-+ grub_uint32_t max_req_size;
-+};
-+
-+/* Data structures for NVMe admin identify commands */
-+
-+struct nvme_identify_ctrl {
-+ grub_uint16_t vid;
-+ grub_uint16_t ssvid;
-+ char sn[20];
-+ char mn[40];
-+ char fr[8];
-+
-+ grub_uint8_t rab;
-+ grub_uint8_t ieee[3];
-+ grub_uint8_t cmic;
-+ grub_uint8_t mdts;
-+
-+ char _boring[516 - 78];
-+
-+ grub_uint32_t nn; /* number of namespaces */
-+};
-+
-+struct nvme_identify_ns_list {
-+ grub_uint32_t ns_id[1024];
-+};
-+
-+struct nvme_lba_format {
-+ grub_uint16_t ms;
-+ grub_uint8_t lbads;
-+ grub_uint8_t rp;
-+};
-+
-+struct nvme_identify_ns {
-+ grub_uint64_t nsze;
-+ grub_uint64_t ncap;
-+ grub_uint64_t nuse;
-+ grub_uint8_t nsfeat;
-+ grub_uint8_t nlbaf;
-+ grub_uint8_t flbas;
-+
-+ char _boring[128 - 27];
-+
-+ struct nvme_lba_format lbaf[16];
-+};
-+
-+union nvme_identify {
-+ struct nvme_identify_ns ns;
-+ struct nvme_identify_ctrl ctrl;
-+ struct nvme_identify_ns_list ns_list;
-+};
-+
-+/* NVMe constants */
-+
-+#define NVME_CAP_CSS_NVME (1ULL << 37)
-+
-+#define NVME_CSTS_FATAL (1U << 1)
-+#define NVME_CSTS_RDY (1U << 0)
-+
-+#define NVME_CC_EN (1U << 0)
-+
-+#define NVME_SQE_OPC_ADMIN_CREATE_IO_SQ 1U
-+#define NVME_SQE_OPC_ADMIN_CREATE_IO_CQ 5U
-+#define NVME_SQE_OPC_ADMIN_IDENTIFY 6U
-+
-+#define NVME_SQE_OPC_IO_WRITE 1U
-+#define NVME_SQE_OPC_IO_READ 2U
-+
-+#define NVME_ADMIN_IDENTIFY_CNS_ID_NS 0U
-+#define NVME_ADMIN_IDENTIFY_CNS_ID_CTRL 1U
-+#define NVME_ADMIN_IDENTIFY_CNS_GET_NS_LIST 2U
-+
-+#define NVME_CQE_DW3_P (1U << 16)
-+
-+#define NVME_PAGE_SIZE 4096
-+#define NVME_PAGE_MASK ~(NVME_PAGE_SIZE - 1)
-+
-+/* Length for the queue entries. */
-+#define NVME_SQE_SIZE_LOG 6
-+#define NVME_CQE_SIZE_LOG 4
-+
-+#endif
-+
-+/* EOF */
-diff --git a/grub-core/disk/nvme.c b/grub-core/disk/nvme.c
-new file mode 100644
-index 000000000..093237c70
---- /dev/null
-+++ b/grub-core/disk/nvme.c
-@@ -0,0 +1,781 @@
-+// Low level NVMe disk access
-+//
-+// Based on SeaBIOS NVMe driver - Copyright 2017 Amazon.com, Inc. or its affiliates.
-+// Port to GRUB2 done by Mate Kukri
-+//
-+// This file may be distributed under the terms of the GNU LGPLv3 license.
-+
-+#include <grub/disk.h>
-+#include <grub/dl.h>
-+#include <grub/pci.h>
-+#include "nvme-int.h"
-+
-+GRUB_MOD_LICENSE ("GPLv3"); /* LGPLv3 in reality but it is GPLv3 compatible */
-+
-+static grub_uint32_t grub_nvme_ctrlcnt;
-+static grub_uint32_t grub_nvme_nscnt;
-+
-+static struct nvme_namespace *grub_nvme_namespaces;
-+
-+// Page aligned "dma bounce buffer" of size NVME_PAGE_SIZE
-+static void *nvme_dma_buffer;
-+
-+static void *
-+zalloc_page_aligned(grub_uint32_t size)
-+{
-+ void *res = grub_memalign(NVME_PAGE_SIZE, size);
-+ if (res) grub_memset(res, 0, size);
-+ return res;
-+}
-+
-+static void
-+nvme_init_queue_common(struct nvme_ctrl *ctrl, struct nvme_queue *q, grub_uint16_t q_idx,
-+ grub_uint16_t length)
-+{
-+ grub_memset(q, 0, sizeof(*q));
-+ q->dbl = (grub_uint32_t *)((char *)ctrl->reg + 0x1000 + q_idx * ctrl->doorbell_stride);
-+ grub_dprintf("nvme", " q %p q_idx %u dbl %p\n", q, q_idx, q->dbl);
-+ q->mask = length - 1;
-+}
-+
-+static int
-+nvme_init_sq(struct nvme_ctrl *ctrl, struct nvme_sq *sq, grub_uint16_t q_idx, grub_uint16_t length,
-+ struct nvme_cq *cq)
-+{
-+ nvme_init_queue_common(ctrl, &sq->common, q_idx, length);
-+ sq->sqe = zalloc_page_aligned(sizeof(*sq->sqe) * length);
-+
-+ if (!sq->sqe) {
-+ return -1;
-+ }
-+
-+ grub_dprintf("nvme", "sq %p q_idx %u sqe %p\n", sq, q_idx, sq->sqe);
-+ sq->cq = cq;
-+ sq->head = 0;
-+ sq->tail = 0;
-+
-+ return 0;
-+}
-+
-+static int
-+nvme_init_cq(struct nvme_ctrl *ctrl, struct nvme_cq *cq, grub_uint16_t q_idx, grub_uint16_t length)
-+{
-+ nvme_init_queue_common(ctrl, &cq->common, q_idx, length);
-+ cq->cqe = zalloc_page_aligned(sizeof(*cq->cqe) * length);
-+ if (!cq->cqe) {
-+ return -1;
-+ }
-+
-+ cq->head = 0;
-+
-+ /* All CQE phase bits are initialized to zero. This means initially we wait
-+ for the host controller to set these to 1. */
-+ cq->phase = 1;
-+
-+ return 0;
-+}
-+
-+static int
-+nvme_poll_cq(struct nvme_cq *cq)
-+{
-+ grub_uint32_t dw3 = *(volatile grub_uint32_t *) &cq->cqe[cq->head].dword[3];
-+ return (!!(dw3 & NVME_CQE_DW3_P) == cq->phase);
-+}
-+
-+static int
-+nvme_is_cqe_success(struct nvme_cqe const *cqe)
-+{
-+ return ((cqe->status >> 1) & 0xFF) == 0;
-+}
-+
-+static struct nvme_cqe
-+nvme_error_cqe(void)
-+{
-+ struct nvme_cqe r;
-+
-+ /* 0xFF is a vendor specific status code != success. Should be okay for
-+ indicating failure. */
-+ grub_memset(&r, 0xFF, sizeof(r));
-+ return r;
-+}
-+
-+static struct nvme_cqe
-+nvme_consume_cqe(struct nvme_sq *sq)
-+{
-+ struct nvme_cq *cq = sq->cq;
-+
-+ if (!nvme_poll_cq(cq)) {
-+ /* Cannot consume a completion queue entry, if there is none ready. */
-+ return nvme_error_cqe();
-+ }
-+
-+ struct nvme_cqe *cqe = &cq->cqe[cq->head];
-+ grub_uint16_t cq_next_head = (cq->head + 1) & cq->common.mask;
-+ grub_dprintf("nvme", "cq %p head %u -> %u\n", cq, cq->head, cq_next_head);
-+ if (cq_next_head < cq->head) {
-+ grub_dprintf("nvme", "cq %p wrap\n", cq);
-+ cq->phase = ~cq->phase;
-+ }
-+ cq->head = cq_next_head;
-+
-+ /* Update the submission queue head. */
-+ if (cqe->sq_head != sq->head) {
-+ sq->head = cqe->sq_head;
-+ grub_dprintf("nvme", "sq %p advanced to %u\n", sq, cqe->sq_head);
-+ }
-+
-+ /* Tell the controller that we consumed the completion. */
-+ *(volatile grub_uint32_t *) cq->common.dbl = cq->head;
-+
-+ return *cqe;
-+}
-+
-+static struct nvme_cqe
-+nvme_wait(struct nvme_sq *sq)
-+{
-+ // static const unsigned nvme_timeout = 5000 /* ms */;
-+ // grub_uint32_t to = timer_calc(nvme_timeout);
-+ while (!nvme_poll_cq(sq->cq)) {
-+ /* FIXME
-+ yield();
-+
-+ if (timer_check(to)) {
-+ warn_timeout();
-+ return nvme_error_cqe();
-+ }*/
-+ }
-+
-+ return nvme_consume_cqe(sq);
-+}
-+
-+/* Returns the next submission queue entry (or NULL if the queue is full). It
-+ also fills out Command Dword 0 and clears the rest. */
-+static struct nvme_sqe *
-+nvme_get_next_sqe(struct nvme_sq *sq, grub_uint8_t opc, void *metadata, void *data, void *data2)
-+{
-+ if (((sq->head + 1) & sq->common.mask) == sq->tail) {
-+ grub_dprintf("nvme", "submission queue is full\n");
-+ return NULL;
-+ }
-+
-+ struct nvme_sqe *sqe = &sq->sqe[sq->tail];
-+ grub_dprintf("nvme", "sq %p next_sqe %u\n", sq, sq->tail);
-+
-+ grub_memset(sqe, 0, sizeof(*sqe));
-+ sqe->cdw0 = opc | (sq->tail << 16 /* CID */);
-+ sqe->mptr = (grub_uint32_t)metadata;
-+ sqe->dptr_prp1 = (grub_uint32_t)data;
-+ sqe->dptr_prp2 = (grub_uint32_t)data2;
-+
-+ return sqe;
-+}
-+
-+/* Call this after you've filled out an sqe that you've got from nvme_get_next_sqe. */
-+static void
-+nvme_commit_sqe(struct nvme_sq *sq)
-+{
-+ grub_dprintf("nvme", "sq %p commit_sqe %u\n", sq, sq->tail);
-+ sq->tail = (sq->tail + 1) & sq->common.mask;
-+ *(volatile grub_uint32_t *) sq->common.dbl = sq->tail;
-+}
-+
-+/* Perform an identify command on the admin queue and return the resulting
-+ buffer. This may be a NULL pointer, if something failed. This function
-+ cannot be used after initialization, because it uses buffers in tmp zone. */
-+static union nvme_identify *
-+nvme_admin_identify(struct nvme_ctrl *ctrl, grub_uint8_t cns, grub_uint32_t nsid)
-+{
-+ union nvme_identify *identify_buf = zalloc_page_aligned(4096);
-+ if (!identify_buf)
-+ return NULL;
-+
-+ struct nvme_sqe *cmd_identify;
-+ cmd_identify = nvme_get_next_sqe(&ctrl->admin_sq,
-+ NVME_SQE_OPC_ADMIN_IDENTIFY, NULL,
-+ identify_buf, NULL);
-+ if (!cmd_identify)
-+ goto error;
-+
-+ cmd_identify->nsid = nsid;
-+ cmd_identify->dword[10] = cns;
-+
-+ nvme_commit_sqe(&ctrl->admin_sq);
-+
-+ struct nvme_cqe cqe = nvme_wait(&ctrl->admin_sq);
-+
-+ if (!nvme_is_cqe_success(&cqe)) {
-+ goto error;
-+ }
-+
-+ return identify_buf;
-+ error:
-+ grub_free(identify_buf);
-+ return NULL;
-+}
-+
-+static struct nvme_identify_ctrl *
-+nvme_admin_identify_ctrl(struct nvme_ctrl *ctrl)
-+{
-+ return &nvme_admin_identify(ctrl, NVME_ADMIN_IDENTIFY_CNS_ID_CTRL, 0)->ctrl;
-+}
-+
-+static struct nvme_identify_ns *
-+nvme_admin_identify_ns(struct nvme_ctrl *ctrl, grub_uint32_t ns_id)
-+{
-+ return &nvme_admin_identify(ctrl, NVME_ADMIN_IDENTIFY_CNS_ID_NS,
-+ ns_id)->ns;
-+}
-+
-+static void
-+nvme_probe_ns(struct nvme_ctrl *ctrl, grub_uint32_t ns_idx, grub_uint8_t mdts)
-+{
-+ grub_uint32_t ns_id = ns_idx + 1;
-+
-+ struct nvme_identify_ns *id = nvme_admin_identify_ns(ctrl, ns_id);
-+ if (!id) {
-+ grub_dprintf("nvme", "NVMe couldn't identify namespace %u.\n", ns_id);
-+ goto free_buffer;
-+ }
-+
-+ grub_uint8_t current_lba_format = id->flbas & 0xF;
-+ if (current_lba_format > id->nlbaf) {
-+ grub_dprintf("nvme", "NVMe NS %u: current LBA format %u is beyond what the "
-+ " namespace supports (%u)?\n",
-+ ns_id, current_lba_format, id->nlbaf + 1);
-+ goto free_buffer;
-+ }
-+
-+ if (!id->nsze) {
-+ grub_dprintf("nvme", "NVMe NS %u is inactive.\n", ns_id);
-+ goto free_buffer;
-+ }
-+
-+ if (!nvme_dma_buffer) {
-+ nvme_dma_buffer = zalloc_page_aligned(NVME_PAGE_SIZE);
-+ if (!nvme_dma_buffer) {
-+ goto free_buffer;
-+ }
-+ }
-+
-+ struct nvme_namespace *ns = grub_malloc(sizeof(*ns));
-+ if (!ns) {
-+ goto free_buffer;
-+ }
-+ grub_memset(ns, 0, sizeof(*ns));
-+ ns->ctrl = ctrl;
-+ ns->ns_id = ns_id;
-+ ns->lba_count = id->nsze;
-+
-+ struct nvme_lba_format *fmt = &id->lbaf[current_lba_format];
-+
-+ ns->block_size = 1U << fmt->lbads;
-+ ns->metadata_size = fmt->ms;
-+
-+ if (ns->block_size > NVME_PAGE_SIZE) {
-+ /* If we see devices that trigger this path, we need to increase our
-+ buffer size. */
-+ grub_free(ns);
-+ goto free_buffer;
-+ }
-+
-+ if (mdts) {
-+ ns->max_req_size = ((1U << mdts) * NVME_PAGE_SIZE) / ns->block_size;
-+ grub_dprintf("nvme", "NVME NS %u max request size: %d sectors\n",
-+ ns_id, ns->max_req_size);
-+ } else {
-+ ns->max_req_size = -1U;
-+ }
-+
-+ ns->devname = grub_xasprintf("nvme%un%u", ctrl->ctrlnum, ns_id);
-+ ns->nsnum = grub_nvme_nscnt++;
-+
-+ grub_list_push (GRUB_AS_LIST_P (&grub_nvme_namespaces), GRUB_AS_LIST (ns));
-+
-+free_buffer:
-+ grub_free(id);
-+}
-+
-+
-+/* Release memory allocated for a completion queue */
-+static void
-+nvme_destroy_cq(struct nvme_cq *cq)
-+{
-+ grub_free(cq->cqe);
-+ cq->cqe = NULL;
-+}
-+
-+/* Release memory allocated for a submission queue */
-+static void
-+nvme_destroy_sq(struct nvme_sq *sq)
-+{
-+ grub_free(sq->sqe);
-+ sq->sqe = NULL;
-+}
-+
-+/* Returns 0 on success. */
-+static int
-+nvme_create_io_cq(struct nvme_ctrl *ctrl, struct nvme_cq *cq, grub_uint16_t q_idx)
-+{
-+ int rc;
-+ struct nvme_sqe *cmd_create_cq;
-+ grub_uint32_t length = 1 + (ctrl->reg->cap & 0xffff);
-+ if (length > NVME_PAGE_SIZE / sizeof(struct nvme_cqe))
-+ length = NVME_PAGE_SIZE / sizeof(struct nvme_cqe);
-+
-+ rc = nvme_init_cq(ctrl, cq, q_idx, length);
-+ if (rc) {
-+ goto err;
-+ }
-+
-+ cmd_create_cq = nvme_get_next_sqe(&ctrl->admin_sq,
-+ NVME_SQE_OPC_ADMIN_CREATE_IO_CQ, NULL,
-+ cq->cqe, NULL);
-+ if (!cmd_create_cq) {
-+ goto err_destroy_cq;
-+ }
-+
-+ cmd_create_cq->dword[10] = (cq->common.mask << 16) | (q_idx >> 1);
-+ cmd_create_cq->dword[11] = 1 /* physically contiguous */;
-+
-+ nvme_commit_sqe(&ctrl->admin_sq);
-+
-+ struct nvme_cqe cqe = nvme_wait(&ctrl->admin_sq);
-+
-+ if (!nvme_is_cqe_success(&cqe)) {
-+ grub_dprintf("nvme", "create io cq failed: %08x %08x %08x %08x\n",
-+ cqe.dword[0], cqe.dword[1], cqe.dword[2], cqe.dword[3]);
-+
-+ goto err_destroy_cq;
-+ }
-+
-+ return 0;
-+
-+err_destroy_cq:
-+ nvme_destroy_cq(cq);
-+err:
-+ return -1;
-+}
-+
-+/* Returns 0 on success. */
-+static int
-+nvme_create_io_sq(struct nvme_ctrl *ctrl, struct nvme_sq *sq, grub_uint16_t q_idx, struct nvme_cq *cq)
-+{
-+ int rc;
-+ struct nvme_sqe *cmd_create_sq;
-+ grub_uint32_t length = 1 + (ctrl->reg->cap & 0xffff);
-+ if (length > NVME_PAGE_SIZE / sizeof(struct nvme_cqe))
-+ length = NVME_PAGE_SIZE / sizeof(struct nvme_cqe);
-+
-+ rc = nvme_init_sq(ctrl, sq, q_idx, length, cq);
-+ if (rc) {
-+ goto err;
-+ }
-+
-+ cmd_create_sq = nvme_get_next_sqe(&ctrl->admin_sq,
-+ NVME_SQE_OPC_ADMIN_CREATE_IO_SQ, NULL,
-+ sq->sqe, NULL);
-+ if (!cmd_create_sq) {
-+ goto err_destroy_sq;
-+ }
-+
-+ cmd_create_sq->dword[10] = (sq->common.mask << 16) | (q_idx >> 1);
-+ cmd_create_sq->dword[11] = (q_idx >> 1) << 16 | 1 /* contiguous */;
-+ grub_dprintf("nvme", "sq %p create dword10 %08x dword11 %08x\n", sq,
-+ cmd_create_sq->dword[10], cmd_create_sq->dword[11]);
-+
-+ nvme_commit_sqe(&ctrl->admin_sq);
-+
-+ struct nvme_cqe cqe = nvme_wait(&ctrl->admin_sq);
-+
-+ if (!nvme_is_cqe_success(&cqe)) {
-+ grub_dprintf("nvme", "create io sq failed: %08x %08x %08x %08x\n",
-+ cqe.dword[0], cqe.dword[1], cqe.dword[2], cqe.dword[3]);
-+ goto err_destroy_sq;
-+ }
-+
-+ return 0;
-+
-+err_destroy_sq:
-+ nvme_destroy_sq(sq);
-+err:
-+ return -1;
-+}
-+
-+/* Reads count sectors into buf. The buffer cannot cross page boundaries. */
-+static int
-+nvme_io_xfer(struct nvme_namespace *ns, grub_uint64_t lba, void *prp1, void *prp2,
-+ grub_uint16_t count, int write)
-+{
-+ if (((grub_uint32_t)prp1 & 0x3) || ((grub_uint32_t)prp2 & 0x3)) {
-+ /* Buffer is misaligned */
-+ return -1;
-+ }
-+
-+ struct nvme_sqe *io_read = nvme_get_next_sqe(&ns->ctrl->io_sq,
-+ write ? NVME_SQE_OPC_IO_WRITE
-+ : NVME_SQE_OPC_IO_READ,
-+ NULL, prp1, prp2);
-+ io_read->nsid = ns->ns_id;
-+ io_read->dword[10] = (grub_uint32_t)lba;
-+ io_read->dword[11] = (grub_uint32_t)(lba >> 32);
-+ io_read->dword[12] = (1U << 31 /* limited retry */) | (count - 1);
-+
-+ nvme_commit_sqe(&ns->ctrl->io_sq);
-+
-+ struct nvme_cqe cqe = nvme_wait(&ns->ctrl->io_sq);
-+
-+ if (!nvme_is_cqe_success(&cqe)) {
-+ grub_dprintf("nvme", "read io: %08x %08x %08x %08x\n",
-+ cqe.dword[0], cqe.dword[1], cqe.dword[2], cqe.dword[3]);
-+
-+ return -1;
-+ }
-+
-+ grub_dprintf("nvme", "ns %u %s lba %llu+%u\n", ns->ns_id, write ? "write" : "read",
-+ lba, count);
-+ return count;
-+}
-+
-+// Transfer up to one page of data using the internal dma bounce buffer
-+static int
-+nvme_bounce_xfer(struct nvme_namespace *ns, grub_uint64_t lba, void *buf, grub_uint16_t count,
-+ int write)
-+{
-+ grub_uint16_t const max_blocks = NVME_PAGE_SIZE / ns->block_size;
-+ grub_uint16_t blocks = count < max_blocks ? count : max_blocks;
-+
-+ if (write)
-+ grub_memcpy(nvme_dma_buffer, buf, blocks * ns->block_size);
-+
-+ int res = nvme_io_xfer(ns, lba, nvme_dma_buffer, NULL, blocks, write);
-+
-+ if (!write && res >= 0)
-+ grub_memcpy(buf, nvme_dma_buffer, res * ns->block_size);
-+
-+ return res;
-+}
-+
-+#define NVME_MAX_PRPL_ENTRIES 15 /* Allows requests up to 64kb */
-+
-+// Transfer data using page list (if applicable)
-+static int
-+nvme_prpl_xfer(struct nvme_namespace *ns, grub_uint64_t lba, void *buf, grub_uint16_t count,
-+ int write)
-+{
-+ grub_uint32_t base = (long)buf;
-+ grub_int32_t size;
-+
-+ if (count > ns->max_req_size)
-+ count = ns->max_req_size;
-+
-+ size = count * ns->block_size;
-+ /* Special case for transfers that fit into PRP1, but are unaligned */
-+ if (((size + (base & ~NVME_PAGE_MASK)) <= NVME_PAGE_SIZE))
-+ goto single;
-+
-+ /* Every request has to be page aligned */
-+ if (base & ~NVME_PAGE_MASK)
-+ goto bounce;
-+
-+ /* Make sure a full block fits into the last chunk */
-+ if (size & (ns->block_size - 1ULL))
-+ goto bounce;
-+
-+ /* Build PRP list if we need to describe more than 2 pages */
-+ if ((ns->block_size * count) > (NVME_PAGE_SIZE * 2)) {
-+ grub_uint32_t prpl_len = 0;
-+ grub_uint64_t *prpl = nvme_dma_buffer;
-+ int first_page = 1;
-+ for (; size > 0; base += NVME_PAGE_SIZE, size -= NVME_PAGE_SIZE) {
-+ if (first_page) {
-+ /* First page is special */
-+ first_page = 0;
-+ continue;
-+ }
-+ if (prpl_len >= NVME_MAX_PRPL_ENTRIES)
-+ goto bounce;
-+ prpl[prpl_len++] = base;
-+ }
-+ return nvme_io_xfer(ns, lba, buf, prpl, count, write);
-+ }
-+
-+ /* Directly embed the 2nd page if we only need 2 pages */
-+ if ((ns->block_size * count) > NVME_PAGE_SIZE)
-+ return nvme_io_xfer(ns, lba, buf, (char *) buf + NVME_PAGE_SIZE, count, write);
-+
-+single:
-+ /* One page is enough, don't expose anything else */
-+ return nvme_io_xfer(ns, lba, buf, NULL, count, write);
-+
-+bounce:
-+ /* Use bounce buffer to make transfer */
-+ return nvme_bounce_xfer(ns, lba, buf, count, write);
-+}
-+
-+static int
-+nvme_create_io_queues(struct nvme_ctrl *ctrl)
-+{
-+ if (nvme_create_io_cq(ctrl, &ctrl->io_cq, 3))
-+ goto err;
-+
-+ if (nvme_create_io_sq(ctrl, &ctrl->io_sq, 2, &ctrl->io_cq))
-+ goto err_free_cq;
-+
-+ return 0;
-+
-+ err_free_cq:
-+ nvme_destroy_cq(&ctrl->io_cq);
-+ err:
-+ return -1;
-+}
-+
-+/* Waits for CSTS.RDY to match rdy. Returns 0 on success. */
-+static int
-+nvme_wait_csts_rdy(struct nvme_ctrl *ctrl, unsigned rdy)
-+{
-+ // grub_uint32_t const max_to = 500 /* ms */ * ((ctrl->reg->cap >> 24) & 0xFFU);
-+ // grub_uint32_t to = timer_calc(max_to);
-+ grub_uint32_t csts;
-+
-+ while (rdy != ((csts = ctrl->reg->csts) & NVME_CSTS_RDY)) {
-+ // FIXME
-+ //yield();
-+
-+ if (csts & NVME_CSTS_FATAL) {
-+ grub_dprintf("nvme", "NVMe fatal error during controller shutdown\n");
-+ return -1;
-+ }
-+
-+ /*
-+ if (timer_check(to)) {
-+ warn_timeout();
-+ return -1;
-+ }*/
-+ }
-+
-+ return 0;
-+}
-+
-+/* Returns 0 on success. */
-+static int grub_nvme_controller_enable(struct nvme_ctrl *ctrl)
-+{
-+ grub_pci_address_t addr;
-+ int rc;
-+
-+ addr = grub_pci_make_address (ctrl->pci, GRUB_PCI_REG_COMMAND);
-+ grub_pci_write_word (addr, grub_pci_read_word (addr) | GRUB_PCI_COMMAND_BUS_MASTER);
-+
-+ /* Turn the controller off. */
-+ ctrl->reg->cc = 0;
-+ if (nvme_wait_csts_rdy(ctrl, 0)) {
-+ grub_dprintf("nvme", "NVMe fatal error during controller shutdown\n");
-+ return -1;
-+ }
-+
-+ ctrl->doorbell_stride = 4U << ((ctrl->reg->cap >> 32) & 0xF);
-+
-+ rc = nvme_init_cq(ctrl, &ctrl->admin_cq, 1,
-+ NVME_PAGE_SIZE / sizeof(struct nvme_cqe));
-+ if (rc) {
-+ return -1;
-+ }
-+
-+ rc = nvme_init_sq(ctrl, &ctrl->admin_sq, 0,
-+ NVME_PAGE_SIZE / sizeof(struct nvme_sqe), &ctrl->admin_cq);
-+ if (rc) {
-+ goto err_destroy_admin_cq;
-+ }
-+
-+ ctrl->reg->aqa = ctrl->admin_cq.common.mask << 16
-+ | ctrl->admin_sq.common.mask;
-+
-+ ctrl->reg->asq = (grub_uint32_t)ctrl->admin_sq.sqe;
-+ ctrl->reg->acq = (grub_uint32_t)ctrl->admin_cq.cqe;
-+
-+ grub_dprintf("nvme", " admin submission queue: %p\n", ctrl->admin_sq.sqe);
-+ grub_dprintf("nvme", " admin completion queue: %p\n", ctrl->admin_cq.cqe);
-+
-+ ctrl->reg->cc = NVME_CC_EN | (NVME_CQE_SIZE_LOG << 20)
-+ | (NVME_SQE_SIZE_LOG << 16 /* IOSQES */);
-+
-+ if (nvme_wait_csts_rdy(ctrl, 1)) {
-+ grub_dprintf("nvme", "NVMe fatal error while enabling controller\n");
-+ goto err_destroy_admin_sq;
-+ }
-+
-+ /* The admin queue is set up and the controller is ready. Let's figure out
-+ what namespaces we have. */
-+
-+ struct nvme_identify_ctrl *identify = nvme_admin_identify_ctrl(ctrl);
-+
-+ if (!identify) {
-+ grub_dprintf("nvme", "NVMe couldn't identify controller.\n");
-+ goto err_destroy_admin_sq;
-+ }
-+
-+ grub_dprintf("nvme", "NVMe has %u namespace%s.\n",
-+ identify->nn, (identify->nn == 1) ? "" : "s");
-+
-+ ctrl->ns_count = identify->nn;
-+ grub_uint8_t mdts = identify->mdts;
-+ grub_free(identify);
-+
-+ if ((ctrl->ns_count == 0) || nvme_create_io_queues(ctrl)) {
-+ /* No point to continue, if the controller says it doesn't have
-+ namespaces or we couldn't create I/O queues. */
-+ goto err_destroy_admin_sq;
-+ }
-+
-+ /* Give the controller a global number */
-+ ctrl->ctrlnum = grub_nvme_ctrlcnt++;
-+
-+ /* Populate namespace IDs */
-+ for (grub_uint32_t ns_idx = 0; ns_idx < ctrl->ns_count; ns_idx++) {
-+ nvme_probe_ns(ctrl, ns_idx, mdts);
-+ }
-+
-+ grub_dprintf("nvme", "NVMe initialization complete!\n");
-+ return 0;
-+
-+ err_destroy_admin_sq:
-+ nvme_destroy_sq(&ctrl->admin_sq);
-+ err_destroy_admin_cq:
-+ nvme_destroy_cq(&ctrl->admin_cq);
-+ return -1;
-+}
-+
-+static int grub_nvme_pci_probe(grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)), void *data __attribute__ ((unused)))
-+{
-+ grub_pci_address_t addr;
-+ grub_uint32_t class, bar, version;
-+ struct nvme_reg volatile *reg;
-+
-+ class = grub_pci_read (grub_pci_make_address (dev, GRUB_PCI_REG_CLASS));
-+ if (class >> 16 != 0x0108)
-+ return 0;
-+ if ((class >> 8 & 0xff) != 2) { /* as of NVM 1.0e */
-+ grub_dprintf("nvme", "Found incompatble NVMe: prog-if=%02x\n", class >> 8 & 0xff);
-+ return 0;
-+ }
-+
-+ bar = grub_pci_read (grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0));
-+ reg = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK, sizeof (*reg));
-+
-+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
-+ grub_pci_write_word (addr, grub_pci_read_word (addr) | GRUB_PCI_COMMAND_MEM_ENABLED);
-+
-+ version = reg->vs;
-+ grub_dprintf("nvme", "Found NVMe controller with version %u.%u.%u.\n", version >> 16, (version >> 8) & 0xFF, version & 0xFF);
-+ grub_dprintf("nvme", " Capabilities %016llx\n", reg->cap);
-+
-+ if (~reg->cap & NVME_CAP_CSS_NVME) {
-+ grub_dprintf("nvme", "Controller doesn't speak NVMe command set. Skipping.\n");
-+ goto err;
-+ }
-+
-+ struct nvme_ctrl *ctrl = grub_malloc(sizeof(*ctrl));
-+ if (!ctrl)
-+ goto err;
-+
-+ grub_memset(ctrl, 0, sizeof(*ctrl));
-+
-+ ctrl->reg = reg;
-+ ctrl->pci = dev;
-+
-+ if (grub_nvme_controller_enable(ctrl))
-+ goto err_free_ctrl;
-+
-+ return 0;
-+
-+ err_free_ctrl:
-+ grub_free(ctrl);
-+ err:
-+ grub_dprintf("nvme", "Failed to enable NVMe controller.\n");
-+ return 0;
-+}
-+
-+static int
-+grub_nvme_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, grub_disk_pull_t pull)
-+{
-+ struct nvme_namespace *ns;
-+
-+ if (pull != GRUB_DISK_PULL_NONE)
-+ return 0;
-+
-+ FOR_LIST_ELEMENTS(ns, grub_nvme_namespaces)
-+ if (hook (ns->devname, hook_data))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static grub_err_t
-+grub_nvme_open (const char *name __attribute ((unused)), grub_disk_t disk __attribute ((unused)))
-+{
-+ struct nvme_namespace *ns;
-+
-+ FOR_LIST_ELEMENTS(ns, grub_nvme_namespaces)
-+ if (grub_strcmp (ns->devname, name) == 0)
-+ break;
-+
-+ if (! ns)
-+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
-+
-+ disk->total_sectors = ns->lba_count;
-+ disk->max_agglomerate = ns->max_req_size;
-+
-+ disk->id = ns->nsnum; /* global id of the namespace */
-+
-+ disk->data = ns;
-+
-+ return 0;
-+}
-+
-+static grub_err_t
-+nvme_readwrite(struct nvme_namespace *ns, grub_disk_addr_t sector, grub_size_t num_sectors, char *buf, int write)
-+{
-+ for (int i = 0; i < num_sectors;) {
-+ grub_uint16_t blocks_remaining = num_sectors - i;
-+ char *op_buf = buf + i * ns->block_size;
-+ int blocks = nvme_prpl_xfer(ns, sector + i, op_buf, blocks_remaining, write);
-+ if (blocks < 0)
-+ return GRUB_ERR_IO;
-+ i += blocks;
-+ }
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_nvme_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t num_sectors, char *buf)
-+{
-+ return nvme_readwrite((struct nvme_namespace *) disk->data, sector, num_sectors, buf, 0);
-+}
-+
-+static grub_err_t
-+grub_nvme_write (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t num_sectors, const char *buf)
-+{
-+ return nvme_readwrite((struct nvme_namespace *) disk->data, sector, num_sectors, buf, 1);
-+}
-+
-+static struct grub_disk_dev grub_nvme_dev =
-+ {
-+ .name = "nvme",
-+ .id = GRUB_DISK_DEVICE_NVME_ID,
-+ .disk_iterate = grub_nvme_iterate,
-+ .disk_open = grub_nvme_open,
-+ .disk_read = grub_nvme_read,
-+ .disk_write = grub_nvme_write,
-+ .next = 0
-+ };
-+
-+GRUB_MOD_INIT(nvme)
-+{
-+ grub_stop_disk_firmware ();
-+ grub_pci_iterate (grub_nvme_pci_probe, NULL);
-+ grub_disk_dev_register (&grub_nvme_dev);
-+}
-+
-+GRUB_MOD_FINI(nvme)
-+{
-+ grub_disk_dev_unregister (&grub_nvme_dev);
-+}
-diff --git a/include/grub/disk.h b/include/grub/disk.h
-index fbf23df7f..186e76f0b 100644
---- a/include/grub/disk.h
-+++ b/include/grub/disk.h
-@@ -52,6 +52,7 @@ enum grub_disk_dev_id
- GRUB_DISK_DEVICE_UBOOTDISK_ID,
- GRUB_DISK_DEVICE_XEN,
- GRUB_DISK_DEVICE_OBDISK_ID,
-+ GRUB_DISK_DEVICE_NVME_ID
- };
-
- struct grub_disk;
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0009-kern-coreboot-mmap-Map-to-reserved.patch b/config/grub/nvme/patches/0009-kern-coreboot-mmap-Map-to-reserved.patch
deleted file mode 100644
index 11b82429..00000000
--- a/config/grub/nvme/patches/0009-kern-coreboot-mmap-Map-to-reserved.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 9ec8534a4d27db37cf4feebd44fd9f8973a89e59 Mon Sep 17 00:00:00 2001
-From: Paul Menzel <pmenzel@molgen.mpg.de>
-Date: Mon, 17 May 2021 10:24:36 +0200
-Subject: [PATCH 09/10] kern/coreboot/mmap: Map to reserved
-
-https://git.savannah.gnu.org/cgit/grub.git/commit/?id=6de9ee86bf9ae50967413e6a73b5dfd13e5ffb50
-
-Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
----
- grub-core/kern/coreboot/mmap.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/kern/coreboot/mmap.c b/grub-core/kern/coreboot/mmap.c
-index caf8f7cef..2fc316e8d 100644
---- a/grub-core/kern/coreboot/mmap.c
-+++ b/grub-core/kern/coreboot/mmap.c
-@@ -59,7 +59,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
- /* Multiboot mmaps match with the coreboot mmap
- definition. Therefore, we can just pass type
- through. */
-- mem_region->type,
-+ (mem_region->type >= 13) ? 2 : mem_region->type,
- ctx->hook_data))
- return 1;
- if (start < 0xa0000)
-@@ -81,7 +81,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
- /* Multiboot mmaps match with the coreboot mmap
- definition. Therefore, we can just pass type
- through. */
-- mem_region->type,
-+ (mem_region->type >= 13) ? 2 : mem_region->type,
- ctx->hook_data))
- return 1;
- }
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0010-Revert-configure-Check-linker-for-image-base-support.patch b/config/grub/nvme/patches/0010-Revert-configure-Check-linker-for-image-base-support.patch
deleted file mode 100644
index 8e78e8b7..00000000
--- a/config/grub/nvme/patches/0010-Revert-configure-Check-linker-for-image-base-support.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From 7b0d621389fc1857c918058f82093f9630ea7730 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Wed, 24 Dec 2025 01:42:17 +0100
-Subject: [PATCH 10/10] Revert "configure: Check linker for --image-base
- support"
-
-This reverts commit 1a5417f39a0ccefcdd5440f2a67f84d2d2e26960.
----
- acinclude.m4 | 5 -----
- configure.ac | 14 ++------------
- 2 files changed, 2 insertions(+), 17 deletions(-)
-
-diff --git a/acinclude.m4 b/acinclude.m4
-index 70c1912f8..fa7840f09 100644
---- a/acinclude.m4
-+++ b/acinclude.m4
-@@ -79,11 +79,6 @@ AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
- [AC_MSG_CHECKING([whether ${TARGET_OBJCOPY} works for absolute addresses])
- AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
- [cat > conftest.c <<\EOF
--asm (
-- ".globl start, _start, __start\n"
-- ".ifdef cmain; .set start = _start = __start = cmain\n.endif\n"
-- ".ifdef _cmain; .set start = _start = __start = _cmain\n.endif\n"
--);
- void cmain (void);
- void
- cmain (void)
-diff --git a/configure.ac b/configure.ac
-index d8ca1b7c1..041cfbab4 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1461,6 +1461,7 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
- TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc"
- TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
- TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc"
-+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
- TARGET_IMG_CFLAGS=
- else
- TARGET_APPLE_LINKER=0
-@@ -1468,6 +1469,7 @@ else
- TARGET_IMG_LDSCRIPT=
- TARGET_IMG_LDFLAGS='-Wl,-N'
- TARGET_IMG_LDFLAGS_AC='-Wl,-N'
-+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
- TARGET_IMG_CFLAGS=
- fi
-
-@@ -1798,18 +1800,6 @@ grub_PROG_TARGET_CC
- m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
-
- if test "x$TARGET_APPLE_LINKER" != x1 ; then
--AX_CHECK_LINK_FLAG([-Wl,--image-base,0x400000],
-- [TARGET_IMG_BASE_LDOPT="-Wl,--image-base"],
-- [TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"],
-- [],
-- [AC_LANG_SOURCE([
--asm (".globl start; start:");
--asm (".globl _start; _start:");
--asm (".globl __start; __start:");
--void __main (void);
--void __main (void) {}
--int main (void);
-- ])])
- grub_PROG_OBJCOPY_ABSOLUTE
- fi
- grub_PROG_LD_BUILD_ID_NONE
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0011-Revert-configure-Print-a-more-helpful-error-if-autoc.patch b/config/grub/nvme/patches/0011-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
deleted file mode 100644
index c0a504ff..00000000
--- a/config/grub/nvme/patches/0011-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From abf2bf6e2973ccaa994f63ff851ba11cbd45f1eb Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Mon, 19 Jan 2026 15:27:23 +0000
-Subject: [PATCH 1/1] Revert "configure: Print a more helpful error if
- autoconf-archive is not installed"
-
-This reverts commit ac042f3f58d33ce9cd5ff61750f06da1a1d7b0eb.
----
- configure.ac | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 041cfbab4..209c0fb11 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1794,11 +1794,6 @@ LIBS=""
- # Defined in acinclude.m4.
- grub_ASM_USCORE
- grub_PROG_TARGET_CC
--
--# The error message produced by autoconf if autoconf-archive is not installed is
--# quite misleading and not very helpful. So, try point people in the right direction.
--m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
--
- if test "x$TARGET_APPLE_LINKER" != x1 ; then
- grub_PROG_OBJCOPY_ABSOLUTE
- fi
---
-2.47.3
-
diff --git a/config/grub/nvme/patches/0012-bootstrap-Don-t-download-po-files.patch b/config/grub/nvme/patches/0012-bootstrap-Don-t-download-po-files.patch
deleted file mode 100644
index cfb66047..00000000
--- a/config/grub/nvme/patches/0012-bootstrap-Don-t-download-po-files.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 5d18c96a22d98d137ea40bfc6aabadce933c2d45 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 1 Feb 2026 20:30:55 +0100
-Subject: [PATCH 1/1] bootstrap: Don't download po files
-
-GRUB doesn't verify checksums at all, and it pulls from
-this URL recursively:
-
-https://translationproject.org/latest/grub/
-
-These files can change at any time, and GRUB is just
-downloading them trustingly. Even if the upstream is
-totally benevolent, what if they got hacked?
-
-I downloaded them, hashed them and decided to mirror
-them on my RSYNC mirror. In this way, Libreboot can now
-use them in a deterministic fashion.
-
-Simply adding them to the GRUB source code would mean
-patching GRUB, which would add 8MB to lbmk. I won't do
-it.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- bootstrap | 31 +++++++++++++------------------
- 1 file changed, 13 insertions(+), 18 deletions(-)
-
-diff --git a/bootstrap b/bootstrap
-index dc9fb4383..9fc5a5c36 100755
---- a/bootstrap
-+++ b/bootstrap
-@@ -1,5 +1,16 @@
- #! /bin/sh
--# DO NOT EDIT! GENERATED AUTOMATICALLY!
-+# THIS FILE WAS EDITED BY LIBREBOOT TO REMOVE
-+# HACKY GRUB BEHAVIOUR; po files now downloaded
-+# by lbmk, via config/submodule/grub/ - so that
-+# versioned files are possible, with proper checksum
-+# verification, and mirrors are used.
-+
-+# Yes. This file has been modified. I intend to
-+# eventually remove this hacky script. Probably
-+# replace the entire GRUB build system.
-+
-+# Please do fix/edit or (when possible) remove
-+# this file. Thank you.
-
- # Bootstrap this package from checked-out sources.
-
-@@ -145,13 +156,6 @@ bootstrap_post_import_hook() { :; }
- # Override it via your own definition in bootstrap.conf.
- bootstrap_epilogue() { :; }
-
--# The command to download all .po files for a specified domain into a
--# specified directory. Fill in the first %s with the destination
--# directory and the second with the domain name.
--po_download_command_format=\
--"wget --mirror --level=1 -nd -nv -A.po -P '%s' \
-- https://translationproject.org/latest/%s/"
--
- # When extracting the package name from an AC_INIT invocation,
- # prefer a non-empty tarname (4th argument of AC_INIT if given), else
- # fall back to the package name (1st argument with munging).
-@@ -909,14 +913,6 @@ autopull()
-
- # ----------------------------- Get translations. -----------------------------
-
--download_po_files() {
-- subdir=$1
-- domain=$2
-- echo "$me: getting translations into $subdir for $domain..."
-- cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
-- eval "$cmd"
--}
--
- # Mirror .po files to $po_dir/.reference and copy only the new
- # or modified ones into $po_dir. Also update $po_dir/LINGUAS.
- # Note po files that exist locally only are left in $po_dir but will
-@@ -932,8 +928,7 @@ update_po_files() {
- ref_po_dir="$po_dir/.reference"
-
- test -d $ref_po_dir || mkdir $ref_po_dir || return
-- download_po_files $ref_po_dir $domain \
-- && ls "$ref_po_dir"/*.po 2>/dev/null |
-+ ls "$ref_po_dir"/*.po 2>/dev/null |
- sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
-
- for po in x $(ls $ref_po_dir | sed -n 's/\.po$//p'); do
---
-2.47.3
-
diff --git a/config/grub/nvme/target.cfg b/config/grub/nvme/target.cfg
deleted file mode 100644
index e2a67cc0..00000000
--- a/config/grub/nvme/target.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-tree="nvme"
-rev="eaa3b8f0f90605a82c6bfda4c5c4b73c58eb81ac"
diff --git a/config/grub/xhci_nvme/config/payload b/config/grub/xhci_nvme/config/payload
deleted file mode 100644
index 9db22fe2..00000000
--- a/config/grub/xhci_nvme/config/payload
+++ /dev/null
@@ -1,321 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-# Copyright (C) 2014-2016,2020-2021,2023-2025 Leah Rowe <leah@libreboot.org>
-# Copyright (C) 2015 Klemens Nanni <contact@autoboot.org>
-
-set prefix=(memdisk)/boot/grub
-
-insmod at_keyboard
-insmod usb_keyboard
-insmod nativedisk
-insmod xhci
-insmod ehci
-insmod ohci
-insmod uhci
-insmod usb
-insmod usbms
-insmod regexp
-
-terminal_input --append at_keyboard
-terminal_input --append usb_keyboard
-terminal_output --append cbmemc
-
-# User interface overrides wherever "keystatus" is supported
-# Keep SHIFT key pressed before powering on to disable graphics
-if keystatus --shift; then
- terminal_output --append vga_text
-else
- gfxpayload=keep
- terminal_output --append gfxterm
-
- for dt in cbfsdisk memdisk; do
- for it in png jpg; do
- if [ -f (${dt})/background.${it} ]; then
- insmod ${it}
- background_image (${dt})/background.${it}
- fi
- done
- done
-fi
-
-# Keep CTRL pressed to enable default serial terminal (COM1 or the like)
-if keystatus --ctrl; then
- serial
- terminal_input --append serial
- terminal_output --append serial
-fi
-
-# Keep ALT pressed to enable spkmodem
-if keystatus --alt; then
- terminal_output --append spkmodem
-fi
-
-
-set default="0"
-if [ -f (cbfsdisk)/timeout.cfg ]; then
- source (cbfsdisk)/timeout.cfg
-else
- set timeout=8
-fi
-set grub_scan_disk="nvme ahci ata"
-if [ -f (cbfsdisk)/scan.cfg ]; then
- source (cbfsdisk)/scan.cfg
-fi
-
-if [ -f (cbfsdisk)/keymap.gkb ]; then
- keymap (cbfsdisk)/keymap.gkb
-fi
-
-function really_try_user_config {
- set root="${1}"
-
- if [ -f /"${2}"/grub.cfg ]; then
- unset superusers
- configfile /"${2}"/grub.cfg
- fi
-}
-
-function try_user_config {
- # The @/... entries are for cases where the BTRFS filesystem is being used
- for dir in grub boot/grub @/grub @/boot/grub grub2 boot/grub2 @/grub2 @/boot/grub2 boot @/boot; do
- really_try_user_config "${1}" "${dir}"
- done
- for dir in ubuntu debian redhat; do
- really_try_user_config "${1}" "EFI/${dir}"
- done
-}
-function search_grub {
- echo -n "Attempting to load grub.cfg from '${1}' devices"
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${1}" != "nvme" ]; then
- try_user_config "(${1}${i},${part})"
- else
- # TODO: do we care about other namesapces
- try_user_config "(nvme${i}n1,${part})"
- fi
- done
- if [ "${1}" != "nvme" ]; then
- # raw devices e.g. (ahci0) instead of (ahci0,1)
- try_user_config "(${1}${i})"
- else
- # TODO: do we care about other namesapces
- try_user_config "(nvme${i}n1)"
- fi
- done
- echo # Insert newline
-}
-
-function try_isolinux_config {
- set root="${1}"
- for dir in '' /boot /EFI /@ /@/boot; do
- if [ -f "${dir}"/isolinux/isolinux.cfg ]; then
- syslinux_configfile -i "${dir}"/isolinux/isolinux.cfg
- elif [ -f "${dir}"/syslinux/syslinux.cfg ]; then
- syslinux_configfile -s "${dir}"/syslinux/syslinux.cfg
- elif [ -f "${dir}"/syslinux/extlinux.conf ]; then
- syslinux_configfile -s "${dir}"/syslinux/extlinux.conf
- elif [ -f "${dir}"/extlinux/extlinux.conf ]; then
- syslinux_configfile -s "${dir}"/extlinux/extlinux.conf
- fi
- done
-}
-function search_isolinux {
- echo "\nAttempting to parse iso/sys/extlinux config from '${1}' devices"
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${1}" != "nvme" ]; then
- try_isolinux_config "(${1}${i},${part})"
- else
- # TODO: see above
- try_isolinux_config "(nvme${i}n1,${part})"
- fi
- done
- if [ "${1}" != "nvme" ]; then
- # raw devices e.g. (usb0) instead of (usb0,1)
- try_isolinux_config "(${1}${i})"
- else
- # TODO: do we care about other namesapces
- try_isolinux_config "(nvme${i}n1)"
- fi
- done
- echo # Insert newline
-}
-function try_bootcfg {
- try_user_config "${1}"
- try_isolinux_config "${1}"
-}
-function search_bootcfg {
- search_grub "${1}"
- search_isolinux "${1}"
-}
-menuentry 'Load Operating System (incl. fully encrypted disks) [o]' --hotkey='o' {
-
- for grub_disk in ${grub_scan_disk}; do
- search_bootcfg ${grub_disk}
- done
-
- # grub device enumeration is very slow, so checks are hardcoded
-
- raidvol="md/0 md/1 md/2 md/3 md/4 md/5 md/6 md/7 md/8 md/9"
-
- # in practise, doing multiple redundant checks is perfectly fast
- # TODO: optimize grub itself, and use */? here for everything
-
- for vol in ${raidvol} ; do
- try_bootcfg "${vol}"
- done
-
- unset bootdev
- for grub_disk in ${grub_scan_disk}; do
- for i in 0 1 2 3 4 5 6 7 8; do
- for part in 1 2 3 4 5 6 7 8 9 10 11 12; do
- if [ "${grub_disk}" = "ahci" ]; then
- bootdev="${bootdev} (ahci${i},${part})"
- elif [ "${grub_disk}" = "ata" ]; then
- bootdev="${bootdev} (ata${i},${part})"
- elif [ "${grub_disk}" = "nvme" ]; then
- # TODO: do we care about other namesapces
- bootdev="${bootdev} (nvme${i}n1,${part})"
- fi
- done
- done
- done
-
- set pager=0
- echo -n "Attempting to unlock encrypted volumes"
- for dev in ${bootdev} ${raidvol}; do
- if cryptomount "${dev}" ; then break ; fi
- done
- set pager=1
- echo
-
- search_bootcfg crypto
-
- lvmvol=""
-
- # after cryptomount, lvm volumes might be available
- # using * is slow on some machines, but we use it here,
- # just once. in so doing, we find every lvm volume
- for vol in (*); do
- if regexp ^\\(lvm/ $vol; then
- lvmvol="${lvmvol} ${vol}"
- try_bootcfg "${vol}"
- fi
- done
-
- # user might have put luks inside lvm
- set pager=0
- echo "Attempting to unlock encrypted LVMs"
- for vol in ${lvmvol}; do
- cryptomount "$vol"
- done
- set pager=1
- echo
-
- search_bootcfg crypto
-
- true # Prevent pager requiring to accept each line instead of whole screen
-}
-
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on USB [s]' --hotkey='s' {
- search_bootcfg usb
-}
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on AHCI [a]' --hotkey='a' {
- search_bootcfg ahci
-}
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on ATA/IDE [d]' --hotkey='d' {
- search_bootcfg ata
-}
-menuentry 'Search for GRUB/SYSLINUX/EXTLINUX/ISOLINUX on NVMe [e]' --hotkey='e' {
- search_bootcfg nvme
-}
-if [ -f (cbfsdisk)/grub.cfg ]; then
-menuentry 'Load configuration (grub.cfg) in CBFS [t]' --hotkey='t' {
- set root='(cbfsdisk)'
- if [ -f /grub.cfg ]; then
- configfile /grub.cfg
- fi
-}
-fi
-if [ -f (cbfsdisk)/grubtest.cfg ]; then
-menuentry 'Load test configuration (grubtest.cfg) in CBFS [t]' --hotkey='t' {
- set root='(cbfsdisk)'
- if [ -f /grubtest.cfg ]; then
- configfile /grubtest.cfg
- fi
-}
-fi
-if [ -f (cbfsdisk)/u-boot ]; then
-menuentry 'U-Boot i386 payload (experimental) [u]' --hotkey='u' {
- set root='cbfsdisk'
- chainloader /u-boot
-}
-fi
-if [ -f (cbfsdisk)/seabios.elf ]; then
-if [ -f (cbfsdisk)/img/u-boot ]; then
-menuentry 'Load SeaBIOS (U-Boot UEFI available in the ESC menu) [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /seabios.elf
-}
-else
-menuentry 'Load SeaBIOS [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /seabios.elf
-}
-fi
-fi
-if [ -f (cbfsdisk)/img/grub2 ]; then
-if [ -f (cbfsdisk)/img/u-boot ]; then
-menuentry 'Return to SeaBIOS (U-Boot UEFI available in the ESC menu) [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /fallback/payload
-}
-else
-menuentry 'Return to SeaBIOS [b]' --hotkey='b' {
- set root='cbfsdisk'
- chainloader /fallback/payload
-}
-fi
-fi
-menuentry 'Poweroff [p]' --hotkey='p' {
- halt
-}
-menuentry 'Reboot [r]' --hotkey='r' {
- reboot
-}
-if [ -f (cbfsdisk)/img/memtest ]; then
-menuentry 'Load MemTest86+ [m]' --hotkey='m' {
- set root='cbfsdisk'
- chainloader /img/memtest
-}
-fi
-
-submenu 'Other [z]' --hotkey='z' {
- menuentry 'Enable default serial terminal [s]' --hotkey='s' {
- serial
- terminal_input --append serial
- terminal_output --append serial
- }
-
- menuentry 'Disable default serial terminal' {
- terminal_input --remove serial
- terminal_output --remove serial
- }
-
- menuentry 'Enable gfxterm' {
- terminal_output --append gfxterm
- terminal_output --remove vga_text
- }
- menuentry 'Disable gfxterm [g]' --hotkey='g' {
- terminal_output --remove gfxterm
- terminal_output --append vga_text
- }
-
- menuentry 'Enable spkmodem [a]' --hotkey='a' {
- terminal_output --append spkmodem
- }
-
- menuentry 'Disable spkmodem [z]' --hotkey='z' {
- terminal_output --remove spkmodem
- }
-}
diff --git a/config/grub/xhci_nvme/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch b/config/grub/xhci_nvme/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch
deleted file mode 100644
index 7f489819..00000000
--- a/config/grub/xhci_nvme/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From 8ce8095abbbcc69b50466cb2b890a59be5a9baed Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 31 Oct 2021 03:47:05 +0000
-Subject: [PATCH 01/21] mitigate grub's missing characters for borders/arrow
- characters
-
-This cleans up the display on the main screen in GRUB.
-
-Just don't draw a border, at all.
----
- grub-core/normal/menu_text.c | 49 ++----------------------------------
- 1 file changed, 2 insertions(+), 47 deletions(-)
-
-diff --git a/grub-core/normal/menu_text.c b/grub-core/normal/menu_text.c
-index 9c383e64a..8ec1dd1e8 100644
---- a/grub-core/normal/menu_text.c
-+++ b/grub-core/normal/menu_text.c
-@@ -108,47 +108,6 @@ grub_print_message_indented (const char *msg, int margin_left, int margin_right,
- grub_print_message_indented_real (msg, margin_left, margin_right, term, 0);
- }
-
--static void
--draw_border (struct grub_term_output *term, const struct grub_term_screen_geometry *geo)
--{
-- int i;
--
-- grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
--
-- grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y - 1 });
-- grub_putcode (GRUB_UNICODE_CORNER_UL, term);
-- for (i = 0; i < geo->entry_width + 1; i++)
-- grub_putcode (GRUB_UNICODE_HLINE, term);
-- grub_putcode (GRUB_UNICODE_CORNER_UR, term);
--
-- for (i = 0; i < geo->num_entries; i++)
-- {
-- grub_term_gotoxy (term, (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y + i });
-- grub_putcode (GRUB_UNICODE_VLINE, term);
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x + geo->entry_width + 1,
-- geo->first_entry_y + i });
-- grub_putcode (GRUB_UNICODE_VLINE, term);
-- }
--
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- geo->first_entry_y - 1 + geo->num_entries + 1 });
-- grub_putcode (GRUB_UNICODE_CORNER_LL, term);
-- for (i = 0; i < geo->entry_width + 1; i++)
-- grub_putcode (GRUB_UNICODE_HLINE, term);
-- grub_putcode (GRUB_UNICODE_CORNER_LR, term);
--
-- grub_term_setcolorstate (term, GRUB_TERM_COLOR_NORMAL);
--
-- grub_term_gotoxy (term,
-- (struct grub_term_coordinate) { geo->first_entry_x - 1,
-- (geo->first_entry_y - 1 + geo->num_entries
-- + GRUB_TERM_MARGIN + 1) });
--}
--
- static int
- print_message (int nested, int edit, struct grub_term_output *term, int dry_run)
- {
-@@ -167,10 +126,8 @@ command-line or ESC to discard edits and return to the GRUB menu."),
- {
- char *msg_translated;
-
-- msg_translated = grub_xasprintf (_("Use the %C and %C keys to select which "
-- "entry is highlighted."),
-- GRUB_UNICODE_UPARROW,
-- GRUB_UNICODE_DOWNARROW);
-+ msg_translated = grub_xasprintf (_("Use the arrow keys to select which "
-+ "entry is highlighted."));
- if (!msg_translated)
- return 0;
- ret += grub_print_message_indented_real (msg_translated, STANDARD_MARGIN,
-@@ -413,8 +370,6 @@ grub_menu_init_page (int nested, int edit,
-
- grub_term_normal_color = grub_color_menu_normal;
- grub_term_highlight_color = grub_color_menu_highlight;
-- if (geo->border)
-- draw_border (term, geo);
- grub_term_normal_color = old_color_normal;
- grub_term_highlight_color = old_color_highlight;
- geo->timeout_y = geo->first_entry_y + geo->num_entries
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch b/config/grub/xhci_nvme/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch
deleted file mode 100644
index fdf97c16..00000000
--- a/config/grub/xhci_nvme/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch
+++ /dev/null
@@ -1,25 +0,0 @@
-From d073d6a6d3c63a2b37df754bb890f88482ef2a75 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sat, 19 Nov 2022 16:30:24 +0000
-Subject: [PATCH 02/21] say the name libreboot, in the grub menu
-
----
- grub-core/normal/main.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/grub-core/normal/main.c b/grub-core/normal/main.c
-index de9a3f961..1fabb9c86 100644
---- a/grub-core/normal/main.c
-+++ b/grub-core/normal/main.c
-@@ -215,7 +215,7 @@ grub_normal_init_page (struct grub_term_output *term,
-
- grub_term_cls (term);
-
-- msg_formatted = grub_xasprintf (_("GNU GRUB version %s"), PACKAGE_VERSION);
-+ msg_formatted = grub_xasprintf (_("Libreboot 26.01 Magnanimous Max (GRUB menu): https://libreboot.org/"));
- if (!msg_formatted)
- return;
-
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch b/config/grub/xhci_nvme/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch
deleted file mode 100644
index 3e6d9203..00000000
--- a/config/grub/xhci_nvme/patches/0003-at_keyboard-coreboot-force-scancodes2-translate.patch
+++ /dev/null
@@ -1,107 +0,0 @@
-From befc0d1c61b4ba0c43981774eeff0f0f026f513d Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Mon, 30 Oct 2023 22:19:21 +0000
-Subject: [PATCH 03/21] at_keyboard coreboot: force scancodes2+translate
-
-Scan code set 2 with translation should be assumed in
-every case, as the default starting position.
-
-However, GRUB is trying to detect and use other modes
-such as set 2 without translation, or set 1 without
-translation from set 2; it also detects no-mode and
-assumes mode 1, on really old keyboards.
-
-The current behaviour has been retained, for everything
-except GRUB_MACHINE_COREBOOT; for the latter, scan code
-set 2 with translation is hardcoded, and forced in code.
-
-This is required to make keyboard initialisation work on
-the MEC5035 EC used by the Dell Latitude E6400, when
-running GRUB as a coreboot payload on that laptop. The
-EC reports scancode set 2 with translation when probed,
-but actually only outputs scancode set 1.
-
-Since GRUB is attempting to use it without translation,
-and since the machine reports set 2 with translation,
-but only ever outputs set 1 scancodes, this results in
-wrong keypresses for every key.
-
-This fix fixed that, by forcing set 2 with translation,
-treating it as set 1, but only on coreboot. This is the
-same behaviour used in GNU+Linux systems and SeaBIOS.
-With this change, GRUB keyboard initialisation now works
-just fine on those machines.
-
-This has *also* been tested on other coreboot machines
-running GRUB; several HP EliteBooks, ThinkPads and
-Dell Precision T1650. All seems to work just fine.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/term/at_keyboard.c | 20 ++++++++++++++++++--
- 1 file changed, 18 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/term/at_keyboard.c b/grub-core/term/at_keyboard.c
-index f8a129eb7..8207225c2 100644
---- a/grub-core/term/at_keyboard.c
-+++ b/grub-core/term/at_keyboard.c
-@@ -138,6 +138,7 @@ write_mode (int mode)
- return (i != GRUB_AT_TRIES);
- }
-
-+#if !defined (GRUB_MACHINE_COREBOOT)
- static int
- query_mode (void)
- {
-@@ -161,10 +162,12 @@ query_mode (void)
- return 3;
- return 0;
- }
-+#endif
-
- static void
- set_scancodes (void)
- {
-+#if !defined (GRUB_MACHINE_COREBOOT)
- /* You must have visited computer museum. Keyboard without scancode set
- knowledge. Assume XT. */
- if (!grub_keyboard_orig_set)
-@@ -173,20 +176,33 @@ set_scancodes (void)
- ps2_state.current_set = 1;
- return;
- }
-+#endif
-
- #if !USE_SCANCODE_SET
- ps2_state.current_set = 1;
- return;
--#else
-+#endif
-
-+#if defined (GRUB_MACHINE_COREBOOT)
-+ /* enable translation */
-+ grub_keyboard_controller_write (grub_keyboard_controller_orig
-+ & ~KEYBOARD_AT_DISABLE);
-+#else
-+ /* if not coreboot, disable translation and try mode 2 first, before 1 */
- grub_keyboard_controller_write (grub_keyboard_controller_orig
- & ~KEYBOARD_AT_TRANSLATE
- & ~KEYBOARD_AT_DISABLE);
-+#endif
-
- keyboard_controller_wait_until_ready ();
- grub_outb (KEYBOARD_COMMAND_ENABLE, KEYBOARD_REG_DATA);
--
- write_mode (2);
-+
-+#if defined (GRUB_MACHINE_COREBOOT)
-+ /* mode 2 with translation, so make grub treat as set 1 */
-+ ps2_state.current_set = 1;
-+#else
-+ /* if not coreboot, translation isn't set; test 2 and fall back to 1 */
- ps2_state.current_set = query_mode ();
- grub_dprintf ("atkeyb", "returned set %d\n", ps2_state.current_set);
- if (ps2_state.current_set == 2)
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch b/config/grub/xhci_nvme/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch
deleted file mode 100644
index 0fdcaac7..00000000
--- a/config/grub/xhci_nvme/patches/0004-keylayouts-don-t-print-Unknown-key-message.patch
+++ /dev/null
@@ -1,38 +0,0 @@
-From abe0aa9a6edba181b0f964f3cf4bcd7155322ac1 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Tue, 31 Oct 2023 10:33:28 +0000
-Subject: [PATCH 04/21] keylayouts: don't print "Unknown key" message
-
-on keyboards with stuck keys, this results in GRUB just
-spewing it repeatedly, preventing use of GRUB.
-
-in such cases, it's still possible to use the keyboard,
-and we should let the user at least boot.
-
-it often appears when people plug in faulty usb keyboards,
-but can appear for laptop keyboards too; one of my e6400
-has stuck keys.
-
-with this patch, grub should be a bit more reliable in
-terms of user experience, when the keyboard is faulty.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/commands/keylayouts.c | 1 -
- 1 file changed, 1 deletion(-)
-
-diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c
-index aa3ba34f2..445fa0601 100644
---- a/grub-core/commands/keylayouts.c
-+++ b/grub-core/commands/keylayouts.c
-@@ -174,7 +174,6 @@ grub_term_map_key (grub_keyboard_key_t code, int status)
- key = map_key_core (code, status, &alt_gr_consumed);
-
- if (key == 0 || key == GRUB_TERM_SHIFT) {
-- grub_printf ("Unknown key 0x%x detected\n", code);
- return GRUB_TERM_NO_KEY;
- }
-
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch b/config/grub/xhci_nvme/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch
deleted file mode 100644
index cec589e1..00000000
--- a/config/grub/xhci_nvme/patches/0005-don-t-print-missing-prefix-errors-on-the-screen.patch
+++ /dev/null
@@ -1,102 +0,0 @@
-From f8d8c00b9ff65bbaef029b087d6b2ad1091b39e4 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 16:14:58 +0000
-Subject: [PATCH 05/21] don't print missing prefix errors on the screen
-
-we do actually set the prefix. this patch modifies
-grub to still set grub_errno and return accordingly,
-so the behaviour is otherwise identical, but it will
-no longer print a warning message on the screen.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/commands/keylayouts.c | 2 +-
- grub-core/commands/loadenv.c | 2 +-
- grub-core/commands/nativedisk.c | 2 +-
- grub-core/efiemu/main.c | 3 +--
- grub-core/font/font.c | 2 +-
- grub-core/kern/dl.c | 2 +-
- 6 files changed, 6 insertions(+), 7 deletions(-)
-
-diff --git a/grub-core/commands/keylayouts.c b/grub-core/commands/keylayouts.c
-index 445fa0601..00bcf7025 100644
---- a/grub-core/commands/keylayouts.c
-+++ b/grub-core/commands/keylayouts.c
-@@ -211,7 +211,7 @@ grub_cmd_keymap (struct grub_command *cmd __attribute__ ((unused)),
- {
- const char *prefix = grub_env_get ("prefix");
- if (!prefix)
-- return grub_error (GRUB_ERR_BAD_ARGUMENT, N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_BAD_ARGUMENT);
- filename = grub_xasprintf ("%s/layouts/%s.gkb", prefix, argv[0]);
- if (!filename)
- return grub_errno;
-diff --git a/grub-core/commands/loadenv.c b/grub-core/commands/loadenv.c
-index 166445849..699b39bfa 100644
---- a/grub-core/commands/loadenv.c
-+++ b/grub-core/commands/loadenv.c
-@@ -58,7 +58,7 @@ open_envblk_file (char *filename,
- prefix = grub_env_get ("prefix");
- if (! prefix)
- {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- return 0;
- }
-
-diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
-index 580c8d3b0..6806bff9c 100644
---- a/grub-core/commands/nativedisk.c
-+++ b/grub-core/commands/nativedisk.c
-@@ -186,7 +186,7 @@ grub_cmd_nativedisk (grub_command_t cmd __attribute__ ((unused)),
- prefix = grub_env_get ("prefix");
-
- if (! prefix)
-- return grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_FILE_NOT_FOUND);
-
- if (prefix)
- path_prefix = (prefix[0] == '(') ? grub_strchr (prefix, ')') : NULL;
-diff --git a/grub-core/efiemu/main.c b/grub-core/efiemu/main.c
-index e7037f4ed..e5d4dbff1 100644
---- a/grub-core/efiemu/main.c
-+++ b/grub-core/efiemu/main.c
-@@ -231,8 +231,7 @@ grub_efiemu_autocore (void)
- prefix = grub_env_get ("prefix");
-
- if (! prefix)
-- return grub_error (GRUB_ERR_FILE_NOT_FOUND,
-- N_("variable `%s' isn't set"), "prefix");
-+ return (grub_errno = GRUB_ERR_FILE_NOT_FOUND);
-
- suffix = grub_efiemu_get_default_core_name ();
-
-diff --git a/grub-core/font/font.c b/grub-core/font/font.c
-index 18de52562..2a0fea6c8 100644
---- a/grub-core/font/font.c
-+++ b/grub-core/font/font.c
-@@ -461,7 +461,7 @@ grub_font_load (const char *filename)
-
- if (!prefix)
- {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- goto fail;
- }
- file = try_open_from_prefix (prefix, filename);
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index de8c3aa8d..eac3ea48d 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -880,7 +880,7 @@ grub_dl_load (const char *name)
- return 0;
-
- if (! grub_dl_dir) {
-- grub_error (GRUB_ERR_FILE_NOT_FOUND, N_("variable `%s' isn't set"), "prefix");
-+ grub_errno = GRUB_ERR_FILE_NOT_FOUND;
- return 0;
- }
-
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0006-don-t-print-error-if-module-not-found.patch b/config/grub/xhci_nvme/patches/0006-don-t-print-error-if-module-not-found.patch
deleted file mode 100644
index afffefca..00000000
--- a/config/grub/xhci_nvme/patches/0006-don-t-print-error-if-module-not-found.patch
+++ /dev/null
@@ -1,34 +0,0 @@
-From 807a54732c3a9b056d33a0fdb0baedd44b581f0b Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 16:36:22 +0000
-Subject: [PATCH 06/21] don't print error if module not found
-
-still set grub_errno accordingly, and otherwise
-behave the same. in libreboot, we remove a lot of
-modules but then rely on loading a grub.cfg
-provided by a distro; in almost all cases that works,
-but also in almost all cases, that will try to load
-a module we don't actually need, but then it prints
-a message. this can annoy some users, so silence it.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/kern/dl.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/grub-core/kern/dl.c b/grub-core/kern/dl.c
-index eac3ea48d..6d67ba54f 100644
---- a/grub-core/kern/dl.c
-+++ b/grub-core/kern/dl.c
-@@ -510,7 +510,7 @@ grub_dl_resolve_name (grub_dl_t mod, Elf_Ehdr *e)
-
- s = grub_dl_find_section (e, ".modname");
- if (!s)
-- return grub_error (GRUB_ERR_BAD_MODULE, "no module name found");
-+ return (grub_errno = GRUB_ERR_BAD_MODULE);
-
- mod->name = grub_strdup ((char *) e + s->sh_offset);
- if (! mod->name)
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0007-don-t-print-empty-error-messages.patch b/config/grub/xhci_nvme/patches/0007-don-t-print-empty-error-messages.patch
deleted file mode 100644
index 44a9c432..00000000
--- a/config/grub/xhci_nvme/patches/0007-don-t-print-empty-error-messages.patch
+++ /dev/null
@@ -1,31 +0,0 @@
-From 53ae675a60c53792b0296828fb66d414b2d3f70e Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 5 Nov 2023 17:25:20 +0000
-Subject: [PATCH 07/21] don't print empty error messages
-
-this is part two of the quest to kill the prefix
-error message. after i disabled prefix-related
-messages, it still printed "error: ." on screen.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- grub-core/kern/err.c | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/kern/err.c b/grub-core/kern/err.c
-index ba04b57fb..dab62646d 100644
---- a/grub-core/kern/err.c
-+++ b/grub-core/kern/err.c
-@@ -116,7 +116,8 @@ grub_print_error (void)
- {
- if (grub_errno != GRUB_ERR_NONE)
- {
-- grub_err_printf (_("error: %s.\n"), grub_errmsg);
-+ if (grub_strlen(grub_errmsg) > 0)
-+ grub_err_printf (_("error: %s.\n"), grub_errmsg);
- grub_err_printed_errors++;
- }
- }
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0008-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch b/config/grub/xhci_nvme/patches/0008-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch
deleted file mode 100644
index 95e9fb7b..00000000
--- a/config/grub/xhci_nvme/patches/0008-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch
+++ /dev/null
@@ -1,246 +0,0 @@
-From 64769f3b285e8bf2c21a65fba81673a0a4f6dde3 Mon Sep 17 00:00:00 2001
-From: Patrick Rudolph <patrick.rudolph@9elements.com>
-Date: Sun, 15 Nov 2020 19:00:27 +0100
-Subject: [PATCH 08/21] grub-core/bus/usb: Parse SuperSpeed companion
- descriptors
-
-Parse the SS_ENDPOINT_COMPANION descriptor, which is only present on USB 3.0
-capable devices and xHCI controllers. Make the descendp an array of pointers
-to the endpoint descriptor as it's no longer an continous array.
-
-Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
----
- grub-core/bus/usb/serial/common.c | 2 +-
- grub-core/bus/usb/usb.c | 44 +++++++++++++++++++------------
- grub-core/bus/usb/usbhub.c | 22 ++++++++++++----
- grub-core/commands/usbtest.c | 2 +-
- grub-core/disk/usbms.c | 2 +-
- grub-core/term/usb_keyboard.c | 2 +-
- include/grub/usb.h | 2 +-
- include/grub/usbdesc.h | 11 +++++++-
- 8 files changed, 59 insertions(+), 28 deletions(-)
-
-diff --git a/grub-core/bus/usb/serial/common.c b/grub-core/bus/usb/serial/common.c
-index e9c995a0a..fc847d66d 100644
---- a/grub-core/bus/usb/serial/common.c
-+++ b/grub-core/bus/usb/serial/common.c
-@@ -72,7 +72,7 @@ grub_usbserial_attach (grub_usb_device_t usbdev, int configno, int interfno,
- for (j = 0; j < interf->endpointcnt; j++)
- {
- struct grub_usb_desc_endp *endp;
-- endp = &usbdev->config[0].interf[interfno].descendp[j];
-+ endp = usbdev->config[0].interf[interfno].descendp[j];
-
- if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2
- && (in_endp == GRUB_USB_SERIAL_ENDPOINT_LAST_MATCHING
-diff --git a/grub-core/bus/usb/usb.c b/grub-core/bus/usb/usb.c
-index 7bd49d201..e578af793 100644
---- a/grub-core/bus/usb/usb.c
-+++ b/grub-core/bus/usb/usb.c
-@@ -118,7 +118,7 @@ grub_usb_device_initialize (grub_usb_device_t dev)
- struct grub_usb_desc_device *descdev;
- struct grub_usb_desc_config config;
- grub_usb_err_t err;
-- int i;
-+ int i, j;
-
- /* First we have to read first 8 bytes only and determine
- * max. size of packet */
-@@ -152,6 +152,7 @@ grub_usb_device_initialize (grub_usb_device_t dev)
- int currif;
- char *data;
- struct grub_usb_desc *desc;
-+ struct grub_usb_desc_endp *endp;
-
- /* First just read the first 4 bytes of the configuration
- descriptor, after that it is known how many bytes really have
-@@ -201,24 +202,27 @@ grub_usb_device_initialize (grub_usb_device_t dev)
- = (struct grub_usb_desc_if *) &data[pos];
- pos += dev->config[i].interf[currif].descif->length;
-
-+ dev->config[i].interf[currif].descendp = grub_malloc (
-+ dev->config[i].interf[currif].descif->endpointcnt *
-+ sizeof(struct grub_usb_desc_endp));
-+
-+ j = 0;
- while (pos < config.totallen)
- {
- desc = (struct grub_usb_desc *)&data[pos];
-- if (desc->type == GRUB_USB_DESCRIPTOR_ENDPOINT)
-- break;
-- if (!desc->length)
-- {
-- err = GRUB_USB_ERR_BADDEVICE;
-- goto fail;
-- }
-- pos += desc->length;
-- }
--
-- /* Point to the first endpoint. */
-- dev->config[i].interf[currif].descendp
-- = (struct grub_usb_desc_endp *) &data[pos];
-- pos += (sizeof (struct grub_usb_desc_endp)
-- * dev->config[i].interf[currif].descif->endpointcnt);
-+ if (desc->type == GRUB_USB_DESCRIPTOR_ENDPOINT) {
-+ endp = (struct grub_usb_desc_endp *) &data[pos];
-+ dev->config[i].interf[currif].descendp[j++] = endp;
-+ pos += desc->length;
-+ } else {
-+ if (!desc->length)
-+ {
-+ err = GRUB_USB_ERR_BADDEVICE;
-+ goto fail;
-+ }
-+ pos += desc->length;
-+ }
-+ }
- }
- }
-
-@@ -226,8 +230,14 @@ grub_usb_device_initialize (grub_usb_device_t dev)
-
- fail:
-
-- for (i = 0; i < GRUB_USB_MAX_CONF; i++)
-+ for (i = 0; i < GRUB_USB_MAX_CONF; i++) {
-+ int currif;
-+
-+ for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
-+ grub_free (dev->config[i].interf[currif].descendp);
-+
- grub_free (dev->config[i].descconf);
-+ }
-
- return err;
- }
-diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
-index f5608e330..2ae29cba1 100644
---- a/grub-core/bus/usb/usbhub.c
-+++ b/grub-core/bus/usb/usbhub.c
-@@ -82,8 +82,14 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
- if (i == GRUB_USBHUB_MAX_DEVICES)
- {
- grub_error (GRUB_ERR_IO, "can't assign address to USB device");
-- for (i = 0; i < GRUB_USB_MAX_CONF; i++)
-- grub_free (dev->config[i].descconf);
-+ for (i = 0; i < GRUB_USB_MAX_CONF; i++) {
-+ int currif;
-+
-+ for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
-+ grub_free (dev->config[i].interf[currif].descendp);
-+
-+ grub_free (dev->config[i].descconf);
-+ }
- grub_free (dev);
- return NULL;
- }
-@@ -96,8 +102,14 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
- i, 0, 0, NULL);
- if (err)
- {
-- for (i = 0; i < GRUB_USB_MAX_CONF; i++)
-- grub_free (dev->config[i].descconf);
-+ for (i = 0; i < GRUB_USB_MAX_CONF; i++) {
-+ int currif;
-+
-+ for (currif = 0; currif < dev->config[i].descconf->numif; currif++)
-+ grub_free (dev->config[i].interf[currif].descendp);
-+
-+ grub_free (dev->config[i].descconf);
-+ }
- grub_free (dev);
- return NULL;
- }
-@@ -176,7 +188,7 @@ grub_usb_add_hub (grub_usb_device_t dev)
- i++)
- {
- struct grub_usb_desc_endp *endp = NULL;
-- endp = &dev->config[0].interf[0].descendp[i];
-+ endp = dev->config[0].interf[0].descendp[i];
-
- if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp)
- == GRUB_USB_EP_INTERRUPT)
-diff --git a/grub-core/commands/usbtest.c b/grub-core/commands/usbtest.c
-index 3184ac9af..7d128449d 100644
---- a/grub-core/commands/usbtest.c
-+++ b/grub-core/commands/usbtest.c
-@@ -185,7 +185,7 @@ usb_iterate (grub_usb_device_t dev, void *data __attribute__ ((unused)))
- for (j = 0; j < interf->endpointcnt; j++)
- {
- struct grub_usb_desc_endp *endp;
-- endp = &dev->config[0].interf[i].descendp[j];
-+ endp = dev->config[0].interf[i].descendp[j];
-
- grub_printf ("Endpoint #%d: %s, max packed size: %d, transfer type: %s, latency: %d\n",
- endp->endp_addr & 15,
-diff --git a/grub-core/disk/usbms.c b/grub-core/disk/usbms.c
-index b81e3ad9d..b1512dc12 100644
---- a/grub-core/disk/usbms.c
-+++ b/grub-core/disk/usbms.c
-@@ -184,7 +184,7 @@ grub_usbms_attach (grub_usb_device_t usbdev, int configno, int interfno)
- for (j = 0; j < interf->endpointcnt; j++)
- {
- struct grub_usb_desc_endp *endp;
-- endp = &usbdev->config[0].interf[interfno].descendp[j];
-+ endp = usbdev->config[0].interf[interfno].descendp[j];
-
- if ((endp->endp_addr & 128) && (endp->attrib & 3) == 2)
- /* Bulk IN endpoint. */
-diff --git a/grub-core/term/usb_keyboard.c b/grub-core/term/usb_keyboard.c
-index 7322d8dff..d590979f5 100644
---- a/grub-core/term/usb_keyboard.c
-+++ b/grub-core/term/usb_keyboard.c
-@@ -175,7 +175,7 @@ grub_usb_keyboard_attach (grub_usb_device_t usbdev, int configno, int interfno)
- for (j = 0; j < usbdev->config[configno].interf[interfno].descif->endpointcnt;
- j++)
- {
-- endp = &usbdev->config[configno].interf[interfno].descendp[j];
-+ endp = usbdev->config[configno].interf[interfno].descendp[j];
-
- if ((endp->endp_addr & 128) && grub_usb_get_ep_type(endp)
- == GRUB_USB_EP_INTERRUPT)
-diff --git a/include/grub/usb.h b/include/grub/usb.h
-index 0f346af12..688c11f6d 100644
---- a/include/grub/usb.h
-+++ b/include/grub/usb.h
-@@ -153,7 +153,7 @@ struct grub_usb_interface
- {
- struct grub_usb_desc_if *descif;
-
-- struct grub_usb_desc_endp *descendp;
-+ struct grub_usb_desc_endp **descendp;
-
- /* A driver is handling this interface. Do we need to support multiple drivers
- for single interface?
-diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h
-index aac5ab05a..bb2ab2e27 100644
---- a/include/grub/usbdesc.h
-+++ b/include/grub/usbdesc.h
-@@ -29,7 +29,8 @@ typedef enum {
- GRUB_USB_DESCRIPTOR_INTERFACE,
- GRUB_USB_DESCRIPTOR_ENDPOINT,
- GRUB_USB_DESCRIPTOR_DEBUG = 10,
-- GRUB_USB_DESCRIPTOR_HUB = 0x29
-+ GRUB_USB_DESCRIPTOR_HUB = 0x29,
-+ GRUB_USB_DESCRIPTOR_SS_ENDPOINT_COMPANION = 0x30
- } grub_usb_descriptor_t;
-
- struct grub_usb_desc
-@@ -105,6 +106,14 @@ struct grub_usb_desc_endp
- grub_uint8_t interval;
- } GRUB_PACKED;
-
-+struct grub_usb_desc_ssep {
-+ grub_uint8_t length;
-+ grub_uint8_t type;
-+ grub_uint8_t maxburst;
-+ grub_uint8_t attrib;
-+ grub_uint16_t interval;
-+} GRUB_PACKED;
-+
- struct grub_usb_desc_str
- {
- grub_uint8_t length;
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0009-usb-Add-enum-for-xHCI.patch b/config/grub/xhci_nvme/patches/0009-usb-Add-enum-for-xHCI.patch
deleted file mode 100644
index 5b79d33c..00000000
--- a/config/grub/xhci_nvme/patches/0009-usb-Add-enum-for-xHCI.patch
+++ /dev/null
@@ -1,29 +0,0 @@
-From 43522cfb0ec375be1b6a226103e9a55d4b88ee1d Mon Sep 17 00:00:00 2001
-From: Patrick Rudolph <patrick.rudolph@9elements.com>
-Date: Mon, 7 Dec 2020 08:41:22 +0100
-Subject: [PATCH 09/21] usb: Add enum for xHCI
-
-Will be used in future patches.
-
-Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
----
- include/grub/usb.h | 3 ++-
- 1 file changed, 2 insertions(+), 1 deletion(-)
-
-diff --git a/include/grub/usb.h b/include/grub/usb.h
-index 688c11f6d..ea6ee8c2c 100644
---- a/include/grub/usb.h
-+++ b/include/grub/usb.h
-@@ -51,7 +51,8 @@ typedef enum
- GRUB_USB_SPEED_NONE,
- GRUB_USB_SPEED_LOW,
- GRUB_USB_SPEED_FULL,
-- GRUB_USB_SPEED_HIGH
-+ GRUB_USB_SPEED_HIGH,
-+ GRUB_USB_SPEED_SUPER
- } grub_usb_speed_t;
-
- typedef int (*grub_usb_iterate_hook_t) (grub_usb_device_t dev, void *data);
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0010-usbtrans-Set-default-maximum-packet-size.patch b/config/grub/xhci_nvme/patches/0010-usbtrans-Set-default-maximum-packet-size.patch
deleted file mode 100644
index c6196f87..00000000
--- a/config/grub/xhci_nvme/patches/0010-usbtrans-Set-default-maximum-packet-size.patch
+++ /dev/null
@@ -1,33 +0,0 @@
-From 296f9b732393315bc3a91f8531f6ac9e7b9f43e0 Mon Sep 17 00:00:00 2001
-From: Patrick Rudolph <patrick.rudolph@9elements.com>
-Date: Mon, 7 Dec 2020 08:41:23 +0100
-Subject: [PATCH 10/21] usbtrans: Set default maximum packet size
-
-Set the maximum packet size to 512 for SuperSpeed devices.
-
-Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
----
- grub-core/bus/usb/usbtrans.c | 6 +++++-
- 1 file changed, 5 insertions(+), 1 deletion(-)
-
-diff --git a/grub-core/bus/usb/usbtrans.c b/grub-core/bus/usb/usbtrans.c
-index c5680b33a..c1080bb33 100644
---- a/grub-core/bus/usb/usbtrans.c
-+++ b/grub-core/bus/usb/usbtrans.c
-@@ -128,8 +128,12 @@ grub_usb_control_msg (grub_usb_device_t dev,
- setupdata_addr = grub_dma_get_phys (setupdata_chunk);
-
- /* Determine the maximum packet size. */
-- if (dev->descdev.maxsize0)
-+ if (dev->descdev.maxsize0 && dev->speed != GRUB_USB_SPEED_SUPER)
- max = dev->descdev.maxsize0;
-+ else if (dev->descdev.maxsize0 && dev->speed == GRUB_USB_SPEED_SUPER)
-+ max = 1UL << dev->descdev.maxsize0;
-+ else if (dev->speed == GRUB_USB_SPEED_SUPER)
-+ max = 512;
- else
- max = 64;
-
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0011-grub-core-bus-usb-Add-function-pointer-for-attach-de.patch b/config/grub/xhci_nvme/patches/0011-grub-core-bus-usb-Add-function-pointer-for-attach-de.patch
deleted file mode 100644
index ac53118a..00000000
--- a/config/grub/xhci_nvme/patches/0011-grub-core-bus-usb-Add-function-pointer-for-attach-de.patch
+++ /dev/null
@@ -1,121 +0,0 @@
-From de471d16aeaab3cf12956d783604f22944ea7ed0 Mon Sep 17 00:00:00 2001
-From: Patrick Rudolph <patrick.rudolph@9elements.com>
-Date: Sun, 15 Nov 2020 19:51:42 +0100
-Subject: [PATCH 11/21] grub-core/bus/usb: Add function pointer for
- attach/detach events
-
-The xHCI code needs to be called for attaching or detaching a device.
-Introduce two functions pointers and call it from the USB hub code.
-
-Will be used in future commits, currently this doesn't change any functionality.
-
-Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
----
- grub-core/bus/usb/ehci.c | 2 ++
- grub-core/bus/usb/ohci.c | 2 ++
- grub-core/bus/usb/uhci.c | 2 ++
- grub-core/bus/usb/usbhub.c | 19 +++++++++++++++++++
- include/grub/usb.h | 4 ++++
- 5 files changed, 29 insertions(+)
-
-diff --git a/grub-core/bus/usb/ehci.c b/grub-core/bus/usb/ehci.c
-index 2db07c7c0..1ee056015 100644
---- a/grub-core/bus/usb/ehci.c
-+++ b/grub-core/bus/usb/ehci.c
-@@ -1812,6 +1812,8 @@ static struct grub_usb_controller_dev usb_controller = {
- .hubports = grub_ehci_hubports,
- .portstatus = grub_ehci_portstatus,
- .detect_dev = grub_ehci_detect_dev,
-+ .attach_dev = NULL,
-+ .detach_dev = NULL,
- /* estimated max. count of TDs for one bulk transfer */
- .max_bulk_tds = GRUB_EHCI_N_TD * 3 / 4
- };
-diff --git a/grub-core/bus/usb/ohci.c b/grub-core/bus/usb/ohci.c
-index 5363a61f6..7a3f3e154 100644
---- a/grub-core/bus/usb/ohci.c
-+++ b/grub-core/bus/usb/ohci.c
-@@ -1440,6 +1440,8 @@ static struct grub_usb_controller_dev usb_controller =
- .hubports = grub_ohci_hubports,
- .portstatus = grub_ohci_portstatus,
- .detect_dev = grub_ohci_detect_dev,
-+ .attach_dev = NULL,
-+ .detach_dev = NULL,
- /* estimated max. count of TDs for one bulk transfer */
- .max_bulk_tds = GRUB_OHCI_TDS * 3 / 4
- };
-diff --git a/grub-core/bus/usb/uhci.c b/grub-core/bus/usb/uhci.c
-index 0fdea4c1e..03c4605b2 100644
---- a/grub-core/bus/usb/uhci.c
-+++ b/grub-core/bus/usb/uhci.c
-@@ -845,6 +845,8 @@ static struct grub_usb_controller_dev usb_controller =
- .hubports = grub_uhci_hubports,
- .portstatus = grub_uhci_portstatus,
- .detect_dev = grub_uhci_detect_dev,
-+ .attach_dev = NULL,
-+ .detach_dev = NULL,
- /* estimated max. count of TDs for one bulk transfer */
- .max_bulk_tds = N_TD * 3 / 4
- };
-diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
-index 2ae29cba1..8e963e84b 100644
---- a/grub-core/bus/usb/usbhub.c
-+++ b/grub-core/bus/usb/usbhub.c
-@@ -66,6 +66,15 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
- dev->split_hubport = split_hubport;
- dev->split_hubaddr = split_hubaddr;
-
-+ if (controller->dev->attach_dev) {
-+ err = controller->dev->attach_dev (controller, dev);
-+ if (err)
-+ {
-+ grub_free (dev);
-+ return NULL;
-+ }
-+ }
-+
- err = grub_usb_device_initialize (dev);
- if (err)
- {
-@@ -405,6 +414,8 @@ static void
- detach_device (grub_usb_device_t dev)
- {
- unsigned i;
-+ grub_usb_err_t err;
-+
- int k;
- if (!dev)
- return;
-@@ -425,6 +436,14 @@ detach_device (grub_usb_device_t dev)
- if (inter && inter->detach_hook)
- inter->detach_hook (dev, i, k);
- }
-+ if (dev->controller.dev->detach_dev) {
-+ err = dev->controller.dev->detach_dev (&dev->controller, dev);
-+ if (err)
-+ {
-+ // XXX
-+ }
-+ }
-+
- grub_usb_devs[dev->addr] = 0;
- }
-
-diff --git a/include/grub/usb.h b/include/grub/usb.h
-index ea6ee8c2c..4dd179db2 100644
---- a/include/grub/usb.h
-+++ b/include/grub/usb.h
-@@ -126,6 +126,10 @@ struct grub_usb_controller_dev
-
- grub_usb_speed_t (*detect_dev) (grub_usb_controller_t dev, int port, int *changed);
-
-+ grub_usb_err_t (*attach_dev) (grub_usb_controller_t ctrl, grub_usb_device_t dev);
-+
-+ grub_usb_err_t (*detach_dev) (grub_usb_controller_t ctrl, grub_usb_device_t dev);
-+
- /* Per controller flag - port reset pending, don't do another reset */
- grub_uint64_t pending_reset;
-
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0012-grub-core-bus-usb-usbhub-Add-new-private-fields-for-.patch b/config/grub/xhci_nvme/patches/0012-grub-core-bus-usb-usbhub-Add-new-private-fields-for-.patch
deleted file mode 100644
index fbedfc77..00000000
--- a/config/grub/xhci_nvme/patches/0012-grub-core-bus-usb-usbhub-Add-new-private-fields-for-.patch
+++ /dev/null
@@ -1,77 +0,0 @@
-From 8966fadb8c19fd5c30dd585a53f465767c1cd627 Mon Sep 17 00:00:00 2001
-From: Patrick Rudolph <patrick.rudolph@9elements.com>
-Date: Mon, 7 Dec 2020 08:41:25 +0100
-Subject: [PATCH 12/21] grub-core/bus/usb/usbhub: Add new private fields for
- xHCI controller
-
-Store the root port number, the route, consisting out of the port ID
-in each nibble, and a pointer to driver private data.
-
-Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
----
- grub-core/bus/usb/usbhub.c | 11 ++++++++---
- include/grub/usb.h | 5 +++++
- 2 files changed, 13 insertions(+), 3 deletions(-)
-
-diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
-index 8e963e84b..b4b3a1a61 100644
---- a/grub-core/bus/usb/usbhub.c
-+++ b/grub-core/bus/usb/usbhub.c
-@@ -49,7 +49,9 @@ static grub_usb_controller_dev_t grub_usb_list;
- static grub_usb_device_t
- grub_usb_hub_add_dev (grub_usb_controller_t controller,
- grub_usb_speed_t speed,
-- int split_hubport, int split_hubaddr)
-+ int split_hubport, int split_hubaddr,
-+ int root_portno,
-+ grub_uint32_t route)
- {
- grub_usb_device_t dev;
- int i;
-@@ -65,6 +67,8 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
- dev->speed = speed;
- dev->split_hubport = split_hubport;
- dev->split_hubaddr = split_hubaddr;
-+ dev->root_port = root_portno;
-+ dev->route = route;
-
- if (controller->dev->attach_dev) {
- err = controller->dev->attach_dev (controller, dev);
-@@ -245,7 +249,7 @@ attach_root_port (struct grub_usb_hub *hub, int portno,
- and full/low speed device connected to OHCI/UHCI needs not
- transaction translation - e.g. hubport and hubaddr should be
- always none (zero) for any device connected to any root hub. */
-- dev = grub_usb_hub_add_dev (hub->controller, speed, 0, 0);
-+ dev = grub_usb_hub_add_dev (hub->controller, speed, 0, 0, portno, 0);
- hub->controller->dev->pending_reset = 0;
- npending--;
- if (! dev)
-@@ -676,7 +680,8 @@ poll_nonroot_hub (grub_usb_device_t dev)
-
- /* Add the device and assign a device address to it. */
- next_dev = grub_usb_hub_add_dev (&dev->controller, speed,
-- split_hubport, split_hubaddr);
-+ split_hubport, split_hubaddr, dev->root_port,
-+ dev->route << 4 | (i & 0xf));
- if (dev->controller.dev->pending_reset)
- {
- dev->controller.dev->pending_reset = 0;
-diff --git a/include/grub/usb.h b/include/grub/usb.h
-index 4dd179db2..609faf7d0 100644
---- a/include/grub/usb.h
-+++ b/include/grub/usb.h
-@@ -237,6 +237,11 @@ struct grub_usb_device
- int split_hubport;
-
- int split_hubaddr;
-+
-+ /* xHCI specific information */
-+ int root_port;
-+ grub_uint32_t route;
-+ void *xhci_priv;
- };
-
-
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0013-grub-core-bus-usb-Add-xhci-support.patch b/config/grub/xhci_nvme/patches/0013-grub-core-bus-usb-Add-xhci-support.patch
deleted file mode 100644
index 1393092a..00000000
--- a/config/grub/xhci_nvme/patches/0013-grub-core-bus-usb-Add-xhci-support.patch
+++ /dev/null
@@ -1,2807 +0,0 @@
-From 764e79efa273fadb8fc4b5ec286dd9e5688a58e8 Mon Sep 17 00:00:00 2001
-From: Patrick Rudolph <patrick.rudolph@9elements.com>
-Date: Mon, 7 Dec 2020 08:41:26 +0100
-Subject: [PATCH 13/21] grub-core/bus/usb: Add xhci support
-
-Add support for xHCI USB controllers.
-The code is based on seabios implementation, but has been heavily
-modified to match grubs internals.
-
-Changes done in version 2:
-* Code cleanup
-* Code style fixes
-* Don't leak memory buffers
-* Compile without warnings
-* Add more defines
-* Add more helper functions
-* Don't assume a 1:1 virtual to physical mapping
-* Flush cachelines after writing buffers
-* Don't use hardcoded page size
-* Proper scratchpad register setup
-* xHCI bios ownership handoff
-
-Changes done in version 3:
-* Fixed a race condition detecting events, which doesn't appear on
- qemu based xHCI controllers
-* Don't accidently disable USB3.0 devices after first command
-* Support arbitrary protocol speed IDs
-* Coding style cleanup
-
-Tested:
-* Qemu system x86_64
- * virtual USB HID keyboard (usb-kbd)
- * virtual USB HID mass storage (usb-storage)
-* init Supermicro X11SSH-F
- * iKVM HID keyboard
- * USB3 HID mass storage (controller root port)
- * USB HID keyboard
-
-TODO:
- * Test on more hardware
- * Test on USB3 hubs
- * Support for USB 3.1 and USB 3.2 controllers
-
-Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
-Signed-off-by: sylv <sylv@sylv.io>
----
- Makefile.am | 2 +-
- grub-core/Makefile.core.def | 7 +
- grub-core/bus/usb/xhci-pci.c | 195 +++
- grub-core/bus/usb/xhci.c | 2496 ++++++++++++++++++++++++++++++++++
- include/grub/usb.h | 4 +
- 5 files changed, 2703 insertions(+), 1 deletion(-)
- create mode 100644 grub-core/bus/usb/xhci-pci.c
- create mode 100644 grub-core/bus/usb/xhci.c
-
-diff --git a/Makefile.am b/Makefile.am
-index 43635d5ff..65016f856 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -434,7 +434,7 @@ if COND_i386_coreboot
- FS_PAYLOAD_MODULES ?= $(shell cat grub-core/fs.lst)
- default_payload.elf: grub-mkstandalone grub-mkimage FORCE
- test -f $@ && rm $@ || true
-- pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
-+ pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata xhci ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
- endif
-
- endif
-diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
-index 0cf155128..ec4c76ea8 100644
---- a/grub-core/Makefile.core.def
-+++ b/grub-core/Makefile.core.def
-@@ -675,6 +675,13 @@ module = {
- enable = arm_coreboot;
- };
-
-+module = {
-+ name = xhci;
-+ common = bus/usb/xhci.c;
-+ pci = bus/usb/xhci-pci.c;
-+ enable = pci;
-+};
-+
- module = {
- name = pci;
- common = bus/pci.c;
-diff --git a/grub-core/bus/usb/xhci-pci.c b/grub-core/bus/usb/xhci-pci.c
-new file mode 100644
-index 000000000..a5bd3c97d
---- /dev/null
-+++ b/grub-core/bus/usb/xhci-pci.c
-@@ -0,0 +1,195 @@
-+/* xhci.c - XHCI Support. */
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2020 9elements Cyber Security
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
-+ */
-+
-+#include <grub/pci.h>
-+#include <grub/cpu/pci.h>
-+#include <grub/cs5536.h>
-+#include <grub/misc.h>
-+#include <grub/mm.h>
-+#include <grub/time.h>
-+#include <grub/usb.h>
-+
-+#define GRUB_XHCI_PCI_SBRN_REG 0x60
-+#define GRUB_XHCI_ADDR_MEM_MASK (~0xff)
-+
-+/* USBLEGSUP bits and related OS OWNED byte offset */
-+enum
-+{
-+ GRUB_XHCI_BIOS_OWNED = (1 << 16),
-+ GRUB_XHCI_OS_OWNED = (1 << 24)
-+};
-+
-+/* PCI iteration function... */
-+static int
-+grub_xhci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
-+ void *data __attribute__ ((unused)))
-+{
-+ volatile grub_uint32_t *regs;
-+ grub_uint32_t base, base_h;
-+ grub_uint32_t eecp_offset;
-+ grub_uint32_t usblegsup = 0;
-+ grub_uint64_t maxtime;
-+ grub_uint32_t interf;
-+ grub_uint32_t subclass;
-+ grub_uint32_t class;
-+ grub_uint8_t release;
-+ grub_uint32_t class_code;
-+
-+ grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: begin\n");
-+
-+ if (pciid == GRUB_CS5536_PCIID)
-+ {
-+ grub_dprintf ("xhci", "CS5536 not supported\n");
-+ return 0;
-+ }
-+ else
-+ {
-+ grub_pci_address_t addr;
-+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_CLASS);
-+ class_code = grub_pci_read (addr) >> 8;
-+ interf = class_code & 0xFF;
-+ subclass = (class_code >> 8) & 0xFF;
-+ class = class_code >> 16;
-+
-+ /* If this is not an XHCI controller, just return. */
-+ if (class != 0x0c || subclass != 0x03 || interf != 0x30)
-+ return 0;
-+
-+ grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: class OK\n");
-+
-+ /* Check Serial Bus Release Number */
-+ addr = grub_pci_make_address (dev, GRUB_XHCI_PCI_SBRN_REG);
-+ release = grub_pci_read_byte (addr);
-+ if (release != 0x30)
-+ {
-+ grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: Wrong SBRN: %0x\n",
-+ release);
-+ return 0;
-+ }
-+ grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: bus rev. num. OK\n");
-+
-+ /* Determine XHCI XHCC registers base address. */
-+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0);
-+ base = grub_pci_read (addr);
-+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG1);
-+ base_h = grub_pci_read (addr);
-+ /* Stop if registers are mapped above 4G - GRUB does not currently
-+ * work with registers mapped above 4G */
-+ if (((base & GRUB_PCI_ADDR_MEM_TYPE_MASK) != GRUB_PCI_ADDR_MEM_TYPE_32)
-+ && (base_h != 0))
-+ {
-+ grub_dprintf ("xhci",
-+ "XHCI grub_xhci_pci_iter: registers above 4G are not supported\n");
-+ return 0;
-+ }
-+ base &= GRUB_PCI_ADDR_MEM_MASK;
-+ if (!base)
-+ {
-+ grub_dprintf ("xhci",
-+ "XHCI: XHCI is not mapped\n");
-+ return 0;
-+ }
-+
-+ /* Set bus master - needed for coreboot, VMware, broken BIOSes etc. */
-+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
-+ grub_pci_write_word(addr,
-+ GRUB_PCI_COMMAND_MEM_ENABLED
-+ | GRUB_PCI_COMMAND_BUS_MASTER
-+ | grub_pci_read_word(addr));
-+
-+ grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: 32-bit XHCI OK\n");
-+ }
-+
-+ grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: iobase of XHCC: %08x\n",
-+ (base & GRUB_XHCI_ADDR_MEM_MASK));
-+
-+ regs = grub_pci_device_map_range (dev,
-+ (base & GRUB_XHCI_ADDR_MEM_MASK),
-+ 0x100);
-+
-+ /* Is there EECP ? */
-+ eecp_offset = (grub_le_to_cpu32 (regs[2]) >> 8) & 0xff;
-+
-+ /* Determine and change ownership. */
-+ /* EECP offset valid in HCCPARAMS */
-+ /* Ownership can be changed via EECP only */
-+ if (pciid != GRUB_CS5536_PCIID && eecp_offset >= 0x40)
-+ {
-+ grub_pci_address_t pciaddr_eecp;
-+ pciaddr_eecp = grub_pci_make_address (dev, eecp_offset);
-+
-+ usblegsup = grub_pci_read (pciaddr_eecp);
-+ if (usblegsup & GRUB_XHCI_BIOS_OWNED)
-+ {
-+ grub_boot_time ("Taking ownership of XHCI controller");
-+ grub_dprintf ("xhci",
-+ "XHCI grub_xhci_pci_iter: XHCI owned by: BIOS\n");
-+ /* Ownership change - set OS_OWNED bit */
-+ grub_pci_write (pciaddr_eecp, usblegsup | GRUB_XHCI_OS_OWNED);
-+ /* Ensure PCI register is written */
-+ grub_pci_read (pciaddr_eecp);
-+
-+ /* Wait for finish of ownership change, XHCI specification
-+ * doesn't say how long it can take... */
-+ maxtime = grub_get_time_ms () + 1000;
-+ while ((grub_pci_read (pciaddr_eecp) & GRUB_XHCI_BIOS_OWNED)
-+ && (grub_get_time_ms () < maxtime));
-+ if (grub_pci_read (pciaddr_eecp) & GRUB_XHCI_BIOS_OWNED)
-+ {
-+ grub_dprintf ("xhci",
-+ "XHCI grub_xhci_pci_iter: XHCI change ownership timeout");
-+ /* Change ownership in "hard way" - reset BIOS ownership */
-+ grub_pci_write (pciaddr_eecp, GRUB_XHCI_OS_OWNED);
-+ /* Ensure PCI register is written */
-+ grub_pci_read (pciaddr_eecp);
-+ }
-+ }
-+ else if (usblegsup & GRUB_XHCI_OS_OWNED)
-+ /* XXX: What to do in this case - nothing ? Can it happen ? */
-+ grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: XHCI owned by: OS\n");
-+ else
-+ {
-+ grub_dprintf ("xhci",
-+ "XHCI grub_Xhci_pci_iter: XHCI owned by: NONE\n");
-+ /* XXX: What to do in this case ? Can it happen ?
-+ * Is code below correct ? */
-+ /* Ownership change - set OS_OWNED bit */
-+ grub_pci_write (pciaddr_eecp, GRUB_XHCI_OS_OWNED);
-+ /* Ensure PCI register is written */
-+ grub_pci_read (pciaddr_eecp);
-+ }
-+
-+ /* Disable SMI, just to be sure. */
-+ pciaddr_eecp = grub_pci_make_address (dev, eecp_offset + 4);
-+ grub_pci_write (pciaddr_eecp, 0);
-+ /* Ensure PCI register is written */
-+ grub_pci_read (pciaddr_eecp);
-+ }
-+
-+ grub_dprintf ("xhci", "inithw: XHCI grub_xhci_pci_iter: ownership OK\n");
-+
-+ grub_xhci_init_device (regs);
-+ return 0;
-+}
-+
-+void
-+grub_xhci_pci_scan (void)
-+{
-+ grub_pci_iterate (grub_xhci_pci_iter, NULL);
-+}
-diff --git a/grub-core/bus/usb/xhci.c b/grub-core/bus/usb/xhci.c
-new file mode 100644
-index 000000000..f4591ffb5
---- /dev/null
-+++ b/grub-core/bus/usb/xhci.c
-@@ -0,0 +1,2496 @@
-+/* xhci.c - XHCI Support. */
-+/*
-+ * GRUB -- GRand Unified Bootloader
-+ * Copyright (C) 2020 9elements Cyber Security
-+ *
-+ * GRUB is free software: you can redistribute it and/or modify
-+ * it under the terms of the GNU General Public License as published by
-+ * the Free Software Foundation, either version 3 of the License, or
-+ * (at your option) any later version.
-+ *
-+ * GRUB is distributed in the hope that it will be useful,
-+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
-+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-+ * GNU General Public License for more details.
-+ *
-+ * You should have received a copy of the GNU General Public License
-+ * along with GRUB. If not, see <http://www.gnu.org/licenses/>.
-+ *
-+ * Big parts of this software are inspired by seabios XHCI implementation
-+ * Released under LGPLv3. Credits to:
-+ *
-+ * Copyright (C) 2013 Gerd Hoffmann <kraxel@redhat.com>
-+ * Copyright (C) 2014 Kevin O'Connor <kevin@koconnor.net>
-+ */
-+
-+#include <grub/dl.h>
-+#include <grub/err.h>
-+#include <grub/mm.h>
-+#include <grub/usb.h>
-+#include <grub/usbtrans.h>
-+#include <grub/misc.h>
-+#include <grub/time.h>
-+#include <grub/loader.h>
-+#include <grub/disk.h>
-+#include <grub/dma.h>
-+#include <grub/cache.h>
-+#include <grub/i386/cpuid.h>
-+
-+GRUB_MOD_LICENSE ("GPLv3+");
-+
-+/* This simple GRUB implementation of XHCI driver */
-+/* Based on the specification
-+ * "eXtensible Host Controller Interface for Universal Serial Bus" Revision 1.2
-+ */
-+
-+
-+#define xhci_get_field(data, field) \
-+ (((data) >> field##_SHIFT) & field##_MASK)
-+#define XHCI_PORTSC_PLS_MASK 0xf
-+#define XHCI_PORTSC_PLS_SHIFT 5
-+#define XHCI_PORTSC_SPEED_MASK 0xf
-+#define XHCI_PORTSC_SPEED_SHIFT 10
-+
-+enum
-+{
-+ XHCI_USB_FULLSPEED = 1,
-+ XHCI_USB_LOWSPEED,
-+ XHCI_USB_HIGHSPEED,
-+ XHCI_USB_SUPERSPEED
-+};
-+
-+/* Chapter 5.3 Host Controller Capability Registers */
-+struct grub_xhci_caps {
-+ grub_uint8_t caplength;
-+ grub_uint8_t reserved_01;
-+ grub_uint16_t hciversion;
-+ grub_uint32_t hcsparams1;
-+ grub_uint32_t hcsparams2;
-+ grub_uint32_t hcsparams3;
-+ grub_uint32_t hccparams;
-+ grub_uint32_t dboff;
-+ grub_uint32_t rtsoff;
-+ grub_uint32_t hccparams2;
-+} GRUB_PACKED;
-+
-+/* extended capabilities */
-+struct grub_xhci_xcap {
-+ grub_uint32_t cap;
-+ grub_uint32_t data[];
-+} GRUB_PACKED;
-+
-+#define XHCI_CAP_LEGACY_SUPPORT 1
-+#define XHCI_CAP_SUPPORTED_PROTOCOL 2
-+
-+struct xhci_portmap {
-+ grub_uint8_t start;
-+ grub_uint8_t count;
-+} GRUB_PACKED;
-+
-+struct grub_xhci_op {
-+ grub_uint32_t usbcmd;
-+ grub_uint32_t usbsts;
-+ grub_uint32_t pagesize;
-+ grub_uint32_t reserved_01[2];
-+ grub_uint32_t dnctl;
-+ grub_uint32_t crcr_low;
-+ grub_uint32_t crcr_high;
-+ grub_uint32_t reserved_02[4];
-+ grub_uint32_t dcbaap_low;
-+ grub_uint32_t dcbaap_high;
-+ grub_uint32_t config;
-+} GRUB_PACKED;
-+
-+enum
-+{
-+ GRUB_XHCI_CMD_RS = (1<<0),
-+ GRUB_XHCI_CMD_HCRST = (1<<1),
-+ GRUB_XHCI_CMD_INTE = (1<<2),
-+ GRUB_XHCI_CMD_HSEE = (1<<3),
-+ GRUB_XHCI_CMD_LHCRST = (1<<7),
-+ GRUB_XHCI_CMD_CSS = (1<<8),
-+ GRUB_XHCI_CMD_CRS = (1<<9),
-+ GRUB_XHCI_CMD_EWE = (1<<10),
-+ GRUB_XHCI_CMD_EU3S = (1<<11)
-+};
-+
-+enum
-+{
-+ GRUB_XHCI_STS_HCH = (1<<0),
-+ GRUB_XHCI_STS_HSE = (1<<2),
-+ GRUB_XHCI_STS_EINT = (1<<3),
-+ GRUB_XHCI_STS_PCD = (1<<4),
-+ GRUB_XHCI_STS_SSS = (1<<8),
-+ GRUB_XHCI_STS_RSS = (1<<9),
-+ GRUB_XHCI_STS_SRE = (1<<10),
-+ GRUB_XHCI_STS_CNR = (1<<11),
-+ GRUB_XHCI_STS_HCE = (1<<12)
-+};
-+
-+
-+/* Port Registers Offset */
-+#define GRUB_XHCI_PR_OFFSET 0x400
-+/* Interrupter Registers Offset */
-+#define GRUB_XHCI_IR_OFFSET 0x20
-+
-+/* Port Status and Control registers offsets */
-+
-+/* Chapter 6 Data Structures */
-+#define ALIGN_SPBA 64
-+#define ALIGN_DCBAA 64
-+#define ALIGN_CMD_RING_SEG 64
-+#define ALIGN_EVT_RING_SEG 64
-+#define ALIGN_EVT_RING_TABLE 64
-+#define ALIGN_TRB 16
-+#define ALIGN_INCTX 64
-+#define ALIGN_SLOTCTX 32
-+
-+#define BOUNDARY_RING 0x10000
-+
-+enum
-+{
-+ GRUB_XHCI_PORTSC_CCS = (1<<0),
-+ GRUB_XHCI_PORTSC_PED = (1<<1),
-+ GRUB_XHCI_PORTSC_OCA = (1<<3),
-+ GRUB_XHCI_PORTSC_PR = (1<<4),
-+ GRUB_XHCI_PORTSC_PP = (1<<9),
-+ GRUB_XHCI_PORTSC_SPEED_FULL = (1<<10),
-+ GRUB_XHCI_PORTSC_SPEED_LOW = (2<<10),
-+ GRUB_XHCI_PORTSC_SPEED_HIGH = (3<<10),
-+ GRUB_XHCI_PORTSC_SPEED_SUPER = (4<<10),
-+ GRUB_XHCI_PORTSC_LWS = (1<<16),
-+ GRUB_XHCI_PORTSC_CSC = (1<<17),
-+ GRUB_XHCI_PORTSC_PEC = (1<<18),
-+ GRUB_XHCI_PORTSC_WRC = (1<<19),
-+ GRUB_XHCI_PORTSC_OCC = (1<<20),
-+ GRUB_XHCI_PORTSC_PRC = (1<<21),
-+ GRUB_XHCI_PORTSC_PLC = (1<<22),
-+ GRUB_XHCI_PORTSC_CEC = (1<<23),
-+ GRUB_XHCI_PORTSC_CAS = (1<<24),
-+ GRUB_XHCI_PORTSC_WCE = (1<<25),
-+ GRUB_XHCI_PORTSC_WDE = (1<<26),
-+ GRUB_XHCI_PORTSC_WOE = (1<<27),
-+ GRUB_XHCI_PORTSC_DR = (1<<30),
-+ GRUB_XHCI_PORTSC_WPR = (1<<31)
-+};
-+
-+/* XHCI memory data structs */
-+#define GRUB_XHCI_MAX_ENDPOINTS 32
-+
-+#define GRUB_XHCI_RING_ITEMS 128
-+#define GRUB_XHCI_RING_SIZE (GRUB_XHCI_RING_ITEMS*sizeof(struct grub_xhci_trb))
-+/*
-+ * xhci_ring structs are allocated with XHCI_RING_SIZE alignment,
-+ * then we can get it from a trb pointer (provided by evt ring).
-+ */
-+#define XHCI_RING(_trb) \
-+ ((struct grub_xhci_ring*)((grub_uint32_t)(_trb) & ~(GRUB_XHCI_RING_SIZE-1)))
-+
-+/* slot context */
-+struct grub_xhci_slotctx {
-+ grub_uint32_t ctx[4];
-+ grub_uint32_t reserved_01[4];
-+} GRUB_PACKED;
-+
-+/* endpoint context */
-+struct grub_xhci_epctx {
-+ grub_uint32_t ctx[2];
-+ grub_uint32_t deq_low;
-+ grub_uint32_t deq_high;
-+ grub_uint32_t length;
-+ grub_uint32_t reserved_01[3];
-+} GRUB_PACKED;
-+
-+/* device context array element */
-+struct grub_xhci_devlist {
-+ grub_uint32_t ptr_low;
-+ grub_uint32_t ptr_high;
-+} GRUB_PACKED;
-+
-+/* input context */
-+struct grub_xhci_inctx {
-+ grub_uint32_t del;
-+ grub_uint32_t add;
-+ grub_uint32_t reserved_01[6];
-+} GRUB_PACKED;
-+
-+/* transfer block (ring element) */
-+struct grub_xhci_trb {
-+ grub_uint32_t ptr_low;
-+ grub_uint32_t ptr_high;
-+ grub_uint32_t status;
-+ grub_uint32_t control;
-+} GRUB_PACKED;
-+
-+#define TRB_C (1<<0)
-+#define TRB_TYPE_SHIFT 10
-+#define TRB_TYPE_MASK 0x3f
-+#define TRB_TYPE(t) (((t) >> TRB_TYPE_SHIFT) & TRB_TYPE_MASK)
-+
-+#define TRB_EV_ED (1<<2)
-+
-+#define TRB_TR_ENT (1<<1)
-+#define TRB_TR_ISP (1<<2)
-+#define TRB_TR_NS (1<<3)
-+#define TRB_TR_CH (1<<4)
-+#define TRB_TR_IOC (1<<5)
-+#define TRB_TR_IDT (1<<6)
-+#define TRB_TR_TBC_SHIFT 7
-+#define TRB_TR_TBC_MASK 0x3
-+#define TRB_TR_BEI (1<<9)
-+#define TRB_TR_TLBPC_SHIFT 16
-+#define TRB_TR_TLBPC_MASK 0xf
-+#define TRB_TR_FRAMEID_SHIFT 20
-+#define TRB_TR_FRAMEID_MASK 0x7ff
-+#define TRB_TR_SIA (1<<31)
-+
-+#define TRB_TR_DIR (1<<16)
-+
-+#define TRB_CR_SLOTID_SHIFT 24
-+#define TRB_CR_SLOTID_MASK 0xff
-+#define TRB_CR_EPID_SHIFT 16
-+#define TRB_CR_EPID_MASK 0x1f
-+
-+#define TRB_CR_BSR (1<<9)
-+#define TRB_CR_DC (1<<9)
-+
-+#define TRB_LK_TC (1<<1)
-+
-+#define TRB_INTR_SHIFT 22
-+#define TRB_INTR_MASK 0x3ff
-+#define TRB_INTR(t) (((t).status >> TRB_INTR_SHIFT) & TRB_INTR_MASK)
-+
-+typedef enum TRBType {
-+ TRB_RESERVED = 0,
-+ TR_NORMAL,
-+ TR_SETUP,
-+ TR_DATA,
-+ TR_STATUS,
-+ TR_ISOCH,
-+ TR_LINK,
-+ TR_EVDATA,
-+ TR_NOOP,
-+ CR_ENABLE_SLOT,
-+ CR_DISABLE_SLOT,
-+ CR_ADDRESS_DEVICE,
-+ CR_CONFIGURE_ENDPOINT,
-+ CR_EVALUATE_CONTEXT,
-+ CR_RESET_ENDPOINT,
-+ CR_STOP_ENDPOINT,
-+ CR_SET_TR_DEQUEUE,
-+ CR_RESET_DEVICE,
-+ CR_FORCE_EVENT,
-+ CR_NEGOTIATE_BW,
-+ CR_SET_LATENCY_TOLERANCE,
-+ CR_GET_PORT_BANDWIDTH,
-+ CR_FORCE_HEADER,
-+ CR_NOOP,
-+ ER_TRANSFER = 32,
-+ ER_COMMAND_COMPLETE,
-+ ER_PORT_STATUS_CHANGE,
-+ ER_BANDWIDTH_REQUEST,
-+ ER_DOORBELL,
-+ ER_HOST_CONTROLLER,
-+ ER_DEVICE_NOTIFICATION,
-+ ER_MFINDEX_WRAP,
-+} TRBType;
-+
-+typedef enum TRBCCode {
-+ CC_INVALID = 0,
-+ CC_SUCCESS,
-+ CC_DATA_BUFFER_ERROR,
-+ CC_BABBLE_DETECTED,
-+ CC_USB_TRANSACTION_ERROR,
-+ CC_TRB_ERROR,
-+ CC_STALL_ERROR,
-+ CC_RESOURCE_ERROR,
-+ CC_BANDWIDTH_ERROR,
-+ CC_NO_SLOTS_ERROR,
-+ CC_INVALID_STREAM_TYPE_ERROR,
-+ CC_SLOT_NOT_ENABLED_ERROR,
-+ CC_EP_NOT_ENABLED_ERROR,
-+ CC_SHORT_PACKET,
-+ CC_RING_UNDERRUN,
-+ CC_RING_OVERRUN,
-+ CC_VF_ER_FULL,
-+ CC_PARAMETER_ERROR,
-+ CC_BANDWIDTH_OVERRUN,
-+ CC_CONTEXT_STATE_ERROR,
-+ CC_NO_PING_RESPONSE_ERROR,
-+ CC_EVENT_RING_FULL_ERROR,
-+ CC_INCOMPATIBLE_DEVICE_ERROR,
-+ CC_MISSED_SERVICE_ERROR,
-+ CC_COMMAND_RING_STOPPED,
-+ CC_COMMAND_ABORTED,
-+ CC_STOPPED,
-+ CC_STOPPED_LENGTH_INVALID,
-+ CC_MAX_EXIT_LATENCY_TOO_LARGE_ERROR = 29,
-+ CC_ISOCH_BUFFER_OVERRUN = 31,
-+ CC_EVENT_LOST_ERROR,
-+ CC_UNDEFINED_ERROR,
-+ CC_INVALID_STREAM_ID_ERROR,
-+ CC_SECONDARY_BANDWIDTH_ERROR,
-+ CC_SPLIT_TRANSACTION_ERROR
-+} TRBCCode;
-+
-+enum {
-+ PLS_U0 = 0,
-+ PLS_U1 = 1,
-+ PLS_U2 = 2,
-+ PLS_U3 = 3,
-+ PLS_DISABLED = 4,
-+ PLS_RX_DETECT = 5,
-+ PLS_INACTIVE = 6,
-+ PLS_POLLING = 7,
-+ PLS_RECOVERY = 8,
-+ PLS_HOT_RESET = 9,
-+ PLS_COMPILANCE_MODE = 10,
-+ PLS_TEST_MODE = 11,
-+ PLS_RESUME = 15,
-+};
-+
-+/* event ring segment */
-+struct grub_xhci_er_seg {
-+ grub_uint32_t ptr_low;
-+ grub_uint32_t ptr_high;
-+ grub_uint32_t size;
-+ grub_uint32_t reserved_01;
-+} GRUB_PACKED;
-+
-+struct grub_xhci_ring {
-+ struct grub_xhci_trb ring[GRUB_XHCI_RING_ITEMS];
-+ struct grub_xhci_trb evt;
-+ grub_uint32_t eidx;
-+ grub_uint32_t nidx;
-+ grub_uint32_t cs;
-+};
-+
-+/* port registers */
-+struct grub_xhci_pr {
-+ grub_uint32_t portsc;
-+ grub_uint32_t portpmsc;
-+ grub_uint32_t portli;
-+ grub_uint32_t reserved_01;
-+} GRUB_PACKED;
-+
-+/* doorbell registers */
-+struct grub_xhci_db {
-+ grub_uint32_t doorbell;
-+} GRUB_PACKED;
-+
-+/* runtime registers */
-+struct grub_xhci_rts {
-+ grub_uint32_t mfindex;
-+} GRUB_PACKED;
-+
-+/* interrupter registers */
-+struct grub_xhci_ir {
-+ grub_uint32_t iman;
-+ grub_uint32_t imod;
-+ grub_uint32_t erstsz;
-+ grub_uint32_t reserved_01;
-+ grub_uint32_t erstba_low;
-+ grub_uint32_t erstba_high;
-+ grub_uint32_t erdp_low;
-+ grub_uint32_t erdp_high;
-+} GRUB_PACKED;
-+
-+struct grub_xhci_psid {
-+ grub_uint8_t id;
-+ grub_uint8_t psie;
-+ grub_uint16_t psim;
-+ grub_uint64_t bitrate;
-+ grub_usb_speed_t grub_usb_speed;
-+};
-+
-+struct grub_xhci_psids {
-+ grub_uint8_t major;
-+ grub_uint8_t minor;
-+ struct grub_xhci_psid psids[16];
-+};
-+
-+struct grub_xhci
-+{
-+ grub_uint8_t shutdown; /* 1 if preparing shutdown of controller */
-+ /* xhci registers */
-+ volatile struct grub_xhci_caps *caps; /* Capability registers */
-+ volatile struct grub_xhci_op *op; /* Operational registers */
-+ volatile struct grub_xhci_pr *pr; /* Port Registers */
-+ volatile struct grub_xhci_db *db; /* doorbell */
-+ volatile struct grub_xhci_ir *ir; /* Interrupt Registers */
-+ /* devinfo */
-+ grub_uint32_t xcap;
-+ grub_uint32_t ports;
-+ grub_uint32_t slots;
-+ grub_uint8_t flag64;
-+ grub_uint16_t spb;
-+ grub_uint32_t pagesize;
-+ struct xhci_portmap usb2;
-+ struct xhci_portmap usb3;
-+ struct grub_xhci_psids *psids;
-+ /* xhci data structures */
-+ struct grub_pci_dma_chunk *devs_dma;
-+ volatile struct grub_xhci_devlist *devs;
-+ struct grub_pci_dma_chunk *cmds_dma;
-+ volatile struct grub_xhci_ring *cmds;
-+ struct grub_pci_dma_chunk *evts_dma;
-+ volatile struct grub_xhci_ring *evts;
-+ struct grub_pci_dma_chunk *eseg_dma;
-+ volatile struct grub_xhci_er_seg *eseg;
-+ struct grub_pci_dma_chunk *spba_dma;
-+ struct grub_pci_dma_chunk *spad_dma;
-+
-+ struct grub_xhci *next;
-+};
-+
-+struct grub_xhci_priv {
-+ grub_uint8_t slotid;
-+ grub_uint32_t max_packet;
-+ struct grub_pci_dma_chunk *enpoint_trbs_dma[32];
-+ volatile struct grub_xhci_ring *enpoint_trbs[32];
-+ struct grub_pci_dma_chunk *slotctx_dma;
-+};
-+
-+struct grub_xhci_port {
-+ grub_uint32_t portsc;
-+ grub_uint32_t portpmsc;
-+ grub_uint32_t portli;
-+ grub_uint32_t reserved_01;
-+};
-+
-+struct grub_xhci_transfer_controller_data {
-+ grub_uint32_t transfer_size;
-+};
-+
-+static struct grub_xhci *xhci;
-+
-+/****************************************************************
-+ * general access functions
-+ ****************************************************************/
-+
-+static inline void
-+grub_xhci_write32(volatile void *addr, grub_uint32_t val) {
-+ *(volatile grub_uint32_t *)addr = val;
-+}
-+static inline void
-+grub_xhci_write16(volatile void *addr, grub_uint16_t val) {
-+ *(volatile grub_uint16_t *)addr = val;
-+}
-+static inline void
-+grub_xhci_write8(void *addr, grub_uint8_t val) {
-+ *(volatile grub_uint8_t *)addr = val;
-+}
-+
-+static inline grub_uint32_t
-+grub_xhci_read32(volatile void *addr) {
-+ return grub_le_to_cpu32 (*((volatile grub_uint32_t *)addr));
-+}
-+
-+static inline grub_uint16_t
-+grub_xhci_read16(volatile void *addr) {
-+ return grub_le_to_cpu16 (*((volatile grub_uint32_t *)addr));
-+}
-+static inline grub_uint8_t
-+grub_xhci_read8(volatile void *addr) {
-+ return (*((volatile grub_uint32_t *)addr));
-+}
-+
-+static inline grub_uint32_t
-+grub_xhci_port_read (struct grub_xhci *x, grub_uint32_t port)
-+{
-+ return grub_xhci_read32(&x->pr[port].portsc);
-+}
-+
-+static inline void
-+grub_xhci_port_write (struct grub_xhci *x, grub_uint32_t port,
-+ grub_uint32_t and_mask, grub_uint32_t or_mask)
-+{
-+ grub_uint32_t reg = grub_xhci_port_read(x, port);
-+ reg &= and_mask;
-+ reg |= or_mask;
-+
-+ grub_xhci_write32(&x->pr[port].portsc, reg);
-+}
-+
-+/****************************************************************
-+ * xhci status and support functions
-+ ****************************************************************/
-+
-+static grub_uint32_t xhci_get_pagesize(struct grub_xhci *x)
-+{
-+ /* Chapter 5.4.3 Page Size Register (PAGESIZE) */
-+ for (grub_uint8_t i = 0; i < 16; i++)
-+ {
-+ if (grub_xhci_read32(&x->op->pagesize) & (1 << i))
-+ return 1 << (12 + i);
-+ }
-+ return 0;
-+}
-+
-+static grub_uint8_t xhci_is_halted(struct grub_xhci *x)
-+{
-+ return !!(grub_xhci_read32(&x->op->usbsts) & 1);
-+}
-+
-+/* Just for debugging */
-+static void xhci_check_status(struct grub_xhci *x)
-+{
-+ grub_uint32_t reg;
-+
-+ reg = grub_xhci_read32(&x->op->usbsts);
-+ if (reg & 1)
-+ grub_dprintf("xhci", "%s: xHCI halted\n", __func__);
-+ if (reg & 2)
-+ grub_dprintf("xhci", "%s: Host system error detected\n", __func__);
-+ if (reg & (1 << 12))
-+ grub_dprintf("xhci", "%s: Internal error detected\n", __func__);
-+ reg = grub_xhci_read32(&x->op->crcr_low);
-+ if (reg & (1 << 3))
-+ grub_dprintf("xhci", "%s: Command ring running\n", __func__);
-+}
-+
-+/* xhci_memalign_dma32 allocates DMA memory satisfying alignment and boundary
-+ * requirements without wasting to much memory */
-+static struct grub_pci_dma_chunk *
-+xhci_memalign_dma32(grub_size_t align,
-+ grub_size_t size,
-+ grub_size_t boundary)
-+{
-+ struct grub_pci_dma_chunk *tmp;
-+ const grub_uint32_t mask = boundary - 1;
-+ grub_uint32_t start, end;
-+
-+ /* Allocate some memory and check if it doesn't cross boundary */
-+ tmp = grub_memalign_dma32(align, size);
-+ start = grub_dma_get_phys(tmp);
-+ end = start + size - 1;
-+ if ((start & mask) == (end & mask))
-+ return tmp;
-+ /* Buffer isn't usable, allocate bigger one */
-+ grub_dma_free(tmp);
-+
-+ return grub_memalign_dma32(boundary, size);
-+}
-+
-+/****************************************************************
-+ * helper functions for in context DMA buffer
-+ ****************************************************************/
-+
-+static int
-+grub_xhci_inctx_size(struct grub_xhci *x)
-+{
-+ const grub_uint8_t cnt = GRUB_XHCI_MAX_ENDPOINTS + 1;
-+ return (sizeof(struct grub_xhci_inctx) * cnt) << x->flag64;
-+}
-+
-+static void
-+grub_xhci_inctx_sync_dma_caches(struct grub_xhci *x, struct grub_pci_dma_chunk *inctx)
-+{
-+ grub_arch_sync_dma_caches(inctx, grub_xhci_inctx_size(x));
-+}
-+
-+static struct grub_pci_dma_chunk *
-+grub_xhci_alloc_inctx(struct grub_xhci *x, int maxepid,
-+ struct grub_usb_device *dev)
-+{
-+ int size = grub_xhci_inctx_size(x);
-+ struct grub_pci_dma_chunk *dma = xhci_memalign_dma32(ALIGN_INCTX, size,
-+ x->pagesize);
-+ if (!dma)
-+ return NULL;
-+
-+ volatile struct grub_xhci_inctx *in = grub_dma_get_virt(dma);
-+ grub_memset((void *)in, 0, size);
-+
-+ struct grub_xhci_slotctx *slot = (void*)&in[1 << x->flag64];
-+ slot->ctx[0] |= maxepid << 27; /* context entries */
-+ grub_dprintf("xhci", "%s: speed=%d root_port=%d\n", __func__, dev->speed, dev->root_port);
-+ switch (dev->speed) {
-+ case GRUB_USB_SPEED_FULL:
-+ slot->ctx[0] |= XHCI_USB_FULLSPEED << 20;
-+ break;
-+ case GRUB_USB_SPEED_HIGH:
-+ slot->ctx[0] |= XHCI_USB_HIGHSPEED << 20;
-+ break;
-+ case GRUB_USB_SPEED_LOW:
-+ slot->ctx[0] |= XHCI_USB_LOWSPEED << 20;
-+ break;
-+ case GRUB_USB_SPEED_SUPER:
-+ slot->ctx[0] |= XHCI_USB_SUPERSPEED << 20;
-+ break;
-+ case GRUB_USB_SPEED_NONE:
-+ slot->ctx[0] |= 0 << 20;
-+ break;
-+ }
-+
-+ /* Route is greater zero on devices that are connected to a non root hub */
-+ if (dev->route)
-+ {
-+ /* FIXME: Implement this code for non SuperSpeed hub devices */
-+ }
-+ slot->ctx[0] |= dev->route;
-+ slot->ctx[1] |= (dev->root_port+1) << 16;
-+
-+ grub_arch_sync_dma_caches(in, size);
-+
-+ return dma;
-+}
-+
-+/****************************************************************
-+ * xHCI event processing
-+ ****************************************************************/
-+
-+/* Dequeue events on the XHCI event ring generated by the hardware */
-+static void xhci_process_events(struct grub_xhci *x)
-+{
-+ volatile struct grub_xhci_ring *evts = x->evts;
-+ /* XXX invalidate caches */
-+
-+ for (;;) {
-+ /* check for event */
-+ grub_uint32_t nidx = grub_xhci_read32(&evts->nidx);
-+ grub_uint32_t cs = grub_xhci_read32(&evts->cs);
-+ volatile struct grub_xhci_trb *etrb = evts->ring + nidx;
-+ grub_uint32_t control = grub_xhci_read32(&etrb->control);
-+ if ((control & TRB_C) != (cs ? 1 : 0))
-+ return;
-+
-+ /* process event */
-+ grub_uint32_t evt_type = TRB_TYPE(control);
-+ grub_uint32_t evt_cc = (grub_xhci_read32(&etrb->status) >> 24) & 0xff;
-+
-+ switch (evt_type)
-+ {
-+ case ER_TRANSFER:
-+ case ER_COMMAND_COMPLETE:
-+ {
-+ struct grub_xhci_trb *rtrb = (void*)grub_xhci_read32(&etrb->ptr_low);
-+ struct grub_xhci_ring *ring = XHCI_RING(rtrb);
-+ volatile struct grub_xhci_trb *evt = &ring->evt;
-+ grub_uint32_t eidx = rtrb - ring->ring + 1;
-+ grub_dprintf("xhci", "%s: ring %p [trb %p, evt %p, type %d, eidx %d, cc %d]\n",
-+ __func__, ring, rtrb, evt, evt_type, eidx, evt_cc);
-+ *evt = *etrb;
-+ grub_xhci_write32(&ring->eidx, eidx);
-+ break;
-+ }
-+ case ER_PORT_STATUS_CHANGE:
-+ {
-+ /* Nothing to do here. grub_xhci_detect_dev will handle it */
-+ break;
-+ }
-+ default:
-+ {
-+ grub_dprintf("xhci", "%s: unknown event, type %d, cc %d\n",
-+ __func__, evt_type, evt_cc);
-+ break;
-+ }
-+ }
-+
-+ /* move ring index, notify xhci */
-+ nidx++;
-+ if (nidx == GRUB_XHCI_RING_ITEMS)
-+ {
-+ nidx = 0;
-+ cs = cs ? 0 : 1;
-+ grub_xhci_write32(&evts->cs, cs);
-+ }
-+ grub_xhci_write32(&evts->nidx, nidx);
-+ volatile struct grub_xhci_ir *ir = x->ir;
-+ grub_uint32_t erdp = (grub_uint32_t)(evts->ring + nidx);
-+ grub_xhci_write32(&ir->erdp_low, erdp);
-+ grub_xhci_write32(&ir->erdp_high, 0);
-+ }
-+}
-+
-+/****************************************************************
-+ * TRB handling
-+ ****************************************************************/
-+
-+/* Signal the hardware to process events on a TRB ring */
-+static void xhci_doorbell(struct grub_xhci *x, grub_uint32_t slotid, grub_uint32_t value)
-+{
-+ xhci_check_status(x);
-+ grub_dprintf("xhci", "%s: slotid %d, epid %d\n", __func__, slotid, value);
-+ grub_xhci_write32(&x->db[slotid].doorbell, value);
-+}
-+
-+/* Check if a ring has any pending TRBs */
-+static int xhci_ring_busy(volatile struct grub_xhci_ring *ring)
-+{
-+ grub_uint32_t eidx = grub_xhci_read32(&ring->eidx);
-+ grub_uint32_t nidx = grub_xhci_read32(&ring->nidx);
-+
-+ return (eidx != nidx);
-+}
-+
-+/* Returns free space in ring */
-+static int xhci_ring_free_space(volatile struct grub_xhci_ring *ring)
-+{
-+ grub_uint32_t eidx = grub_xhci_read32(&ring->eidx);
-+ grub_uint32_t nidx = grub_xhci_read32(&ring->nidx);
-+
-+ /* nidx is never 0, so reduce ring buffer size by one */
-+ return (eidx > nidx) ? eidx-nidx
-+ : (ARRAY_SIZE(ring->ring) - 1) - nidx + eidx;
-+}
-+
-+/* Check if a ring is full */
-+static int xhci_ring_full(volatile struct grub_xhci_ring *ring)
-+{
-+ /* Might need to insert one link TRB */
-+ return xhci_ring_free_space(ring) <= 1;
-+}
-+
-+/* Check if a ring is almost full */
-+static int xhci_ring_almost_full(volatile struct grub_xhci_ring *ring)
-+{
-+ /* Might need to insert one link TRB */
-+ return xhci_ring_free_space(ring) <= 2;
-+}
-+
-+/* Wait for a ring to empty (all TRBs processed by hardware) */
-+static int xhci_event_wait(struct grub_xhci *x,
-+ volatile struct grub_xhci_ring *ring,
-+ grub_uint32_t timeout)
-+{
-+ grub_uint32_t end = grub_get_time_ms () + timeout;
-+
-+ for (;;)
-+ {
-+ xhci_check_status(x);
-+ xhci_process_events(x);
-+ if (!xhci_ring_busy(ring))
-+ {
-+ grub_uint32_t status = ring->evt.status;
-+ return (status >> 24) & 0xff;
-+ }
-+ if (grub_get_time_ms () > end)
-+ {
-+ xhci_check_status(x);
-+ grub_dprintf("xhci", "%s: Timeout waiting for event\n", __func__);
-+ return -1;
-+ }
-+ }
-+}
-+
-+/* Add a TRB to the given ring, either regular or inline */
-+static void xhci_trb_fill(volatile struct grub_xhci_ring *ring,
-+ grub_uint64_t ptr, grub_uint32_t xferlen,
-+ grub_uint32_t flags)
-+{
-+ volatile struct grub_xhci_trb *dst = &ring->ring[ring->nidx];
-+ dst->ptr_low = ptr & 0xffffffff;
-+ dst->ptr_high = ptr >> 32;
-+ dst->status = xferlen;
-+ dst->control = flags | (ring->cs ? TRB_C : 0);
-+
-+ grub_arch_sync_dma_caches(dst, sizeof(ring->ring[0]));
-+}
-+
-+/*
-+ * Queue a TRB onto a ring.
-+ *
-+ * The caller must pass a pointer to the data in physical address-space or the
-+ * data itself (but no more than 8 bytes) in data_or_addr. Inline data must have
-+ * the flag TRB_TR_IDT set.
-+ */
-+static void xhci_trb_queue(volatile struct grub_xhci_ring *ring,
-+ grub_uint64_t data_or_addr,
-+ grub_uint32_t xferlen, grub_uint32_t flags)
-+{
-+ grub_dprintf("xhci", "%s: ring %p data %llx len %d flags 0x%x remain 0x%x\n", __func__,
-+ ring, data_or_addr, xferlen & 0x1ffff, flags, xferlen >> 17);
-+
-+ if (xhci_ring_full(ring))
-+ {
-+ grub_dprintf("xhci", "%s: ERROR: ring %p is full, discarding TRB\n",
-+ __func__, ring);
-+ return;
-+ }
-+
-+ if (ring->nidx >= ARRAY_SIZE(ring->ring) - 1)
-+ {
-+ /* Reset to command buffer pointer to the first element */
-+ xhci_trb_fill(ring, (grub_addr_t)ring->ring, 0, (TR_LINK << 10) | TRB_LK_TC);
-+ ring->nidx = 0;
-+ ring->cs ^= 1;
-+ grub_dprintf("xhci", "%s: ring %p [linked]\n", __func__, ring);
-+ }
-+
-+ xhci_trb_fill(ring, data_or_addr, xferlen, flags);
-+ ring->nidx++;
-+ grub_dprintf("xhci", "%s: ring %p [nidx %d, len %d]\n",
-+ __func__, ring, ring->nidx, xferlen);
-+}
-+
-+/*
-+ * Queue a TRB onto a ring and flush it if necessary.
-+ *
-+ * The caller must pass a pointer to the data in physical address-space or the
-+ * data itself (but no more than 8 bytes) in data_or_addr. Inline data must have
-+ * the flag TRB_TR_IDT set.
-+ */
-+static int xhci_trb_queue_and_flush(struct grub_xhci *x,
-+ grub_uint32_t slotid,
-+ grub_uint32_t epid,
-+ volatile struct grub_xhci_ring *ring,
-+ grub_uint64_t data_or_addr,
-+ grub_uint32_t xferlen, grub_uint32_t flags)
-+{
-+ grub_uint8_t submit = 0;
-+ if (xhci_ring_almost_full(ring))
-+ {
-+ grub_dprintf("xhci", "%s: almost full e %d n %d\n", __func__, ring->eidx, ring->nidx);
-+ flags |= TRB_TR_IOC;
-+ submit = 1;
-+ }
-+ /* Note: xhci_trb_queue might queue on or two elements, if the end of the TRB
-+ * has been reached. The caller must account for that when filling the TRB. */
-+ xhci_trb_queue(ring, data_or_addr, xferlen, flags);
-+ /* Submit if less no free slot is remaining, we might need an additional
-+ * one on the next call to this function. */
-+ if (submit)
-+ {
-+ xhci_doorbell(x, slotid, epid);
-+ int rc = xhci_event_wait(x, ring, 1000);
-+ grub_dprintf("xhci", "%s: xhci_event_wait = %d\n", __func__, rc);
-+ return rc;
-+ }
-+ return 0;
-+}
-+
-+/****************************************************************
-+ * xHCI command functions
-+ ****************************************************************/
-+
-+/* Submit a command to the xHCI command TRB */
-+static int xhci_cmd_submit(struct grub_xhci *x,
-+ struct grub_pci_dma_chunk *inctx_dma,
-+ grub_uint32_t flags)
-+{
-+ volatile struct grub_xhci_inctx *inctx;
-+ /* Don't submit if halted, it will fail */
-+ if (xhci_is_halted(x))
-+ return -1;
-+
-+ if (inctx_dma)
-+ {
-+ grub_xhci_inctx_sync_dma_caches(x, inctx_dma);
-+
-+ inctx = grub_dma_get_virt(inctx_dma);
-+
-+ struct grub_xhci_slotctx *slot = (void*)&inctx[1 << x->flag64];
-+ grub_uint32_t port = ((slot->ctx[1] >> 16) & 0xff) - 1;
-+ grub_uint32_t portsc = grub_xhci_port_read(x, port);
-+ if (!(portsc & GRUB_XHCI_PORTSC_CCS))
-+ {
-+ grub_dprintf("xhci", "%s: root port %d no longer connected\n",
-+ __func__, port);
-+ return -1;
-+ }
-+ xhci_trb_queue(x->cmds, grub_dma_get_phys(inctx_dma), 0, flags);
-+ }
-+ else
-+ {
-+ xhci_trb_queue(x->cmds, 0, 0, flags);
-+ }
-+
-+ xhci_doorbell(x, 0, 0);
-+ int rc = xhci_event_wait(x, x->cmds, 1000);
-+ grub_dprintf("xhci", "%s: xhci_event_wait = %d\n", __func__, rc);
-+
-+ return rc;
-+}
-+
-+static int xhci_cmd_enable_slot(struct grub_xhci *x)
-+{
-+ grub_uint32_t flags = 0;
-+ flags |= (CR_ENABLE_SLOT << 10);
-+
-+ grub_dprintf("xhci", "%s:\n", __func__);
-+ int cc = xhci_cmd_submit(x, NULL, flags);
-+ if (cc != CC_SUCCESS)
-+ return -1;
-+ grub_dprintf("xhci", "%s: %p\n", __func__, &x->cmds->evt.control);
-+ grub_dprintf("xhci", "%s: %x\n", __func__, grub_xhci_read32(&x->cmds->evt.control));
-+
-+ return (grub_xhci_read32(&x->cmds->evt.control) >> 24) & 0xff;
-+}
-+
-+static int xhci_cmd_disable_slot(struct grub_xhci *x, grub_uint32_t slotid)
-+{
-+ grub_uint32_t flags = 0;
-+ flags |= (CR_DISABLE_SLOT << 10);
-+ flags |= (slotid << 24);
-+
-+ grub_dprintf("xhci", "%s: slotid %d\n", __func__, slotid);
-+ return xhci_cmd_submit(x, NULL, flags);
-+}
-+
-+static int xhci_cmd_stop_endpoint(struct grub_xhci *x, grub_uint32_t slotid
-+ , grub_uint32_t epid
-+ , grub_uint32_t suspend)
-+{
-+ grub_uint32_t flags = 0;
-+ flags |= (CR_STOP_ENDPOINT << 10);
-+ flags |= (epid << 16);
-+ flags |= (suspend << 23) ;
-+ flags |= (slotid << 24);
-+
-+ return xhci_cmd_submit(x, NULL, flags);
-+}
-+
-+static int xhci_cmd_reset_endpoint(struct grub_xhci *x, grub_uint32_t slotid
-+ , grub_uint32_t epid
-+ , grub_uint32_t preserve)
-+{
-+ grub_uint32_t flags = 0;
-+ flags |= (preserve << 9);
-+ flags |= (CR_RESET_ENDPOINT << 10);
-+ flags |= (epid << 16);
-+ flags |= (slotid << 24);
-+
-+ return xhci_cmd_submit(x, NULL, flags);
-+}
-+
-+static int xhci_cmd_set_dequeue_pointer(struct grub_xhci *x, grub_uint32_t slotid
-+ , grub_uint32_t epid
-+ , grub_addr_t tr_deque_pointer)
-+{
-+ grub_uint32_t flags = 0;
-+ flags |= (CR_SET_TR_DEQUEUE << 10);
-+ flags |= (epid << 16);
-+ flags |= (slotid << 24);
-+
-+ xhci_trb_queue(x->cmds, tr_deque_pointer, 0, flags);
-+
-+ xhci_doorbell(x, 0, 0);
-+ int rc = xhci_event_wait(x, x->cmds, 1000);
-+ grub_dprintf("xhci", "%s: xhci_event_wait = %d\n", __func__, rc);
-+
-+ return rc;
-+}
-+
-+static int xhci_cmd_address_device(struct grub_xhci *x, grub_uint32_t slotid,
-+ struct grub_pci_dma_chunk *inctx_dma)
-+{
-+ grub_uint32_t flags = 0;
-+ flags |= (CR_ADDRESS_DEVICE << 10);
-+ flags |= (slotid << 24);
-+
-+ grub_dprintf("xhci", "%s: slotid %d\n", __func__, slotid);
-+ return xhci_cmd_submit(x, inctx_dma, flags);
-+}
-+
-+static int xhci_cmd_configure_endpoint(struct grub_xhci *x, grub_uint32_t slotid,
-+ struct grub_pci_dma_chunk *inctx_dma)
-+{
-+ grub_uint32_t flags = 0;
-+ flags |= (CR_CONFIGURE_ENDPOINT << 10);
-+ flags |= (slotid << 24);
-+
-+ grub_dprintf("xhci", "%s: slotid %d\n", __func__, slotid);
-+ return xhci_cmd_submit(x, inctx_dma, flags);
-+}
-+
-+static int xhci_cmd_evaluate_context(struct grub_xhci *x, grub_uint32_t slotid,
-+ struct grub_pci_dma_chunk *inctx_dma)
-+{
-+ grub_uint32_t flags = 0;
-+ flags |= (CR_EVALUATE_CONTEXT << 10);
-+ flags |= (slotid << 24);
-+
-+ grub_dprintf("xhci", "%s: slotid %d\n", __func__, slotid);
-+ return xhci_cmd_submit(x, inctx_dma, flags);
-+}
-+
-+/****************************************************************
-+ * xHCI host controller initialization
-+ ****************************************************************/
-+
-+static grub_usb_err_t
-+grub_xhci_reset (struct grub_xhci *x)
-+{
-+ grub_uint32_t reg;
-+ grub_uint32_t end;
-+
-+ reg = grub_xhci_read32(&x->op->usbcmd);
-+ if (reg & GRUB_XHCI_CMD_RS)
-+ {
-+ reg &= ~GRUB_XHCI_CMD_RS;
-+ grub_xhci_write32(&x->op->usbcmd, reg);
-+
-+ end = grub_get_time_ms () + 32;
-+ while (grub_xhci_read32(&x->op->usbcmd) & GRUB_XHCI_STS_HCH)
-+ {
-+ if (grub_get_time_ms () > end)
-+ return GRUB_USB_ERR_TIMEOUT;
-+
-+ grub_millisleep(1);
-+ }
-+ }
-+
-+ grub_dprintf("xhci", "grub_xhci_reset: resetting HC\n");
-+ grub_xhci_write32(&x->op->usbcmd, GRUB_XHCI_CMD_HCRST);
-+
-+ /* Wait for device to complete reset and be enabled */
-+ end = grub_get_time_ms () + 100;
-+ while (grub_xhci_read32(&x->op->usbcmd) & GRUB_XHCI_CMD_HCRST)
-+ {
-+ if (grub_get_time_ms () > end)
-+ return GRUB_USB_ERR_TIMEOUT;
-+
-+ grub_millisleep(1);
-+ }
-+
-+ /* Wait for device to complete reset and be enabled */
-+ end = grub_get_time_ms () + 100;
-+ while (grub_xhci_read32(&x->op->usbsts) & GRUB_XHCI_STS_CNR)
-+ {
-+ if (grub_get_time_ms () > end)
-+ return GRUB_USB_ERR_TIMEOUT;
-+
-+ grub_millisleep(1);
-+ }
-+
-+ grub_xhci_write32(&x->op->config, x->slots);
-+ grub_xhci_write32(&x->op->dcbaap_low, grub_dma_get_phys(x->devs_dma));
-+ grub_xhci_write32(&x->op->dcbaap_high, 0);
-+ grub_xhci_write32(&x->op->crcr_low, grub_dma_get_phys(x->cmds_dma)| 1);
-+ grub_xhci_write32(&x->op->crcr_high, 0);
-+ x->cmds->cs = 1;
-+
-+ grub_arch_sync_dma_caches(x->cmds, sizeof(*x->cmds));
-+
-+ x->eseg->ptr_low = grub_dma_get_phys(x->evts_dma);
-+ x->eseg->ptr_high = 0;
-+ x->eseg->size = GRUB_XHCI_RING_ITEMS;
-+
-+ grub_arch_sync_dma_caches(x->eseg, sizeof(*x->eseg));
-+
-+ grub_xhci_write32(&x->ir->erstsz, 1);
-+ grub_xhci_write32(&x->ir->erdp_low, grub_dma_get_phys(x->evts_dma));
-+ grub_xhci_write32(&x->ir->erdp_high, 0);
-+ grub_xhci_write32(&x->ir->erstba_low, grub_dma_get_phys(x->eseg_dma));
-+ grub_xhci_write32(&x->ir->erstba_high, 0);
-+ x->evts->cs = 1;
-+
-+ grub_arch_sync_dma_caches(x->evts, sizeof(*x->eseg));
-+
-+ xhci_check_status(x);
-+
-+ grub_dprintf ("xhci", "XHCI OP COMMAND: %08x\n",
-+ grub_xhci_read32 (&x->op->usbcmd));
-+ grub_dprintf ("xhci", "XHCI OP STATUS: %08x\n",
-+ grub_xhci_read32 (&x->op->usbsts));
-+ grub_dprintf ("xhci", "XHCI OP PAGESIZE: %08x\n",
-+ grub_xhci_read32 (&x->op->pagesize));
-+ grub_dprintf ("xhci", "XHCI OP DNCTRL: %08x\n",
-+ grub_xhci_read32 (&x->op->dnctl));
-+ grub_dprintf ("xhci", "XHCI OP CRCR_LOW: %08x\n",
-+ grub_xhci_read32 (&x->op->crcr_low));
-+ grub_dprintf ("xhci", "XHCI OP CRCR_HIGH: %08x\n",
-+ grub_xhci_read32 (&x->op->crcr_high));
-+ grub_dprintf ("xhci", "XHCI OP DCBAAP_LOW: %08x\n",
-+ grub_xhci_read32 (&x->op->dcbaap_low));
-+ grub_dprintf ("xhci", "XHCI OP DCBAAP_HIGH: %08x\n",
-+ grub_xhci_read32 (&x->op->dcbaap_high));
-+ grub_dprintf ("xhci", "XHCI OP CONFIG: %08x\n",
-+ grub_xhci_read32 (&x->op->config));
-+ grub_dprintf ("xhci", "XHCI IR ERSTSZ: %08x\n",
-+ grub_xhci_read32 (&x->ir->erstsz));
-+ grub_dprintf ("xhci", "XHCI IR ERDP: %08x\n",
-+ grub_xhci_read32 (&x->ir->erdp_low));
-+ grub_dprintf ("xhci", "XHCI IR ERSTBA: %08x\n",
-+ grub_xhci_read32 (&x->ir->erstba_low));
-+
-+ xhci_check_status(x);
-+
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+static grub_usb_err_t
-+grub_xhci_request_legacy_handoff(volatile struct grub_xhci_xcap *xcap)
-+{
-+ grub_uint32_t end;
-+
-+ end = grub_get_time_ms () + 10;
-+ for (;;)
-+ {
-+ grub_uint32_t cap = grub_xhci_read32(&xcap->cap);
-+ if (cap & (1 << 16))
-+ grub_xhci_write32(&xcap->cap, cap | (1 << 24));
-+ else
-+ break;
-+
-+ if (grub_get_time_ms () > end)
-+ {
-+ grub_dprintf ("xhci","ERROR: %s TIMEOUT\n", __func__);
-+ return GRUB_USB_ERR_TIMEOUT;
-+ }
-+ grub_millisleep(1);
-+ }
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+static void
-+grub_xhci_fill_default_speed_mapping(struct grub_xhci_psids *ids)
-+{
-+ /* Chapter 7.2.2.1.1 "Default USB Speed ID Mapping" */
-+ ids->psids[0].id = 1;
-+ ids->psids[0].psie = 2;
-+ ids->psids[0].psim = 12;
-+ ids->psids[1].id = 2;
-+ ids->psids[1].psie = 1;
-+ ids->psids[1].psim = 1500;
-+ ids->psids[2].id = 3;
-+ ids->psids[2].psie = 2;
-+ ids->psids[2].psim = 480;
-+ ids->psids[3].id = 4;
-+ ids->psids[3].psie = 3;
-+ ids->psids[3].psim = 5;
-+ ids->psids[4].id = 5;
-+ ids->psids[4].psie = 3;
-+ ids->psids[4].psim = 10;
-+ ids->psids[5].id = 6;
-+ ids->psids[5].psie = 3;
-+ ids->psids[5].psim = 10;
-+ ids->psids[6].id = 7;
-+ ids->psids[6].psie = 3;
-+ ids->psids[6].psim = 20;
-+}
-+
-+static void
-+grub_xhci_calc_speed_mapping(struct grub_xhci_psids *ids)
-+{
-+ const grub_uint64_t mult[4] = {1ULL, 1000ULL, 1000000ULL, 1000000000ULL};
-+
-+ for (grub_uint8_t i = 0; i < 16; i++)
-+ {
-+ if (ids->psids[i].id == 0)
-+ continue;
-+ ids->psids[i].bitrate = mult[ids->psids[i].psie & 3] * (grub_uint64_t)ids->psids[i].psim;
-+ if (ids->psids[i].bitrate < 12000000ULL)
-+ ids->psids[i].grub_usb_speed = GRUB_USB_SPEED_LOW;
-+ else if (ids->psids[i].bitrate < 480000000ULL)
-+ ids->psids[i].grub_usb_speed = GRUB_USB_SPEED_FULL;
-+ else if (ids->psids[i].bitrate > 1200000000ULL)
-+ ids->psids[i].grub_usb_speed = GRUB_USB_SPEED_SUPER;
-+ else
-+ ids->psids[i].grub_usb_speed = GRUB_USB_SPEED_HIGH;
-+ }
-+}
-+
-+
-+/* PCI iteration function... */
-+void
-+grub_xhci_init_device (volatile void *regs)
-+{
-+ struct grub_xhci *x;
-+ grub_uint32_t hcs1, hcc, reg;
-+
-+ /* Allocate memory for the controller and fill basic values. */
-+ x = grub_zalloc (sizeof (*x));
-+ if (!x)
-+ {
-+ grub_dprintf("xhci", "Failed to allocate memory\n");
-+ return;
-+ }
-+ x->caps = (volatile struct grub_xhci_caps *) regs;
-+ x->op = (volatile struct grub_xhci_op *) (((grub_uint8_t *)regs) +
-+ grub_xhci_read8(&x->caps->caplength));
-+ x->pr = (volatile struct grub_xhci_pr *) (((grub_uint8_t *)x->op) +
-+ GRUB_XHCI_PR_OFFSET);
-+ x->db = (volatile struct grub_xhci_db *) (((grub_uint8_t *)regs) +
-+ grub_xhci_read32(&x->caps->dboff));
-+ x->ir = (volatile struct grub_xhci_ir *) (((grub_uint8_t *)regs) +
-+ grub_xhci_read32(&x->caps->rtsoff) + GRUB_XHCI_IR_OFFSET);
-+
-+ grub_dprintf ("xhci", "XHCI init: CAPLENGTH: 0x%02x\n",
-+ grub_xhci_read8 (&x->caps->caplength));
-+ grub_dprintf ("xhci", "XHCI init: HCIVERSION: 0x%04x\n",
-+ grub_xhci_read16 (&x->caps->hciversion));
-+ grub_dprintf ("xhci", "XHCI init: HCSPARAMS1: 0x%08x\n",
-+ grub_xhci_read32 (&x->caps->hcsparams1));
-+ grub_dprintf ("xhci", "XHCI init: HCSPARAMS2: 0x%08x\n",
-+ grub_xhci_read32 (&x->caps->hcsparams2));
-+ grub_dprintf ("xhci", "XHCI init: HCSPARAMS3: 0x%08x\n",
-+ grub_xhci_read32 (&x->caps->hcsparams3));
-+ grub_dprintf ("xhci", "XHCI init: HCCPARAMS: 0x%08x\n",
-+ grub_xhci_read32 (&x->caps->hcsparams3));
-+ grub_dprintf ("xhci", "XHCI init: DBOFF: 0x%08x\n",
-+ grub_xhci_read32 (&x->caps->dboff));
-+ grub_dprintf ("xhci", "XHCI init: RTOFF: 0x%08x\n",
-+ grub_xhci_read32 (&x->caps->rtsoff));
-+
-+ hcs1 = grub_xhci_read32(&x->caps->hcsparams1);
-+ hcc = grub_xhci_read32(&x->caps->hccparams);
-+ x->ports = (grub_uint32_t) ((hcs1 >> 24) & 0xff);
-+ x->slots = (grub_uint32_t) (hcs1 & 0xff);
-+ x->xcap = (grub_uint32_t) ((hcc >> 16) & 0xffff) * sizeof(grub_uint32_t);
-+ x->flag64 = (grub_uint8_t) ((hcc & 0x04) ? 1 : 0);
-+ grub_dprintf("xhci", "XHCI init: %d ports, %d slots, %d byte contexts\n"
-+ , x->ports, x->slots, x->flag64 ? 64 : 32);
-+
-+ x->psids = grub_zalloc (sizeof (struct grub_xhci_psids) * x->ports);
-+ if (x->xcap)
-+ {
-+ grub_uint32_t off;
-+ volatile grub_uint8_t *addr = (grub_uint8_t *) x->caps + x->xcap;
-+ do
-+ {
-+ volatile struct grub_xhci_xcap *xcap = (void *)addr;
-+ grub_uint32_t ports, name, cap = grub_xhci_read32(&xcap->cap);
-+ switch (cap & 0xff) {
-+ case XHCI_CAP_LEGACY_SUPPORT:
-+ {
-+ if (grub_xhci_request_legacy_handoff(xcap) != GRUB_USB_ERR_NONE)
-+ {
-+ grub_dprintf("xhci", "XHCI init: Failed to get xHCI ownership\n");
-+ goto fail;
-+ }
-+ break;
-+ }
-+ case XHCI_CAP_SUPPORTED_PROTOCOL:
-+ {
-+ name = grub_xhci_read32(&xcap->data[0]);
-+ ports = grub_xhci_read32(&xcap->data[1]);
-+ const grub_uint8_t major = (cap >> 24) & 0xff;
-+ const grub_uint8_t minor = (cap >> 16) & 0xff;
-+ const grub_uint8_t psic = (ports >> 28) & 0xf;
-+ const grub_uint8_t count = (ports >> 8) & 0xff;
-+ const grub_uint8_t start = (ports >> 0) & 0xff;
-+ grub_dprintf("xhci", "XHCI init: protocol %c%c%c%c %x.%02x"
-+ ", %d ports (offset %d), def %x, psic %d\n"
-+ , (name >> 0) & 0xff
-+ , (name >> 8) & 0xff
-+ , (name >> 16) & 0xff
-+ , (name >> 24) & 0xff
-+ , major, minor
-+ , count, start
-+ , ports >> 16
-+ , psic);
-+ if (name == 0x20425355 /* "USB " */)
-+ {
-+ if (major == 2)
-+ {
-+ x->usb2.start = start;
-+ x->usb2.count = count;
-+ }
-+ else if (major == 3)
-+ {
-+ x->usb3.start = start;
-+ x->usb3.count = count;
-+ }
-+
-+ for (grub_uint32_t p = start - 1; p < start + count - 1UL; p++)
-+ {
-+ x->psids[p].major = major;
-+ x->psids[p].minor = minor;
-+ grub_xhci_fill_default_speed_mapping(&x->psids[p]);
-+ for (grub_uint8_t i = 0; i < psic; i++)
-+ {
-+ grub_uint32_t psid = grub_xhci_read32(&xcap->data[3 + i]);
-+ x->psids[p].psids[i].id = (psid >> 0) & 0xf;
-+ x->psids[p].psids[i].psie = (psid >> 4) & 0x3;
-+ x->psids[p].psids[i].psim = (psid >> 16) & 0xfffff;
-+ }
-+ grub_xhci_calc_speed_mapping(&x->psids[p]);
-+ }
-+ }
-+
-+ break;
-+ }
-+ default:
-+ {
-+ grub_dprintf("xhci", "XHCI extcap 0x%x @ %p\n", cap & 0xff, addr);
-+ break;
-+ }
-+ }
-+ off = (cap >> 8) & 0xff;
-+ addr += off << 2;
-+ }
-+ while (off > 0);
-+ }
-+
-+ x->pagesize = xhci_get_pagesize(x);
-+ grub_dprintf("xhci", "XHCI init: Minimum supported page size 0x%x\n",
-+ x->pagesize);
-+
-+ /* Chapter 6.1 Device Context Base Address Array */
-+ x->devs_dma = xhci_memalign_dma32(ALIGN_DCBAA,
-+ sizeof(*x->devs) * (x->slots + 1),
-+ x->pagesize);
-+ if (!x->devs_dma)
-+ goto fail;
-+ x->devs = grub_dma_get_virt(x->devs_dma);
-+ grub_memset((void *)x->devs, 0, sizeof(*x->devs) * (x->slots + 1));
-+ grub_arch_sync_dma_caches(x->devs, sizeof(*x->devs) * (x->slots + 1));
-+ grub_dprintf ("xhci", "XHCI init: device memory %p (%x)\n",
-+ grub_dma_get_virt(x->devs_dma),
-+ grub_dma_get_phys(x->devs_dma));
-+
-+ /* Chapter 6.5 Event Ring Segment Table */
-+ x->eseg_dma = xhci_memalign_dma32(ALIGN_EVT_RING_TABLE, sizeof(*x->eseg), 0);
-+ if (!x->eseg_dma)
-+ goto fail;
-+ x->eseg = grub_dma_get_virt(x->eseg_dma);
-+ grub_memset((void *)x->eseg, 0, sizeof(*x->eseg));
-+ grub_arch_sync_dma_caches(x->eseg, sizeof(*x->eseg));
-+ grub_dprintf ("xhci", "XHCI init: event ring table memory %p (%x)\n",
-+ grub_dma_get_virt(x->eseg_dma),
-+ grub_dma_get_phys(x->eseg_dma));
-+
-+ x->cmds_dma = xhci_memalign_dma32(ALIGN_CMD_RING_SEG, sizeof(*x->cmds),
-+ BOUNDARY_RING);
-+ if (!x->cmds_dma)
-+ goto fail;
-+ x->cmds = grub_dma_get_virt(x->cmds_dma);
-+ grub_memset((void *)x->cmds, 0, sizeof(*x->cmds));
-+ grub_arch_sync_dma_caches(x->cmds, sizeof(*x->cmds));
-+ grub_dprintf ("xhci", "XHCI init: command ring memory %p (%x)\n",
-+ grub_dma_get_virt(x->cmds_dma),
-+ grub_dma_get_phys(x->cmds_dma));
-+
-+ x->evts_dma = xhci_memalign_dma32(ALIGN_EVT_RING_SEG, sizeof(*x->evts),
-+ BOUNDARY_RING);
-+ if (!x->evts_dma)
-+ goto fail;
-+ x->evts = grub_dma_get_virt(x->evts_dma);
-+ grub_memset((void *)x->evts, 0, sizeof(*x->evts));
-+ grub_arch_sync_dma_caches(x->evts, sizeof(*x->evts));
-+ grub_dprintf ("xhci", "XHCI init: event ring memory %p (%x)\n",
-+ grub_dma_get_virt(x->evts_dma),
-+ grub_dma_get_phys(x->evts_dma));
-+
-+ /* Chapter 4.20 Scratchpad Buffers */
-+ reg = grub_xhci_read32(&x->caps->hcsparams2);
-+ x->spb = (reg >> 21 & 0x1f) << 5 | reg >> 27;
-+ if (x->spb)
-+ {
-+ volatile grub_uint64_t *spba;
-+ grub_dprintf("xhci", "XHCI init: set up %d scratch pad buffers\n",
-+ x->spb);
-+ x->spba_dma = xhci_memalign_dma32(ALIGN_SPBA, sizeof(*spba) * x->spb,
-+ x->pagesize);
-+ if (!x->spba_dma)
-+ goto fail;
-+
-+ x->spad_dma = xhci_memalign_dma32(x->pagesize, x->pagesize * x->spb,
-+ x->pagesize);
-+ if (!x->spad_dma)
-+ {
-+ grub_dma_free(x->spba_dma);
-+ goto fail;
-+ }
-+
-+ spba = grub_dma_get_virt(x->spba_dma);
-+ for (grub_uint32_t i = 0; i < x->spb; i++)
-+ spba[i] = (grub_addr_t)grub_dma_get_phys(x->spad_dma) + (i * x->pagesize);
-+ grub_arch_sync_dma_caches(x->spba_dma, sizeof(*spba) * x->spb);
-+
-+ x->devs[0].ptr_low = grub_dma_get_phys(x->spba_dma);
-+ x->devs[0].ptr_high = 0;
-+ grub_arch_sync_dma_caches(x->devs_dma, sizeof(x->devs[0]));
-+ grub_dprintf ("xhci", "XHCI init: Allocated %d scratch buffers of size 0x%x\n",
-+ x->spb, x->pagesize);
-+ }
-+
-+ grub_xhci_reset(x);
-+
-+ /* Set the running bit */
-+ reg = grub_xhci_read32 (&x->op->usbcmd);
-+ reg |= GRUB_XHCI_CMD_RS;
-+ grub_xhci_write32 (&x->op->usbcmd, reg);
-+
-+
-+ /* Link to xhci now that initialisation is successful. */
-+ x->next = xhci;
-+ xhci = x;
-+
-+ return;
-+
-+fail:
-+ grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: FAILED!\n");
-+ if (x)
-+ {
-+ if (x->devs_dma)
-+ grub_dma_free (x->devs_dma);
-+ if (x->eseg_dma)
-+ grub_dma_free (x->eseg_dma);
-+ if (x->cmds_dma)
-+ grub_dma_free (x->cmds_dma);
-+ if (x->evts_dma)
-+ grub_dma_free (x->evts_dma);
-+ if (x->spad_dma)
-+ grub_dma_free (x->spad_dma);
-+ if (x->spba_dma)
-+ grub_dma_free (x->spba_dma);
-+ }
-+ grub_free (x);
-+
-+ return;
-+}
-+
-+static int
-+grub_xhci_iterate (grub_usb_controller_iterate_hook_t hook, void *hook_data)
-+{
-+ struct grub_xhci *x;
-+ struct grub_usb_controller dev;
-+
-+ for (x = xhci; x; x = x->next)
-+ {
-+ dev.data = x;
-+ if (hook (&dev, hook_data))
-+ return 1;
-+ }
-+
-+ return 0;
-+}
-+
-+/****************************************************************
-+ * xHCI maintainance functions
-+ ****************************************************************/
-+
-+static grub_usb_err_t
-+grub_xhci_update_hub_portcount (struct grub_xhci *x,
-+ grub_usb_transfer_t transfer,
-+ grub_uint32_t slotid)
-+{
-+ struct grub_pci_dma_chunk *in_dma;
-+ volatile struct grub_xhci_slotctx *hdslot;
-+ grub_uint32_t epid = 0;
-+
-+ if (!transfer || !transfer->dev || !transfer->dev->nports)
-+ return GRUB_USB_ERR_NONE;
-+
-+ hdslot = grub_dma_phys2virt(x->devs[slotid].ptr_low, x->devs_dma);
-+ if ((hdslot->ctx[3] >> 27) == 3)
-+ /* Already configured */
-+ return 0;
-+
-+ grub_dprintf("xhci", "%s: updating hub config to %d ports\n", __func__,
-+ transfer->dev->nports);
-+
-+ xhci_check_status(x);
-+
-+ /* Allocate input context and initialize endpoint info. */
-+ in_dma = grub_xhci_alloc_inctx(x, epid, transfer->dev);
-+ if (!in_dma)
-+ return GRUB_USB_ERR_INTERNAL;
-+ volatile struct grub_xhci_inctx *in = grub_dma_get_virt(in_dma);
-+
-+ in->add = (1 << epid);
-+
-+ struct grub_xhci_epctx *ep = (void*)&in[(epid+1) << x->flag64];
-+ ep->ctx[0] |= 1 << 26;
-+ ep->ctx[1] |= transfer->dev->nports << 24;
-+
-+ int cc = xhci_cmd_configure_endpoint(x, slotid, in_dma);
-+ grub_dma_free(in_dma);
-+
-+ if (cc != CC_SUCCESS)
-+ {
-+ grub_dprintf("xhci", "%s: reconf ctl endpoint: failed (cc %d)\n",
-+ __func__, cc);
-+ return GRUB_USB_ERR_BADDEVICE;
-+ }
-+
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+static grub_usb_err_t
-+grub_xhci_update_max_paket_size (struct grub_xhci *x,
-+ grub_usb_transfer_t transfer,
-+ grub_uint32_t slotid,
-+ grub_uint32_t max_packet)
-+{
-+ struct grub_pci_dma_chunk *in_dma;
-+ grub_uint32_t epid = 1;
-+
-+ if (!transfer || !transfer->dev || !max_packet)
-+ return GRUB_USB_ERR_NONE;
-+
-+ grub_dprintf("xhci", "%s: updating max packet size to 0x%x\n", __func__,
-+ max_packet);
-+
-+ xhci_check_status(x);
-+
-+ /* Allocate input context and initialize endpoint info. */
-+ in_dma = grub_xhci_alloc_inctx(x, epid, transfer->dev);
-+ if (!in_dma)
-+ return GRUB_USB_ERR_INTERNAL;
-+ volatile struct grub_xhci_inctx *in = grub_dma_get_virt(in_dma);
-+ in->add = (1 << epid);
-+
-+ struct grub_xhci_epctx *ep = (void*)&in[(epid+1) << x->flag64];
-+ ep->ctx[1] |= max_packet << 16;
-+
-+ int cc = xhci_cmd_evaluate_context(x, slotid, in_dma);
-+ grub_dma_free(in_dma);
-+
-+ if (cc != CC_SUCCESS)
-+ {
-+ grub_dprintf("xhci", "%s: reconf ctl endpoint: failed (cc %d)\n",
-+ __func__, cc);
-+ return GRUB_USB_ERR_BADDEVICE;
-+ }
-+
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+/****************************************************************
-+ * xHCI endpoint enablement functions
-+ ****************************************************************/
-+
-+static grub_usb_err_t
-+grub_xhci_prepare_endpoint (struct grub_xhci *x,
-+ struct grub_usb_device *dev,
-+ grub_uint8_t endpoint,
-+ grub_transfer_type_t dir,
-+ grub_transaction_type_t type,
-+ grub_uint32_t maxpaket,
-+ struct grub_xhci_priv *priv)
-+{
-+ grub_uint32_t epid;
-+ struct grub_pci_dma_chunk *reqs_dma;
-+ struct grub_pci_dma_chunk *in_dma;
-+ volatile struct grub_xhci_ring *reqs;
-+ volatile struct grub_xhci_slotctx *slotctx;
-+
-+ if (!x || !priv)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+ xhci_check_status(x);
-+
-+ if (endpoint == 0)
-+ {
-+ epid = 1;
-+ }
-+ else
-+ {
-+ epid = (endpoint & 0x0f) * 2;
-+ epid += (dir == GRUB_USB_TRANSFER_TYPE_IN) ? 1 : 0;
-+ }
-+ grub_dprintf("xhci", "%s: epid %d\n", __func__, epid);
-+
-+ /* Test if already prepared */
-+ if (priv->slotid > 0 && priv->enpoint_trbs[epid] != NULL)
-+ return GRUB_USB_ERR_NONE;
-+
-+ /* Allocate DMA buffer as endpoint cmd TRB */
-+ reqs_dma = xhci_memalign_dma32(ALIGN_TRB, sizeof(*reqs),
-+ BOUNDARY_RING);
-+ if (!reqs_dma)
-+ return GRUB_USB_ERR_INTERNAL;
-+ reqs = grub_dma_get_virt(reqs_dma);
-+ grub_memset((void *)reqs, 0, sizeof(*reqs));
-+ reqs->cs = 1;
-+
-+ grub_arch_sync_dma_caches(reqs, sizeof(*reqs));
-+
-+ /* Allocate input context and initialize endpoint info. */
-+ in_dma = grub_xhci_alloc_inctx(x, epid, dev);
-+ if (!in_dma)
-+ {
-+ grub_dma_free(reqs_dma);
-+ return GRUB_USB_ERR_INTERNAL;
-+ }
-+ volatile struct grub_xhci_inctx *in = grub_dma_get_virt(in_dma);
-+ in->add = 0x01 | (1 << epid);
-+
-+ struct grub_xhci_epctx *ep = (void*)&in[(epid+1) << x->flag64];
-+ switch (type)
-+ {
-+ case GRUB_USB_TRANSACTION_TYPE_CONTROL:
-+ ep->ctx[1] |= 0 << 3;
-+ break;
-+ case GRUB_USB_TRANSACTION_TYPE_BULK:
-+ ep->ctx[1] |= 2 << 3;
-+ break;
-+ }
-+ if (dir == GRUB_USB_TRANSFER_TYPE_IN
-+ || type== GRUB_USB_TRANSACTION_TYPE_CONTROL)
-+ ep->ctx[1] |= 1 << 5;
-+ ep->ctx[1] |= maxpaket << 16;
-+ ep->deq_low = grub_dma_get_phys(reqs_dma);
-+ ep->deq_low |= 1; /* dcs */
-+ ep->length = maxpaket;
-+
-+ grub_dprintf("xhci", "%s: ring %p, epid %d, max %d\n", __func__,
-+ reqs, epid, maxpaket);
-+ if (epid == 1 || priv->slotid == 0) {
-+ /* Enable slot. */
-+ int slotid = xhci_cmd_enable_slot(x);
-+ if (slotid < 0)
-+ {
-+ grub_dprintf("xhci", "%s: enable slot: failed\n", __func__);
-+ grub_dma_free(reqs_dma);
-+ grub_dma_free(in_dma);
-+ return GRUB_USB_ERR_BADDEVICE;
-+ }
-+ grub_dprintf("xhci", "%s: get slot %d assigned\n", __func__, slotid);
-+
-+ grub_uint32_t size = (sizeof(struct grub_xhci_slotctx) * GRUB_XHCI_MAX_ENDPOINTS) << x->flag64;
-+
-+ /* Allocate memory for the device specific slot context */
-+ priv->slotctx_dma = xhci_memalign_dma32(ALIGN_SLOTCTX, size,
-+ x->pagesize);
-+ if (!priv->slotctx_dma)
-+ {
-+ grub_dprintf("xhci", "%s: grub_memalign_dma32 failed\n", __func__);
-+ grub_dma_free(reqs_dma);
-+ grub_dma_free(in_dma);
-+ return GRUB_USB_ERR_INTERNAL;
-+ }
-+ slotctx = grub_dma_get_virt(priv->slotctx_dma);
-+
-+ grub_dprintf("xhci", "%s: enable slot: got slotid %d\n", __func__, slotid);
-+ grub_memset((void *)slotctx, 0, size);
-+ grub_arch_sync_dma_caches(slotctx, size);
-+
-+ x->devs[slotid].ptr_low = grub_dma_get_phys(priv->slotctx_dma);
-+ x->devs[slotid].ptr_high = 0;
-+ grub_arch_sync_dma_caches(&x->devs[slotid], sizeof(x->devs[0]));
-+
-+ /* Send set_address command. */
-+ int cc = xhci_cmd_address_device(x, slotid, in_dma);
-+ if (cc != CC_SUCCESS)
-+ {
-+ grub_dprintf("xhci","%s: address device: failed (cc %d)\n", __func__, cc);
-+ cc = xhci_cmd_disable_slot(x, slotid);
-+ if (cc != CC_SUCCESS) {
-+ grub_dprintf("xhci", "%s: disable failed (cc %d)\n", __func__, cc);
-+ } else {
-+ x->devs[slotid].ptr_low = 0;
-+ x->devs[slotid].ptr_high = 0;
-+ grub_arch_sync_dma_caches(&x->devs[slotid], sizeof(x->devs[0]));
-+ }
-+ grub_dma_free(priv->slotctx_dma);
-+ grub_dma_free(reqs_dma);
-+ grub_dma_free(in_dma);
-+ return GRUB_USB_ERR_BADDEVICE;
-+ }
-+ priv->enpoint_trbs[epid] = reqs;
-+ priv->enpoint_trbs_dma[epid] = reqs_dma;
-+ priv->slotid = slotid;
-+ priv->max_packet = 0;
-+ }
-+ if (epid != 1)
-+ {
-+ /* Send configure command. */
-+ int cc = xhci_cmd_configure_endpoint(x, priv->slotid, in_dma);
-+ if (cc != CC_SUCCESS)
-+ {
-+ grub_dprintf("xhci", "%s: configure endpoint: failed (cc %d)\n",
-+ __func__, cc);
-+ grub_dma_free(reqs_dma);
-+ grub_dma_free(in_dma);
-+ return GRUB_USB_ERR_BADDEVICE;
-+ }
-+ priv->enpoint_trbs[epid] = reqs;
-+ priv->enpoint_trbs_dma[epid] = reqs_dma;
-+ }
-+
-+ grub_dprintf("xhci", "%s: done\n", __func__);
-+ grub_dma_free(in_dma);
-+
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+
-+/****************************************************************
-+ * xHCI transfer helper functions
-+ ****************************************************************/
-+
-+static grub_usb_err_t
-+grub_xhci_usb_to_grub_err (unsigned char status)
-+{
-+ if (status != CC_SUCCESS)
-+ grub_dprintf("xhci", "%s: xfer failed (cc %d)\n", __func__, status);
-+ else
-+ grub_dprintf("xhci", "%s: xfer done (cc %d)\n", __func__, status);
-+
-+ if (status == CC_BABBLE_DETECTED)
-+ return GRUB_USB_ERR_BABBLE;
-+ else if (status == CC_DATA_BUFFER_ERROR)
-+ return GRUB_USB_ERR_DATA;
-+ else if (status == CC_STALL_ERROR)
-+ return GRUB_USB_ERR_STALL;
-+ else if (status != CC_SUCCESS)
-+ return GRUB_USB_ERR_NAK;
-+
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+static int
-+grub_xhci_transfer_is_zlp(grub_usb_transfer_t transfer, int idx)
-+{
-+ if (idx >= transfer->transcnt)
-+ return 0;
-+
-+ grub_usb_transaction_t tr = &transfer->transactions[idx];
-+
-+ return (tr->size == 0) &&
-+ ((tr->pid == GRUB_USB_TRANSFER_TYPE_OUT) ||
-+ (tr->pid == GRUB_USB_TRANSFER_TYPE_IN));
-+}
-+
-+static int
-+grub_xhci_transfer_is_last(grub_usb_transfer_t transfer, int idx)
-+{
-+ return (idx + 1) == transfer->transcnt;
-+}
-+
-+static int
-+grub_xhci_transfer_is_data(grub_usb_transfer_t transfer, int idx)
-+{
-+ grub_usb_transaction_t tr;
-+
-+ if (idx >= transfer->transcnt)
-+ return 0;
-+
-+ tr = &transfer->transactions[idx];
-+ if (tr->size == 0 ||
-+ (tr->pid == GRUB_USB_TRANSFER_TYPE_SETUP))
-+ return 0;
-+
-+ /* If there's are no DATA pakets before it's a DATA paket */
-+ for (int i = idx - 1; i >= 0; i--)
-+ {
-+ tr = &transfer->transactions[i];
-+ if (tr->size > 0 &&
-+ ((tr->pid == GRUB_USB_TRANSFER_TYPE_OUT) ||
-+ (tr->pid == GRUB_USB_TRANSFER_TYPE_IN)))
-+ return 0;
-+ }
-+ return 1;
-+}
-+
-+static int
-+grub_xhci_transfer_is_in(grub_usb_transfer_t transfer, int idx)
-+{
-+ grub_usb_transaction_t tr;
-+
-+ if (idx >= transfer->transcnt)
-+ return 0;
-+
-+ tr = &transfer->transactions[idx];
-+
-+ return tr->pid == GRUB_USB_TRANSFER_TYPE_IN;
-+}
-+
-+static int
-+grub_xhci_transfer_is_normal(grub_usb_transfer_t transfer, int idx)
-+{
-+ grub_usb_transaction_t tr;
-+
-+ if (idx >= transfer->transcnt)
-+ return 0;
-+
-+ tr = &transfer->transactions[idx];
-+ if (tr->size == 0 ||
-+ (tr->pid == GRUB_USB_TRANSFER_TYPE_SETUP))
-+ return 0;
-+
-+ /* If there's at least one DATA paket before it's a normal */
-+ for (int i = idx - 1; i >= 0; i--)
-+ {
-+ tr = &transfer->transactions[i];
-+ if (tr->size > 0 &&
-+ ((tr->pid == GRUB_USB_TRANSFER_TYPE_OUT) ||
-+ (tr->pid == GRUB_USB_TRANSFER_TYPE_IN)))
-+ return 1;
-+
-+ }
-+ return 0;
-+}
-+
-+static int
-+grub_xhci_transfer_next_is_normal(grub_usb_transfer_t transfer, int idx)
-+{
-+ return grub_xhci_transfer_is_normal(transfer, idx + 1);
-+}
-+
-+static int
-+grub_xhci_transfer_next_is_in(grub_usb_transfer_t transfer, int idx)
-+{
-+ return grub_xhci_transfer_is_in(transfer, idx + 1);
-+}
-+
-+static grub_uint8_t grub_xhci_epid_from_transfer(grub_usb_transfer_t transfer)
-+{
-+ grub_uint8_t epid;
-+
-+ if (transfer->endpoint == 0) {
-+ epid = 1;
-+ } else {
-+ epid = (transfer->endpoint & 0x0f) * 2;
-+ epid += (transfer->dir == GRUB_USB_TRANSFER_TYPE_IN) ? 1 : 0;
-+ }
-+ return epid;
-+}
-+
-+/****************************************************************
-+ * xHCI transfer functions
-+ ****************************************************************/
-+
-+static grub_usb_err_t
-+grub_xhci_setup_transfer (grub_usb_controller_t dev,
-+ grub_usb_transfer_t transfer)
-+{
-+ struct grub_xhci_transfer_controller_data *cdata;
-+ struct grub_xhci *x = (struct grub_xhci *) dev->data;
-+ grub_uint8_t epid;
-+ grub_usb_err_t err;
-+ volatile struct grub_xhci_ring *reqs;
-+ int rc;
-+ struct grub_xhci_priv *priv;
-+
-+ xhci_check_status(x);
-+
-+ if (!dev || !transfer || !transfer->dev || !transfer->dev->xhci_priv)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+ priv = transfer->dev->xhci_priv;
-+ err = grub_xhci_prepare_endpoint(x, transfer->dev,
-+ transfer->endpoint,
-+ transfer->dir,
-+ transfer->type,
-+ transfer->max,
-+ priv);
-+
-+ if (err != GRUB_USB_ERR_NONE)
-+ return err;
-+
-+ epid = grub_xhci_epid_from_transfer(transfer);
-+
-+ /* Update the max packet size once descdev.maxsize0 is valid */
-+ if (epid == 1 &&
-+ (priv->max_packet == 0) &&
-+ (transfer->dev->descdev.maxsize0 > 0))
-+ {
-+ if (transfer->dev->speed == GRUB_USB_SPEED_SUPER)
-+ priv->max_packet = 1UL << transfer->dev->descdev.maxsize0;
-+ else
-+ priv->max_packet = transfer->dev->descdev.maxsize0;
-+ err = grub_xhci_update_max_paket_size(x, transfer, priv->slotid, priv->max_packet);
-+ if (err != GRUB_USB_ERR_NONE)
-+ {
-+ grub_dprintf("xhci", "%s: Updating max paket size failed\n", __func__);
-+ return err;
-+ }
-+ }
-+ if (epid == 1 &&
-+ transfer->dev->descdev.class == 9 &&
-+ transfer->dev->nports > 0)
-+ {
-+ err = grub_xhci_update_hub_portcount(x, transfer, priv->slotid);
-+ if (err != GRUB_USB_ERR_NONE)
-+ {
-+ grub_dprintf("xhci", "%s: Updating max paket size failed\n", __func__);
-+ return err;
-+ }
-+ }
-+
-+ /* Allocate private data for the transfer */
-+ cdata = grub_zalloc(sizeof(*cdata));
-+ if (!cdata)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+ reqs = priv->enpoint_trbs[epid];
-+
-+ transfer->controller_data = cdata;
-+
-+ /* Now queue the transfer onto the TRB */
-+ if (transfer->type == GRUB_USB_TRANSACTION_TYPE_CONTROL)
-+ {
-+ volatile struct grub_usb_packet_setup *setupdata;
-+ setupdata = (void *)transfer->transactions[0].data;
-+ grub_dprintf("xhci", "%s: CONTROLL TRANS req %d\n", __func__, setupdata->request);
-+ grub_dprintf("xhci", "%s: CONTROLL TRANS length %d\n", __func__, setupdata->length);
-+
-+ if (setupdata && setupdata->request == GRUB_USB_REQ_SET_ADDRESS)
-+ return GRUB_USB_ERR_NONE;
-+
-+ if (transfer->transcnt < 2)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+ for (int i = 0; i < transfer->transcnt; i++)
-+ {
-+ grub_uint32_t flags = 0;
-+ grub_uint64_t inline_data;
-+ grub_usb_transaction_t tr = &transfer->transactions[i];
-+
-+ switch (tr->pid)
-+ {
-+ case GRUB_USB_TRANSFER_TYPE_SETUP:
-+ {
-+ grub_dprintf("xhci", "%s: SETUP PKG\n", __func__);
-+ grub_dprintf("xhci", "%s: transfer->size %d\n", __func__, transfer->size);
-+ grub_dprintf("xhci", "%s: tr->size %d SETUP PKG\n", __func__, tr->size);
-+
-+ flags |= (TR_SETUP << 10);
-+ flags |= TRB_TR_IDT;
-+
-+ if (transfer->size > 0)
-+ {
-+ if (grub_xhci_transfer_next_is_in(transfer, i))
-+ flags |= (3 << 16); /* TRT IN */
-+ else
-+ flags |= (2 << 16); /* TRT OUT */
-+ }
-+ break;
-+ }
-+ case GRUB_USB_TRANSFER_TYPE_OUT:
-+ {
-+ grub_dprintf("xhci", "%s: OUT PKG\n", __func__);
-+ cdata->transfer_size += tr->size;
-+ break;
-+ }
-+ case GRUB_USB_TRANSFER_TYPE_IN:
-+ {
-+ grub_dprintf("xhci", "%s: IN PKG\n", __func__);
-+ cdata->transfer_size += tr->size;
-+ flags |= TRB_TR_DIR;
-+ break;
-+ }
-+ }
-+
-+ if (grub_xhci_transfer_is_normal(transfer, i))
-+ flags |= (TR_NORMAL << 10);
-+ else if (grub_xhci_transfer_is_data(transfer, i))
-+ flags |= (TR_DATA << 10);
-+ else if (grub_xhci_transfer_is_zlp(transfer, i))
-+ flags |= (TR_STATUS << 10);
-+
-+ if (grub_xhci_transfer_next_is_normal(transfer, i))
-+ flags |= TRB_TR_CH;
-+
-+ if (grub_xhci_transfer_is_last(transfer, i))
-+ flags |= TRB_TR_IOC;
-+
-+ /* Assume the ring has enough free space for all TRBs */
-+ if (flags & TRB_TR_IDT && tr->size <= (int)sizeof(inline_data))
-+ {
-+ grub_memcpy(&inline_data, (void *)tr->data, tr->size);
-+ xhci_trb_queue(reqs, inline_data, tr->size, flags);
-+ }
-+ else
-+ {
-+ xhci_trb_queue(reqs, tr->data, tr->size, flags);
-+ }
-+ }
-+ }
-+ else if (transfer->type == GRUB_USB_TRANSACTION_TYPE_BULK)
-+ {
-+ for (int i = 0; i < transfer->transcnt; i++)
-+ {
-+ grub_uint32_t flags = (TR_NORMAL << 10);
-+ grub_usb_transaction_t tr = &transfer->transactions[i];
-+ switch (tr->pid)
-+ {
-+ case GRUB_USB_TRANSFER_TYPE_OUT:
-+ {
-+ grub_dprintf("xhci", "%s: OUT PKG\n", __func__);
-+ cdata->transfer_size += tr->size;
-+ break;
-+ }
-+ case GRUB_USB_TRANSFER_TYPE_IN:
-+ {
-+ grub_dprintf("xhci", "%s: IN PKG\n", __func__);
-+ cdata->transfer_size += tr->size;
-+ flags |= TRB_TR_DIR;
-+ break;
-+ }
-+ case GRUB_USB_TRANSFER_TYPE_SETUP:
-+ break;
-+ }
-+ if (grub_xhci_transfer_is_last(transfer, i))
-+ flags |= TRB_TR_IOC;
-+
-+ /* The ring might be to small, submit while adding new entries */
-+ rc = xhci_trb_queue_and_flush(x, priv->slotid, epid,
-+ reqs, tr->data, tr->size, flags);
-+ if (rc < 0)
-+ return GRUB_USB_ERR_TIMEOUT;
-+ else if (rc > 1)
-+ return grub_xhci_usb_to_grub_err(rc);
-+
-+ }
-+ }
-+ xhci_doorbell(x, priv->slotid, epid);
-+
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+static grub_usb_err_t
-+grub_xhci_check_transfer (grub_usb_controller_t dev,
-+ grub_usb_transfer_t transfer, grub_size_t * actual)
-+{
-+ grub_uint32_t status;
-+ grub_uint32_t remaining;
-+ grub_uint8_t epid;
-+ volatile struct grub_xhci_ring *reqs;
-+ grub_usb_err_t err;
-+ int rc;
-+
-+ if (!dev->data || !transfer->controller_data || !transfer->dev ||
-+ !transfer->dev->xhci_priv)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+
-+ struct grub_xhci_priv *priv = transfer->dev->xhci_priv;
-+ struct grub_xhci *x = (struct grub_xhci *) dev->data;
-+ struct grub_xhci_transfer_controller_data *cdata =
-+ transfer->controller_data;
-+
-+ xhci_check_status(x);
-+ xhci_process_events(x);
-+
-+ epid = grub_xhci_epid_from_transfer(transfer);
-+
-+ reqs = priv->enpoint_trbs[epid];
-+
-+ /* XXX: invalidate caches */
-+
-+ /* Get current status from event ring buffer */
-+ status = (reqs->evt.status>> 24) & 0xff;
-+ remaining = reqs->evt.status & 0xffffff;
-+
-+ if (status != CC_STOPPED_LENGTH_INVALID)
-+ *actual = cdata->transfer_size - remaining;
-+ else
-+ *actual = 0;
-+
-+ if (xhci_ring_busy(reqs))
-+ return GRUB_USB_ERR_WAIT;
-+
-+ grub_free(cdata);
-+
-+ grub_dprintf("xhci", "%s: xfer done\n", __func__);
-+
-+ err = grub_xhci_usb_to_grub_err(status);
-+ if (err != GRUB_USB_ERR_NONE)
-+ {
-+ if (status == CC_STALL_ERROR)
-+ {
-+ /* Clear the stall by resetting the endpoint */
-+ rc = xhci_cmd_reset_endpoint(x, priv->slotid, epid, 1);
-+
-+ if (rc < 0)
-+ return GRUB_USB_ERR_TIMEOUT;
-+
-+ return GRUB_USB_ERR_STALL;
-+ }
-+ else if (remaining > 0)
-+ {
-+ return GRUB_USB_ERR_DATA;
-+ }
-+ }
-+
-+ return err;
-+}
-+
-+static grub_usb_err_t
-+grub_xhci_cancel_transfer (grub_usb_controller_t dev,
-+ grub_usb_transfer_t transfer)
-+{
-+ grub_uint8_t epid;
-+ volatile struct grub_xhci_ring *reqs;
-+ struct grub_pci_dma_chunk *enpoint_trbs_dma;
-+ grub_addr_t deque_pointer;
-+ int rc;
-+
-+ if (!dev->data || !transfer->controller_data || !transfer->dev ||
-+ !transfer->dev->xhci_priv)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+ struct grub_xhci *x = (struct grub_xhci *) dev->data;
-+ struct grub_xhci_transfer_controller_data *cdata =
-+ transfer->controller_data;
-+ struct grub_xhci_priv *priv = transfer->dev->xhci_priv;
-+
-+ epid = grub_xhci_epid_from_transfer(transfer);
-+
-+ enpoint_trbs_dma = priv->enpoint_trbs_dma[epid];
-+ reqs = priv->enpoint_trbs[epid];
-+
-+ /* Abort current command */
-+ rc = xhci_cmd_stop_endpoint(x, priv->slotid, epid, 0);
-+ if (rc < 0)
-+ return GRUB_USB_ERR_TIMEOUT;
-+
-+ /* Reset state */
-+ reqs->nidx = 0;
-+ reqs->eidx = 0;
-+ reqs->cs = 1;
-+
-+ grub_arch_sync_dma_caches(reqs, sizeof(*reqs));
-+
-+ /* Reset the dequeue pointer to the begging of the TRB */
-+ deque_pointer = grub_dma_get_phys(enpoint_trbs_dma);
-+ rc = xhci_cmd_set_dequeue_pointer(x, priv->slotid, epid, deque_pointer| 1 );
-+ if (rc < 0)
-+ return GRUB_USB_ERR_TIMEOUT;
-+
-+ reqs->evt.ptr_low = 0;
-+ reqs->evt.ptr_high = 0;
-+ reqs->evt.control = 0;
-+ reqs->evt.status = 0;
-+
-+ grub_arch_sync_dma_caches(reqs, sizeof(*reqs));
-+
-+ /* Restart ring buffer processing */
-+ xhci_doorbell(x, priv->slotid, epid);
-+
-+ grub_free (cdata);
-+
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+/****************************************************************
-+ * xHCI port status functions
-+ ****************************************************************/
-+
-+static int
-+grub_xhci_hubports (grub_usb_controller_t dev)
-+{
-+ struct grub_xhci *x = (struct grub_xhci *) dev->data;
-+ grub_uint32_t portinfo;
-+
-+ portinfo = x->ports;
-+ grub_dprintf ("xhci", "root hub ports=%d\n", portinfo);
-+ return portinfo;
-+}
-+
-+static grub_usb_err_t
-+grub_xhci_portstatus (grub_usb_controller_t dev,
-+ unsigned int port, unsigned int enable)
-+{
-+ struct grub_xhci *x = (struct grub_xhci *) dev->data;
-+ grub_uint32_t portsc, pls;
-+ grub_uint32_t end;
-+
-+ portsc = grub_xhci_port_read(x, port);
-+ pls = xhci_get_field(portsc, XHCI_PORTSC_PLS);
-+
-+ grub_dprintf("xhci", "grub_xhci_portstatus port #%d: 0x%08x,%s%s pls %d enable %d\n",
-+ port, portsc,
-+ (portsc & GRUB_XHCI_PORTSC_PP) ? " powered," : "",
-+ (portsc & GRUB_XHCI_PORTSC_PED) ? " enabled," : "",
-+ pls, enable);
-+ xhci_check_status(x);
-+
-+ if ((enable && (portsc & GRUB_XHCI_PORTSC_PED)) ||
-+ (!enable && !(portsc & GRUB_XHCI_PORTSC_PED)))
-+ return GRUB_USB_ERR_NONE;
-+
-+ if (!enable)
-+ {
-+ /* Disable port */
-+ grub_xhci_port_write(x, port, ~0, GRUB_XHCI_PORTSC_PED);
-+ return GRUB_USB_ERR_NONE;
-+ }
-+
-+ grub_dprintf ("xhci", "portstatus: XHCI STATUS: %08x\n",
-+ grub_xhci_read32(&x->op->usbsts));
-+ grub_dprintf ("xhci",
-+ "portstatus: begin, iobase=%p, port=%d, status=0x%08x\n",
-+ x->caps, port, portsc);
-+
-+ switch (pls)
-+ {
-+ case PLS_U0:
-+ /* A USB3 port - controller automatically performs reset */
-+ break;
-+ case PLS_POLLING:
-+ /* A USB2 port - perform device reset */
-+ grub_xhci_port_write(x, port, ~GRUB_XHCI_PORTSC_PED, GRUB_XHCI_PORTSC_PR);
-+ break;
-+ default:
-+ return GRUB_USB_ERR_NONE;
-+ }
-+
-+ /* Wait for device to complete reset and be enabled */
-+ end = grub_get_time_ms () + 100;
-+ for (;;)
-+ {
-+ portsc = grub_xhci_port_read(x, port);
-+ if (!(portsc & GRUB_XHCI_PORTSC_CCS))
-+ {
-+ /* Device disconnected during reset */
-+ grub_dprintf ("xhci","ERROR: %s device disconnected\n", __func__);
-+ return GRUB_USB_ERR_BADDEVICE;
-+ }
-+ if (portsc & GRUB_XHCI_PORTSC_PED)
-+ /* Reset complete */
-+ break;
-+ if (grub_get_time_ms () > end)
-+ {
-+ grub_dprintf ("xhci","ERROR: %s TIMEOUT\n", __func__);
-+ return GRUB_USB_ERR_TIMEOUT;
-+ }
-+ }
-+ xhci_check_status(x);
-+
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+/****************************************************************
-+ * xHCI detect device functions
-+ ****************************************************************/
-+
-+static grub_usb_speed_t
-+grub_xhci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
-+{
-+ struct grub_xhci *x = (struct grub_xhci *) dev->data;
-+ grub_uint32_t portsc, speed;
-+
-+ *changed = 0;
-+ grub_dprintf("xhci", "%s: dev=%p USB%d_%d port %d\n", __func__, dev,
-+ x->psids[port-1].major, x->psids[port-1].minor, port);
-+
-+ /* On shutdown advertise all ports as disconnected. This will trigger
-+ * a gracefull detatch. */
-+ if (x->shutdown)
-+ {
-+ *changed = 1;
-+ return GRUB_USB_SPEED_NONE;
-+ }
-+
-+ /* Don't advertise new devices, connecting will fail if halted */
-+ if (xhci_is_halted(x))
-+ return GRUB_USB_SPEED_NONE;
-+
-+ portsc = grub_xhci_port_read(x, port);
-+ speed = xhci_get_field(portsc, XHCI_PORTSC_SPEED);
-+ grub_uint8_t pls = xhci_get_field(portsc, XHCI_PORTSC_PLS);
-+
-+ grub_dprintf("xhci", "grub_xhci_portstatus port #%d: 0x%08x,%s%s pls %d\n",
-+ port, portsc,
-+ (portsc & GRUB_XHCI_PORTSC_PP) ? " powered," : "",
-+ (portsc & GRUB_XHCI_PORTSC_PED) ? " enabled," : "",
-+ pls);
-+
-+ /* Connect Status Change bit - it detects change of connection */
-+ if (portsc & GRUB_XHCI_PORTSC_CSC)
-+ {
-+ *changed = 1;
-+
-+ grub_xhci_port_write(x, port, ~GRUB_XHCI_PORTSC_PED, GRUB_XHCI_PORTSC_CSC);
-+ }
-+
-+ if (!(portsc & GRUB_XHCI_PORTSC_CCS))
-+ return GRUB_USB_SPEED_NONE;
-+
-+ for (grub_uint8_t i = 0; i < 16 && x->psids[port-1].psids[i].id > 0; i++)
-+ {
-+ if (x->psids[port-1].psids[i].id == speed)
-+ {
-+ grub_dprintf("xhci", "%s: grub_usb_speed = %d\n", __func__,
-+ x->psids[port-1].psids[i].grub_usb_speed );
-+ return x->psids[port-1].psids[i].grub_usb_speed;
-+ }
-+ }
-+
-+ return GRUB_USB_SPEED_NONE;
-+}
-+
-+/****************************************************************
-+ * xHCI attach/detach functions
-+ ****************************************************************/
-+
-+static grub_usb_err_t
-+grub_xhci_attach_dev (grub_usb_controller_t ctrl, grub_usb_device_t dev)
-+{
-+ struct grub_xhci *x = (struct grub_xhci *) ctrl->data;
-+ grub_usb_err_t err;
-+ grub_uint32_t max;
-+
-+ grub_dprintf("xhci", "%s: dev=%p\n", __func__, dev);
-+
-+ if (!dev || !x)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+ dev->xhci_priv = grub_zalloc (sizeof (struct grub_xhci_priv));
-+ if (!dev->xhci_priv)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+
-+ switch (dev->speed)
-+ {
-+ case GRUB_USB_SPEED_LOW:
-+ {
-+ max = 8;
-+ break;
-+ }
-+ case GRUB_USB_SPEED_FULL:
-+ case GRUB_USB_SPEED_HIGH:
-+ {
-+ max = 64;
-+ break;
-+ }
-+ case GRUB_USB_SPEED_SUPER:
-+ {
-+ max = 512;
-+ break;
-+ }
-+ default:
-+ case GRUB_USB_SPEED_NONE:
-+ {
-+ max = 0;
-+ }
-+ }
-+
-+ /* Assign a slot, assign an address and configure endpoint 0 */
-+ err = grub_xhci_prepare_endpoint(x, dev,
-+ 0,
-+ 0,
-+ GRUB_USB_TRANSACTION_TYPE_CONTROL,
-+ max,
-+ dev->xhci_priv);
-+
-+ return err;
-+}
-+
-+static grub_usb_err_t
-+grub_xhci_detach_dev (grub_usb_controller_t ctrl, grub_usb_device_t dev)
-+{
-+ struct grub_xhci *x = (struct grub_xhci *) ctrl->data;
-+ struct grub_xhci_priv *priv;
-+ int cc = CC_SUCCESS;
-+
-+ grub_dprintf("xhci", "%s: dev=%p\n", __func__, dev);
-+
-+ if (!dev)
-+ return GRUB_USB_ERR_INTERNAL;
-+
-+ if (dev->xhci_priv)
-+ {
-+ priv = dev->xhci_priv;
-+ /* Stop endpoints and free ring buffer */
-+ for (int i = 0; i < GRUB_XHCI_MAX_ENDPOINTS; i++)
-+ {
-+ if (priv->enpoint_trbs[i] != NULL)
-+ {
-+ cc = xhci_cmd_stop_endpoint(x, priv->slotid, i, 1);
-+ if (cc != CC_SUCCESS)
-+ grub_dprintf("xhci", "Failed to disable EP%d on slot %d\n", i,
-+ priv->slotid);
-+
-+ grub_dprintf("xhci", "grub_dma_free[%d]\n", i);
-+
-+ grub_dma_free(priv->enpoint_trbs_dma[i]);
-+ priv->enpoint_trbs[i] = NULL;
-+ priv->enpoint_trbs_dma[i] = NULL;
-+ }
-+ }
-+
-+ cc = xhci_cmd_disable_slot(x, priv->slotid);
-+ if (cc == CC_SUCCESS)
-+ {
-+ if (priv->slotctx_dma)
-+ grub_dma_free(priv->slotctx_dma);
-+ x->devs[priv->slotid].ptr_low = 0;
-+ x->devs[priv->slotid].ptr_high = 0;
-+ grub_arch_sync_dma_caches(&x->devs[priv->slotid], sizeof(x->devs[0]));
-+ }
-+ else
-+ grub_dprintf("xhci", "Failed to disable slot %d\n", priv->slotid);
-+
-+ grub_free(dev->xhci_priv);
-+ }
-+
-+ dev->xhci_priv = NULL;
-+
-+ if (cc != CC_SUCCESS)
-+ return GRUB_USB_ERR_BADDEVICE;
-+ return GRUB_USB_ERR_NONE;
-+}
-+
-+/****************************************************************
-+ * xHCI terminate functions
-+ ****************************************************************/
-+
-+static void
-+grub_xhci_halt(struct grub_xhci *x)
-+{
-+ grub_uint32_t reg;
-+
-+ /* Halt the command ring */
-+ reg = grub_xhci_read32(&x->op->crcr_low);
-+ grub_xhci_write32(&x->op->crcr_low, reg | 4);
-+
-+ int rc = xhci_event_wait(x, x->cmds, 100);
-+ grub_dprintf("xhci", "%s: xhci_event_wait = %d\n", __func__, rc);
-+ if (rc < 0)
-+ return;
-+
-+ /* Stop the controller */
-+ reg = grub_xhci_read32(&x->op->usbcmd);
-+ if (reg & GRUB_XHCI_CMD_RS)
-+ {
-+ reg &= ~GRUB_XHCI_CMD_RS;
-+ grub_xhci_write32(&x->op->usbcmd, reg);
-+ }
-+
-+ return;
-+}
-+
-+static grub_err_t
-+grub_xhci_fini_hw (int noreturn __attribute__ ((unused)))
-+{
-+ struct grub_xhci *x;
-+
-+ /* We should disable all XHCI HW to prevent any DMA access etc. */
-+ for (x = xhci; x; x = x->next)
-+ {
-+ x->shutdown = 1;
-+
-+ /* Gracefully detach active devices */
-+ grub_usb_poll_devices(0);
-+
-+ /* Check if xHCI is halted and halt it if not */
-+ grub_xhci_halt (x);
-+
-+ /* Reset xHCI */
-+ if (grub_xhci_reset (x) != GRUB_USB_ERR_NONE)
-+ return GRUB_ERR_BAD_DEVICE;
-+ }
-+
-+ return GRUB_ERR_NONE;
-+}
-+
-+static struct grub_usb_controller_dev usb_controller = {
-+ .name = "xhci",
-+ .iterate = grub_xhci_iterate,
-+ .setup_transfer = grub_xhci_setup_transfer,
-+ .check_transfer = grub_xhci_check_transfer,
-+ .cancel_transfer = grub_xhci_cancel_transfer,
-+ .hubports = grub_xhci_hubports,
-+ .portstatus = grub_xhci_portstatus,
-+ .detect_dev = grub_xhci_detect_dev,
-+ .attach_dev = grub_xhci_attach_dev,
-+ .detach_dev = grub_xhci_detach_dev,
-+ /* estimated max. count of TDs for one bulk transfer */
-+ .max_bulk_tds = GRUB_XHCI_RING_ITEMS - 3
-+};
-+
-+GRUB_MOD_INIT (xhci)
-+{
-+ grub_stop_disk_firmware ();
-+
-+ grub_boot_time ("Initing XHCI hardware");
-+ grub_xhci_pci_scan ();
-+ grub_boot_time ("Registering XHCI driver");
-+ grub_usb_controller_dev_register (&usb_controller);
-+ grub_boot_time ("XHCI driver registered");
-+}
-+
-+GRUB_MOD_FINI (xhci)
-+{
-+ grub_xhci_fini_hw (0);
-+ grub_usb_controller_dev_unregister (&usb_controller);
-+}
-diff --git a/include/grub/usb.h b/include/grub/usb.h
-index 609faf7d0..eb71fa1c7 100644
---- a/include/grub/usb.h
-+++ b/include/grub/usb.h
-@@ -338,6 +338,10 @@ grub_usb_cancel_transfer (grub_usb_transfer_t trans);
- void
- grub_ehci_init_device (volatile void *regs);
- void
-+grub_xhci_init_device (volatile void *regs);
-+void
- grub_ehci_pci_scan (void);
-+void
-+grub_xhci_pci_scan (void);
-
- #endif /* GRUB_USB_H */
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0014-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch b/config/grub/xhci_nvme/patches/0014-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch
deleted file mode 100644
index bb5c4fd8..00000000
--- a/config/grub/xhci_nvme/patches/0014-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch
+++ /dev/null
@@ -1,127 +0,0 @@
-From f289290da21c2eafdf52ae4859623971a3da07bb Mon Sep 17 00:00:00 2001
-From: Patrick Rudolph <patrick.rudolph@9elements.com>
-Date: Mon, 7 Dec 2020 08:41:27 +0100
-Subject: [PATCH 14/21] grub-core/bus/usb/usbhub: Add xHCI non root hub support
-
-Tested on Intel PCH C246, the USB3 hub can be configured by grub.
-
-Issues:
-* USB3 devices connected behind that hub are sometimes not detected.
-
-Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
----
- grub-core/bus/usb/usbhub.c | 38 +++++++++++++++++++++++++++++++++-----
- include/grub/usbdesc.h | 1 +
- include/grub/usbtrans.h | 4 ++++
- 3 files changed, 38 insertions(+), 5 deletions(-)
-
-diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
-index b4b3a1a61..e96505aa9 100644
---- a/grub-core/bus/usb/usbhub.c
-+++ b/grub-core/bus/usb/usbhub.c
-@@ -148,19 +148,32 @@ grub_usb_hub_add_dev (grub_usb_controller_t controller,
- return dev;
- }
-
--
-+static grub_usb_err_t
-+grub_usb_set_hub_depth(grub_usb_device_t dev, grub_uint8_t depth)
-+{
-+ return grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_OUT
-+ | GRUB_USB_REQTYPE_CLASS
-+ | GRUB_USB_REQTYPE_TARGET_DEV),
-+ GRUB_USB_HUB_REQ_SET_HUB_DEPTH, depth,
-+ 0, 0, NULL);
-+}
-+
- static grub_usb_err_t
- grub_usb_add_hub (grub_usb_device_t dev)
- {
- struct grub_usb_usb_hubdesc hubdesc;
- grub_usb_err_t err;
-+ grub_uint16_t req;
- int i;
-
-+ req = (dev->speed == GRUB_USB_SPEED_SUPER) ? GRUB_USB_DESCRIPTOR_SS_HUB :
-+ GRUB_USB_DESCRIPTOR_HUB;
-+
- err = grub_usb_control_msg (dev, (GRUB_USB_REQTYPE_IN
- | GRUB_USB_REQTYPE_CLASS
- | GRUB_USB_REQTYPE_TARGET_DEV),
-- GRUB_USB_REQ_GET_DESCRIPTOR,
-- (GRUB_USB_DESCRIPTOR_HUB << 8) | 0,
-+ GRUB_USB_REQ_GET_DESCRIPTOR,
-+ (req << 8) | 0,
- 0, sizeof (hubdesc), (char *) &hubdesc);
- if (err)
- return err;
-@@ -183,6 +196,19 @@ grub_usb_add_hub (grub_usb_device_t dev)
- return GRUB_USB_ERR_INTERNAL;
- }
-
-+ if (dev->speed == GRUB_USB_SPEED_SUPER)
-+ {
-+ grub_uint8_t depth;
-+ grub_uint32_t route;
-+ /* Depth maximum value is 5, but root hubs doesn't count */
-+ for (depth = 0, route = dev->route; (route & 0xf) > 0; route >>= 4)
-+ depth++;
-+
-+ err = grub_usb_set_hub_depth(dev, depth);
-+ if (err)
-+ return err;
-+ }
-+
- /* Power on all Hub ports. */
- for (i = 1; i <= hubdesc.portcnt; i++)
- {
-@@ -637,7 +663,9 @@ poll_nonroot_hub (grub_usb_device_t dev)
- int split_hubaddr = 0;
-
- /* Determine the device speed. */
-- if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED)
-+ if (dev->speed == GRUB_USB_SPEED_SUPER)
-+ speed = GRUB_USB_SPEED_SUPER;
-+ else if (status & GRUB_USB_HUB_STATUS_PORT_LOWSPEED)
- speed = GRUB_USB_SPEED_LOW;
- else
- {
-@@ -651,7 +679,7 @@ poll_nonroot_hub (grub_usb_device_t dev)
- grub_millisleep (10);
-
- /* Find correct values for SPLIT hubport and hubaddr */
-- if (speed == GRUB_USB_SPEED_HIGH)
-+ if (speed == GRUB_USB_SPEED_HIGH || speed == GRUB_USB_SPEED_SUPER)
- {
- /* HIGH speed device needs not transaction translation */
- split_hubport = 0;
-diff --git a/include/grub/usbdesc.h b/include/grub/usbdesc.h
-index bb2ab2e27..1697aa465 100644
---- a/include/grub/usbdesc.h
-+++ b/include/grub/usbdesc.h
-@@ -30,6 +30,7 @@ typedef enum {
- GRUB_USB_DESCRIPTOR_ENDPOINT,
- GRUB_USB_DESCRIPTOR_DEBUG = 10,
- GRUB_USB_DESCRIPTOR_HUB = 0x29,
-+ GRUB_USB_DESCRIPTOR_SS_HUB = 0x2a,
- GRUB_USB_DESCRIPTOR_SS_ENDPOINT_COMPANION = 0x30
- } grub_usb_descriptor_t;
-
-diff --git a/include/grub/usbtrans.h b/include/grub/usbtrans.h
-index 039ebed65..d6c3f71dc 100644
---- a/include/grub/usbtrans.h
-+++ b/include/grub/usbtrans.h
-@@ -110,6 +110,10 @@ enum
- GRUB_USB_REQ_SET_INTERFACE = 0x0B,
- GRUB_USB_REQ_SYNC_FRAME = 0x0C
- };
-+enum
-+ {
-+ GRUB_USB_HUB_REQ_SET_HUB_DEPTH = 0x0C,
-+ };
-
- #define GRUB_USB_FEATURE_ENDP_HALT 0x00
- #define GRUB_USB_FEATURE_DEV_REMOTE_WU 0x01
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0015-xHCI-also-accept-SBRN-0x31-and-0x32.patch b/config/grub/xhci_nvme/patches/0015-xHCI-also-accept-SBRN-0x31-and-0x32.patch
deleted file mode 100644
index 9deb581d..00000000
--- a/config/grub/xhci_nvme/patches/0015-xHCI-also-accept-SBRN-0x31-and-0x32.patch
+++ /dev/null
@@ -1,26 +0,0 @@
-From e8bb5e7445dad3514c88d5286563781f27233e5e Mon Sep 17 00:00:00 2001
-From: Sven Anderson <sven@anderson.de>
-Date: Sat, 28 May 2022 21:39:23 +0200
-Subject: [PATCH 15/21] xHCI: also accept SBRN 0x31 and 0x32
-
-Signed-off-by: Sven Anderson <sven@anderson.de>
----
- grub-core/bus/usb/xhci-pci.c | 2 +-
- 1 file changed, 1 insertion(+), 1 deletion(-)
-
-diff --git a/grub-core/bus/usb/xhci-pci.c b/grub-core/bus/usb/xhci-pci.c
-index a5bd3c97d..cde21f57a 100644
---- a/grub-core/bus/usb/xhci-pci.c
-+++ b/grub-core/bus/usb/xhci-pci.c
-@@ -76,7 +76,7 @@ grub_xhci_pci_iter (grub_pci_device_t dev, grub_pci_id_t pciid,
- /* Check Serial Bus Release Number */
- addr = grub_pci_make_address (dev, GRUB_XHCI_PCI_SBRN_REG);
- release = grub_pci_read_byte (addr);
-- if (release != 0x30)
-+ if (release != 0x30 && release != 0x31 &&release != 0x32)
- {
- grub_dprintf ("xhci", "XHCI grub_xhci_pci_iter: Wrong SBRN: %0x\n",
- release);
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0016-xhci-fix-port-indexing.patch b/config/grub/xhci_nvme/patches/0016-xhci-fix-port-indexing.patch
deleted file mode 100644
index b1cb368a..00000000
--- a/config/grub/xhci_nvme/patches/0016-xhci-fix-port-indexing.patch
+++ /dev/null
@@ -1,43 +0,0 @@
-From 3db55ea63bc2c4fb41f7489a77a42c821256bbf5 Mon Sep 17 00:00:00 2001
-From: Sven Anderson <sven@anderson.de>
-Date: Mon, 13 Jan 2025 19:51:41 +0100
-Subject: [PATCH 16/21] xhci: fix port indexing
-
----
- grub-core/bus/usb/xhci.c | 10 +++++-----
- 1 file changed, 5 insertions(+), 5 deletions(-)
-
-diff --git a/grub-core/bus/usb/xhci.c b/grub-core/bus/usb/xhci.c
-index f4591ffb5..dc89b9619 100644
---- a/grub-core/bus/usb/xhci.c
-+++ b/grub-core/bus/usb/xhci.c
-@@ -2250,7 +2250,7 @@ grub_xhci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
-
- *changed = 0;
- grub_dprintf("xhci", "%s: dev=%p USB%d_%d port %d\n", __func__, dev,
-- x->psids[port-1].major, x->psids[port-1].minor, port);
-+ x->psids[port].major, x->psids[port].minor, port);
-
- /* On shutdown advertise all ports as disconnected. This will trigger
- * a gracefull detatch. */
-@@ -2285,13 +2285,13 @@ grub_xhci_detect_dev (grub_usb_controller_t dev, int port, int *changed)
- if (!(portsc & GRUB_XHCI_PORTSC_CCS))
- return GRUB_USB_SPEED_NONE;
-
-- for (grub_uint8_t i = 0; i < 16 && x->psids[port-1].psids[i].id > 0; i++)
-+ for (grub_uint8_t i = 0; i < 16 && x->psids[port].psids[i].id > 0; i++)
- {
-- if (x->psids[port-1].psids[i].id == speed)
-+ if (x->psids[port].psids[i].id == speed)
- {
- grub_dprintf("xhci", "%s: grub_usb_speed = %d\n", __func__,
-- x->psids[port-1].psids[i].grub_usb_speed );
-- return x->psids[port-1].psids[i].grub_usb_speed;
-+ x->psids[port].psids[i].grub_usb_speed );
-+ return x->psids[port].psids[i].grub_usb_speed;
- }
- }
-
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0017-xhci-configure-TT-for-non-root-hubs.patch b/config/grub/xhci_nvme/patches/0017-xhci-configure-TT-for-non-root-hubs.patch
deleted file mode 100644
index fb8ed0b4..00000000
--- a/config/grub/xhci_nvme/patches/0017-xhci-configure-TT-for-non-root-hubs.patch
+++ /dev/null
@@ -1,98 +0,0 @@
-From a82ef95fffc0a869e90467ce4f7c28282c084518 Mon Sep 17 00:00:00 2001
-From: Sven Anderson <sven@anderson.de>
-Date: Mon, 13 Jan 2025 20:26:32 +0100
-Subject: [PATCH 17/21] xhci: configure TT for non-root-hubs
-
----
- grub-core/bus/usb/usbhub.c | 6 +++++
- grub-core/bus/usb/xhci.c | 45 +++++++++++++++++++++++++++++++++-----
- include/grub/usb.h | 2 ++
- 3 files changed, 47 insertions(+), 6 deletions(-)
-
-diff --git a/grub-core/bus/usb/usbhub.c b/grub-core/bus/usb/usbhub.c
-index e96505aa9..629b3ed53 100644
---- a/grub-core/bus/usb/usbhub.c
-+++ b/grub-core/bus/usb/usbhub.c
-@@ -818,3 +818,9 @@ grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data)
-
- return 0;
- }
-+
-+grub_usb_device_t
-+grub_usb_get_dev (int addr)
-+{
-+ return grub_usb_devs[addr];
-+}
-diff --git a/grub-core/bus/usb/xhci.c b/grub-core/bus/usb/xhci.c
-index dc89b9619..88c9ac57f 100644
---- a/grub-core/bus/usb/xhci.c
-+++ b/grub-core/bus/usb/xhci.c
-@@ -623,13 +623,46 @@ grub_xhci_alloc_inctx(struct grub_xhci *x, int maxepid,
- break;
- }
-
-- /* Route is greater zero on devices that are connected to a non root hub */
-- if (dev->route)
-- {
-- /* FIXME: Implement this code for non SuperSpeed hub devices */
-+ /* Set routing string */
-+ slot->ctx[0] |= dev->route;
-+
-+ /* Set root hub port number */
-+ slot->ctx[1] |= (dev->root_port + 1) << 16;
-+
-+ if (dev->split_hubaddr && (dev->speed == GRUB_USB_SPEED_LOW ||
-+ dev->speed == GRUB_USB_SPEED_FULL)) {
-+
-+ grub_usb_device_t hubdev = grub_usb_get_dev(dev->split_hubaddr);
-+
-+ if (!hubdev || hubdev->descdev.class != GRUB_USB_CLASS_HUB) {
-+ grub_dprintf("xhci", "Invalid hub device at addr %d!\n", dev->split_hubaddr);
-+ return NULL;
-+ }
-+
-+ struct grub_xhci_priv *hub_priv = hubdev->xhci_priv;
-+ if (!hub_priv) {
-+ grub_dprintf("xhci", "Hub has no xhci_priv!\n");
-+ return NULL;
-+ }
-+
-+ if (hubdev->speed == GRUB_USB_SPEED_HIGH) {
-+ /* Direct connection to high-speed hub - set up TT */
-+ grub_dprintf("xhci", "Direct high-speed hub connection - configuring TT with "
-+ "hub slot %d port %d\n", hub_priv->slotid, dev->split_hubport);
-+ slot->ctx[2] |= hub_priv->slotid;
-+ slot->ctx[2] |= dev->split_hubport << 8;
- }
-- slot->ctx[0] |= dev->route;
-- slot->ctx[1] |= (dev->root_port+1) << 16;
-+ else {
-+ /* Hub is not high-speed, inherit TT settings from parent */
-+ volatile struct grub_xhci_slotctx *hubslot;
-+ grub_dprintf("xhci", "Non high-speed hub - inheriting TT settings from parent\n");
-+ hubslot = grub_dma_phys2virt(x->devs[hub_priv->slotid].ptr_low, x->devs_dma);
-+ slot->ctx[2] = hubslot->ctx[2];
-+ }
-+ }
-+
-+ grub_dprintf("xhci", "Slot context: ctx[0]=0x%08x ctx[1]=0x%08x ctx[2]=0x%08x\n",
-+ slot->ctx[0], slot->ctx[1], slot->ctx[2]);
-
- grub_arch_sync_dma_caches(in, size);
-
-diff --git a/include/grub/usb.h b/include/grub/usb.h
-index eb71fa1c7..df97a60cc 100644
---- a/include/grub/usb.h
-+++ b/include/grub/usb.h
-@@ -62,6 +62,8 @@ typedef int (*grub_usb_controller_iterate_hook_t) (grub_usb_controller_t dev,
- /* Call HOOK with each device, until HOOK returns non-zero. */
- int grub_usb_iterate (grub_usb_iterate_hook_t hook, void *hook_data);
-
-+grub_usb_device_t grub_usb_get_dev (int addr);
-+
- grub_usb_err_t grub_usb_device_initialize (grub_usb_device_t dev);
-
- grub_usb_err_t grub_usb_get_descriptor (grub_usb_device_t dev,
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0018-Fix-compilation-on-x86_64.patch b/config/grub/xhci_nvme/patches/0018-Fix-compilation-on-x86_64.patch
deleted file mode 100644
index 70a1a22c..00000000
--- a/config/grub/xhci_nvme/patches/0018-Fix-compilation-on-x86_64.patch
+++ /dev/null
@@ -1,90 +0,0 @@
-From cc671d76816c8370a85e289d5ac7bdf1f687ff3a Mon Sep 17 00:00:00 2001
-From: Patrick Rudolph <patrick.rudolph@9elements.com>
-Date: Wed, 24 Feb 2021 08:25:41 +0100
-Subject: [PATCH 18/21] Fix compilation on x86_64
-
-Signed-off-by: Patrick Rudolph <patrick.rudolph@9elements.com>
----
- grub-core/bus/usb/xhci.c | 24 ++++++++++++++++--------
- 1 file changed, 16 insertions(+), 8 deletions(-)
-
-diff --git a/grub-core/bus/usb/xhci.c b/grub-core/bus/usb/xhci.c
-index 88c9ac57f..9b9bae6e5 100644
---- a/grub-core/bus/usb/xhci.c
-+++ b/grub-core/bus/usb/xhci.c
-@@ -184,7 +184,7 @@ enum
- * then we can get it from a trb pointer (provided by evt ring).
- */
- #define XHCI_RING(_trb) \
-- ((struct grub_xhci_ring*)((grub_uint32_t)(_trb) & ~(GRUB_XHCI_RING_SIZE-1)))
-+ ((struct grub_xhci_ring*)((grub_addr_t)(_trb) & ~(GRUB_XHCI_RING_SIZE-1)))
-
- /* slot context */
- struct grub_xhci_slotctx {
-@@ -495,6 +495,14 @@ grub_xhci_read8(volatile void *addr) {
- return (*((volatile grub_uint32_t *)addr));
- }
-
-+static inline void *
-+grub_xhci_read_etrb_ptr(volatile struct grub_xhci_trb *trb) {
-+ grub_uint64_t tmp;
-+ tmp = (grub_uint64_t)grub_xhci_read32(&trb->ptr_low);
-+ tmp |= ((grub_uint64_t)grub_xhci_read32(&trb->ptr_high)) << 32;
-+ return (void *)(grub_addr_t)tmp;
-+}
-+
- static inline grub_uint32_t
- grub_xhci_port_read (struct grub_xhci *x, grub_uint32_t port)
- {
-@@ -697,7 +705,7 @@ static void xhci_process_events(struct grub_xhci *x)
- case ER_TRANSFER:
- case ER_COMMAND_COMPLETE:
- {
-- struct grub_xhci_trb *rtrb = (void*)grub_xhci_read32(&etrb->ptr_low);
-+ struct grub_xhci_trb *rtrb = grub_xhci_read_etrb_ptr(etrb);
- struct grub_xhci_ring *ring = XHCI_RING(rtrb);
- volatile struct grub_xhci_trb *evt = &ring->evt;
- grub_uint32_t eidx = rtrb - ring->ring + 1;
-@@ -730,9 +738,9 @@ static void xhci_process_events(struct grub_xhci *x)
- }
- grub_xhci_write32(&evts->nidx, nidx);
- volatile struct grub_xhci_ir *ir = x->ir;
-- grub_uint32_t erdp = (grub_uint32_t)(evts->ring + nidx);
-- grub_xhci_write32(&ir->erdp_low, erdp);
-- grub_xhci_write32(&ir->erdp_high, 0);
-+ grub_uint64_t erdp = (grub_addr_t)(void *)(&evts->ring[nidx]);
-+ grub_xhci_write32(&ir->erdp_low, erdp & 0xffffffff);
-+ grub_xhci_write32(&ir->erdp_high, erdp >> 32);
- }
- }
-
-@@ -833,7 +841,7 @@ static void xhci_trb_queue(volatile struct grub_xhci_ring *ring,
- grub_uint32_t xferlen, grub_uint32_t flags)
- {
- grub_dprintf("xhci", "%s: ring %p data %llx len %d flags 0x%x remain 0x%x\n", __func__,
-- ring, data_or_addr, xferlen & 0x1ffff, flags, xferlen >> 17);
-+ ring, (unsigned long long)data_or_addr, xferlen & 0x1ffff, flags, xferlen >> 17);
-
- if (xhci_ring_full(ring))
- {
-@@ -1940,7 +1948,7 @@ grub_xhci_setup_transfer (grub_usb_controller_t dev,
- if (transfer->type == GRUB_USB_TRANSACTION_TYPE_CONTROL)
- {
- volatile struct grub_usb_packet_setup *setupdata;
-- setupdata = (void *)transfer->transactions[0].data;
-+ setupdata = (void *)(grub_addr_t)transfer->transactions[0].data;
- grub_dprintf("xhci", "%s: CONTROLL TRANS req %d\n", __func__, setupdata->request);
- grub_dprintf("xhci", "%s: CONTROLL TRANS length %d\n", __func__, setupdata->length);
-
-@@ -2007,7 +2015,7 @@ grub_xhci_setup_transfer (grub_usb_controller_t dev,
- /* Assume the ring has enough free space for all TRBs */
- if (flags & TRB_TR_IDT && tr->size <= (int)sizeof(inline_data))
- {
-- grub_memcpy(&inline_data, (void *)tr->data, tr->size);
-+ grub_memcpy(&inline_data, (void *)(grub_addr_t)tr->data, tr->size);
- xhci_trb_queue(reqs, inline_data, tr->size, flags);
- }
- else
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0019-Add-native-NVMe-driver-based-on-SeaBIOS.patch b/config/grub/xhci_nvme/patches/0019-Add-native-NVMe-driver-based-on-SeaBIOS.patch
deleted file mode 100644
index f09ae69d..00000000
--- a/config/grub/xhci_nvme/patches/0019-Add-native-NVMe-driver-based-on-SeaBIOS.patch
+++ /dev/null
@@ -1,1074 +0,0 @@
-From 467fe4c5a98c0cfc1b357ec8acc360a03b5f7038 Mon Sep 17 00:00:00 2001
-From: Mate Kukri <km@mkukri.xyz>
-Date: Mon, 20 May 2024 11:43:35 +0100
-Subject: [PATCH 19/21] Add native NVMe driver based on SeaBIOS
-
-Tested to successfully boot Debian on QEMU and OptiPlex 3050.
-
-Signed-off-by: Mate Kukri <km@mkukri.xyz>
----
- Makefile.am | 2 +-
- grub-core/Makefile.core.def | 6 +
- grub-core/commands/nativedisk.c | 1 +
- grub-core/disk/nvme-int.h | 208 +++++++++
- grub-core/disk/nvme.c | 781 ++++++++++++++++++++++++++++++++
- include/grub/disk.h | 1 +
- 6 files changed, 998 insertions(+), 1 deletion(-)
- create mode 100644 grub-core/disk/nvme-int.h
- create mode 100644 grub-core/disk/nvme.c
-
-diff --git a/Makefile.am b/Makefile.am
-index 65016f856..7bc0866ba 100644
---- a/Makefile.am
-+++ b/Makefile.am
-@@ -434,7 +434,7 @@ if COND_i386_coreboot
- FS_PAYLOAD_MODULES ?= $(shell cat grub-core/fs.lst)
- default_payload.elf: grub-mkstandalone grub-mkimage FORCE
- test -f $@ && rm $@ || true
-- pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata xhci ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
-+ pkgdatadir=. ./grub-mkstandalone --grub-mkimage=./grub-mkimage -O i386-coreboot -o $@ --modules='ahci pata nvme xhci ehci uhci ohci usb_keyboard usbms part_msdos ext2 fat at_keyboard part_gpt usbserial_usbdebug cbfs' --install-modules='ls linux search configfile normal cbtime cbls memrw iorw minicmd lsmmap lspci halt reboot hexdump pcidump regexp setpci lsacpi chain test serial multiboot cbmemc linux16 gzio echo help syslinuxcfg xnu $(FS_PAYLOAD_MODULES) password_pbkdf2 $(EXTRA_PAYLOAD_MODULES)' --fonts= --themes= --locales= -d grub-core/ /boot/grub/grub.cfg=$(srcdir)/coreboot.cfg
- endif
-
- endif
-diff --git a/grub-core/Makefile.core.def b/grub-core/Makefile.core.def
-index ec4c76ea8..08b83ad06 100644
---- a/grub-core/Makefile.core.def
-+++ b/grub-core/Makefile.core.def
-@@ -2780,3 +2780,9 @@ module = {
- cflags = '-Wno-uninitialized';
- cppflags = '-I$(srcdir)/lib/libtasn1-grub -I$(srcdir)/tests/asn1/';
- };
-+
-+module = {
-+ name = nvme;
-+ common = disk/nvme.c;
-+ enable = pci;
-+};
-diff --git a/grub-core/commands/nativedisk.c b/grub-core/commands/nativedisk.c
-index 6806bff9c..fd68a513e 100644
---- a/grub-core/commands/nativedisk.c
-+++ b/grub-core/commands/nativedisk.c
-@@ -78,6 +78,7 @@ get_uuid (const char *name, char **uuid, int getnative)
- case GRUB_DISK_DEVICE_ATA_ID:
- case GRUB_DISK_DEVICE_SCSI_ID:
- case GRUB_DISK_DEVICE_XEN:
-+ case GRUB_DISK_DEVICE_NVME_ID:
- if (getnative)
- break;
- /* FALLTHROUGH */
-diff --git a/grub-core/disk/nvme-int.h b/grub-core/disk/nvme-int.h
-new file mode 100644
-index 000000000..1295b58aa
---- /dev/null
-+++ b/grub-core/disk/nvme-int.h
-@@ -0,0 +1,208 @@
-+// NVMe datastructures and constants
-+//
-+// Copyright 2017 Amazon.com, Inc. or its affiliates.
-+//
-+// This file may be distributed under the terms of the GNU LGPLv3 license.
-+
-+#ifndef __NVME_INT_H
-+#define __NVME_INT_H
-+
-+#include <grub/types.h>
-+
-+/* Data structures */
-+
-+/* The register file of a NVMe host controller. This struct follows the naming
-+ scheme in the NVMe specification. */
-+struct nvme_reg {
-+ grub_uint64_t cap; /* controller capabilities */
-+ grub_uint32_t vs; /* version */
-+ grub_uint32_t intms; /* interrupt mask set */
-+ grub_uint32_t intmc; /* interrupt mask clear */
-+ grub_uint32_t cc; /* controller configuration */
-+ grub_uint32_t _res0;
-+ grub_uint32_t csts; /* controller status */
-+ grub_uint32_t _res1;
-+ grub_uint32_t aqa; /* admin queue attributes */
-+ grub_uint64_t asq; /* admin submission queue base address */
-+ grub_uint64_t acq; /* admin completion queue base address */
-+};
-+
-+/* Submission queue entry */
-+struct nvme_sqe {
-+ union {
-+ grub_uint32_t dword[16];
-+ struct {
-+ grub_uint32_t cdw0; /* Command DWORD 0 */
-+ grub_uint32_t nsid; /* Namespace ID */
-+ grub_uint64_t _res0;
-+ grub_uint64_t mptr; /* metadata ptr */
-+
-+ grub_uint64_t dptr_prp1;
-+ grub_uint64_t dptr_prp2;
-+ };
-+ };
-+};
-+
-+/* Completion queue entry */
-+struct nvme_cqe {
-+ union {
-+ grub_uint32_t dword[4];
-+ struct {
-+ grub_uint32_t cdw0;
-+ grub_uint32_t _res0;
-+ grub_uint16_t sq_head;
-+ grub_uint16_t sq_id;
-+ grub_uint16_t cid;
-+ grub_uint16_t status;
-+ };
-+ };
-+};
-+
-+/* The common part of every submission or completion queue. */
-+struct nvme_queue {
-+ grub_uint32_t *dbl; /* doorbell */
-+ grub_uint16_t mask; /* length - 1 */
-+};
-+
-+struct nvme_cq {
-+ struct nvme_queue common;
-+ struct nvme_cqe *cqe;
-+
-+ /* We have read upto (but not including) this entry in the queue. */
-+ grub_uint16_t head;
-+
-+ /* The current phase bit the controller uses to indicate that it has written
-+ a new entry. This is inverted after each wrap. */
-+ unsigned phase : 1;
-+};
-+
-+struct nvme_sq {
-+ struct nvme_queue common;
-+ struct nvme_sqe *sqe;
-+
-+ /* Corresponding completion queue. We only support a single SQ per CQ. */
-+ struct nvme_cq *cq;
-+
-+ /* The last entry the controller has fetched. */
-+ grub_uint16_t head;
-+
-+ /* The last value we have written to the tail doorbell. */
-+ grub_uint16_t tail;
-+};
-+
-+struct nvme_ctrl {
-+ grub_pci_device_t pci;
-+ struct nvme_reg volatile *reg;
-+
-+ grub_uint32_t ctrlnum;
-+
-+ grub_uint32_t doorbell_stride; /* in bytes */
-+
-+ struct nvme_sq admin_sq;
-+ struct nvme_cq admin_cq;
-+
-+ grub_uint32_t ns_count;
-+
-+ struct nvme_sq io_sq;
-+ struct nvme_cq io_cq;
-+};
-+
-+struct nvme_namespace {
-+ struct nvme_namespace *next;
-+ struct nvme_namespace **prev;
-+
-+ char *devname;
-+
-+ grub_uint32_t nsnum;
-+
-+ struct nvme_ctrl *ctrl;
-+
-+ grub_uint32_t ns_id;
-+
-+ grub_uint64_t lba_count; /* The total amount of sectors. */
-+
-+ grub_uint32_t block_size;
-+ grub_uint32_t metadata_size;
-+ grub_uint32_t max_req_size;
-+};
-+
-+/* Data structures for NVMe admin identify commands */
-+
-+struct nvme_identify_ctrl {
-+ grub_uint16_t vid;
-+ grub_uint16_t ssvid;
-+ char sn[20];
-+ char mn[40];
-+ char fr[8];
-+
-+ grub_uint8_t rab;
-+ grub_uint8_t ieee[3];
-+ grub_uint8_t cmic;
-+ grub_uint8_t mdts;
-+
-+ char _boring[516 - 78];
-+
-+ grub_uint32_t nn; /* number of namespaces */
-+};
-+
-+struct nvme_identify_ns_list {
-+ grub_uint32_t ns_id[1024];
-+};
-+
-+struct nvme_lba_format {
-+ grub_uint16_t ms;
-+ grub_uint8_t lbads;
-+ grub_uint8_t rp;
-+};
-+
-+struct nvme_identify_ns {
-+ grub_uint64_t nsze;
-+ grub_uint64_t ncap;
-+ grub_uint64_t nuse;
-+ grub_uint8_t nsfeat;
-+ grub_uint8_t nlbaf;
-+ grub_uint8_t flbas;
-+
-+ char _boring[128 - 27];
-+
-+ struct nvme_lba_format lbaf[16];
-+};
-+
-+union nvme_identify {
-+ struct nvme_identify_ns ns;
-+ struct nvme_identify_ctrl ctrl;
-+ struct nvme_identify_ns_list ns_list;
-+};
-+
-+/* NVMe constants */
-+
-+#define NVME_CAP_CSS_NVME (1ULL << 37)
-+
-+#define NVME_CSTS_FATAL (1U << 1)
-+#define NVME_CSTS_RDY (1U << 0)
-+
-+#define NVME_CC_EN (1U << 0)
-+
-+#define NVME_SQE_OPC_ADMIN_CREATE_IO_SQ 1U
-+#define NVME_SQE_OPC_ADMIN_CREATE_IO_CQ 5U
-+#define NVME_SQE_OPC_ADMIN_IDENTIFY 6U
-+
-+#define NVME_SQE_OPC_IO_WRITE 1U
-+#define NVME_SQE_OPC_IO_READ 2U
-+
-+#define NVME_ADMIN_IDENTIFY_CNS_ID_NS 0U
-+#define NVME_ADMIN_IDENTIFY_CNS_ID_CTRL 1U
-+#define NVME_ADMIN_IDENTIFY_CNS_GET_NS_LIST 2U
-+
-+#define NVME_CQE_DW3_P (1U << 16)
-+
-+#define NVME_PAGE_SIZE 4096
-+#define NVME_PAGE_MASK ~(NVME_PAGE_SIZE - 1)
-+
-+/* Length for the queue entries. */
-+#define NVME_SQE_SIZE_LOG 6
-+#define NVME_CQE_SIZE_LOG 4
-+
-+#endif
-+
-+/* EOF */
-diff --git a/grub-core/disk/nvme.c b/grub-core/disk/nvme.c
-new file mode 100644
-index 000000000..093237c70
---- /dev/null
-+++ b/grub-core/disk/nvme.c
-@@ -0,0 +1,781 @@
-+// Low level NVMe disk access
-+//
-+// Based on SeaBIOS NVMe driver - Copyright 2017 Amazon.com, Inc. or its affiliates.
-+// Port to GRUB2 done by Mate Kukri
-+//
-+// This file may be distributed under the terms of the GNU LGPLv3 license.
-+
-+#include <grub/disk.h>
-+#include <grub/dl.h>
-+#include <grub/pci.h>
-+#include "nvme-int.h"
-+
-+GRUB_MOD_LICENSE ("GPLv3"); /* LGPLv3 in reality but it is GPLv3 compatible */
-+
-+static grub_uint32_t grub_nvme_ctrlcnt;
-+static grub_uint32_t grub_nvme_nscnt;
-+
-+static struct nvme_namespace *grub_nvme_namespaces;
-+
-+// Page aligned "dma bounce buffer" of size NVME_PAGE_SIZE
-+static void *nvme_dma_buffer;
-+
-+static void *
-+zalloc_page_aligned(grub_uint32_t size)
-+{
-+ void *res = grub_memalign(NVME_PAGE_SIZE, size);
-+ if (res) grub_memset(res, 0, size);
-+ return res;
-+}
-+
-+static void
-+nvme_init_queue_common(struct nvme_ctrl *ctrl, struct nvme_queue *q, grub_uint16_t q_idx,
-+ grub_uint16_t length)
-+{
-+ grub_memset(q, 0, sizeof(*q));
-+ q->dbl = (grub_uint32_t *)((char *)ctrl->reg + 0x1000 + q_idx * ctrl->doorbell_stride);
-+ grub_dprintf("nvme", " q %p q_idx %u dbl %p\n", q, q_idx, q->dbl);
-+ q->mask = length - 1;
-+}
-+
-+static int
-+nvme_init_sq(struct nvme_ctrl *ctrl, struct nvme_sq *sq, grub_uint16_t q_idx, grub_uint16_t length,
-+ struct nvme_cq *cq)
-+{
-+ nvme_init_queue_common(ctrl, &sq->common, q_idx, length);
-+ sq->sqe = zalloc_page_aligned(sizeof(*sq->sqe) * length);
-+
-+ if (!sq->sqe) {
-+ return -1;
-+ }
-+
-+ grub_dprintf("nvme", "sq %p q_idx %u sqe %p\n", sq, q_idx, sq->sqe);
-+ sq->cq = cq;
-+ sq->head = 0;
-+ sq->tail = 0;
-+
-+ return 0;
-+}
-+
-+static int
-+nvme_init_cq(struct nvme_ctrl *ctrl, struct nvme_cq *cq, grub_uint16_t q_idx, grub_uint16_t length)
-+{
-+ nvme_init_queue_common(ctrl, &cq->common, q_idx, length);
-+ cq->cqe = zalloc_page_aligned(sizeof(*cq->cqe) * length);
-+ if (!cq->cqe) {
-+ return -1;
-+ }
-+
-+ cq->head = 0;
-+
-+ /* All CQE phase bits are initialized to zero. This means initially we wait
-+ for the host controller to set these to 1. */
-+ cq->phase = 1;
-+
-+ return 0;
-+}
-+
-+static int
-+nvme_poll_cq(struct nvme_cq *cq)
-+{
-+ grub_uint32_t dw3 = *(volatile grub_uint32_t *) &cq->cqe[cq->head].dword[3];
-+ return (!!(dw3 & NVME_CQE_DW3_P) == cq->phase);
-+}
-+
-+static int
-+nvme_is_cqe_success(struct nvme_cqe const *cqe)
-+{
-+ return ((cqe->status >> 1) & 0xFF) == 0;
-+}
-+
-+static struct nvme_cqe
-+nvme_error_cqe(void)
-+{
-+ struct nvme_cqe r;
-+
-+ /* 0xFF is a vendor specific status code != success. Should be okay for
-+ indicating failure. */
-+ grub_memset(&r, 0xFF, sizeof(r));
-+ return r;
-+}
-+
-+static struct nvme_cqe
-+nvme_consume_cqe(struct nvme_sq *sq)
-+{
-+ struct nvme_cq *cq = sq->cq;
-+
-+ if (!nvme_poll_cq(cq)) {
-+ /* Cannot consume a completion queue entry, if there is none ready. */
-+ return nvme_error_cqe();
-+ }
-+
-+ struct nvme_cqe *cqe = &cq->cqe[cq->head];
-+ grub_uint16_t cq_next_head = (cq->head + 1) & cq->common.mask;
-+ grub_dprintf("nvme", "cq %p head %u -> %u\n", cq, cq->head, cq_next_head);
-+ if (cq_next_head < cq->head) {
-+ grub_dprintf("nvme", "cq %p wrap\n", cq);
-+ cq->phase = ~cq->phase;
-+ }
-+ cq->head = cq_next_head;
-+
-+ /* Update the submission queue head. */
-+ if (cqe->sq_head != sq->head) {
-+ sq->head = cqe->sq_head;
-+ grub_dprintf("nvme", "sq %p advanced to %u\n", sq, cqe->sq_head);
-+ }
-+
-+ /* Tell the controller that we consumed the completion. */
-+ *(volatile grub_uint32_t *) cq->common.dbl = cq->head;
-+
-+ return *cqe;
-+}
-+
-+static struct nvme_cqe
-+nvme_wait(struct nvme_sq *sq)
-+{
-+ // static const unsigned nvme_timeout = 5000 /* ms */;
-+ // grub_uint32_t to = timer_calc(nvme_timeout);
-+ while (!nvme_poll_cq(sq->cq)) {
-+ /* FIXME
-+ yield();
-+
-+ if (timer_check(to)) {
-+ warn_timeout();
-+ return nvme_error_cqe();
-+ }*/
-+ }
-+
-+ return nvme_consume_cqe(sq);
-+}
-+
-+/* Returns the next submission queue entry (or NULL if the queue is full). It
-+ also fills out Command Dword 0 and clears the rest. */
-+static struct nvme_sqe *
-+nvme_get_next_sqe(struct nvme_sq *sq, grub_uint8_t opc, void *metadata, void *data, void *data2)
-+{
-+ if (((sq->head + 1) & sq->common.mask) == sq->tail) {
-+ grub_dprintf("nvme", "submission queue is full\n");
-+ return NULL;
-+ }
-+
-+ struct nvme_sqe *sqe = &sq->sqe[sq->tail];
-+ grub_dprintf("nvme", "sq %p next_sqe %u\n", sq, sq->tail);
-+
-+ grub_memset(sqe, 0, sizeof(*sqe));
-+ sqe->cdw0 = opc | (sq->tail << 16 /* CID */);
-+ sqe->mptr = (grub_uint32_t)metadata;
-+ sqe->dptr_prp1 = (grub_uint32_t)data;
-+ sqe->dptr_prp2 = (grub_uint32_t)data2;
-+
-+ return sqe;
-+}
-+
-+/* Call this after you've filled out an sqe that you've got from nvme_get_next_sqe. */
-+static void
-+nvme_commit_sqe(struct nvme_sq *sq)
-+{
-+ grub_dprintf("nvme", "sq %p commit_sqe %u\n", sq, sq->tail);
-+ sq->tail = (sq->tail + 1) & sq->common.mask;
-+ *(volatile grub_uint32_t *) sq->common.dbl = sq->tail;
-+}
-+
-+/* Perform an identify command on the admin queue and return the resulting
-+ buffer. This may be a NULL pointer, if something failed. This function
-+ cannot be used after initialization, because it uses buffers in tmp zone. */
-+static union nvme_identify *
-+nvme_admin_identify(struct nvme_ctrl *ctrl, grub_uint8_t cns, grub_uint32_t nsid)
-+{
-+ union nvme_identify *identify_buf = zalloc_page_aligned(4096);
-+ if (!identify_buf)
-+ return NULL;
-+
-+ struct nvme_sqe *cmd_identify;
-+ cmd_identify = nvme_get_next_sqe(&ctrl->admin_sq,
-+ NVME_SQE_OPC_ADMIN_IDENTIFY, NULL,
-+ identify_buf, NULL);
-+ if (!cmd_identify)
-+ goto error;
-+
-+ cmd_identify->nsid = nsid;
-+ cmd_identify->dword[10] = cns;
-+
-+ nvme_commit_sqe(&ctrl->admin_sq);
-+
-+ struct nvme_cqe cqe = nvme_wait(&ctrl->admin_sq);
-+
-+ if (!nvme_is_cqe_success(&cqe)) {
-+ goto error;
-+ }
-+
-+ return identify_buf;
-+ error:
-+ grub_free(identify_buf);
-+ return NULL;
-+}
-+
-+static struct nvme_identify_ctrl *
-+nvme_admin_identify_ctrl(struct nvme_ctrl *ctrl)
-+{
-+ return &nvme_admin_identify(ctrl, NVME_ADMIN_IDENTIFY_CNS_ID_CTRL, 0)->ctrl;
-+}
-+
-+static struct nvme_identify_ns *
-+nvme_admin_identify_ns(struct nvme_ctrl *ctrl, grub_uint32_t ns_id)
-+{
-+ return &nvme_admin_identify(ctrl, NVME_ADMIN_IDENTIFY_CNS_ID_NS,
-+ ns_id)->ns;
-+}
-+
-+static void
-+nvme_probe_ns(struct nvme_ctrl *ctrl, grub_uint32_t ns_idx, grub_uint8_t mdts)
-+{
-+ grub_uint32_t ns_id = ns_idx + 1;
-+
-+ struct nvme_identify_ns *id = nvme_admin_identify_ns(ctrl, ns_id);
-+ if (!id) {
-+ grub_dprintf("nvme", "NVMe couldn't identify namespace %u.\n", ns_id);
-+ goto free_buffer;
-+ }
-+
-+ grub_uint8_t current_lba_format = id->flbas & 0xF;
-+ if (current_lba_format > id->nlbaf) {
-+ grub_dprintf("nvme", "NVMe NS %u: current LBA format %u is beyond what the "
-+ " namespace supports (%u)?\n",
-+ ns_id, current_lba_format, id->nlbaf + 1);
-+ goto free_buffer;
-+ }
-+
-+ if (!id->nsze) {
-+ grub_dprintf("nvme", "NVMe NS %u is inactive.\n", ns_id);
-+ goto free_buffer;
-+ }
-+
-+ if (!nvme_dma_buffer) {
-+ nvme_dma_buffer = zalloc_page_aligned(NVME_PAGE_SIZE);
-+ if (!nvme_dma_buffer) {
-+ goto free_buffer;
-+ }
-+ }
-+
-+ struct nvme_namespace *ns = grub_malloc(sizeof(*ns));
-+ if (!ns) {
-+ goto free_buffer;
-+ }
-+ grub_memset(ns, 0, sizeof(*ns));
-+ ns->ctrl = ctrl;
-+ ns->ns_id = ns_id;
-+ ns->lba_count = id->nsze;
-+
-+ struct nvme_lba_format *fmt = &id->lbaf[current_lba_format];
-+
-+ ns->block_size = 1U << fmt->lbads;
-+ ns->metadata_size = fmt->ms;
-+
-+ if (ns->block_size > NVME_PAGE_SIZE) {
-+ /* If we see devices that trigger this path, we need to increase our
-+ buffer size. */
-+ grub_free(ns);
-+ goto free_buffer;
-+ }
-+
-+ if (mdts) {
-+ ns->max_req_size = ((1U << mdts) * NVME_PAGE_SIZE) / ns->block_size;
-+ grub_dprintf("nvme", "NVME NS %u max request size: %d sectors\n",
-+ ns_id, ns->max_req_size);
-+ } else {
-+ ns->max_req_size = -1U;
-+ }
-+
-+ ns->devname = grub_xasprintf("nvme%un%u", ctrl->ctrlnum, ns_id);
-+ ns->nsnum = grub_nvme_nscnt++;
-+
-+ grub_list_push (GRUB_AS_LIST_P (&grub_nvme_namespaces), GRUB_AS_LIST (ns));
-+
-+free_buffer:
-+ grub_free(id);
-+}
-+
-+
-+/* Release memory allocated for a completion queue */
-+static void
-+nvme_destroy_cq(struct nvme_cq *cq)
-+{
-+ grub_free(cq->cqe);
-+ cq->cqe = NULL;
-+}
-+
-+/* Release memory allocated for a submission queue */
-+static void
-+nvme_destroy_sq(struct nvme_sq *sq)
-+{
-+ grub_free(sq->sqe);
-+ sq->sqe = NULL;
-+}
-+
-+/* Returns 0 on success. */
-+static int
-+nvme_create_io_cq(struct nvme_ctrl *ctrl, struct nvme_cq *cq, grub_uint16_t q_idx)
-+{
-+ int rc;
-+ struct nvme_sqe *cmd_create_cq;
-+ grub_uint32_t length = 1 + (ctrl->reg->cap & 0xffff);
-+ if (length > NVME_PAGE_SIZE / sizeof(struct nvme_cqe))
-+ length = NVME_PAGE_SIZE / sizeof(struct nvme_cqe);
-+
-+ rc = nvme_init_cq(ctrl, cq, q_idx, length);
-+ if (rc) {
-+ goto err;
-+ }
-+
-+ cmd_create_cq = nvme_get_next_sqe(&ctrl->admin_sq,
-+ NVME_SQE_OPC_ADMIN_CREATE_IO_CQ, NULL,
-+ cq->cqe, NULL);
-+ if (!cmd_create_cq) {
-+ goto err_destroy_cq;
-+ }
-+
-+ cmd_create_cq->dword[10] = (cq->common.mask << 16) | (q_idx >> 1);
-+ cmd_create_cq->dword[11] = 1 /* physically contiguous */;
-+
-+ nvme_commit_sqe(&ctrl->admin_sq);
-+
-+ struct nvme_cqe cqe = nvme_wait(&ctrl->admin_sq);
-+
-+ if (!nvme_is_cqe_success(&cqe)) {
-+ grub_dprintf("nvme", "create io cq failed: %08x %08x %08x %08x\n",
-+ cqe.dword[0], cqe.dword[1], cqe.dword[2], cqe.dword[3]);
-+
-+ goto err_destroy_cq;
-+ }
-+
-+ return 0;
-+
-+err_destroy_cq:
-+ nvme_destroy_cq(cq);
-+err:
-+ return -1;
-+}
-+
-+/* Returns 0 on success. */
-+static int
-+nvme_create_io_sq(struct nvme_ctrl *ctrl, struct nvme_sq *sq, grub_uint16_t q_idx, struct nvme_cq *cq)
-+{
-+ int rc;
-+ struct nvme_sqe *cmd_create_sq;
-+ grub_uint32_t length = 1 + (ctrl->reg->cap & 0xffff);
-+ if (length > NVME_PAGE_SIZE / sizeof(struct nvme_cqe))
-+ length = NVME_PAGE_SIZE / sizeof(struct nvme_cqe);
-+
-+ rc = nvme_init_sq(ctrl, sq, q_idx, length, cq);
-+ if (rc) {
-+ goto err;
-+ }
-+
-+ cmd_create_sq = nvme_get_next_sqe(&ctrl->admin_sq,
-+ NVME_SQE_OPC_ADMIN_CREATE_IO_SQ, NULL,
-+ sq->sqe, NULL);
-+ if (!cmd_create_sq) {
-+ goto err_destroy_sq;
-+ }
-+
-+ cmd_create_sq->dword[10] = (sq->common.mask << 16) | (q_idx >> 1);
-+ cmd_create_sq->dword[11] = (q_idx >> 1) << 16 | 1 /* contiguous */;
-+ grub_dprintf("nvme", "sq %p create dword10 %08x dword11 %08x\n", sq,
-+ cmd_create_sq->dword[10], cmd_create_sq->dword[11]);
-+
-+ nvme_commit_sqe(&ctrl->admin_sq);
-+
-+ struct nvme_cqe cqe = nvme_wait(&ctrl->admin_sq);
-+
-+ if (!nvme_is_cqe_success(&cqe)) {
-+ grub_dprintf("nvme", "create io sq failed: %08x %08x %08x %08x\n",
-+ cqe.dword[0], cqe.dword[1], cqe.dword[2], cqe.dword[3]);
-+ goto err_destroy_sq;
-+ }
-+
-+ return 0;
-+
-+err_destroy_sq:
-+ nvme_destroy_sq(sq);
-+err:
-+ return -1;
-+}
-+
-+/* Reads count sectors into buf. The buffer cannot cross page boundaries. */
-+static int
-+nvme_io_xfer(struct nvme_namespace *ns, grub_uint64_t lba, void *prp1, void *prp2,
-+ grub_uint16_t count, int write)
-+{
-+ if (((grub_uint32_t)prp1 & 0x3) || ((grub_uint32_t)prp2 & 0x3)) {
-+ /* Buffer is misaligned */
-+ return -1;
-+ }
-+
-+ struct nvme_sqe *io_read = nvme_get_next_sqe(&ns->ctrl->io_sq,
-+ write ? NVME_SQE_OPC_IO_WRITE
-+ : NVME_SQE_OPC_IO_READ,
-+ NULL, prp1, prp2);
-+ io_read->nsid = ns->ns_id;
-+ io_read->dword[10] = (grub_uint32_t)lba;
-+ io_read->dword[11] = (grub_uint32_t)(lba >> 32);
-+ io_read->dword[12] = (1U << 31 /* limited retry */) | (count - 1);
-+
-+ nvme_commit_sqe(&ns->ctrl->io_sq);
-+
-+ struct nvme_cqe cqe = nvme_wait(&ns->ctrl->io_sq);
-+
-+ if (!nvme_is_cqe_success(&cqe)) {
-+ grub_dprintf("nvme", "read io: %08x %08x %08x %08x\n",
-+ cqe.dword[0], cqe.dword[1], cqe.dword[2], cqe.dword[3]);
-+
-+ return -1;
-+ }
-+
-+ grub_dprintf("nvme", "ns %u %s lba %llu+%u\n", ns->ns_id, write ? "write" : "read",
-+ lba, count);
-+ return count;
-+}
-+
-+// Transfer up to one page of data using the internal dma bounce buffer
-+static int
-+nvme_bounce_xfer(struct nvme_namespace *ns, grub_uint64_t lba, void *buf, grub_uint16_t count,
-+ int write)
-+{
-+ grub_uint16_t const max_blocks = NVME_PAGE_SIZE / ns->block_size;
-+ grub_uint16_t blocks = count < max_blocks ? count : max_blocks;
-+
-+ if (write)
-+ grub_memcpy(nvme_dma_buffer, buf, blocks * ns->block_size);
-+
-+ int res = nvme_io_xfer(ns, lba, nvme_dma_buffer, NULL, blocks, write);
-+
-+ if (!write && res >= 0)
-+ grub_memcpy(buf, nvme_dma_buffer, res * ns->block_size);
-+
-+ return res;
-+}
-+
-+#define NVME_MAX_PRPL_ENTRIES 15 /* Allows requests up to 64kb */
-+
-+// Transfer data using page list (if applicable)
-+static int
-+nvme_prpl_xfer(struct nvme_namespace *ns, grub_uint64_t lba, void *buf, grub_uint16_t count,
-+ int write)
-+{
-+ grub_uint32_t base = (long)buf;
-+ grub_int32_t size;
-+
-+ if (count > ns->max_req_size)
-+ count = ns->max_req_size;
-+
-+ size = count * ns->block_size;
-+ /* Special case for transfers that fit into PRP1, but are unaligned */
-+ if (((size + (base & ~NVME_PAGE_MASK)) <= NVME_PAGE_SIZE))
-+ goto single;
-+
-+ /* Every request has to be page aligned */
-+ if (base & ~NVME_PAGE_MASK)
-+ goto bounce;
-+
-+ /* Make sure a full block fits into the last chunk */
-+ if (size & (ns->block_size - 1ULL))
-+ goto bounce;
-+
-+ /* Build PRP list if we need to describe more than 2 pages */
-+ if ((ns->block_size * count) > (NVME_PAGE_SIZE * 2)) {
-+ grub_uint32_t prpl_len = 0;
-+ grub_uint64_t *prpl = nvme_dma_buffer;
-+ int first_page = 1;
-+ for (; size > 0; base += NVME_PAGE_SIZE, size -= NVME_PAGE_SIZE) {
-+ if (first_page) {
-+ /* First page is special */
-+ first_page = 0;
-+ continue;
-+ }
-+ if (prpl_len >= NVME_MAX_PRPL_ENTRIES)
-+ goto bounce;
-+ prpl[prpl_len++] = base;
-+ }
-+ return nvme_io_xfer(ns, lba, buf, prpl, count, write);
-+ }
-+
-+ /* Directly embed the 2nd page if we only need 2 pages */
-+ if ((ns->block_size * count) > NVME_PAGE_SIZE)
-+ return nvme_io_xfer(ns, lba, buf, (char *) buf + NVME_PAGE_SIZE, count, write);
-+
-+single:
-+ /* One page is enough, don't expose anything else */
-+ return nvme_io_xfer(ns, lba, buf, NULL, count, write);
-+
-+bounce:
-+ /* Use bounce buffer to make transfer */
-+ return nvme_bounce_xfer(ns, lba, buf, count, write);
-+}
-+
-+static int
-+nvme_create_io_queues(struct nvme_ctrl *ctrl)
-+{
-+ if (nvme_create_io_cq(ctrl, &ctrl->io_cq, 3))
-+ goto err;
-+
-+ if (nvme_create_io_sq(ctrl, &ctrl->io_sq, 2, &ctrl->io_cq))
-+ goto err_free_cq;
-+
-+ return 0;
-+
-+ err_free_cq:
-+ nvme_destroy_cq(&ctrl->io_cq);
-+ err:
-+ return -1;
-+}
-+
-+/* Waits for CSTS.RDY to match rdy. Returns 0 on success. */
-+static int
-+nvme_wait_csts_rdy(struct nvme_ctrl *ctrl, unsigned rdy)
-+{
-+ // grub_uint32_t const max_to = 500 /* ms */ * ((ctrl->reg->cap >> 24) & 0xFFU);
-+ // grub_uint32_t to = timer_calc(max_to);
-+ grub_uint32_t csts;
-+
-+ while (rdy != ((csts = ctrl->reg->csts) & NVME_CSTS_RDY)) {
-+ // FIXME
-+ //yield();
-+
-+ if (csts & NVME_CSTS_FATAL) {
-+ grub_dprintf("nvme", "NVMe fatal error during controller shutdown\n");
-+ return -1;
-+ }
-+
-+ /*
-+ if (timer_check(to)) {
-+ warn_timeout();
-+ return -1;
-+ }*/
-+ }
-+
-+ return 0;
-+}
-+
-+/* Returns 0 on success. */
-+static int grub_nvme_controller_enable(struct nvme_ctrl *ctrl)
-+{
-+ grub_pci_address_t addr;
-+ int rc;
-+
-+ addr = grub_pci_make_address (ctrl->pci, GRUB_PCI_REG_COMMAND);
-+ grub_pci_write_word (addr, grub_pci_read_word (addr) | GRUB_PCI_COMMAND_BUS_MASTER);
-+
-+ /* Turn the controller off. */
-+ ctrl->reg->cc = 0;
-+ if (nvme_wait_csts_rdy(ctrl, 0)) {
-+ grub_dprintf("nvme", "NVMe fatal error during controller shutdown\n");
-+ return -1;
-+ }
-+
-+ ctrl->doorbell_stride = 4U << ((ctrl->reg->cap >> 32) & 0xF);
-+
-+ rc = nvme_init_cq(ctrl, &ctrl->admin_cq, 1,
-+ NVME_PAGE_SIZE / sizeof(struct nvme_cqe));
-+ if (rc) {
-+ return -1;
-+ }
-+
-+ rc = nvme_init_sq(ctrl, &ctrl->admin_sq, 0,
-+ NVME_PAGE_SIZE / sizeof(struct nvme_sqe), &ctrl->admin_cq);
-+ if (rc) {
-+ goto err_destroy_admin_cq;
-+ }
-+
-+ ctrl->reg->aqa = ctrl->admin_cq.common.mask << 16
-+ | ctrl->admin_sq.common.mask;
-+
-+ ctrl->reg->asq = (grub_uint32_t)ctrl->admin_sq.sqe;
-+ ctrl->reg->acq = (grub_uint32_t)ctrl->admin_cq.cqe;
-+
-+ grub_dprintf("nvme", " admin submission queue: %p\n", ctrl->admin_sq.sqe);
-+ grub_dprintf("nvme", " admin completion queue: %p\n", ctrl->admin_cq.cqe);
-+
-+ ctrl->reg->cc = NVME_CC_EN | (NVME_CQE_SIZE_LOG << 20)
-+ | (NVME_SQE_SIZE_LOG << 16 /* IOSQES */);
-+
-+ if (nvme_wait_csts_rdy(ctrl, 1)) {
-+ grub_dprintf("nvme", "NVMe fatal error while enabling controller\n");
-+ goto err_destroy_admin_sq;
-+ }
-+
-+ /* The admin queue is set up and the controller is ready. Let's figure out
-+ what namespaces we have. */
-+
-+ struct nvme_identify_ctrl *identify = nvme_admin_identify_ctrl(ctrl);
-+
-+ if (!identify) {
-+ grub_dprintf("nvme", "NVMe couldn't identify controller.\n");
-+ goto err_destroy_admin_sq;
-+ }
-+
-+ grub_dprintf("nvme", "NVMe has %u namespace%s.\n",
-+ identify->nn, (identify->nn == 1) ? "" : "s");
-+
-+ ctrl->ns_count = identify->nn;
-+ grub_uint8_t mdts = identify->mdts;
-+ grub_free(identify);
-+
-+ if ((ctrl->ns_count == 0) || nvme_create_io_queues(ctrl)) {
-+ /* No point to continue, if the controller says it doesn't have
-+ namespaces or we couldn't create I/O queues. */
-+ goto err_destroy_admin_sq;
-+ }
-+
-+ /* Give the controller a global number */
-+ ctrl->ctrlnum = grub_nvme_ctrlcnt++;
-+
-+ /* Populate namespace IDs */
-+ for (grub_uint32_t ns_idx = 0; ns_idx < ctrl->ns_count; ns_idx++) {
-+ nvme_probe_ns(ctrl, ns_idx, mdts);
-+ }
-+
-+ grub_dprintf("nvme", "NVMe initialization complete!\n");
-+ return 0;
-+
-+ err_destroy_admin_sq:
-+ nvme_destroy_sq(&ctrl->admin_sq);
-+ err_destroy_admin_cq:
-+ nvme_destroy_cq(&ctrl->admin_cq);
-+ return -1;
-+}
-+
-+static int grub_nvme_pci_probe(grub_pci_device_t dev, grub_pci_id_t pciid __attribute__ ((unused)), void *data __attribute__ ((unused)))
-+{
-+ grub_pci_address_t addr;
-+ grub_uint32_t class, bar, version;
-+ struct nvme_reg volatile *reg;
-+
-+ class = grub_pci_read (grub_pci_make_address (dev, GRUB_PCI_REG_CLASS));
-+ if (class >> 16 != 0x0108)
-+ return 0;
-+ if ((class >> 8 & 0xff) != 2) { /* as of NVM 1.0e */
-+ grub_dprintf("nvme", "Found incompatble NVMe: prog-if=%02x\n", class >> 8 & 0xff);
-+ return 0;
-+ }
-+
-+ bar = grub_pci_read (grub_pci_make_address (dev, GRUB_PCI_REG_ADDRESS_REG0));
-+ reg = grub_pci_device_map_range (dev, bar & GRUB_PCI_ADDR_MEM_MASK, sizeof (*reg));
-+
-+ addr = grub_pci_make_address (dev, GRUB_PCI_REG_COMMAND);
-+ grub_pci_write_word (addr, grub_pci_read_word (addr) | GRUB_PCI_COMMAND_MEM_ENABLED);
-+
-+ version = reg->vs;
-+ grub_dprintf("nvme", "Found NVMe controller with version %u.%u.%u.\n", version >> 16, (version >> 8) & 0xFF, version & 0xFF);
-+ grub_dprintf("nvme", " Capabilities %016llx\n", reg->cap);
-+
-+ if (~reg->cap & NVME_CAP_CSS_NVME) {
-+ grub_dprintf("nvme", "Controller doesn't speak NVMe command set. Skipping.\n");
-+ goto err;
-+ }
-+
-+ struct nvme_ctrl *ctrl = grub_malloc(sizeof(*ctrl));
-+ if (!ctrl)
-+ goto err;
-+
-+ grub_memset(ctrl, 0, sizeof(*ctrl));
-+
-+ ctrl->reg = reg;
-+ ctrl->pci = dev;
-+
-+ if (grub_nvme_controller_enable(ctrl))
-+ goto err_free_ctrl;
-+
-+ return 0;
-+
-+ err_free_ctrl:
-+ grub_free(ctrl);
-+ err:
-+ grub_dprintf("nvme", "Failed to enable NVMe controller.\n");
-+ return 0;
-+}
-+
-+static int
-+grub_nvme_iterate (grub_disk_dev_iterate_hook_t hook, void *hook_data, grub_disk_pull_t pull)
-+{
-+ struct nvme_namespace *ns;
-+
-+ if (pull != GRUB_DISK_PULL_NONE)
-+ return 0;
-+
-+ FOR_LIST_ELEMENTS(ns, grub_nvme_namespaces)
-+ if (hook (ns->devname, hook_data))
-+ return 1;
-+
-+ return 0;
-+}
-+
-+static grub_err_t
-+grub_nvme_open (const char *name __attribute ((unused)), grub_disk_t disk __attribute ((unused)))
-+{
-+ struct nvme_namespace *ns;
-+
-+ FOR_LIST_ELEMENTS(ns, grub_nvme_namespaces)
-+ if (grub_strcmp (ns->devname, name) == 0)
-+ break;
-+
-+ if (! ns)
-+ return grub_error (GRUB_ERR_UNKNOWN_DEVICE, "can't open device");
-+
-+ disk->total_sectors = ns->lba_count;
-+ disk->max_agglomerate = ns->max_req_size;
-+
-+ disk->id = ns->nsnum; /* global id of the namespace */
-+
-+ disk->data = ns;
-+
-+ return 0;
-+}
-+
-+static grub_err_t
-+nvme_readwrite(struct nvme_namespace *ns, grub_disk_addr_t sector, grub_size_t num_sectors, char *buf, int write)
-+{
-+ for (int i = 0; i < num_sectors;) {
-+ grub_uint16_t blocks_remaining = num_sectors - i;
-+ char *op_buf = buf + i * ns->block_size;
-+ int blocks = nvme_prpl_xfer(ns, sector + i, op_buf, blocks_remaining, write);
-+ if (blocks < 0)
-+ return GRUB_ERR_IO;
-+ i += blocks;
-+ }
-+ return GRUB_ERR_NONE;
-+}
-+
-+static grub_err_t
-+grub_nvme_read (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t num_sectors, char *buf)
-+{
-+ return nvme_readwrite((struct nvme_namespace *) disk->data, sector, num_sectors, buf, 0);
-+}
-+
-+static grub_err_t
-+grub_nvme_write (grub_disk_t disk, grub_disk_addr_t sector, grub_size_t num_sectors, const char *buf)
-+{
-+ return nvme_readwrite((struct nvme_namespace *) disk->data, sector, num_sectors, buf, 1);
-+}
-+
-+static struct grub_disk_dev grub_nvme_dev =
-+ {
-+ .name = "nvme",
-+ .id = GRUB_DISK_DEVICE_NVME_ID,
-+ .disk_iterate = grub_nvme_iterate,
-+ .disk_open = grub_nvme_open,
-+ .disk_read = grub_nvme_read,
-+ .disk_write = grub_nvme_write,
-+ .next = 0
-+ };
-+
-+GRUB_MOD_INIT(nvme)
-+{
-+ grub_stop_disk_firmware ();
-+ grub_pci_iterate (grub_nvme_pci_probe, NULL);
-+ grub_disk_dev_register (&grub_nvme_dev);
-+}
-+
-+GRUB_MOD_FINI(nvme)
-+{
-+ grub_disk_dev_unregister (&grub_nvme_dev);
-+}
-diff --git a/include/grub/disk.h b/include/grub/disk.h
-index fbf23df7f..186e76f0b 100644
---- a/include/grub/disk.h
-+++ b/include/grub/disk.h
-@@ -52,6 +52,7 @@ enum grub_disk_dev_id
- GRUB_DISK_DEVICE_UBOOTDISK_ID,
- GRUB_DISK_DEVICE_XEN,
- GRUB_DISK_DEVICE_OBDISK_ID,
-+ GRUB_DISK_DEVICE_NVME_ID
- };
-
- struct grub_disk;
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0020-kern-coreboot-mmap-Map-to-reserved.patch b/config/grub/xhci_nvme/patches/0020-kern-coreboot-mmap-Map-to-reserved.patch
deleted file mode 100644
index ffa01e7a..00000000
--- a/config/grub/xhci_nvme/patches/0020-kern-coreboot-mmap-Map-to-reserved.patch
+++ /dev/null
@@ -1,37 +0,0 @@
-From 331af0cc985aa5ec57964c6e3ab69f65c23f6481 Mon Sep 17 00:00:00 2001
-From: Paul Menzel <pmenzel@molgen.mpg.de>
-Date: Mon, 17 May 2021 10:24:36 +0200
-Subject: [PATCH 20/21] kern/coreboot/mmap: Map to reserved
-
-https://git.savannah.gnu.org/cgit/grub.git/commit/?id=6de9ee86bf9ae50967413e6a73b5dfd13e5ffb50
-
-Signed-off-by: Paul Menzel <pmenzel@molgen.mpg.de>
----
- grub-core/kern/coreboot/mmap.c | 4 ++--
- 1 file changed, 2 insertions(+), 2 deletions(-)
-
-diff --git a/grub-core/kern/coreboot/mmap.c b/grub-core/kern/coreboot/mmap.c
-index caf8f7cef..2fc316e8d 100644
---- a/grub-core/kern/coreboot/mmap.c
-+++ b/grub-core/kern/coreboot/mmap.c
-@@ -59,7 +59,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
- /* Multiboot mmaps match with the coreboot mmap
- definition. Therefore, we can just pass type
- through. */
-- mem_region->type,
-+ (mem_region->type >= 13) ? 2 : mem_region->type,
- ctx->hook_data))
- return 1;
- if (start < 0xa0000)
-@@ -81,7 +81,7 @@ iterate_linuxbios_table (grub_linuxbios_table_item_t table_item, void *data)
- /* Multiboot mmaps match with the coreboot mmap
- definition. Therefore, we can just pass type
- through. */
-- mem_region->type,
-+ (mem_region->type >= 13) ? 2 : mem_region->type,
- ctx->hook_data))
- return 1;
- }
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0021-Revert-configure-Check-linker-for-image-base-support.patch b/config/grub/xhci_nvme/patches/0021-Revert-configure-Check-linker-for-image-base-support.patch
deleted file mode 100644
index 0e563fd5..00000000
--- a/config/grub/xhci_nvme/patches/0021-Revert-configure-Check-linker-for-image-base-support.patch
+++ /dev/null
@@ -1,70 +0,0 @@
-From cf791012987ea90f7a88edd21a0f619fbc40986d Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Wed, 24 Dec 2025 01:42:17 +0100
-Subject: [PATCH 21/21] Revert "configure: Check linker for --image-base
- support"
-
-This reverts commit 1a5417f39a0ccefcdd5440f2a67f84d2d2e26960.
----
- acinclude.m4 | 5 -----
- configure.ac | 14 ++------------
- 2 files changed, 2 insertions(+), 17 deletions(-)
-
-diff --git a/acinclude.m4 b/acinclude.m4
-index 70c1912f8..fa7840f09 100644
---- a/acinclude.m4
-+++ b/acinclude.m4
-@@ -79,11 +79,6 @@ AC_DEFUN([grub_PROG_OBJCOPY_ABSOLUTE],
- [AC_MSG_CHECKING([whether ${TARGET_OBJCOPY} works for absolute addresses])
- AC_CACHE_VAL(grub_cv_prog_objcopy_absolute,
- [cat > conftest.c <<\EOF
--asm (
-- ".globl start, _start, __start\n"
-- ".ifdef cmain; .set start = _start = __start = cmain\n.endif\n"
-- ".ifdef _cmain; .set start = _start = __start = _cmain\n.endif\n"
--);
- void cmain (void);
- void
- cmain (void)
-diff --git a/configure.ac b/configure.ac
-index d8ca1b7c1..041cfbab4 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1461,6 +1461,7 @@ elif test x$grub_cv_target_cc_link_format = x-mi386pe || test x$grub_cv_target_c
- TARGET_IMG_LDSCRIPT='$(top_srcdir)'"/conf/i386-cygwin-img-ld.sc"
- TARGET_IMG_LDFLAGS="-Wl,-T${TARGET_IMG_LDSCRIPT}"
- TARGET_IMG_LDFLAGS_AC="-Wl,-T${srcdir}/conf/i386-cygwin-img-ld.sc"
-+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
- TARGET_IMG_CFLAGS=
- else
- TARGET_APPLE_LINKER=0
-@@ -1468,6 +1469,7 @@ else
- TARGET_IMG_LDSCRIPT=
- TARGET_IMG_LDFLAGS='-Wl,-N'
- TARGET_IMG_LDFLAGS_AC='-Wl,-N'
-+ TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"
- TARGET_IMG_CFLAGS=
- fi
-
-@@ -1798,18 +1800,6 @@ grub_PROG_TARGET_CC
- m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
-
- if test "x$TARGET_APPLE_LINKER" != x1 ; then
--AX_CHECK_LINK_FLAG([-Wl,--image-base,0x400000],
-- [TARGET_IMG_BASE_LDOPT="-Wl,--image-base"],
-- [TARGET_IMG_BASE_LDOPT="-Wl,-Ttext"],
-- [],
-- [AC_LANG_SOURCE([
--asm (".globl start; start:");
--asm (".globl _start; _start:");
--asm (".globl __start; __start:");
--void __main (void);
--void __main (void) {}
--int main (void);
-- ])])
- grub_PROG_OBJCOPY_ABSOLUTE
- fi
- grub_PROG_LD_BUILD_ID_NONE
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0022-Revert-configure-Print-a-more-helpful-error-if-autoc.patch b/config/grub/xhci_nvme/patches/0022-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
deleted file mode 100644
index c0a504ff..00000000
--- a/config/grub/xhci_nvme/patches/0022-Revert-configure-Print-a-more-helpful-error-if-autoc.patch
+++ /dev/null
@@ -1,30 +0,0 @@
-From abf2bf6e2973ccaa994f63ff851ba11cbd45f1eb Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Mon, 19 Jan 2026 15:27:23 +0000
-Subject: [PATCH 1/1] Revert "configure: Print a more helpful error if
- autoconf-archive is not installed"
-
-This reverts commit ac042f3f58d33ce9cd5ff61750f06da1a1d7b0eb.
----
- configure.ac | 5 -----
- 1 file changed, 5 deletions(-)
-
-diff --git a/configure.ac b/configure.ac
-index 041cfbab4..209c0fb11 100644
---- a/configure.ac
-+++ b/configure.ac
-@@ -1794,11 +1794,6 @@ LIBS=""
- # Defined in acinclude.m4.
- grub_ASM_USCORE
- grub_PROG_TARGET_CC
--
--# The error message produced by autoconf if autoconf-archive is not installed is
--# quite misleading and not very helpful. So, try point people in the right direction.
--m4_ifndef([AX_CHECK_LINK_FLAG], [m4_fatal([autoconf-archive is missing. You must install it to generate the configure script.])])
--
- if test "x$TARGET_APPLE_LINKER" != x1 ; then
- grub_PROG_OBJCOPY_ABSOLUTE
- fi
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/patches/0023-bootstrap-Don-t-download-po-files.patch b/config/grub/xhci_nvme/patches/0023-bootstrap-Don-t-download-po-files.patch
deleted file mode 100644
index cfb66047..00000000
--- a/config/grub/xhci_nvme/patches/0023-bootstrap-Don-t-download-po-files.patch
+++ /dev/null
@@ -1,91 +0,0 @@
-From 5d18c96a22d98d137ea40bfc6aabadce933c2d45 Mon Sep 17 00:00:00 2001
-From: Leah Rowe <leah@libreboot.org>
-Date: Sun, 1 Feb 2026 20:30:55 +0100
-Subject: [PATCH 1/1] bootstrap: Don't download po files
-
-GRUB doesn't verify checksums at all, and it pulls from
-this URL recursively:
-
-https://translationproject.org/latest/grub/
-
-These files can change at any time, and GRUB is just
-downloading them trustingly. Even if the upstream is
-totally benevolent, what if they got hacked?
-
-I downloaded them, hashed them and decided to mirror
-them on my RSYNC mirror. In this way, Libreboot can now
-use them in a deterministic fashion.
-
-Simply adding them to the GRUB source code would mean
-patching GRUB, which would add 8MB to lbmk. I won't do
-it.
-
-Signed-off-by: Leah Rowe <leah@libreboot.org>
----
- bootstrap | 31 +++++++++++++------------------
- 1 file changed, 13 insertions(+), 18 deletions(-)
-
-diff --git a/bootstrap b/bootstrap
-index dc9fb4383..9fc5a5c36 100755
---- a/bootstrap
-+++ b/bootstrap
-@@ -1,5 +1,16 @@
- #! /bin/sh
--# DO NOT EDIT! GENERATED AUTOMATICALLY!
-+# THIS FILE WAS EDITED BY LIBREBOOT TO REMOVE
-+# HACKY GRUB BEHAVIOUR; po files now downloaded
-+# by lbmk, via config/submodule/grub/ - so that
-+# versioned files are possible, with proper checksum
-+# verification, and mirrors are used.
-+
-+# Yes. This file has been modified. I intend to
-+# eventually remove this hacky script. Probably
-+# replace the entire GRUB build system.
-+
-+# Please do fix/edit or (when possible) remove
-+# this file. Thank you.
-
- # Bootstrap this package from checked-out sources.
-
-@@ -145,13 +156,6 @@ bootstrap_post_import_hook() { :; }
- # Override it via your own definition in bootstrap.conf.
- bootstrap_epilogue() { :; }
-
--# The command to download all .po files for a specified domain into a
--# specified directory. Fill in the first %s with the destination
--# directory and the second with the domain name.
--po_download_command_format=\
--"wget --mirror --level=1 -nd -nv -A.po -P '%s' \
-- https://translationproject.org/latest/%s/"
--
- # When extracting the package name from an AC_INIT invocation,
- # prefer a non-empty tarname (4th argument of AC_INIT if given), else
- # fall back to the package name (1st argument with munging).
-@@ -909,14 +913,6 @@ autopull()
-
- # ----------------------------- Get translations. -----------------------------
-
--download_po_files() {
-- subdir=$1
-- domain=$2
-- echo "$me: getting translations into $subdir for $domain..."
-- cmd=$(printf "$po_download_command_format" "$subdir" "$domain")
-- eval "$cmd"
--}
--
- # Mirror .po files to $po_dir/.reference and copy only the new
- # or modified ones into $po_dir. Also update $po_dir/LINGUAS.
- # Note po files that exist locally only are left in $po_dir but will
-@@ -932,8 +928,7 @@ update_po_files() {
- ref_po_dir="$po_dir/.reference"
-
- test -d $ref_po_dir || mkdir $ref_po_dir || return
-- download_po_files $ref_po_dir $domain \
-- && ls "$ref_po_dir"/*.po 2>/dev/null |
-+ ls "$ref_po_dir"/*.po 2>/dev/null |
- sed 's|.*/||; s|\.po$||' > "$po_dir/LINGUAS" || return
-
- for po in x $(ls $ref_po_dir | sed -n 's/\.po$//p'); do
---
-2.47.3
-
diff --git a/config/grub/xhci_nvme/target.cfg b/config/grub/xhci_nvme/target.cfg
deleted file mode 100644
index 15e3e00e..00000000
--- a/config/grub/xhci_nvme/target.cfg
+++ /dev/null
@@ -1,4 +0,0 @@
-# SPDX-License-Identifier: GPL-3.0-or-later
-
-tree="xhci_nvme"
-rev="eaa3b8f0f90605a82c6bfda4c5c4b73c58eb81ac"