summaryrefslogtreecommitdiff
path: root/stand/uboot
diff options
context:
space:
mode:
authorIan Lepore <ian@FreeBSD.org>2019-02-18 04:44:52 +0000
committerIan Lepore <ian@FreeBSD.org>2019-02-18 04:44:52 +0000
commit5a75fc4b11cb31ff90e0f4a93292861e26320ab3 (patch)
tree02dd88752b8b6d62f3d0366605cb52d30cc43aa4 /stand/uboot
parentc0347e182cc23853aaca05004d2da9b4d7e47e4a (diff)
downloadsrc-test-5a75fc4b11cb31ff90e0f4a93292861e26320ab3.tar.gz
src-test-5a75fc4b11cb31ff90e0f4a93292861e26320ab3.zip
Make uboot_devdesc properly alias disk_devdesc, so that parsing the u-boot
loaderdev variable works correctly. The uboot_devdesc struct is variously cast back and forth between uboot_devdesc and disk_devdesc as pointers are handed off through various opaque interfaces. uboot_devdesc attempted to mimic the layout of disk_devdesc by having a devdesc struct, followed by a union of some device-specific stuff that included a struct that contains the same fields as a disk_devdesc. However, one of those fields inside the struct is 64-bit which causes the entire union to be 64-bit aligned -- 32 bits of padding is added between the struct devdesc and the union, so the whole mess ends up NOT properly mimicking a disk_devdesc after all. (In disk_devdesc there is also 32 bits of padding, but it shows up immediately before the d_offset field, rather than before the whole collection of d_* fields.) This fixes the problem by using an anonymous union to overlay the devdesc field uboot network devices need with the disk_devdesc that uboot storage devices need. This is a different solution than the one contributed with the PR (so if anything goes wrong, the blame goes to me), but 95% of the credit for this fix goes to Pawel Worach and Manuel Stuhn who analyzed the problem and proposed a fix. PR: 233097
Notes
Notes: svn path=/head/; revision=344247
Diffstat (limited to 'stand/uboot')
-rw-r--r--stand/uboot/common/main.c12
-rw-r--r--stand/uboot/lib/libuboot.h14
2 files changed, 11 insertions, 15 deletions
diff --git a/stand/uboot/common/main.c b/stand/uboot/common/main.c
index 50a12cd425fb0..b1534b00d2683 100644
--- a/stand/uboot/common/main.c
+++ b/stand/uboot/common/main.c
@@ -310,13 +310,13 @@ print_disk_probe_info()
char slice[32];
char partition[32];
- if (currdev.d_disk.slice > 0)
- sprintf(slice, "%d", currdev.d_disk.slice);
+ if (currdev.d_disk.d_slice > 0)
+ sprintf(slice, "%d", currdev.d_disk.d_slice);
else
strcpy(slice, "<auto>");
- if (currdev.d_disk.partition >= 0)
- sprintf(partition, "%d", currdev.d_disk.partition);
+ if (currdev.d_disk.d_partition >= 0)
+ sprintf(partition, "%d", currdev.d_disk.d_partition);
else
strcpy(partition, "<auto>");
@@ -332,8 +332,8 @@ probe_disks(int devidx, int load_type, int load_unit, int load_slice,
int open_result, unit;
struct open_file f;
- currdev.d_disk.slice = load_slice;
- currdev.d_disk.partition = load_partition;
+ currdev.d_disk.d_slice = load_slice;
+ currdev.d_disk.d_partition = load_partition;
f.f_devdata = &currdev;
open_result = -1;
diff --git a/stand/uboot/lib/libuboot.h b/stand/uboot/lib/libuboot.h
index 8b81486b1fae9..59438e711a652 100644
--- a/stand/uboot/lib/libuboot.h
+++ b/stand/uboot/lib/libuboot.h
@@ -27,19 +27,15 @@
* $FreeBSD$
*/
+#include <disk.h>
+
struct uboot_devdesc {
- struct devdesc dd; /* Must be first. */
union {
- struct {
- int slice;
- int partition;
- off_t offset;
- } disk;
- } d_kind;
+ struct devdesc dd;
+ struct disk_devdesc d_disk;
+ };
};
-#define d_disk d_kind.disk
-
/*
* Default network packet alignment in memory. On arm arches packets must be
* aligned to cacheline boundaries.