drv.c revision 308915
1/*- 2 * Copyright (c) 1998 Robert Nordier 3 * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 4 * All rights reserved. 5 * 6 * Redistribution and use in source and binary forms are freely 7 * permitted provided that the above copyright notice and this 8 * paragraph and the following disclaimer are duplicated in all 9 * such forms. 10 * 11 * This software is provided "AS IS" and without any express or 12 * implied warranties, including, without limitation, the implied 13 * warranties of merchantability and fitness for a particular 14 * purpose. 15 */ 16 17#include <sys/cdefs.h> 18__FBSDID("$FreeBSD: stable/10/sys/boot/i386/common/drv.c 308915 2016-11-21 10:14:36Z avg $"); 19 20#include <sys/param.h> 21 22#include <btxv86.h> 23 24#include "rbx.h" 25#include "util.h" 26#include "drv.h" 27#include "edd.h" 28#ifdef USE_XREAD 29#include "xreadorg.h" 30#endif 31 32#ifdef GPT 33static struct edd_params params; 34 35uint64_t 36drvsize(struct dsk *dskp) 37{ 38 39 params.len = sizeof(struct edd_params); 40 v86.ctl = V86_FLAGS; 41 v86.addr = 0x13; 42 v86.eax = 0x4800; 43 v86.edx = dskp->drive; 44 v86.ds = VTOPSEG(¶ms); 45 v86.esi = VTOPOFF(¶ms); 46 v86int(); 47 if (V86_CY(v86.efl)) { 48 printf("error %u\n", v86.eax >> 8 & 0xff); 49 return (0); 50 } 51 return (params.sectors); 52} 53#endif /* GPT */ 54 55#ifndef USE_XREAD 56static struct edd_packet packet; 57#endif 58 59int 60drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) 61{ 62 static unsigned c = 0x2d5c7c2f; 63 64 if (!OPT_CHECK(RBX_QUIET)) 65 printf("%c\b", c = c << 8 | c >> 24); 66#ifndef USE_XREAD 67 packet.len = sizeof(struct edd_packet); 68 packet.count = nblk; 69 packet.off = VTOPOFF(buf); 70 packet.seg = VTOPSEG(buf); 71 packet.lba = lba; 72 v86.ctl = V86_FLAGS; 73 v86.addr = 0x13; 74 v86.eax = 0x4200; 75 v86.edx = dskp->drive; 76 v86.ds = VTOPSEG(&packet); 77 v86.esi = VTOPOFF(&packet); 78#else /* USE_XREAD */ 79 v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; 80 v86.addr = XREADORG; /* call to xread in boot1 */ 81 v86.es = VTOPSEG(buf); 82 v86.eax = lba; 83 v86.ebx = VTOPOFF(buf); 84 v86.ecx = lba >> 32; 85 v86.edx = nblk << 8 | dskp->drive; 86#endif /* USE_XREAD */ 87 v86int(); 88 if (V86_CY(v86.efl)) { 89 printf("%s: error %u lba %u\n", 90 BOOTPROG, v86.eax >> 8 & 0xff, lba); 91 return (-1); 92 } 93 return (0); 94} 95 96#if defined(GPT) || defined(ZFS) 97int 98drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) 99{ 100 101 packet.len = sizeof(struct edd_packet); 102 packet.count = nblk; 103 packet.off = VTOPOFF(buf); 104 packet.seg = VTOPSEG(buf); 105 packet.lba = lba; 106 v86.ctl = V86_FLAGS; 107 v86.addr = 0x13; 108 v86.eax = 0x4300; 109 v86.edx = dskp->drive; 110 v86.ds = VTOPSEG(&packet); 111 v86.esi = VTOPOFF(&packet); 112 v86int(); 113 if (V86_CY(v86.efl)) { 114 printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba); 115 return (-1); 116 } 117 return (0); 118} 119#endif /* GPT || ZFS */ 120