Script 'mail_helper' called by obssrc
Hello community,

here is the log from the commit of package limine for openSUSE:Factory checked 
in at 2026-02-06 19:10:32
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/limine (Old)
 and      /work/SRC/openSUSE:Factory/.limine.new.1670 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "limine"

Fri Feb  6 19:10:32 2026 rev:32 rq:1331538 version:10.6.6

Changes:
--------
--- /work/SRC/openSUSE:Factory/limine/limine.changes    2026-01-15 
16:48:47.710584822 +0100
+++ /work/SRC/openSUSE:Factory/.limine.new.1670/limine.changes  2026-02-06 
19:17:06.093164298 +0100
@@ -1,0 +2,9 @@
+Thu Feb  5 23:43:28 UTC 2026 - Marvin Friedrich <[email protected]>
+
+- Update to 10.6.6:
+  * Re-add a mistakenly removed check for EFI volume responsiveness. Lack
+    of this check would indirectly cause hangs due to EFI volumes being
+    indexed despite their non-responsiveness.
+  * Replace suboptimal code to handle reads close to the end of a volume.
+
+-------------------------------------------------------------------

Old:
----
  limine-10.6.3.tar.gz

New:
----
  limine-10.6.6.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ limine.spec ++++++
--- /var/tmp/diff_new_pack.4ct9YU/_old  2026-02-06 19:17:06.761192563 +0100
+++ /var/tmp/diff_new_pack.4ct9YU/_new  2026-02-06 19:17:06.765192732 +0100
@@ -15,7 +15,7 @@
 #
 
 Name:           limine
-Version:        10.6.3
+Version:        10.6.6
 Release:        0
 Summary:        Modern, advanced, portable, multiprotocol bootloader and boot 
manager
 License:        BSD-2-Clause

++++++ limine-10.6.3.tar.gz -> limine-10.6.6.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/limine-10.6.3/ChangeLog new/limine-10.6.6/ChangeLog
--- old/limine-10.6.3/ChangeLog 2026-01-14 19:04:20.000000000 +0100
+++ new/limine-10.6.6/ChangeLog 2026-02-05 13:39:03.000000000 +0100
@@ -1,3 +1,54 @@
+2026-02-05  Mintsuki  <[email protected]>
+
+    *** Release 10.6.6 ***
+
+    Noteworthy changes compared to the previous release, 10.6.5:
+
+    Bug fixes:
+        - Re-add a mistakenly removed check for EFI volume responsiveness. Lack
+          of this check would indirectly cause hangs due to EFI volumes being
+          indexed despite their non-responsiveness.
+
+    Miscellaneous:
+        - Replace suboptimal code to handle reads close to the end of a volume.
+
+2026-02-04  Mintsuki  <[email protected]>
+
+    *** Release 10.6.5 ***
+
+    Noteworthy changes compared to the previous release, 10.6.4:
+
+    Bug fixes:
+        - Work around PicoEFI structure definition issue related to padding
+          that would cause volume_by_device_path() to always fail for
+          non-optical media.
+        - Fix issue that would cause unique sector detection on systems with 3+
+          collisions to fail and misreport unique sectors.
+        - Add extra layer of verification for unique sector matches to minimise
+          the chance of volume mismatches.
+
+    Miscellaneous:
+        - RISC-V: Implement Flanterm refresh path for SoCs not exposing Zicbom
+          in the device tree or ACPI (often the case with U-boot).
+        - Use volume_by_device_path() as primary disk_volume_from_efi_handle()
+          detection method.
+        - Lazily discover unique sectors only when the fallback requiring this
+          procedure is actually used.
+
+2026-02-02  Mintsuki  <[email protected]>
+
+    *** Release 10.6.4 ***
+
+    Noteworthy changes compared to the previous release, 10.6.3:
+
+    Bug fixes:
+        - Strip out all code relying on disk writes from the codebase. This
+          gets rid of the (remote) possibility of disk corruption and the (even
+          more remote) possibility of firmware/flash corruption. This also
+          sorts out an issue on Apple Silicon where m1n1/U-boot appears to
+          leave the NVMe controller in an inconsistent state after write
+          operations are attempted.
+
 2026-01-14  Mintsuki  <[email protected]>
 
     *** Release 10.6.3 ***
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/limine-10.6.3/common/drivers/disk.s2.c 
new/limine-10.6.6/common/drivers/disk.s2.c
--- old/limine-10.6.3/common/drivers/disk.s2.c  2026-01-14 19:04:20.000000000 
+0100
+++ new/limine-10.6.6/common/drivers/disk.s2.c  2026-02-05 13:39:03.000000000 
+0100
@@ -141,39 +141,6 @@
     return DISK_SUCCESS;
 }
 
-static int disk_write_sectors(struct volume *volume, void *buf, uint64_t 
block, size_t count) {
-    struct dap dap = {0};
-
-    if (count * volume->sector_size > XFER_BUF_SIZE)
-        panic(false, "XFER");
-
-    if (xfer_buf == NULL)
-        xfer_buf = conv_mem_alloc(XFER_BUF_SIZE);
-
-    dap.size    = 16;
-    dap.count   = count;
-    dap.segment = rm_seg(xfer_buf);
-    dap.offset  = rm_off(xfer_buf);
-    dap.lba     = block;
-
-    struct rm_regs r = {0};
-    r.eax = 0x4301;
-    r.edx = volume->drive;
-    r.esi = (uint32_t)rm_off(&dap);
-    r.ds  = rm_seg(&dap);
-
-    if (buf != NULL)
-        memcpy(xfer_buf, buf, count * volume->sector_size);
-
-    rm_int(0x13, &r, &r);
-
-    if (r.eflags & EFLAGS_CF) {
-        return DISK_FAILURE;
-    }
-
-    return DISK_SUCCESS;
-}
-
 static bool detect_sector_size(struct volume *volume) {
     struct dap dap = {0};
 
@@ -304,18 +271,23 @@
         block->drive = drive;
         block->partition = 0;
         block->first_sect = 0;
-        block->sect_count = drive_params.lba_count;
         block->max_partition = -1;
 
         if (!detect_sector_size(block)) {
             continue;
         }
 
-        if (disk_read_sectors(block, xfer_buf, 0, 1) != DISK_SUCCESS) {
-            continue;
+        // Normalize sect_count to 512-byte sectors for consistency with 
partitions
+        // Preserve (uint64_t)-1 sentinel value (means "unknown size")
+        if (drive_params.lba_count == (uint64_t)-1 || drive_params.lba_count 
== 0) {
+            block->sect_count = (uint64_t)-1;
+        } else {
+            block->sect_count = drive_params.lba_count * (block->sector_size / 
512);
         }
 
-        block->is_optical = (disk_write_sectors(block, xfer_buf, 0, 1) != 
DISK_SUCCESS) && block->sector_size == 2048;
+        // Detect optical drives via DPTE ATAPI bit (bit 6) or sector size 
heuristic
+        bool is_atapi = (dpte != NULL && (dpte->flags & (1 << 6)));
+        block->is_optical = is_atapi || (block->sector_size == 2048 && 
is_removable);
 
         if (!is_removable && !block->is_optical) {
             if (consumed_bda_disks == bda_disk_count) {
@@ -421,6 +393,9 @@
 
 #define UNIQUE_SECTOR_POOL_SIZE 65536
 static uint8_t *unique_sector_pool;
+static bool unique_sectors_calculated = false;
+
+static void find_unique_sectors(void);
 
 static struct volume *volume_by_unique_sector(void *b2b) {
     for (size_t i = 0; i < volume_index_i; i++) {
@@ -436,6 +411,23 @@
     return NULL;
 }
 
+// Search for matching hash including invalidated volumes (for collision 
detection)
+static struct volume *volume_by_sector_hash(void *b2b) {
+    for (size_t i = 0; i < volume_index_i; i++) {
+        if (volume_index[i]->unique_sector_valid == false
+         && memcmp(volume_index[i]->unique_sector_b2b, 
(uint8_t[BLAKE2B_OUT_BYTES]){0}, BLAKE2B_OUT_BYTES) == 0) {
+            // Hash was never set, skip
+            continue;
+        }
+
+        if (memcmp(volume_index[i]->unique_sector_b2b, b2b, BLAKE2B_OUT_BYTES) 
== 0) {
+            return volume_index[i];
+        }
+    }
+
+    return NULL;
+}
+
 static bool is_efi_handle_to_skip(EFI_HANDLE efi_handle) {
     EFI_STATUS status;
 
@@ -484,7 +476,7 @@
     return false;
 }
 
-static bool is_efi_handle_hdd(EFI_HANDLE efi_handle) {
+static bool is_efi_handle_optical(EFI_HANDLE efi_handle) {
     EFI_STATUS status;
 
     EFI_GUID dp_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
@@ -500,11 +492,8 @@
             break;
         }
 
-        if (dp->Type == MEDIA_DEVICE_PATH) {
-            switch (dp->SubType) {
-                case MEDIA_HARDDRIVE_DP:
-                    return true;
-            }
+        if (dp->Type == MEDIA_DEVICE_PATH && dp->SubType == MEDIA_CDROM_DP) {
+            return true;
         }
 
         uint16_t len = *(uint16_t *)dp->Length;
@@ -517,139 +506,174 @@
     return false;
 }
 
-struct volume *disk_volume_from_efi_handle(EFI_HANDLE efi_handle) {
-    struct volume *ret;
-
+static EFI_DEVICE_PATH_PROTOCOL *get_device_path(EFI_HANDLE efi_handle) {
     EFI_STATUS status;
+    EFI_GUID dp_guid = EFI_DEVICE_PATH_PROTOCOL_GUID;
+    EFI_DEVICE_PATH_PROTOCOL *dp = NULL;
 
-    EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL;
-    EFI_BLOCK_IO *block_io = NULL;
-
-    if (is_efi_handle_to_skip(efi_handle)) {
-        return NULL;
-    }
-
-    status = gBS->HandleProtocol(efi_handle, &block_io_guid, (void 
**)&block_io);
+    status = gBS->HandleProtocol(efi_handle, &dp_guid, (void **)&dp);
     if (status) {
-        return pxe_from_efi_handle(efi_handle);
+        return NULL;
     }
+    return dp;
+}
 
-    uint64_t bdev_size = ((uint64_t)block_io->Media->LastBlock + 1) * 
(uint64_t)block_io->Media->BlockSize;
-    if (bdev_size < UNIQUE_SECTOR_POOL_SIZE) {
-        goto fallback;
+// Compare device paths up to (but not including) partition nodes
+static bool device_paths_match_disk(EFI_DEVICE_PATH_PROTOCOL *dp1,
+                                    EFI_DEVICE_PATH_PROTOCOL *dp2) {
+    if (dp1 == NULL || dp2 == NULL) {
+        return false;
     }
 
-    status = block_io->ReadBlocks(block_io, block_io->Media->MediaId,
-                                  0,
-                                  UNIQUE_SECTOR_POOL_SIZE,
-                                  unique_sector_pool);
-    if (status != 0) {
-        goto fallback;
-    }
+    while (!IsDevicePathEnd(dp1) && !IsDevicePathEnd(dp2)) {
+        // Stop at partition nodes
+        if (dp1->Type == MEDIA_DEVICE_PATH &&
+            (dp1->SubType == MEDIA_HARDDRIVE_DP || dp1->SubType == 
MEDIA_CDROM_DP)) {
+            break;
+        }
+        if (dp2->Type == MEDIA_DEVICE_PATH &&
+            (dp2->SubType == MEDIA_HARDDRIVE_DP || dp2->SubType == 
MEDIA_CDROM_DP)) {
+            break;
+        }
 
-    uint8_t b2b[BLAKE2B_OUT_BYTES];
-    blake2b(b2b, unique_sector_pool, UNIQUE_SECTOR_POOL_SIZE);
+        uint16_t len1 = DevicePathNodeLength(dp1);
+        uint16_t len2 = DevicePathNodeLength(dp2);
 
-    ret = volume_by_unique_sector(b2b);
-    if (ret != NULL) {
-        return ret;
-    }
+        if (len1 != len2) {
+            return false;
+        }
 
-    // Fallback to read-back method
-fallback:;
-    if (!is_efi_handle_hdd(efi_handle)) {
-        return NULL;
-    }
+        if (len1 < sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+            return false;
+        }
 
-    uint64_t signature = rand64();
-    uint64_t new_signature;
-    do { new_signature = rand64(); } while (new_signature == signature);
-    uint64_t orig;
+        if (memcmp(dp1, dp2, len1) != 0) {
+            return false;
+        }
 
-    status = block_io->ReadBlocks(block_io, block_io->Media->MediaId, 0, 4096, 
unique_sector_pool);
-    orig = *(uint64_t *)unique_sector_pool;
-    if (status) {
-        return NULL;
+        dp1 = (void *)dp1 + len1;
+        dp2 = (void *)dp2 + len2;
     }
 
-    *(uint64_t *)unique_sector_pool = signature;
-    status = block_io->WriteBlocks(block_io, block_io->Media->MediaId, 0, 
4096, unique_sector_pool);
-    if (status) {
-        // Attempt to restore anyways, just in case.
-        *(uint64_t *)unique_sector_pool = orig;
-        block_io->WriteBlocks(block_io, block_io->Media->MediaId, 0, 4096, 
unique_sector_pool);
+    return true;
+}
+
+static struct volume *volume_by_device_path(EFI_HANDLE query_handle) {
+    EFI_DEVICE_PATH_PROTOCOL *query_dp = get_device_path(query_handle);
+    if (query_dp == NULL) {
         return NULL;
     }
 
-    ret = NULL;
     for (size_t i = 0; i < volume_index_i; i++) {
-        uint64_t compare;
-
-        status = 
volume_index[i]->block_io->ReadBlocks(volume_index[i]->block_io,
-                          volume_index[i]->block_io->Media->MediaId,
-                          (volume_index[i]->first_sect * 512) / 
volume_index[i]->sector_size,
-                          4096, unique_sector_pool);
-        compare = *(uint64_t *)unique_sector_pool;
-        if (status) {
+        EFI_DEVICE_PATH_PROTOCOL *vol_dp = 
get_device_path(volume_index[i]->efi_handle);
+        if (vol_dp == NULL) {
             continue;
         }
 
-        if (compare == signature) {
-            // Double check
-            status = block_io->ReadBlocks(block_io, block_io->Media->MediaId, 
0, 4096, unique_sector_pool);
-            if (status) {
-                break;
-            }
-            *(uint64_t *)unique_sector_pool = new_signature;
-            status = block_io->WriteBlocks(block_io, block_io->Media->MediaId, 
0, 4096, unique_sector_pool);
-            if (status) {
-                break;
-            }
-
-            status = 
volume_index[i]->block_io->ReadBlocks(volume_index[i]->block_io,
-                          volume_index[i]->block_io->Media->MediaId,
-                          (volume_index[i]->first_sect * 512) / 
volume_index[i]->sector_size,
-                          4096, unique_sector_pool);
-            compare = *(uint64_t *)unique_sector_pool;
-            if (status) {
-                continue;
-            }
-
-            if (compare == new_signature) {
-                ret = volume_index[i];
-                break;
+        if (device_paths_match_disk(query_dp, vol_dp)) {
+            // Convert first_sect from 512-byte sectors to device LBAs
+            int sector_size = volume_index[i]->sector_size;
+            if ((volume_index[i]->first_sect * 512) % sector_size) {
+                continue;  // Misaligned, skip this volume
+            }
+            uint64_t first_sect_lba = (volume_index[i]->first_sect * 512) / 
sector_size;
+
+            EFI_DEVICE_PATH_PROTOCOL *qp = query_dp;
+            while (!IsDevicePathEnd(qp)) {
+                if (qp->Type == MEDIA_DEVICE_PATH && qp->SubType == 
MEDIA_HARDDRIVE_DP) {
+                    uint16_t len = DevicePathNodeLength(qp);
+                    // UEFI spec size is 42 bytes, but sizeof() may be larger 
due to padding
+                    if (len < 42) {
+                        break;
+                    }
+                    HARDDRIVE_DEVICE_PATH *query_hd = (HARDDRIVE_DEVICE_PATH 
*)qp;
+                    if (first_sect_lba == query_hd->PartitionStart) {
+                        return volume_index[i];
+                    }
+                    break;
+                }
+                if (qp->Type == MEDIA_DEVICE_PATH && qp->SubType == 
MEDIA_CDROM_DP) {
+                    uint16_t len = DevicePathNodeLength(qp);
+                    if (len < sizeof(CDROM_DEVICE_PATH)) {
+                        break;
+                    }
+                    CDROM_DEVICE_PATH *query_cd = (CDROM_DEVICE_PATH *)qp;
+                    if (first_sect_lba == query_cd->PartitionStart) {
+                        return volume_index[i];
+                    }
+                    break;
+                }
+                uint16_t len = DevicePathNodeLength(qp);
+                if (len < sizeof(EFI_DEVICE_PATH_PROTOCOL)) {
+                    break;
+                }
+                qp = (void *)qp + len;
             }
 
-            status = block_io->ReadBlocks(block_io, block_io->Media->MediaId, 
0, 4096, unique_sector_pool);
-            if (status) {
-                break;
-            }
-            *(uint64_t *)unique_sector_pool = signature;
-            status = block_io->WriteBlocks(block_io, block_io->Media->MediaId, 
0, 4096, unique_sector_pool);
-            if (status) {
-                break;
+            if (IsDevicePathEnd(qp) && volume_index[i]->partition == 0) {
+                return volume_index[i];
             }
         }
     }
 
-    status = block_io->ReadBlocks(block_io, block_io->Media->MediaId, 0, 4096, 
unique_sector_pool);
-    if (status) {
+    return NULL;
+}
+
+struct volume *disk_volume_from_efi_handle(EFI_HANDLE efi_handle) {
+    EFI_STATUS status;
+
+    EFI_GUID block_io_guid = BLOCK_IO_PROTOCOL;
+    EFI_BLOCK_IO *block_io = NULL;
+
+    if (is_efi_handle_to_skip(efi_handle)) {
         return NULL;
     }
-    *(uint64_t *)unique_sector_pool = orig;
-    status = block_io->WriteBlocks(block_io, block_io->Media->MediaId, 0, 
4096, unique_sector_pool);
+
+    status = gBS->HandleProtocol(efi_handle, &block_io_guid, (void 
**)&block_io);
     if (status) {
-        return NULL;
+        return pxe_from_efi_handle(efi_handle);
     }
 
+    // Try device path matching first (primary method)
+    struct volume *ret = volume_by_device_path(efi_handle);
     if (ret != NULL) {
         return ret;
     }
 
+    // Fallback to unique sector matching
+    uint64_t bdev_size = ((uint64_t)block_io->Media->LastBlock + 1) * 
(uint64_t)block_io->Media->BlockSize;
+    if (bdev_size >= UNIQUE_SECTOR_POOL_SIZE) {
+        status = block_io->ReadBlocks(block_io, block_io->Media->MediaId,
+                                      0,
+                                      UNIQUE_SECTOR_POOL_SIZE,
+                                      unique_sector_pool);
+        if (status == 0) {
+            find_unique_sectors();
+
+            uint8_t b2b[BLAKE2B_OUT_BYTES];
+            blake2b(b2b, unique_sector_pool, UNIQUE_SECTOR_POOL_SIZE);
+
+            ret = volume_by_unique_sector(b2b);
+            if (ret != NULL) {
+                // Verify size, block size, and partition status match
+                if (block_io->Media->BlockSize == (uint32_t)ret->sector_size
+                 && bdev_size == ret->sect_count * 512
+                 && block_io->Media->LogicalPartition == (ret->partition != 
0)) {
+                    return ret;
+                }
+            }
+        }
+    }
+
     return NULL;
 }
 
 static void find_unique_sectors(void) {
+    if (unique_sectors_calculated) {
+        return;
+    }
+    unique_sectors_calculated = true;
+
     EFI_STATUS status;
 
     for (size_t i = 0; i < volume_index_i; i++) {
@@ -659,7 +683,8 @@
 
         size_t first_sect = (volume_index[i]->first_sect * 512) / 
volume_index[i]->sector_size;
 
-        if (volume_index[i]->sect_count * volume_index[i]->sector_size < 
UNIQUE_SECTOR_POOL_SIZE) {
+        // sect_count is always in 512-byte sectors
+        if (volume_index[i]->sect_count * 512 < UNIQUE_SECTOR_POOL_SIZE) {
             continue;
         }
 
@@ -676,15 +701,21 @@
         uint8_t b2b[BLAKE2B_OUT_BYTES];
         blake2b(b2b, unique_sector_pool, UNIQUE_SECTOR_POOL_SIZE);
 
-        struct volume *collision = volume_by_unique_sector(b2b);
+        // Check for collision BEFORE storing hash (so we don't find ourselves)
+        // This searches all volumes including previously invalidated ones
+        struct volume *collision = volume_by_sector_hash(b2b);
+
+        // Always store the hash so future volumes can detect collisions
+        memcpy(volume_index[i]->unique_sector_b2b, b2b, BLAKE2B_OUT_BYTES);
+
         if (collision == NULL) {
             volume_index[i]->unique_sector_valid = true;
-            memcpy(volume_index[i]->unique_sector_b2b, b2b, BLAKE2B_OUT_BYTES);
             continue;
         }
 
-        // Invalidate collision's unique sector
+        // Collision found - invalidate both volumes
         collision->unique_sector_valid = false;
+        volume_index[i]->unique_sector_valid = false;
     }
 }
 
@@ -751,20 +782,18 @@
         if (drive->Media->LogicalPartition)
             continue;
 
-        drive->Media->WriteCaching = false;
-
+        // Read test to ensure device is responsive (skipping this causes 
hangs on some systems)
         status = drive->ReadBlocks(drive, drive->Media->MediaId, 0, 4096, 
unique_sector_pool);
         if (status) {
             continue;
         }
 
-        status = drive->WriteBlocks(drive, drive->Media->MediaId, 0, 4096, 
unique_sector_pool);
-
-        drive->Media->WriteCaching = true;
-
         struct volume *block = ext_mem_alloc(sizeof(struct volume));
 
-        if ((status || drive->Media->ReadOnly) && drive->Media->BlockSize == 
2048) {
+        bool is_optical = is_efi_handle_optical(handles[i]) ||
+                          (drive->Media->ReadOnly && drive->Media->BlockSize 
== 2048);
+
+        if (is_optical) {
             block->index = optical_indices++;
             block->is_optical = true;
         } else {
@@ -776,7 +805,8 @@
         block->partition = 0;
         block->sector_size = drive->Media->BlockSize;
         block->first_sect = 0;
-        block->sect_count = drive->Media->LastBlock + 1;
+        // Normalize sect_count to 512-byte sectors for consistency with 
partitions
+        block->sect_count = (drive->Media->LastBlock + 1) * 
(drive->Media->BlockSize / 512);
         block->max_partition = -1;
 
         if (drive->Revision >= EFI_BLOCK_IO_PROTOCOL_REVISION3) {
@@ -824,7 +854,6 @@
         }
     }
 
-    find_unique_sectors();
     find_part_handles(handles, handle_count);
 
     pmm_free(handles, handles_size);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/limine-10.6.3/common/lib/gterm.c 
new/limine-10.6.6/common/lib/gterm.c
--- old/limine-10.6.3/common/lib/gterm.c        2026-01-14 19:04:20.000000000 
+0100
+++ new/limine-10.6.6/common/lib/gterm.c        2026-02-05 13:39:03.000000000 
+0100
@@ -477,6 +477,13 @@
         asm volatile("cbo.flush (%0)" :: "r"(ptr) : "memory");
     }
 }
+static void riscv_flush_callback_nozicbom(volatile void *base, size_t length) {
+    volatile uint64_t *p = (volatile uint64_t *)base;
+    for (size_t i = 0; i < (length * 2) / sizeof(uint64_t); i += (64 / 
sizeof(uint64_t))) {
+        (void)p[i];
+    }
+    asm volatile ("fence r, r" ::: "memory");
+}
 #elif defined (__aarch64__)
 static void aarch64_flush_callback(volatile void *base, size_t length) {
     clean_dcache_poc((uintptr_t)base, (uintptr_t)base + length);
@@ -847,6 +854,8 @@
 #if defined (__riscv)
         if (riscv_check_isa_extension("zicbom", NULL, NULL)) {
             flanterm_fb_set_flush_callback(term, riscv_flush_callback);
+        } else {
+            flanterm_fb_set_flush_callback(term, 
riscv_flush_callback_nozicbom);
         }
 #elif defined (__aarch64__)
         flanterm_fb_set_flush_callback(term, aarch64_flush_callback);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/limine-10.6.3/common/lib/part.s2.c 
new/limine-10.6.6/common/lib/part.s2.c
--- old/limine-10.6.3/common/lib/part.s2.c      2026-01-14 19:04:20.000000000 
+0100
+++ new/limine-10.6.6/common/lib/part.s2.c      2026-02-05 13:39:03.000000000 
+0100
@@ -44,25 +44,27 @@
         return false;
     }
 
-    for (;;) {
-        int ret = disk_read_sectors(volume, volume->cache,
-                           read_sector,
-                           xfer_size);
-
-        switch (ret) {
-            case DISK_NO_MEDIA:
-                return false;
-            case DISK_SUCCESS:
-                goto disk_success;
+    // Clamp xfer_size to remaining sectors in volume
+    if (volume->sect_count != (uint64_t)-1) {
+        uint64_t volume_sectors = volume->sect_count / (volume->sector_size / 
512);
+        uint64_t end_sector;
+        if (__builtin_add_overflow(first_sect, volume_sectors, &end_sector)) {
+            end_sector = UINT64_MAX;
         }
-
-        xfer_size--;
-        if (xfer_size == 0) {
+        if (read_sector >= end_sector) {
             return false;
         }
+        uint64_t remaining = end_sector - read_sector;
+        if (xfer_size > remaining) {
+            xfer_size = remaining;
+        }
+    }
+
+    int ret = disk_read_sectors(volume, volume->cache, read_sector, xfer_size);
+    if (ret != DISK_SUCCESS) {
+        return false;
     }
 
-disk_success:
     volume->cache_status = CACHE_READY;
     volume->cached_block = block;
 
@@ -75,8 +77,9 @@
     }
 
     if (volume->sect_count != (uint64_t)-1) {
+        // sect_count is always in 512-byte sectors for both whole disks and 
partitions
         uint64_t part_size;
-        if (__builtin_mul_overflow(volume->sect_count, volume->sector_size, 
&part_size)) {
+        if (__builtin_mul_overflow(volume->sect_count, (uint64_t)512, 
&part_size)) {
             return false;
         }
         if (loc >= part_size || count > part_size - loc) {
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/limine-10.6.3/configure new/limine-10.6.6/configure
--- old/limine-10.6.3/configure 2026-01-14 19:04:25.000000000 +0100
+++ new/limine-10.6.6/configure 2026-02-05 13:39:09.000000000 +0100
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.72 for Limine 10.6.3.
+# Generated by GNU Autoconf 2.72 for Limine 10.6.6.
 #
 # Report bugs to <https://codeberg.org/Limine/Limine/issues>.
 #
@@ -604,8 +604,8 @@
 # Identity of this package.
 PACKAGE_NAME='Limine'
 PACKAGE_TARNAME='limine'
-PACKAGE_VERSION='10.6.3'
-PACKAGE_STRING='Limine 10.6.3'
+PACKAGE_VERSION='10.6.6'
+PACKAGE_STRING='Limine 10.6.6'
 PACKAGE_BUGREPORT='https://codeberg.org/Limine/Limine/issues'
 PACKAGE_URL='https://limine-bootloader.org/'
 
@@ -1324,7 +1324,7 @@
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-'configure' configures Limine 10.6.3 to adapt to many kinds of systems.
+'configure' configures Limine 10.6.6 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1390,7 +1390,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of Limine 10.6.3:";;
+     short | recursive ) echo "Configuration of Limine 10.6.6:";;
    esac
   cat <<\_ACEOF
 
@@ -1509,7 +1509,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-Limine configure 10.6.3
+Limine configure 10.6.6
 generated by GNU Autoconf 2.72
 
 Copyright (C) 2023 Free Software Foundation, Inc.
@@ -1621,7 +1621,7 @@
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by Limine $as_me 10.6.3, which was
+It was created by Limine $as_me 10.6.6, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -6334,7 +6334,7 @@
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by Limine $as_me 10.6.3, which was
+This file was extended by Limine $as_me 10.6.6, which was
 generated by GNU Autoconf 2.72.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -6390,7 +6390,7 @@
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 ac_cs_config='$ac_cs_config_escaped'
 ac_cs_version="\\
-Limine config.status 10.6.3
+Limine config.status 10.6.6
 configured by $0, generated by GNU Autoconf 2.72,
   with options \\"\$ac_cs_config\\"
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/limine-10.6.3/timestamps new/limine-10.6.6/timestamps
--- old/limine-10.6.3/timestamps        2026-01-14 19:04:22.000000000 +0100
+++ new/limine-10.6.6/timestamps        2026-02-05 13:39:05.000000000 +0100
@@ -1,3 +1,3 @@
-REGEN_DATE="January 2026"
-SOURCE_DATE_EPOCH="1768412449"
-SOURCE_DATE_EPOCH_TOUCH="202601141840"
+REGEN_DATE="February 2026"
+SOURCE_DATE_EPOCH="1770294498"
+SOURCE_DATE_EPOCH_TOUCH="202602051328"
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/limine-10.6.3/version new/limine-10.6.6/version
--- old/limine-10.6.3/version   2026-01-14 19:04:25.000000000 +0100
+++ new/limine-10.6.6/version   2026-02-05 13:39:09.000000000 +0100
@@ -1 +1 @@
-10.6.3
+10.6.6

Reply via email to