loader: r316585 did miss sparc/ofw

This update does add the code to pass partition size to vdev_probe() via
simple callback. Tested via tinderbox build, but not yet with actual boot.
The code can be improved still, but to verify the idea to read media
block size and amedia size has to be confirmed first.

Reviewed by:	imp
Differential Revision:	https://reviews.freebsd.org/D10302
This commit is contained in:
Toomas Soome 2017-04-10 17:57:56 +00:00
parent a4834289d6
commit d02973d5d3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=316682
4 changed files with 86 additions and 13 deletions

View File

@ -37,6 +37,7 @@ __FBSDID("$FreeBSD$");
#include <machine/stdarg.h>
#include <stand.h>
#include <sys/disk.h>
#include "bootstrap.h"
#include "libofw.h"
@ -154,11 +155,26 @@ ofwd_close(struct open_file *f)
}
static int
ofwd_ioctl(struct open_file *f __unused, u_long cmd __unused,
void *data __unused)
ofwd_ioctl(struct open_file *f, u_long cmd, void *data)
{
struct ofw_devdesc *dev = f->f_devdata;
int block_size;
unsigned int n;
return (EINVAL);
switch (cmd) {
case DIOCGSECTORSIZE:
block_size = OF_block_size(dev->d_handle);
*(u_int *)data = block_size;
break;
case DIOCGMEDIASIZE:
block_size = OF_block_size(dev->d_handle);
n = OF_blocks(dev->d_handle);
*(uint64_t *)data = (uint64_t)(n * block_size);
break;
default:
return (ENOTTY);
}
return (0);
}
static int

View File

@ -622,6 +622,53 @@ OF_seek(ihandle_t instance, u_int64_t pos)
return (args.status);
}
/* Blocks. */
unsigned int
OF_blocks(ihandle_t instance)
{
static struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
cell_t instance;
cell_t result;
cell_t blocks;
} args = {
(cell_t)"#blocks",
2,
1,
};
args.instance = instance;
if (openfirmware(&args) == -1)
return ((unsigned int)-1);
return (args.blocks);
}
/* Block size. */
int
OF_block_size(ihandle_t instance)
{
static struct {
cell_t name;
cell_t nargs;
cell_t nreturns;
cell_t instance;
cell_t result;
cell_t size;
} args = {
(cell_t)"block-size",
2,
1,
};
args.instance = instance;
if (openfirmware(&args) == -1)
return (512);
return (args.size);
}
/*
/*
* Memory functions
*/

View File

@ -105,6 +105,8 @@ void OF_close(ihandle_t);
int OF_read(ihandle_t, void *, int);
int OF_write(ihandle_t, void *, int);
int OF_seek(ihandle_t, u_quad_t);
unsigned int OF_blocks(ihandle_t);
int OF_block_size(ihandle_t);
/* Memory functions */
void *OF_claim(void *, u_int, u_int);

View File

@ -735,6 +735,16 @@ tlb_init_sun4u(void)
}
#ifdef LOADER_ZFS_SUPPORT
/* Set by sparc64_zfs_probe to provide partition size. */
static size_t part_size;
uint64_t
ldi_get_size(void *priv __unused)
{
return ((uint64_t)part_size);
}
static void
sparc64_zfs_probe(void)
{
@ -742,13 +752,11 @@ sparc64_zfs_probe(void)
char alias[64], devname[sizeof(alias) + sizeof(":x") - 1];
char type[sizeof("device_type")];
char *bdev, *dev, *odev;
uint64_t guid;
uint64_t guid, *guidp;
int fd, len, part;
phandle_t aliases, options;
/* Get the GUID of the ZFS pool on the boot device. */
guid = 0;
zfs_probe_dev(bootpath, &guid);
/*
* Get the GUIDs of the ZFS pools on any additional disks listed in
@ -771,12 +779,6 @@ sparc64_zfs_probe(void)
continue;
strcpy(alias, dev);
(void)OF_getprop(aliases, dev, alias, sizeof(alias));
/*
* Don't probe the boot disk twice. Note that bootpath
* includes the partition specifier.
*/
if (strncmp(alias, bootpath, strlen(alias)) == 0)
continue;
if (OF_getprop(OF_finddevice(alias), "device_type", type,
sizeof(type)) == -1)
continue;
@ -798,8 +800,14 @@ sparc64_zfs_probe(void)
if (part == 2 || vtoc.part[part].tag !=
VTOC_TAG_FREEBSD_ZFS)
continue;
part_size = vtoc.map[part].nblks;
(void)sprintf(devname, "%s:%c", alias, part + 'a');
if (zfs_probe_dev(devname, NULL) == ENXIO)
/* Get the GUID of the ZFS pool on the boot device. */
if (strcmp(devname, bootpath) == 0)
guidp = &guid;
else
guidp = NULL;
if (zfs_probe_dev(devname, guidp) == ENXIO)
break;
}
}