2 * Copyright (c) 1998 Robert Nordier
4 * Copyright (c) 2001 Robert Drehmel
6 * Copyright (c) 2014 Nathan Whitehorn
8 * Copyright (c) 2015 Eric McCorkle
11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions
14 * 1. Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * 2. Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
20 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
21 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 * $FreeBSD: head/sys/boot/efi/boot1/ufs_module.c 295320 2016-02-05 15:35:33Z smh $
37 #include <sys/cdefs.h>
38 #include <sys/param.h>
39 #include <sys/disklabel64.h>
40 #include <sys/dtype.h>
43 #include "boot_module.h"
45 static dev_info_t
*devinfo
;
46 static dev_info_t
*devices
;
47 static u_int64_t label_off
;
50 dskread(void *buf
, u_int64_t lba
, int nblk
)
55 lba
+= label_off
/ DEV_BSIZE
; /* adjust for disklabel partition */
56 lba
= lba
/ (devinfo
->dev
->Media
->BlockSize
/ DEV_BSIZE
);
57 size
= nblk
* DEV_BSIZE
;
59 status
= devinfo
->dev
->ReadBlocks(devinfo
->dev
,
60 devinfo
->dev
->Media
->MediaId
, lba
, size
, buf
);
62 if (status
!= EFI_SUCCESS
) {
63 DPRINTF("dskread: failed dev: %p, id: %u, lba: %lu, size: %d, "
64 "status: %llu\n", devinfo
->dev
,
65 devinfo
->dev
->Media
->MediaId
, lba
, size
,
77 static struct ufs_dmadat __dmadat
;
78 static struct ufs_dmadat
*boot2_dmadat
;
82 #define fsread boot2_ufs_read
83 #define fsread_size boot2_ufs_read_size
84 #define lookup boot2_ufs_lookup
87 init_dev(dev_info_t
* dev
)
90 boot2_dmadat
= &__dmadat
;
91 struct disklabel64
*label
;
95 label_size
= (sizeof(*label
) + 2047) & ~(size_t)2047;
98 status
= bs
->AllocatePool(EfiLoaderData
, label_size
, (void **)&label
);
99 if (status
== EFI_SUCCESS
) {
100 if (dskread(label
, 0, label_size
/ DEV_BSIZE
) == 0 &&
101 label
->d_magic
== DISKMAGIC64
&&
102 label
->d_npartitions
> 0 &&
103 label
->d_partitions
[0].p_fstype
== FS_BSDFFS
) {
104 label_off
= label
->d_partitions
[0].p_boffset
;
108 return fsread(0, NULL
, 0);
112 probe(dev_info_t
* dev
)
115 if (init_dev(dev
) < 0)
116 return (EFI_UNSUPPORTED
);
118 add_device(&devices
, dev
);
120 return (EFI_SUCCESS
);
124 load(const char *filepath
, dev_info_t
*dev
, void **bufp
, size_t *bufsize
)
132 DPRINTF("Loading '%s' from %s\n", filepath
, devpath_str(dev
->devpath
));
134 if (init_dev(dev
) < 0) {
135 DPRINTF("Failed to init device\n");
136 return (EFI_UNSUPPORTED
);
139 if ((ino
= lookup(filepath
)) == 0) {
140 DPRINTF("Failed to lookup '%s' (file not found?)\n", filepath
);
141 return (EFI_NOT_FOUND
);
144 if (fsread_size(ino
, NULL
, 0, &size
) < 0 || size
<= 0) {
145 printf("Failed to read size of '%s' ino: %d\n", filepath
, ino
);
146 return (EFI_INVALID_PARAMETER
);
149 if ((status
= bs
->AllocatePool(EfiLoaderData
, size
, &buf
)) !=
151 printf("Failed to allocate read buffer %zu for '%s' (%llu)\n",
152 size
, filepath
, status
);
156 read
= fsread(ino
, buf
, size
);
157 if ((size_t)read
!= size
) {
158 printf("Failed to read '%s' (%zd != %zu)\n", filepath
, read
,
160 (void)bs
->FreePool(buf
);
161 return (EFI_INVALID_PARAMETER
);
164 DPRINTF("Load complete\n");
169 return (EFI_SUCCESS
);
178 for (dev
= devices
, i
= 0; dev
!= NULL
; dev
= dev
->next
, i
++)
181 printf("%s found ", ufs_module
.name
);
184 printf("no partitions\n");
187 printf("%d partition\n", i
);
190 printf("%d partitions\n", i
);
201 const boot_module_t ufs_module
=