From: kettenis Date: Wed, 2 Jun 2021 15:31:15 +0000 (+0000) Subject: Add support for booting from disks with 4k sectors. Inspired by the X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=d85b3a350bffdcf64883382092be32adc5fdc528;p=openbsd Add support for booting from disks with 4k sectors. Inspired by the code we already have for amd64, but changed to use EFI memory allocation interfaces as some implementations seem to insist on page-aligned memory. ok krw@ --- diff --git a/sys/arch/arm64/stand/efiboot/conf.c b/sys/arch/arm64/stand/efiboot/conf.c index f54f7916456..e9e62adf243 100644 --- a/sys/arch/arm64/stand/efiboot/conf.c +++ b/sys/arch/arm64/stand/efiboot/conf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: conf.c,v 1.32 2021/02/09 23:58:33 kettenis Exp $ */ +/* $OpenBSD: conf.c,v 1.33 2021/06/02 15:31:15 kettenis Exp $ */ /* * Copyright (c) 1996 Michael Shalayeff @@ -46,7 +46,7 @@ #include "efipxe.h" #include "softraid_arm64.h" -const char version[] = "1.4"; +const char version[] = "1.5"; int debug = 0; struct fs_ops file_system[] = { diff --git a/sys/arch/arm64/stand/efiboot/efidev.c b/sys/arch/arm64/stand/efiboot/efidev.c index b79d6bac071..a877173afe4 100644 --- a/sys/arch/arm64/stand/efiboot/efidev.c +++ b/sys/arch/arm64/stand/efiboot/efidev.c @@ -1,4 +1,4 @@ -/* $OpenBSD: efidev.c,v 1.6 2020/12/09 18:10:18 krw Exp $ */ +/* $OpenBSD: efidev.c,v 1.7 2021/06/02 15:31:15 kettenis Exp $ */ /* * Copyright (c) 2015 YASUOKA Masahiko @@ -75,15 +75,24 @@ efid_init(struct diskinfo *dip, void *handle) static EFI_STATUS efid_io(int rw, efi_diskinfo_t ed, u_int off, int nsect, void *buf) { - EFI_STATUS status = EFI_SUCCESS; + u_int blks, start, end; EFI_PHYSICAL_ADDRESS addr; + EFI_STATUS status; caddr_t data; + size_t size; - if (ed->blkio->Media->BlockSize != DEV_BSIZE) + /* block count of the intrisic block size in DEV_BSIZE */ + blks = EFI_BLKSPERSEC(ed); + if (blks == 0) + /* block size < 512. HP Stream 13 actually has such a disk. */ return (EFI_UNSUPPORTED); - status = BS->AllocatePages(AllocateAnyPages, EfiLoaderData, - EFI_SIZE_TO_PAGES(nsect * DEV_BSIZE), &addr); + start = off / blks; + end = (off + nsect + blks - 1) / blks; + size = (end - start) * ed->blkio->Media->BlockSize; + + status = EFI_CALL(BS->AllocatePages, AllocateAnyPages, EfiLoaderData, + EFI_SIZE_TO_PAGES(size), &addr); if (EFI_ERROR(status)) goto on_eio; data = (caddr_t)(uintptr_t)addr; @@ -91,27 +100,32 @@ efid_io(int rw, efi_diskinfo_t ed, u_int off, int nsect, void *buf) switch (rw) { case F_READ: status = EFI_CALL(ed->blkio->ReadBlocks, - ed->blkio, ed->mediaid, off, - nsect * DEV_BSIZE, data); + ed->blkio, ed->mediaid, start, size, data); if (EFI_ERROR(status)) goto on_eio; - memcpy(buf, data, nsect * DEV_BSIZE); + memcpy(buf, data + DEV_BSIZE * (off - start * blks), + DEV_BSIZE * nsect); break; case F_WRITE: if (ed->blkio->Media->ReadOnly) goto on_eio; - memcpy(data, buf, nsect * DEV_BSIZE); + if (off % blks != 0 || nsect % blks != 0) { + status = EFI_CALL(ed->blkio->ReadBlocks, + ed->blkio, ed->mediaid, start, size, data); + if (EFI_ERROR(status)) + goto on_eio; + } + memcpy(data + DEV_BSIZE * (off - start * blks), buf, + DEV_BSIZE * nsect); status = EFI_CALL(ed->blkio->WriteBlocks, - ed->blkio, ed->mediaid, off, - nsect * DEV_BSIZE, data); + ed->blkio, ed->mediaid, start, size, data); if (EFI_ERROR(status)) goto on_eio; break; } - return (EFI_SUCCESS); on_eio: - BS->FreePages(addr, EFI_SIZE_TO_PAGES(nsect * DEV_BSIZE)); + EFI_CALL(BS->FreePages, addr, EFI_SIZE_TO_PAGES(size)); return (status); }