Changeset View
Changeset View
Standalone View
Standalone View
stand/efi/boot1/ufs_module.c
Show All 30 Lines | |||||
* | * | ||||
* $FreeBSD$ | * $FreeBSD$ | ||||
*/ | */ | ||||
#include <stdarg.h> | #include <stdarg.h> | ||||
#include <stdbool.h> | #include <stdbool.h> | ||||
#include <sys/cdefs.h> | #include <sys/cdefs.h> | ||||
#include <sys/param.h> | #include <sys/param.h> | ||||
#include <sys/disk/bsd.h> | |||||
#include <efi.h> | #include <efi.h> | ||||
#include "boot_module.h" | #include "boot_module.h" | ||||
#define BSD_LABEL_BUFFER 8192 | |||||
#define BSD_LABEL_OFFSET DEV_BSIZE | |||||
static dev_info_t *devinfo; | static dev_info_t *devinfo; | ||||
static dev_info_t *devices; | static dev_info_t *devices; | ||||
static int | static int | ||||
dskread(void *buf, uint64_t lba, int nblk) | dskread(void *buf, uint64_t lba, int nblk) | ||||
{ | { | ||||
int size; | int size; | ||||
EFI_STATUS status; | EFI_STATUS status; | ||||
lba += devinfo->partoff; | |||||
lba = lba / (devinfo->dev->Media->BlockSize / DEV_BSIZE); | lba = lba / (devinfo->dev->Media->BlockSize / DEV_BSIZE); | ||||
size = nblk * DEV_BSIZE; | size = nblk * DEV_BSIZE; | ||||
status = devinfo->dev->ReadBlocks(devinfo->dev, | status = devinfo->dev->ReadBlocks(devinfo->dev, | ||||
devinfo->dev->Media->MediaId, lba, size, buf); | devinfo->dev->Media->MediaId, lba, size, buf); | ||||
if (status != EFI_SUCCESS) { | if (status != EFI_SUCCESS) { | ||||
DPRINTF("dskread: failed dev: %p, id: %u, lba: %ju, size: %d, " | DPRINTF("dskread: failed dev: %p, id: %u, lba: %ju, size: %d, " | ||||
"status: %lu\n", devinfo->dev, | "status: %lu\n", devinfo->dev, | ||||
devinfo->dev->Media->MediaId, (uintmax_t)lba, size, | devinfo->dev->Media->MediaId, (uintmax_t)lba, size, | ||||
EFI_ERROR_CODE(status)); | EFI_ERROR_CODE(status)); | ||||
return (-1); | return (-1); | ||||
} | } | ||||
return (0); | return (0); | ||||
} | } | ||||
#include "ufsread.c" | #include "ufsread.c" | ||||
static struct dmadat __dmadat; | static struct dmadat __dmadat; | ||||
static int | static int | ||||
init_dev(dev_info_t* dev) | init_dev(dev_info_t* dev) | ||||
{ | { | ||||
char buffer[BSD_LABEL_BUFFER]; | |||||
struct disklabel *dl; | |||||
emaste: `char *buffer[]`?
also stack variable ordering | |||||
Not Done Inline ActionsDoh! Yea, right. bad. It works because sizeof(char *) > sizeof(char) imp: Doh! Yea, right. bad. It works because sizeof(char *) > sizeof(char) | |||||
Not Done Inline Actionsthese should still be reordered largest to smallest emaste: these should still be reordered largest to smallest | |||||
uint64_t bs; | |||||
int ok; | |||||
devinfo = dev; | devinfo = dev; | ||||
dmadat = &__dmadat; | dmadat = &__dmadat; | ||||
return fsread(0, NULL, 0); | /* | ||||
* First try offset 0. This is the typical GPT case where we have no | |||||
Done Inline Actionss/normal/common/ or s/normal//? emaste: `s/normal/common/` or `s/normal//`? | |||||
* further partitioning (as well as the degenerate MBR case where | |||||
* the bsdlabel has a 0 offset). | |||||
*/ | |||||
devinfo->partoff = 0; | |||||
ok = fsread(0, NULL, 0); | |||||
if (ok >= 0) | |||||
return (ok); | |||||
/* | |||||
* Next, we look for a bsdlabel. This is technically located in sector | |||||
* 1. For 4k sectors, this offset is 4096, for 512b sectors it's | |||||
Done Inline ActionsMaybe a static_assert that we're building on a little-endian system? Although hopefully we svn rm efi/boot1 before we look at EFI on say BE MIPS. emaste: Maybe a `static_assert` that we're building on a little-endian system? Although hopefully we… | |||||
Not Done Inline ActionsI don't see the point. UEFI is defined in the standard to be little endian. It's quite pervasive through everything, top to bottom. We will never have a BE UEFI thing it's so pervasive.... imp: I don't see the point. UEFI is defined in the standard to be little endian. It's quite… | |||||
Not Done Inline ActionsFair enough - this one spot is not the right place to make sure we don't try going down the UEFI path on a BE host. emaste: Fair enough - this one spot is not the right place to make sure we don't try going down the… | |||||
* 512. However, we have to fall back to 512 here because we create | |||||
* images that assume 512 byte blocks, but these can be put on devices | |||||
* who have 4k (or other) block sizes. If there's a crazy block size, we | |||||
* skip the 'at one sector' and go stright to checking at 512 bytes. | |||||
* There are other offsets that are historic, but we don't probe those | |||||
Done Inline Actionsperhaps include a || dl->d_partitions[0].p_offset == 0) case? emaste: perhaps include a `|| dl->d_partitions[0].p_offset == 0)` case? | |||||
Not Done Inline ActionsSure, it's an optimization, but likely a good one. imp: Sure, it's an optimization, but likely a good one. | |||||
* since they were never used for MBR disks on FreeBSD on systems that | |||||
Done Inline Actionsreturn style emaste: return style | |||||
* could boot UEFI. UEFI is little endian only, as are BSD labels. We | |||||
* will retry fsread(0) only if there's a label found with a non-zero | |||||
* offset. | |||||
*/ | |||||
if (dskread(buffer, 0, BSD_LABEL_BUFFER / DEV_BSIZE) != 0) | |||||
return (-1); | |||||
dl = NULL; | |||||
bs = devinfo->dev->Media->BlockSize; | |||||
if (bs != 0 && bs <= BSD_LABEL_BUFFER / 2) | |||||
dl = (struct disklabel *)&buffer[bs]; | |||||
if (dl == NULL || dl->d_magic != BSD_MAGIC || dl->d_magic2 != BSD_MAGIC) | |||||
dl = (struct disklabel *)&buffer[BSD_LABEL_OFFSET]; | |||||
if (dl->d_magic != BSD_MAGIC || dl->d_magic2 != BSD_MAGIC || | |||||
dl->d_partitions[0].p_offset == 0) | |||||
return (-1); | |||||
devinfo->partoff = dl->d_partitions[0].p_offset; | |||||
return (fsread(0, NULL, 0)); | |||||
} | } | ||||
static EFI_STATUS | static EFI_STATUS | ||||
probe(dev_info_t* dev) | probe(dev_info_t* dev) | ||||
{ | { | ||||
if (init_dev(dev) < 0) | if (init_dev(dev) < 0) | ||||
return (EFI_UNSUPPORTED); | return (EFI_UNSUPPORTED); | ||||
▲ Show 20 Lines • Show All 97 Lines • Show Last 20 Lines |
char *buffer[]?
also stack variable ordering