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