freebsd-skq/stand/i386/common/drv.c
Warner Losh 6562843997 Remove the 'mini libstand in libstand' that util.[ch] provided. These
weren't needed, and their existance interfered with things in subtle
ways. One of these subtle ways was that malloc could be different
based on what files were included when (even within the same .c file,
it turns out). Move to a single malloc implementation as well by
adding the calls to setheap() to gptboot.c and zfsboot.c. Once upon a
time, these boot loaders strove to not use libstand. However, with the
proliferation of features, that striving is too hard for too little
gain and lead to stupid mistakes.

This fixes the GELI-enabled (but not even using) boot environment. The
geli routines were calling libstand malloc but zfsboot.c and gptboot.c
were using the mini libstand malloc, so this failed when we tried to
probe for GELI partitions. Subtle changes in build order when moving
to self-contained stand build in r326593 toggled what it used from one
type to another due to odd nesting of the zfs implementation code that
differed subtly between zfsloader and zfsboot.

Sponsored by: Netflix
2017-12-15 23:16:53 +00:00

103 lines
2.2 KiB
C

/*-
* Copyright (c) 1998 Robert Nordier
* Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
* All rights reserved.
*
* Redistribution and use in source and binary forms are freely
* permitted provided that the above copyright notice and this
* paragraph and the following disclaimer are duplicated in all
* such forms.
*
* This software is provided "AS IS" and without any express or
* implied warranties, including, without limitation, the implied
* warranties of merchantability and fitness for a particular
* purpose.
*/
#include <sys/cdefs.h>
__FBSDID("$FreeBSD$");
#include <sys/param.h>
#include <btxv86.h>
#include "stand.h"
#include "rbx.h"
#include "drv.h"
#include "edd.h"
static struct edd_params params;
uint64_t
drvsize(struct dsk *dskp)
{
params.len = sizeof(struct edd_params);
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
v86.eax = 0x4800;
v86.edx = dskp->drive;
v86.ds = VTOPSEG(&params);
v86.esi = VTOPOFF(&params);
v86int();
if (V86_CY(v86.efl)) {
printf("error %u\n", v86.eax >> 8 & 0xff);
return (0);
}
return (params.sectors);
}
static struct edd_packet packet;
int
drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
{
static unsigned c = 0x2d5c7c2f;
if (!OPT_CHECK(RBX_QUIET))
printf("%c\b", c = c << 8 | c >> 24);
packet.len = sizeof(struct edd_packet);
packet.count = nblk;
packet.off = VTOPOFF(buf);
packet.seg = VTOPSEG(buf);
packet.lba = lba;
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
v86.eax = 0x4200;
v86.edx = dskp->drive;
v86.ds = VTOPSEG(&packet);
v86.esi = VTOPOFF(&packet);
v86int();
if (V86_CY(v86.efl)) {
printf("%s: error %u lba %llu\n",
BOOTPROG, v86.eax >> 8 & 0xff, lba);
return (-1);
}
return (0);
}
#if defined(GPT) || defined(ZFS)
int
drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
{
packet.len = sizeof(struct edd_packet);
packet.count = nblk;
packet.off = VTOPOFF(buf);
packet.seg = VTOPSEG(buf);
packet.lba = lba;
v86.ctl = V86_FLAGS;
v86.addr = 0x13;
v86.eax = 0x4300;
v86.edx = dskp->drive;
v86.ds = VTOPSEG(&packet);
v86.esi = VTOPOFF(&packet);
v86int();
if (V86_CY(v86.efl)) {
printf("error %u lba %llu\n", v86.eax >> 8 & 0xff, lba);
return (-1);
}
return (0);
}
#endif /* GPT || ZFS */