1213136Spjd/*- 2213136Spjd * Copyright (c) 1998 Robert Nordier 3213136Spjd * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org> 4213136Spjd * All rights reserved. 5213136Spjd * 6213136Spjd * Redistribution and use in source and binary forms are freely 7213136Spjd * permitted provided that the above copyright notice and this 8213136Spjd * paragraph and the following disclaimer are duplicated in all 9213136Spjd * such forms. 10213136Spjd * 11213136Spjd * This software is provided "AS IS" and without any express or 12213136Spjd * implied warranties, including, without limitation, the implied 13213136Spjd * warranties of merchantability and fitness for a particular 14213136Spjd * purpose. 15213136Spjd */ 16213136Spjd 17213136Spjd#include <sys/cdefs.h> 18213136Spjd__FBSDID("$FreeBSD: releng/10.3/sys/boot/i386/common/drv.c 226748 2011-10-25 19:54:06Z jhb $"); 19213136Spjd 20213136Spjd#include <sys/param.h> 21213136Spjd 22213136Spjd#include <btxv86.h> 23213136Spjd 24213136Spjd#include "rbx.h" 25213136Spjd#include "util.h" 26213136Spjd#include "drv.h" 27226748Sjhb#include "edd.h" 28221177Sjhb#ifdef USE_XREAD 29213136Spjd#include "xreadorg.h" 30213136Spjd#endif 31213136Spjd 32213136Spjd#ifdef GPT 33226748Sjhbstatic struct edd_params params; 34226748Sjhb 35213136Spjduint64_t 36213136Spjddrvsize(struct dsk *dskp) 37213136Spjd{ 38213136Spjd 39226748Sjhb params.len = sizeof(struct edd_params); 40213136Spjd v86.ctl = V86_FLAGS; 41213136Spjd v86.addr = 0x13; 42213136Spjd v86.eax = 0x4800; 43213136Spjd v86.edx = dskp->drive; 44226748Sjhb v86.ds = VTOPSEG(¶ms); 45226748Sjhb v86.esi = VTOPOFF(¶ms); 46213136Spjd v86int(); 47213136Spjd if (V86_CY(v86.efl)) { 48213136Spjd printf("error %u\n", v86.eax >> 8 & 0xff); 49213136Spjd return (0); 50213136Spjd } 51226748Sjhb return (params.sectors); 52213136Spjd} 53213136Spjd#endif /* GPT */ 54213136Spjd 55221177Sjhb#ifndef USE_XREAD 56226748Sjhbstatic struct edd_packet packet; 57221177Sjhb#endif 58213136Spjd 59213136Spjdint 60213136Spjddrvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) 61213136Spjd{ 62213136Spjd static unsigned c = 0x2d5c7c2f; 63213136Spjd 64213136Spjd if (!OPT_CHECK(RBX_QUIET)) 65213136Spjd printf("%c\b", c = c << 8 | c >> 24); 66221177Sjhb#ifndef USE_XREAD 67226748Sjhb packet.len = sizeof(struct edd_packet); 68213136Spjd packet.count = nblk; 69213136Spjd packet.off = VTOPOFF(buf); 70213136Spjd packet.seg = VTOPSEG(buf); 71213136Spjd packet.lba = lba; 72213136Spjd v86.ctl = V86_FLAGS; 73213136Spjd v86.addr = 0x13; 74213136Spjd v86.eax = 0x4200; 75213136Spjd v86.edx = dskp->drive; 76213136Spjd v86.ds = VTOPSEG(&packet); 77213136Spjd v86.esi = VTOPOFF(&packet); 78221177Sjhb#else /* USE_XREAD */ 79213136Spjd v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; 80213136Spjd v86.addr = XREADORG; /* call to xread in boot1 */ 81213136Spjd v86.es = VTOPSEG(buf); 82213136Spjd v86.eax = lba; 83213136Spjd v86.ebx = VTOPOFF(buf); 84213136Spjd v86.ecx = lba >> 32; 85213136Spjd v86.edx = nblk << 8 | dskp->drive; 86221177Sjhb#endif /* USE_XREAD */ 87213136Spjd v86int(); 88213136Spjd if (V86_CY(v86.efl)) { 89213136Spjd printf("%s: error %u lba %u\n", 90213136Spjd BOOTPROG, v86.eax >> 8 & 0xff, lba); 91213136Spjd return (-1); 92213136Spjd } 93213136Spjd return (0); 94213136Spjd} 95213136Spjd 96213136Spjd#ifdef GPT 97213136Spjdint 98213136Spjddrvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk) 99213136Spjd{ 100213136Spjd 101226748Sjhb packet.len = sizeof(struct edd_packet); 102213136Spjd packet.count = nblk; 103213136Spjd packet.off = VTOPOFF(buf); 104213136Spjd packet.seg = VTOPSEG(buf); 105213136Spjd packet.lba = lba; 106213136Spjd v86.ctl = V86_FLAGS; 107213136Spjd v86.addr = 0x13; 108213136Spjd v86.eax = 0x4300; 109213136Spjd v86.edx = dskp->drive; 110213136Spjd v86.ds = VTOPSEG(&packet); 111213136Spjd v86.esi = VTOPOFF(&packet); 112213136Spjd v86int(); 113213136Spjd if (V86_CY(v86.efl)) { 114213136Spjd printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba); 115213136Spjd return (-1); 116213136Spjd } 117213136Spjd return (0); 118213136Spjd} 119213136Spjd#endif /* GPT */ 120