From 3f8d71e17485e19c0cd9148edfe39ce8bf921569 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 20 Apr 2025 05:42:50 +0100 Subject: Update the GRUB revisions A number of regressions were caused by the recent CVE fixes, many of which have since been fixed upstream. This includes several ext4 file system bugs, which caused some systems not to boot properly, when dealing with very large initramfs files. No additional patching has been made. This will be tested, and then used to provide a revision update for Libreboot 20241206. After this, there are several additional OOT patches that will be merged, for the next *testing release* of Libreboot. Update to this revision, for all GRUB trees: a4da71dafeea519b034beb159dfe80c486c2107c This brings in the following changes from upstream: * a4da71daf util/grub-install: Include raid5rec module for RAID 4 as well * 223fcf808 loader/ia64/efi/linux: Reset grub_errno on failure to allocate * 6504a8d4b lib/datetime: Specify license in emu module * 8fef533cf configure: Add -mno-relax on riscv* * 1fe094855 docs: Document the long options of tpm2_key_protect_init * 6252eb97c INSTALL: Document the packages needed for TPM2 key protector tests * 9d4b382aa docs: Update NV index mode of TPM2 key protector * 2043b6899 tests/tpm2_key_protector_test: Add more NV index mode tests * 9f66a4719 tests/tpm2_key_protector_test: Reset "ret" on fail * b7d89e667 tests/tpm2_key_protector_test: Simplify the NV index mode test * 5934bf51c util/grub-protect: Support NV index mode * cd9cb944d tpm2_key_protector: Support NV index handles * fa69deac5 tpm2_key_protector: Unseal key from a buffer * 75c480885 tss2: Add TPM 2.0 NV index commands * 041164d00 tss2: Fix the missing authCommand * 46c9f3a8d tpm2_key_protector: Add tpm2_dump_pcr command * 617dab9e4 tpm2_key_protector: Dump PCRs on policy fail * 204a6ddfb loader/i386/linux: Update linux_kernel_params to match upstream * 6b64f297e loader/xnu: Fix memory leak * f94d257e8 fs/btrfs: Fix memory leaks * 81146fb62 loader/i386/linux: Fix resource leak * 1d0059447 lib/reloacator: Fix memory leaks * f3f1fcecd disk/ldm: Fix memory leaks * aae2ea619 fs/ntfs: Fix NULL pointer dereference and possible infinite loop * 3b25e494d net/drivers/ieee1275/ofnet: Add missing grub_malloc() * fee6081ec kern/ieee1275/init: Increase MIN_RMA size for CAS negotiation on PowerPC machines * b66c6f918 fs/zfs: Fix a number of memory leaks in ZFS code * 1d59f39b5 tests/util/grub-shell: Remove the work directory on successful run and debug is not on * e0116f3bd tests/grub_cmd_cryptomount: Remove temporary directories if successful and debug is not on * e6e2b73db tests/grub_cmd_cryptomount: Default TMPDIR to /tmp * 32b02bb92 tests/grub_cmd_cryptomount: Cleanup the cryptsetup script unless debug is enabled * c188ca5d5 tests: Cleanup generated files on expected failure in grub_cmd_cryptomount * 50320c093 tests/util/grub-shell-luks-tester: Add missing line to create RET variable in cleanup * bb6d3199b tests/util/grub-shell-luks-tester: Find cryptodisk by UUID * 3fd163e45 tests/util/grub-shell: Default qemuopts to envvar $GRUB_QEMU_OPTS * ff7f55307 disk/lvm: Add informational messages in error cases of ignored features * a16b4304a disk/lvm: Add support for cachevol LV * 9a37d6114 disk/lvm: Add support for integrity LV * 6c14b87d6 lvm: Match all LVM segments before validation * d34b9120e disk/lvm: Remove unused cache_pool * 90848a1f7 disk/lvm: Make cache_lv more generic as ignored_feature_lv * 488ac8bda commands/ls: Add directory header for dir args * 096bf59e4 commands/ls: Print full paths for file args * 90288fc48 commands/ls: Output path for single file arguments given with path * 6337d84af commands/ls: Show modification time for file paths * cbfb031b1 commands/ls: Merge print_files_long() and print_files() into print_file() * 112d2069c commands/ls: Return proper GRUB_ERR_* for functions returning type grub_err_t * da9740cd5 commands/acpi: Use options enum to index command options * 1acf11fe4 docs: Capture additional commands restricted by lockdown * 6a168afd3 docs: Document restricted filesystems in lockdown * be0ae9583 loader/i386/bsd: Fix type passed for the kernel * ee27f07a6 kern/partition: Unbreak support for nested partitions * cb639acea lib/tss2/tss2_structs.h: Fix clang build - remove duplicate typedef * 696e35b7f include/grub/mm.h: Remove duplicate inclusion of grub/err.h * 187338f1a script/execute: Don't let trailing blank lines determine the return code * ff173a1c0 gitignore: Ignore generated files from libtasn * fbcc38891 util/grub.d/30_os-prober.in: Conditionally show or hide chain and efi menu entries * 56ccc5ed5 util/grub.d/30_os-prober.in: Fix GRUB_OS_PROBER_SKIP_LIST for non-EFI * 01f064064 docs: Do not reference non-existent --dumb option * 3f440b5a5 docs: Replace @lbracechar{} and @rbracechar{} with @{ and @} * f20988738 fs/xfs: Fix grub_xfs_iterate_dir() return value in case of failure * 1ed2628b5 fs/xfs: Add new superblock features added in Linux 6.12/6.13 * 348cd416a fs/ext2: Rework out-of-bounds read for inline and external extents * c730eddd2 disk/ahci: Remove conditional operator for endtime * f0a08324d term/ns8250-spcr: Return if redirection is disabled * 7161e2437 commands/file: Fix NULL dereference in the knetbsd tests * 11b9c2dd0 gdb_helper: Typo hueristic * 224aefd05 kern/efi/mm: Reset grub_mm_add_region_fn after ExitBootServices() call * 531750f7b i386/tsc: The GRUB menu gets stuck due to unserialized rdtsc * f2a1f66e7 kern/i386/tsc_pmtimer: The GRUB menu gets stuck due to failed calibration * 13f005ed8 loader/i386/linux: Fix cleanup if kernel doesn't support 64-bit addressing Signed-off-by: Leah Rowe --- ...ub-s-missing-characters-for-borders-arrow.patch | 2 +- ...2-say-the-name-libreboot-in-the-grub-menu.patch | 2 +- .../default/patches/0003-Add-CC0-license.patch | 2 +- .../patches/0004-Define-GRUB_UINT32_MAX.patch | 2 +- .../patches/0005-Add-Argon2-algorithm.patch | 4 +- ...0006-Error-on-missing-Argon2id-parameters.patch | 2 +- .../0007-Compile-with-Argon2id-support.patch | 2 +- .../0008-Make-grub-install-work-with-Argon2.patch | 4 +- ...board-coreboot-force-scancodes2-translate.patch | 2 +- ...eylayouts-don-t-print-Unknown-key-message.patch | 2 +- ...print-missing-prefix-errors-on-the-screen.patch | 2 +- ...012-don-t-print-error-if-module-not-found.patch | 2 +- .../0013-don-t-print-empty-error-messages.patch | 2 +- config/grub/default/target.cfg | 2 +- ...ub-s-missing-characters-for-borders-arrow.patch | 2 +- ...2-say-the-name-libreboot-in-the-grub-menu.patch | 2 +- .../grub/nvme/patches/0003-Add-CC0-license.patch | 2 +- .../nvme/patches/0004-Define-GRUB_UINT32_MAX.patch | 2 +- .../nvme/patches/0005-Add-Argon2-algorithm.patch | 4 +- ...0006-Error-on-missing-Argon2id-parameters.patch | 2 +- .../0007-Compile-with-Argon2id-support.patch | 2 +- .../0008-Make-grub-install-work-with-Argon2.patch | 4 +- ...board-coreboot-force-scancodes2-translate.patch | 2 +- ...eylayouts-don-t-print-Unknown-key-message.patch | 2 +- ...print-missing-prefix-errors-on-the-screen.patch | 2 +- ...012-don-t-print-error-if-module-not-found.patch | 2 +- .../0013-don-t-print-empty-error-messages.patch | 2 +- ...4-Add-native-NVMe-driver-based-on-SeaBIOS.patch | 2 +- config/grub/nvme/target.cfg | 2 +- ...ub-s-missing-characters-for-borders-arrow.patch | 4 +- ...2-say-the-name-libreboot-in-the-grub-menu.patch | 4 +- .../grub/xhci/patches/0003-Add-CC0-license.patch | 4 +- .../xhci/patches/0004-Define-GRUB_UINT32_MAX.patch | 4 +- .../xhci/patches/0005-Add-Argon2-algorithm.patch | 6 +- ...0006-Error-on-missing-Argon2id-parameters.patch | 4 +- .../0007-Compile-with-Argon2id-support.patch | 4 +- .../0008-Make-grub-install-work-with-Argon2.patch | 6 +- ...board-coreboot-force-scancodes2-translate.patch | 4 +- ...eylayouts-don-t-print-Unknown-key-message.patch | 4 +- ...print-missing-prefix-errors-on-the-screen.patch | 4 +- ...012-don-t-print-error-if-module-not-found.patch | 4 +- .../0013-don-t-print-empty-error-messages.patch | 4 +- ...us-usb-Parse-SuperSpeed-companion-descrip.patch | 4 +- .../xhci/patches/0015-usb-Add-enum-for-xHCI.patch | 4 +- ...-usbtrans-Set-default-maximum-packet-size.patch | 4 +- ...us-usb-Add-function-pointer-for-attach-de.patch | 4 +- ...us-usb-usbhub-Add-new-private-fields-for-.patch | 4 +- .../0019-grub-core-bus-usb-Add-xhci-support.patch | 4 +- ...us-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch | 4 +- .../0021-xHCI-also-accept-SBRN-0x31-and-0x32.patch | 4 +- .../xhci/patches/0022-xhci-fix-port-indexing.patch | 4 +- .../0023-xhci-configure-TT-for-non-root-hubs.patch | 98 ++ .../patches/0024-Fix-compilation-on-x86_64.patch | 90 ++ .../0024-xhci-configure-TT-for-non-root-hubs.patch | 98 -- ...5-Add-native-NVMe-driver-based-on-SeaBIOS.patch | 1074 ++++++++++++++++++++ .../patches/0025-Fix-compilation-on-x86_64.patch | 90 -- ...6-Add-native-NVMe-driver-based-on-SeaBIOS.patch | 1074 -------------------- config/grub/xhci/target.cfg | 2 +- 58 files changed, 1342 insertions(+), 1342 deletions(-) create mode 100644 config/grub/xhci/patches/0023-xhci-configure-TT-for-non-root-hubs.patch create mode 100644 config/grub/xhci/patches/0024-Fix-compilation-on-x86_64.patch delete mode 100644 config/grub/xhci/patches/0024-xhci-configure-TT-for-non-root-hubs.patch create mode 100644 config/grub/xhci/patches/0025-Add-native-NVMe-driver-based-on-SeaBIOS.patch delete mode 100644 config/grub/xhci/patches/0025-Fix-compilation-on-x86_64.patch delete mode 100644 config/grub/xhci/patches/0026-Add-native-NVMe-driver-based-on-SeaBIOS.patch 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 index 391beaf1..ffd2c537 100644 --- 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 @@ -1,4 +1,4 @@ -From 016f8655f5bed2b65c19e0e127b72ba3cfbcfb7d Mon Sep 17 00:00:00 2001 +From 8ccafb60665bba3759248b13d2d1683818aaf4ee Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 31 Oct 2021 03:47:05 +0000 Subject: [PATCH 01/13] mitigate grub's missing characters for borders/arrow 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 index 64a3b644..01276007 100644 --- 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 @@ -1,4 +1,4 @@ -From d7f6f258ea14ec47d586eccbd0f5d96784e8bd15 Mon Sep 17 00:00:00 2001 +From 3fb09986e62a9945862456d5f1d63a6ccba2c861 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sat, 19 Nov 2022 16:30:24 +0000 Subject: [PATCH 02/13] say the name libreboot, in the grub menu diff --git a/config/grub/default/patches/0003-Add-CC0-license.patch b/config/grub/default/patches/0003-Add-CC0-license.patch index 09c55867..c074099a 100644 --- a/config/grub/default/patches/0003-Add-CC0-license.patch +++ b/config/grub/default/patches/0003-Add-CC0-license.patch @@ -1,4 +1,4 @@ -From 85a88ecf10e1dd5cef7244aedaf7db76e845045f Mon Sep 17 00:00:00 2001 +From dc790ff2ba2702ee863c9d16e05cf843a152f3d4 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 03/13] Add CC0 license diff --git a/config/grub/default/patches/0004-Define-GRUB_UINT32_MAX.patch b/config/grub/default/patches/0004-Define-GRUB_UINT32_MAX.patch index 8277df92..af617683 100644 --- a/config/grub/default/patches/0004-Define-GRUB_UINT32_MAX.patch +++ b/config/grub/default/patches/0004-Define-GRUB_UINT32_MAX.patch @@ -1,4 +1,4 @@ -From bb12d671182c455c894979a8a5890f5f4baa02dc Mon Sep 17 00:00:00 2001 +From 298eaaca770545e19dfacd47511c2081c1fece08 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 04/13] Define GRUB_UINT32_MAX diff --git a/config/grub/default/patches/0005-Add-Argon2-algorithm.patch b/config/grub/default/patches/0005-Add-Argon2-algorithm.patch index 452c0937..dacd83ee 100644 --- a/config/grub/default/patches/0005-Add-Argon2-algorithm.patch +++ b/config/grub/default/patches/0005-Add-Argon2-algorithm.patch @@ -1,4 +1,4 @@ -From 216e1351e5957e0589d488427a6dfee246705d0d Mon Sep 17 00:00:00 2001 +From 378aa081ac1211d0bf4043eeb0bb7d4aa534043f Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 05/13] Add Argon2 algorithm @@ -30,7 +30,7 @@ Signed-off-by: Nicholas Johnson create mode 100644 grub-core/lib/argon2/ref.c diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 3ad8e3efa..d7c6232af 100644 +index f4367f895..9d96cedf9 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -503,12 +503,76 @@ GRUB includes some code from other projects, and it is sometimes necessary diff --git a/config/grub/default/patches/0006-Error-on-missing-Argon2id-parameters.patch b/config/grub/default/patches/0006-Error-on-missing-Argon2id-parameters.patch index 33bc9417..f1ea10c2 100644 --- a/config/grub/default/patches/0006-Error-on-missing-Argon2id-parameters.patch +++ b/config/grub/default/patches/0006-Error-on-missing-Argon2id-parameters.patch @@ -1,4 +1,4 @@ -From a2687cc594714ff33a4c50d40222c113768ed826 Mon Sep 17 00:00:00 2001 +From febaf431d235f07b97f07f935611dc168b0b35bb Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 06/13] Error on missing Argon2id parameters diff --git a/config/grub/default/patches/0007-Compile-with-Argon2id-support.patch b/config/grub/default/patches/0007-Compile-with-Argon2id-support.patch index 7d22cc74..c0a8fffb 100644 --- a/config/grub/default/patches/0007-Compile-with-Argon2id-support.patch +++ b/config/grub/default/patches/0007-Compile-with-Argon2id-support.patch @@ -1,4 +1,4 @@ -From 2d1af8f5dfd1492ac95bcf7db4e6c789aa83018e Mon Sep 17 00:00:00 2001 +From 12d3e4dfff3f92daf2f3f73cc0797425f7bb9df6 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 07/13] Compile with Argon2id support diff --git a/config/grub/default/patches/0008-Make-grub-install-work-with-Argon2.patch b/config/grub/default/patches/0008-Make-grub-install-work-with-Argon2.patch index e73a7ccb..12e78752 100644 --- a/config/grub/default/patches/0008-Make-grub-install-work-with-Argon2.patch +++ b/config/grub/default/patches/0008-Make-grub-install-work-with-Argon2.patch @@ -1,4 +1,4 @@ -From 67900e39bd45018b5611862b9438081c618b916f Mon Sep 17 00:00:00 2001 +From 8e639e9558c98019566743cc5723e641b1726d15 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 08/13] Make grub-install work with Argon2 @@ -9,7 +9,7 @@ Signed-off-by: Nicholas Johnson 1 file changed, 2 insertions(+) diff --git a/util/grub-install.c b/util/grub-install.c -index 7dc5657bb..cf7315891 100644 +index 060246589..059036d3c 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -448,6 +448,8 @@ probe_mods (grub_disk_t disk) diff --git a/config/grub/default/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch b/config/grub/default/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch index d1973955..50195201 100644 --- a/config/grub/default/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch +++ b/config/grub/default/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch @@ -1,4 +1,4 @@ -From e8ae938700e715194e47d346c43aa4be23f1b4bf Mon Sep 17 00:00:00 2001 +From 8a098ee241040ccfdf03636f558ef6a3b431bb90 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Mon, 30 Oct 2023 22:19:21 +0000 Subject: [PATCH 09/13] at_keyboard coreboot: force scancodes2+translate diff --git a/config/grub/default/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch b/config/grub/default/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch index c9e41d8e..685e21c4 100644 --- a/config/grub/default/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch +++ b/config/grub/default/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch @@ -1,4 +1,4 @@ -From dfd1639bb999e3dbbd346cc97f4bbaf32d129cd6 Mon Sep 17 00:00:00 2001 +From d86b69fa2c0d73440e5b990d8ab4b66c5c23fa46 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Tue, 31 Oct 2023 10:33:28 +0000 Subject: [PATCH 10/13] keylayouts: don't print "Unknown key" message diff --git a/config/grub/default/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch b/config/grub/default/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch index 72c51f8b..f15d78e1 100644 --- a/config/grub/default/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch +++ b/config/grub/default/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch @@ -1,4 +1,4 @@ -From 8421c59fa62ce954dcba05ad04591c651d6dcf43 Mon Sep 17 00:00:00 2001 +From 3726c1e12b8896e4a77cc7a2b490e933dc2c08da Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 16:14:58 +0000 Subject: [PATCH 11/13] don't print missing prefix errors on the screen diff --git a/config/grub/default/patches/0012-don-t-print-error-if-module-not-found.patch b/config/grub/default/patches/0012-don-t-print-error-if-module-not-found.patch index dab4318c..713f1244 100644 --- a/config/grub/default/patches/0012-don-t-print-error-if-module-not-found.patch +++ b/config/grub/default/patches/0012-don-t-print-error-if-module-not-found.patch @@ -1,4 +1,4 @@ -From c377f3c025101da17252a43449cc58fdd44c44af Mon Sep 17 00:00:00 2001 +From c86a635609a4623baa9312f5c1bebfd51f5883a1 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 16:36:22 +0000 Subject: [PATCH 12/13] don't print error if module not found diff --git a/config/grub/default/patches/0013-don-t-print-empty-error-messages.patch b/config/grub/default/patches/0013-don-t-print-empty-error-messages.patch index c351a74a..d23ea109 100644 --- a/config/grub/default/patches/0013-don-t-print-empty-error-messages.patch +++ b/config/grub/default/patches/0013-don-t-print-empty-error-messages.patch @@ -1,4 +1,4 @@ -From 664ce75106049547d7595fc021a0a1f9a69e585a Mon Sep 17 00:00:00 2001 +From 715ba566042aa140cbeb06836c558460ef6f446f Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 17:25:20 +0000 Subject: [PATCH 13/13] don't print empty error messages diff --git a/config/grub/default/target.cfg b/config/grub/default/target.cfg index 8264d306..a9dab736 100644 --- a/config/grub/default/target.cfg +++ b/config/grub/default/target.cfg @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-3.0-or-later tree="default" -rev="4dc6166571645780c459dde2cdc1b001a5ec844c" +rev="a4da71dafeea519b034beb159dfe80c486c2107c" 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 index 1421d21b..dff2503c 100644 --- 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 @@ -1,4 +1,4 @@ -From 07cd05c1756cdb18cf5e55d72e4002e271e8af12 Mon Sep 17 00:00:00 2001 +From 5f8189d928309146675a56279458d8bb7534ec0c Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 31 Oct 2021 03:47:05 +0000 Subject: [PATCH 01/14] mitigate grub's missing characters for borders/arrow 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 index 3946cbc2..9231d18d 100644 --- 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 @@ -1,4 +1,4 @@ -From c1617d04ac24544d578643863c545bb885444030 Mon Sep 17 00:00:00 2001 +From fce8730b8c20b7de0394976861b3d2ebcc21f425 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sat, 19 Nov 2022 16:30:24 +0000 Subject: [PATCH 02/14] say the name libreboot, in the grub menu diff --git a/config/grub/nvme/patches/0003-Add-CC0-license.patch b/config/grub/nvme/patches/0003-Add-CC0-license.patch index e4704e6e..5a664f32 100644 --- a/config/grub/nvme/patches/0003-Add-CC0-license.patch +++ b/config/grub/nvme/patches/0003-Add-CC0-license.patch @@ -1,4 +1,4 @@ -From 4987b1725277f0e16895b7a67b8b2af9de3183ed Mon Sep 17 00:00:00 2001 +From 088901d1a7577b52d110803d3c6a0e198130e524 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 03/14] Add CC0 license diff --git a/config/grub/nvme/patches/0004-Define-GRUB_UINT32_MAX.patch b/config/grub/nvme/patches/0004-Define-GRUB_UINT32_MAX.patch index ff11241f..9e7b2b99 100644 --- a/config/grub/nvme/patches/0004-Define-GRUB_UINT32_MAX.patch +++ b/config/grub/nvme/patches/0004-Define-GRUB_UINT32_MAX.patch @@ -1,4 +1,4 @@ -From 6e3672bcba5075908f2a3b2ec235168bf2a4b1ed Mon Sep 17 00:00:00 2001 +From 1a3fdb4075f32eab6ebda0c813720f0336f1bde7 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 04/14] Define GRUB_UINT32_MAX diff --git a/config/grub/nvme/patches/0005-Add-Argon2-algorithm.patch b/config/grub/nvme/patches/0005-Add-Argon2-algorithm.patch index 1bdc0717..df088e63 100644 --- a/config/grub/nvme/patches/0005-Add-Argon2-algorithm.patch +++ b/config/grub/nvme/patches/0005-Add-Argon2-algorithm.patch @@ -1,4 +1,4 @@ -From ec94eb604358bd87236fc3cce9d14770c3595461 Mon Sep 17 00:00:00 2001 +From 490fb23a8bd4d669a3dc48f0581321f08f6f2020 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 05/14] Add Argon2 algorithm @@ -30,7 +30,7 @@ Signed-off-by: Nicholas Johnson create mode 100644 grub-core/lib/argon2/ref.c diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 3ad8e3efa..d7c6232af 100644 +index f4367f895..9d96cedf9 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -503,12 +503,76 @@ GRUB includes some code from other projects, and it is sometimes necessary diff --git a/config/grub/nvme/patches/0006-Error-on-missing-Argon2id-parameters.patch b/config/grub/nvme/patches/0006-Error-on-missing-Argon2id-parameters.patch index ffacb5fa..ef109bd3 100644 --- a/config/grub/nvme/patches/0006-Error-on-missing-Argon2id-parameters.patch +++ b/config/grub/nvme/patches/0006-Error-on-missing-Argon2id-parameters.patch @@ -1,4 +1,4 @@ -From e02e392863dd30f40c538770c31268a8337433c5 Mon Sep 17 00:00:00 2001 +From c8fac788716d0c8723149eee205f1f0bdc92efbe Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 06/14] Error on missing Argon2id parameters diff --git a/config/grub/nvme/patches/0007-Compile-with-Argon2id-support.patch b/config/grub/nvme/patches/0007-Compile-with-Argon2id-support.patch index e34fd631..517752ee 100644 --- a/config/grub/nvme/patches/0007-Compile-with-Argon2id-support.patch +++ b/config/grub/nvme/patches/0007-Compile-with-Argon2id-support.patch @@ -1,4 +1,4 @@ -From 67a96fa1d99ebf28dbdaefbce57e6f3cba2f6bf3 Mon Sep 17 00:00:00 2001 +From c9046b0a40ddc43d97e93127538bec0fde62d04e Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 07/14] Compile with Argon2id support diff --git a/config/grub/nvme/patches/0008-Make-grub-install-work-with-Argon2.patch b/config/grub/nvme/patches/0008-Make-grub-install-work-with-Argon2.patch index c1726631..1cf06602 100644 --- a/config/grub/nvme/patches/0008-Make-grub-install-work-with-Argon2.patch +++ b/config/grub/nvme/patches/0008-Make-grub-install-work-with-Argon2.patch @@ -1,4 +1,4 @@ -From de000f70873b61d62b0d561e0af5302e178c4e42 Mon Sep 17 00:00:00 2001 +From bc99124fb0de2e4b0407f5b8591306241ffc7dc1 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 Subject: [PATCH 08/14] Make grub-install work with Argon2 @@ -9,7 +9,7 @@ Signed-off-by: Nicholas Johnson 1 file changed, 2 insertions(+) diff --git a/util/grub-install.c b/util/grub-install.c -index 7dc5657bb..cf7315891 100644 +index 060246589..059036d3c 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -448,6 +448,8 @@ probe_mods (grub_disk_t disk) diff --git a/config/grub/nvme/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch b/config/grub/nvme/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch index bc1fa260..9a1d866b 100644 --- a/config/grub/nvme/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch +++ b/config/grub/nvme/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch @@ -1,4 +1,4 @@ -From 5b239742565ed20fce545aa32952a37bbb45beb8 Mon Sep 17 00:00:00 2001 +From 47ee3e0a5635e99d04fb1248a4896c24ff5bc746 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Mon, 30 Oct 2023 22:19:21 +0000 Subject: [PATCH 09/14] at_keyboard coreboot: force scancodes2+translate diff --git a/config/grub/nvme/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch b/config/grub/nvme/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch index 62c320ba..d11d424f 100644 --- a/config/grub/nvme/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch +++ b/config/grub/nvme/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch @@ -1,4 +1,4 @@ -From f8c3f597daf62a13f1c1169fddd78c833dd05cf1 Mon Sep 17 00:00:00 2001 +From 1934b92519503bfbb8c2f331afab6a34255250ad Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Tue, 31 Oct 2023 10:33:28 +0000 Subject: [PATCH 10/14] keylayouts: don't print "Unknown key" message diff --git a/config/grub/nvme/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch b/config/grub/nvme/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch index db720a76..3315f731 100644 --- a/config/grub/nvme/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch +++ b/config/grub/nvme/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch @@ -1,4 +1,4 @@ -From 27c79cf561fd5eef0c8eb5dda9f536cee3926b57 Mon Sep 17 00:00:00 2001 +From 6f48f88cd472729f0274f36cef87e76a31b6db35 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 16:14:58 +0000 Subject: [PATCH 11/14] don't print missing prefix errors on the screen diff --git a/config/grub/nvme/patches/0012-don-t-print-error-if-module-not-found.patch b/config/grub/nvme/patches/0012-don-t-print-error-if-module-not-found.patch index 63e4b39c..26e08383 100644 --- a/config/grub/nvme/patches/0012-don-t-print-error-if-module-not-found.patch +++ b/config/grub/nvme/patches/0012-don-t-print-error-if-module-not-found.patch @@ -1,4 +1,4 @@ -From 752ac0c09c7ac3f1ecc5d3d4d8410d424b433da2 Mon Sep 17 00:00:00 2001 +From aab095ed496aec3be4428b48a36a502426e0d275 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 16:36:22 +0000 Subject: [PATCH 12/14] don't print error if module not found diff --git a/config/grub/nvme/patches/0013-don-t-print-empty-error-messages.patch b/config/grub/nvme/patches/0013-don-t-print-empty-error-messages.patch index bbc9410e..2519d1cc 100644 --- a/config/grub/nvme/patches/0013-don-t-print-empty-error-messages.patch +++ b/config/grub/nvme/patches/0013-don-t-print-empty-error-messages.patch @@ -1,4 +1,4 @@ -From ac7a47b0a80a0f398c1250384fd5bc8c228c5d09 Mon Sep 17 00:00:00 2001 +From 703903ca50b9a5705db0cf5dad1ed2561b28d886 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 17:25:20 +0000 Subject: [PATCH 13/14] don't print empty error messages diff --git a/config/grub/nvme/patches/0014-Add-native-NVMe-driver-based-on-SeaBIOS.patch b/config/grub/nvme/patches/0014-Add-native-NVMe-driver-based-on-SeaBIOS.patch index 3d7db82c..9f2ee88f 100644 --- a/config/grub/nvme/patches/0014-Add-native-NVMe-driver-based-on-SeaBIOS.patch +++ b/config/grub/nvme/patches/0014-Add-native-NVMe-driver-based-on-SeaBIOS.patch @@ -1,4 +1,4 @@ -From 421a826c41882baafb2c5710959810657f24a52e Mon Sep 17 00:00:00 2001 +From e2d0d0695ded985463aac53f6fec5ce945bd4893 Mon Sep 17 00:00:00 2001 From: Mate Kukri Date: Mon, 20 May 2024 11:43:35 +0100 Subject: [PATCH 14/14] Add native NVMe driver based on SeaBIOS diff --git a/config/grub/nvme/target.cfg b/config/grub/nvme/target.cfg index 822d27b6..aa86509f 100644 --- a/config/grub/nvme/target.cfg +++ b/config/grub/nvme/target.cfg @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-3.0-or-later tree="nvme" -rev="4dc6166571645780c459dde2cdc1b001a5ec844c" +rev="a4da71dafeea519b034beb159dfe80c486c2107c" diff --git a/config/grub/xhci/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch b/config/grub/xhci/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch index d1ddc352..5ce90533 100644 --- a/config/grub/xhci/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch +++ b/config/grub/xhci/patches/0001-mitigate-grub-s-missing-characters-for-borders-arrow.patch @@ -1,7 +1,7 @@ -From 96e8baf58dcae1dbc016420ea1972d50f09f8f9b Mon Sep 17 00:00:00 2001 +From 836f5ba3fe25ef53b4cfcd8a0a1f7a6fb9bcb21c Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 31 Oct 2021 03:47:05 +0000 -Subject: [PATCH 01/26] mitigate grub's missing characters for borders/arrow +Subject: [PATCH 01/25] mitigate grub's missing characters for borders/arrow characters This cleans up the display on the main screen in GRUB. diff --git a/config/grub/xhci/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch b/config/grub/xhci/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch index a69a5780..ee277465 100644 --- a/config/grub/xhci/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch +++ b/config/grub/xhci/patches/0002-say-the-name-libreboot-in-the-grub-menu.patch @@ -1,7 +1,7 @@ -From f23a77c22e61e466c081d2b81b968bac4812e6b6 Mon Sep 17 00:00:00 2001 +From cb5fe4b9cae34e6ebb12953f62328c883a89a9f2 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sat, 19 Nov 2022 16:30:24 +0000 -Subject: [PATCH 02/26] say the name libreboot, in the grub menu +Subject: [PATCH 02/25] say the name libreboot, in the grub menu --- grub-core/normal/main.c | 2 +- diff --git a/config/grub/xhci/patches/0003-Add-CC0-license.patch b/config/grub/xhci/patches/0003-Add-CC0-license.patch index 1903a465..19e195fa 100644 --- a/config/grub/xhci/patches/0003-Add-CC0-license.patch +++ b/config/grub/xhci/patches/0003-Add-CC0-license.patch @@ -1,7 +1,7 @@ -From 4e2ba04266f006369dc10b981803ba3a237f2ad8 Mon Sep 17 00:00:00 2001 +From ef94d2c0a9dab9cb1a6888b07893fa341c463649 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 -Subject: [PATCH 03/26] Add CC0 license +Subject: [PATCH 03/25] Add CC0 license Signed-off-by: Nicholas Johnson --- diff --git a/config/grub/xhci/patches/0004-Define-GRUB_UINT32_MAX.patch b/config/grub/xhci/patches/0004-Define-GRUB_UINT32_MAX.patch index 2adba78b..cc309abd 100644 --- a/config/grub/xhci/patches/0004-Define-GRUB_UINT32_MAX.patch +++ b/config/grub/xhci/patches/0004-Define-GRUB_UINT32_MAX.patch @@ -1,7 +1,7 @@ -From c0b5c14042ee44e0e3ed814ebba3190b47514d82 Mon Sep 17 00:00:00 2001 +From aebfb4ee87203cc0dbe53ae1e951061efb73452f Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 -Subject: [PATCH 04/26] Define GRUB_UINT32_MAX +Subject: [PATCH 04/25] Define GRUB_UINT32_MAX Signed-off-by: Nicholas Johnson --- diff --git a/config/grub/xhci/patches/0005-Add-Argon2-algorithm.patch b/config/grub/xhci/patches/0005-Add-Argon2-algorithm.patch index 0db13c60..35b96718 100644 --- a/config/grub/xhci/patches/0005-Add-Argon2-algorithm.patch +++ b/config/grub/xhci/patches/0005-Add-Argon2-algorithm.patch @@ -1,7 +1,7 @@ -From 46aa2f307de53b305045f7706b38a4e0d198875e Mon Sep 17 00:00:00 2001 +From 22a609e508350e2606f90f96d9d0569b2294cfcf Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 -Subject: [PATCH 05/26] Add Argon2 algorithm +Subject: [PATCH 05/25] Add Argon2 algorithm Signed-off-by: Nicholas Johnson --- @@ -30,7 +30,7 @@ Signed-off-by: Nicholas Johnson create mode 100644 grub-core/lib/argon2/ref.c diff --git a/docs/grub-dev.texi b/docs/grub-dev.texi -index 3ad8e3efa..d7c6232af 100644 +index f4367f895..9d96cedf9 100644 --- a/docs/grub-dev.texi +++ b/docs/grub-dev.texi @@ -503,12 +503,76 @@ GRUB includes some code from other projects, and it is sometimes necessary diff --git a/config/grub/xhci/patches/0006-Error-on-missing-Argon2id-parameters.patch b/config/grub/xhci/patches/0006-Error-on-missing-Argon2id-parameters.patch index b9da0bec..5f487314 100644 --- a/config/grub/xhci/patches/0006-Error-on-missing-Argon2id-parameters.patch +++ b/config/grub/xhci/patches/0006-Error-on-missing-Argon2id-parameters.patch @@ -1,7 +1,7 @@ -From c3a68f158725a858206c1fc91407b4993142a4a5 Mon Sep 17 00:00:00 2001 +From 0c0da88e7619e5424ef062ea6867dfe32f032164 Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 -Subject: [PATCH 06/26] Error on missing Argon2id parameters +Subject: [PATCH 06/25] Error on missing Argon2id parameters Signed-off-by: Nicholas Johnson --- diff --git a/config/grub/xhci/patches/0007-Compile-with-Argon2id-support.patch b/config/grub/xhci/patches/0007-Compile-with-Argon2id-support.patch index c6369367..a809e2e4 100644 --- a/config/grub/xhci/patches/0007-Compile-with-Argon2id-support.patch +++ b/config/grub/xhci/patches/0007-Compile-with-Argon2id-support.patch @@ -1,7 +1,7 @@ -From 13f149fa5fe4e2ae0e95b3055584335beb9bdee8 Mon Sep 17 00:00:00 2001 +From 2a52c5c4f481469667c7c00e43befac28645d57f Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 -Subject: [PATCH 07/26] Compile with Argon2id support +Subject: [PATCH 07/25] Compile with Argon2id support Signed-off-by: Nicholas Johnson --- diff --git a/config/grub/xhci/patches/0008-Make-grub-install-work-with-Argon2.patch b/config/grub/xhci/patches/0008-Make-grub-install-work-with-Argon2.patch index b0e36f9e..7948ec91 100644 --- a/config/grub/xhci/patches/0008-Make-grub-install-work-with-Argon2.patch +++ b/config/grub/xhci/patches/0008-Make-grub-install-work-with-Argon2.patch @@ -1,7 +1,7 @@ -From 068442a692ab28298eab6bfd89a286c1d2ab91e0 Mon Sep 17 00:00:00 2001 +From 15076c6c38f4b7bc8e684974a908295478fbae9d Mon Sep 17 00:00:00 2001 From: Ax333l Date: Thu, 17 Aug 2023 00:00:00 +0000 -Subject: [PATCH 08/26] Make grub-install work with Argon2 +Subject: [PATCH 08/25] Make grub-install work with Argon2 Signed-off-by: Nicholas Johnson --- @@ -9,7 +9,7 @@ Signed-off-by: Nicholas Johnson 1 file changed, 2 insertions(+) diff --git a/util/grub-install.c b/util/grub-install.c -index 7dc5657bb..cf7315891 100644 +index 060246589..059036d3c 100644 --- a/util/grub-install.c +++ b/util/grub-install.c @@ -448,6 +448,8 @@ probe_mods (grub_disk_t disk) diff --git a/config/grub/xhci/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch b/config/grub/xhci/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch index 9d7a9387..c18061ba 100644 --- a/config/grub/xhci/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch +++ b/config/grub/xhci/patches/0009-at_keyboard-coreboot-force-scancodes2-translate.patch @@ -1,7 +1,7 @@ -From 063d8d5fe39d2addca7806ca0a7c6f0544affa8f Mon Sep 17 00:00:00 2001 +From 696f0d54d306472ad00b46e5a702080ae16d0101 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Mon, 30 Oct 2023 22:19:21 +0000 -Subject: [PATCH 09/26] at_keyboard coreboot: force scancodes2+translate +Subject: [PATCH 09/25] at_keyboard coreboot: force scancodes2+translate Scan code set 2 with translation should be assumed in every case, as the default starting position. diff --git a/config/grub/xhci/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch b/config/grub/xhci/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch index b116ea52..80f04547 100644 --- a/config/grub/xhci/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch +++ b/config/grub/xhci/patches/0010-keylayouts-don-t-print-Unknown-key-message.patch @@ -1,7 +1,7 @@ -From cb7d93059959eb921328bd285f18e363f0f44aec Mon Sep 17 00:00:00 2001 +From 907e8f373bac0c618c491a3a5cb4137d4446de05 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Tue, 31 Oct 2023 10:33:28 +0000 -Subject: [PATCH 10/26] keylayouts: don't print "Unknown key" message +Subject: [PATCH 10/25] keylayouts: don't print "Unknown key" message on keyboards with stuck keys, this results in GRUB just spewing it repeatedly, preventing use of GRUB. diff --git a/config/grub/xhci/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch b/config/grub/xhci/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch index 655e0005..a89f9e29 100644 --- a/config/grub/xhci/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch +++ b/config/grub/xhci/patches/0011-don-t-print-missing-prefix-errors-on-the-screen.patch @@ -1,7 +1,7 @@ -From 2ca7390361d1ff8ea18399b41e38436c8d506d60 Mon Sep 17 00:00:00 2001 +From b5693f53db4d337b4345192da08130b0f2f9bd08 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 16:14:58 +0000 -Subject: [PATCH 11/26] don't print missing prefix errors on the screen +Subject: [PATCH 11/25] 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, diff --git a/config/grub/xhci/patches/0012-don-t-print-error-if-module-not-found.patch b/config/grub/xhci/patches/0012-don-t-print-error-if-module-not-found.patch index 589dd4d7..913e148c 100644 --- a/config/grub/xhci/patches/0012-don-t-print-error-if-module-not-found.patch +++ b/config/grub/xhci/patches/0012-don-t-print-error-if-module-not-found.patch @@ -1,7 +1,7 @@ -From 51b439fc0aea4ef2c52c80fa765d9bda992a8ac2 Mon Sep 17 00:00:00 2001 +From 55c2e4b1d413fa03d9597007b16d136b3a6fa713 Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 16:36:22 +0000 -Subject: [PATCH 12/26] don't print error if module not found +Subject: [PATCH 12/25] 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 diff --git a/config/grub/xhci/patches/0013-don-t-print-empty-error-messages.patch b/config/grub/xhci/patches/0013-don-t-print-empty-error-messages.patch index 7cd354e3..381bca8b 100644 --- a/config/grub/xhci/patches/0013-don-t-print-empty-error-messages.patch +++ b/config/grub/xhci/patches/0013-don-t-print-empty-error-messages.patch @@ -1,7 +1,7 @@ -From 88c2d1618283c7f1c3b4adbce532789b0ca2447d Mon Sep 17 00:00:00 2001 +From 93210cf7c046c0c9c8c77ffde4397a25d391c64d Mon Sep 17 00:00:00 2001 From: Leah Rowe Date: Sun, 5 Nov 2023 17:25:20 +0000 -Subject: [PATCH 13/26] don't print empty error messages +Subject: [PATCH 13/25] don't print empty error messages this is part two of the quest to kill the prefix error message. after i disabled prefix-related diff --git a/config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch b/config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch index a35a16e9..a2df041f 100644 --- a/config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch +++ b/config/grub/xhci/patches/0014-grub-core-bus-usb-Parse-SuperSpeed-companion-descrip.patch @@ -1,7 +1,7 @@ -From 2472f3c2e465863c51a3cacf96ab910c015cfa8e Mon Sep 17 00:00:00 2001 +From a216d09bffcb2f2bff96445cca412c9328b4a6bf Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 15 Nov 2020 19:00:27 +0100 -Subject: [PATCH 14/26] grub-core/bus/usb: Parse SuperSpeed companion +Subject: [PATCH 14/25] grub-core/bus/usb: Parse SuperSpeed companion descriptors Parse the SS_ENDPOINT_COMPANION descriptor, which is only present on USB 3.0 diff --git a/config/grub/xhci/patches/0015-usb-Add-enum-for-xHCI.patch b/config/grub/xhci/patches/0015-usb-Add-enum-for-xHCI.patch index 84b81df7..1e45acc8 100644 --- a/config/grub/xhci/patches/0015-usb-Add-enum-for-xHCI.patch +++ b/config/grub/xhci/patches/0015-usb-Add-enum-for-xHCI.patch @@ -1,7 +1,7 @@ -From 681a247209c83451cdebf6fc02cee6737a1921b6 Mon Sep 17 00:00:00 2001 +From cb56fbac65869f04fcf9b0b4b360f4ccc6deabed Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 7 Dec 2020 08:41:22 +0100 -Subject: [PATCH 15/26] usb: Add enum for xHCI +Subject: [PATCH 15/25] usb: Add enum for xHCI Will be used in future patches. diff --git a/config/grub/xhci/patches/0016-usbtrans-Set-default-maximum-packet-size.patch b/config/grub/xhci/patches/0016-usbtrans-Set-default-maximum-packet-size.patch index 611db609..537ed958 100644 --- a/config/grub/xhci/patches/0016-usbtrans-Set-default-maximum-packet-size.patch +++ b/config/grub/xhci/patches/0016-usbtrans-Set-default-maximum-packet-size.patch @@ -1,7 +1,7 @@ -From 8af01b2548f61a9197b9f931831ca397a7e7c9b3 Mon Sep 17 00:00:00 2001 +From 3c735bf84a74e5a5612ca9b59868e050da8a46fe Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 7 Dec 2020 08:41:23 +0100 -Subject: [PATCH 16/26] usbtrans: Set default maximum packet size +Subject: [PATCH 16/25] usbtrans: Set default maximum packet size Set the maximum packet size to 512 for SuperSpeed devices. diff --git a/config/grub/xhci/patches/0017-grub-core-bus-usb-Add-function-pointer-for-attach-de.patch b/config/grub/xhci/patches/0017-grub-core-bus-usb-Add-function-pointer-for-attach-de.patch index 05540fa6..d61f2a8a 100644 --- a/config/grub/xhci/patches/0017-grub-core-bus-usb-Add-function-pointer-for-attach-de.patch +++ b/config/grub/xhci/patches/0017-grub-core-bus-usb-Add-function-pointer-for-attach-de.patch @@ -1,7 +1,7 @@ -From 7a977001a1574c884c4f711686c2de01386b9230 Mon Sep 17 00:00:00 2001 +From c01366a852d40e060fc060dda6cf2891c9c50bd0 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Sun, 15 Nov 2020 19:51:42 +0100 -Subject: [PATCH 17/26] grub-core/bus/usb: Add function pointer for +Subject: [PATCH 17/25] grub-core/bus/usb: Add function pointer for attach/detach events The xHCI code needs to be called for attaching or detaching a device. diff --git a/config/grub/xhci/patches/0018-grub-core-bus-usb-usbhub-Add-new-private-fields-for-.patch b/config/grub/xhci/patches/0018-grub-core-bus-usb-usbhub-Add-new-private-fields-for-.patch index a3eaba15..75314780 100644 --- a/config/grub/xhci/patches/0018-grub-core-bus-usb-usbhub-Add-new-private-fields-for-.patch +++ b/config/grub/xhci/patches/0018-grub-core-bus-usb-usbhub-Add-new-private-fields-for-.patch @@ -1,7 +1,7 @@ -From e8a237ffb5bd3ba5258ce5c173b31424f3a39392 Mon Sep 17 00:00:00 2001 +From 1ec77a83178e5c1c005b6b27139287f1463f1b49 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 7 Dec 2020 08:41:25 +0100 -Subject: [PATCH 18/26] grub-core/bus/usb/usbhub: Add new private fields for +Subject: [PATCH 18/25] 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 diff --git a/config/grub/xhci/patches/0019-grub-core-bus-usb-Add-xhci-support.patch b/config/grub/xhci/patches/0019-grub-core-bus-usb-Add-xhci-support.patch index e6c0d474..043320b9 100644 --- a/config/grub/xhci/patches/0019-grub-core-bus-usb-Add-xhci-support.patch +++ b/config/grub/xhci/patches/0019-grub-core-bus-usb-Add-xhci-support.patch @@ -1,7 +1,7 @@ -From badcc0d5ff1d4b194c93a530344788c4231d8789 Mon Sep 17 00:00:00 2001 +From 03998bc9b74366ecf64d5f76fe4b398ec7fc5d31 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 7 Dec 2020 08:41:26 +0100 -Subject: [PATCH 19/26] grub-core/bus/usb: Add xhci support +Subject: [PATCH 19/25] grub-core/bus/usb: Add xhci support Add support for xHCI USB controllers. The code is based on seabios implementation, but has been heavily diff --git a/config/grub/xhci/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch b/config/grub/xhci/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch index 01d7d008..6c5c1731 100644 --- a/config/grub/xhci/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch +++ b/config/grub/xhci/patches/0020-grub-core-bus-usb-usbhub-Add-xHCI-non-root-hub-suppo.patch @@ -1,7 +1,7 @@ -From e4416b166e501777e53de387ac4329150483a160 Mon Sep 17 00:00:00 2001 +From 7571efed2cdd949a203401630a19f42c74095797 Mon Sep 17 00:00:00 2001 From: Patrick Rudolph Date: Mon, 7 Dec 2020 08:41:27 +0100 -Subject: [PATCH 20/26] grub-core/bus/usb/usbhub: Add xHCI non root hub support +Subject: [PATCH 20/25] grub-core/bus/usb/usbhub: Add xHCI non root hub support Tested on Intel PCH C246, the USB3 hub can be configured by grub. diff --git a/config/grub/xhci/patches/0021-xHCI-also-accept-SBRN-0x31-and-0x32.patch b/config/grub/xhci/patches/0021-xHCI-also-accept-SBRN-0x31-and-0x32.patch index d0874f85..587782c2 100644 --- a/config/grub/xhci/patches/0021-xHCI-also-accept-SBRN-0x31-and-0x32.patch +++ b/config/grub/xhci/patches/0021-xHCI-also-accept-SBRN-0x31-and-0x32.patch @@ -1,7 +1,7 @@ -From 8e6d5b598b3e21c905023b438110d71f487a2289 Mon Sep 17 00:00:00 2001 +From 0c58853bd1e4ca63cdeb5b5ef949d78cbd9028d0 Mon Sep 17 00:00:00 2001 From: Sven Anderson Date: Sat, 28 May 2022 21:39:23 +0200 -Subject: [PATCH 21/26] xHCI: also accept SBRN 0x31 and 0x32 +Subject: [PATCH 21/25] xHCI: also accept SBRN 0x31 and 0x32 Signed-off-by: Sven Anderson --- diff --git a/config/grub/xhci/patches/0022-xhci-fix-port-indexing.patch b/config/grub/xhci/patches/0022-xhci-fix-port-indexing.patch index 7e0bcb74..64872650 100644 --- a/config/grub/xhci/patches/0022-xhci-fix-port-indexing.patch +++ b/config/grub/xhci/patches/0022-xhci-fix-port-indexing.patch @@ -1,7 +1,7 @@ -From 32c6d97e2a80c2e74dd9daf74281a89d1a05faaa Mon Sep 17 00:00:00 2001 +From 0da64bd7a144361198ee3dbcd4921fbbdf5c08fa Mon Sep 17 00:00:00 2001 From: Sven Anderson Date: Mon, 13 Jan 2025 19:51:41 +0100 -Subject: [PATCH 22/26] xhci: fix port indexing +Subject: [PATCH 22/25] xhci: fix port indexing --- grub-core/bus/usb/xhci.c | 10 +++++----- diff --git a/config/grub/xhci/patches/0023-xhci-configure-TT-for-non-root-hubs.patch b/config/grub/xhci/patches/0023-xhci-configure-TT-for-non-root-hubs.patch new file mode 100644 index 00000000..c63850d6 --- /dev/null +++ b/config/grub/xhci/patches/0023-xhci-configure-TT-for-non-root-hubs.patch @@ -0,0 +1,98 @@ +From fa9c2124b1ca476f8b2ce168d56527100757ef90 Mon Sep 17 00:00:00 2001 +From: Sven Anderson +Date: Mon, 13 Jan 2025 20:26:32 +0100 +Subject: [PATCH 23/25] 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.39.5 + diff --git a/config/grub/xhci/patches/0024-Fix-compilation-on-x86_64.patch b/config/grub/xhci/patches/0024-Fix-compilation-on-x86_64.patch new file mode 100644 index 00000000..d03db740 --- /dev/null +++ b/config/grub/xhci/patches/0024-Fix-compilation-on-x86_64.patch @@ -0,0 +1,90 @@ +From b049a11e2cf54e51b3a9fd4d3435089999e61702 Mon Sep 17 00:00:00 2001 +From: Patrick Rudolph +Date: Wed, 24 Feb 2021 08:25:41 +0100 +Subject: [PATCH 24/25] Fix compilation on x86_64 + +Signed-off-by: Patrick Rudolph +--- + 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.39.5 + diff --git a/config/grub/xhci/patches/0024-xhci-configure-TT-for-non-root-hubs.patch b/config/grub/xhci/patches/0024-xhci-configure-TT-for-non-root-hubs.patch deleted file mode 100644 index a605e210..00000000 --- a/config/grub/xhci/patches/0024-xhci-configure-TT-for-non-root-hubs.patch +++ /dev/null @@ -1,98 +0,0 @@ -From 233f7dd274ef2ccac7b1fc0f5cfdeb7c01aef58b Mon Sep 17 00:00:00 2001 -From: Sven Anderson -Date: Mon, 13 Jan 2025 20:26:32 +0100 -Subject: [PATCH 24/26] 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 d13a7c39d..8ad2a10f9 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.39.5 - diff --git a/config/grub/xhci/patches/0025-Add-native-NVMe-driver-based-on-SeaBIOS.patch b/config/grub/xhci/patches/0025-Add-native-NVMe-driver-based-on-SeaBIOS.patch new file mode 100644 index 00000000..96ecbaaf --- /dev/null +++ b/config/grub/xhci/patches/0025-Add-native-NVMe-driver-based-on-SeaBIOS.patch @@ -0,0 +1,1074 @@ +From 7bb8bb98b86fc97e1ce04e6169d517acbd476e1e Mon Sep 17 00:00:00 2001 +From: Mate Kukri +Date: Mon, 20 May 2024 11:43:35 +0100 +Subject: [PATCH 25/25] Add native NVMe driver based on SeaBIOS + +Tested to successfully boot Debian on QEMU and OptiPlex 3050. + +Signed-off-by: Mate Kukri +--- + 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 fda723f0c..367e4b5e6 100644 +--- a/grub-core/Makefile.core.def ++++ b/grub-core/Makefile.core.def +@@ -2684,3 +2684,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 ++ ++/* 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 ++#include ++#include ++#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.39.5 + diff --git a/config/grub/xhci/patches/0025-Fix-compilation-on-x86_64.patch b/config/grub/xhci/patches/0025-Fix-compilation-on-x86_64.patch deleted file mode 100644 index e75cc5e9..00000000 --- a/config/grub/xhci/patches/0025-Fix-compilation-on-x86_64.patch +++ /dev/null @@ -1,90 +0,0 @@ -From 0441e7eff7950bfd47fc2f5533ce2c64b785dc1d Mon Sep 17 00:00:00 2001 -From: Patrick Rudolph -Date: Wed, 24 Feb 2021 08:25:41 +0100 -Subject: [PATCH 25/26] Fix compilation on x86_64 - -Signed-off-by: Patrick Rudolph ---- - 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 8ad2a10f9..ceb57c9b3 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.39.5 - diff --git a/config/grub/xhci/patches/0026-Add-native-NVMe-driver-based-on-SeaBIOS.patch b/config/grub/xhci/patches/0026-Add-native-NVMe-driver-based-on-SeaBIOS.patch deleted file mode 100644 index 36bbecd9..00000000 --- a/config/grub/xhci/patches/0026-Add-native-NVMe-driver-based-on-SeaBIOS.patch +++ /dev/null @@ -1,1074 +0,0 @@ -From 4440b01a702368c81520f630aa16852de55bb808 Mon Sep 17 00:00:00 2001 -From: Mate Kukri -Date: Mon, 20 May 2024 11:43:35 +0100 -Subject: [PATCH 26/26] Add native NVMe driver based on SeaBIOS - -Tested to successfully boot Debian on QEMU and OptiPlex 3050. - -Signed-off-by: Mate Kukri ---- - 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 fda723f0c..367e4b5e6 100644 ---- a/grub-core/Makefile.core.def -+++ b/grub-core/Makefile.core.def -@@ -2684,3 +2684,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 -+ -+/* 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 -+#include -+#include -+#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.39.5 - diff --git a/config/grub/xhci/target.cfg b/config/grub/xhci/target.cfg index aca71fca..5727e70b 100644 --- a/config/grub/xhci/target.cfg +++ b/config/grub/xhci/target.cfg @@ -1,4 +1,4 @@ # SPDX-License-Identifier: GPL-3.0-or-later tree="xhci" -rev="4dc6166571645780c459dde2cdc1b001a5ec844c" +rev="a4da71dafeea519b034beb159dfe80c486c2107c" -- cgit v1.2.1