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/param.h>
18
19 #include <btxv86.h>
20
21 #include "stand.h"
22 #include "rbx.h"
23 #include "drv.h"
24 #include "edd.h"
25
26 static struct edd_params params;
27
28 uint64_t
drvsize(struct dsk * dskp)29 drvsize(struct dsk *dskp)
30 {
31
32 params.len = sizeof(struct edd_params);
33 v86.ctl = V86_FLAGS;
34 v86.addr = 0x13;
35 v86.eax = 0x4800;
36 v86.edx = dskp->drive;
37 v86.ds = VTOPSEG(¶ms);
38 v86.esi = VTOPOFF(¶ms);
39 v86int();
40 if (V86_CY(v86.efl)) {
41 printf("error %u\n", v86.eax >> 8 & 0xff);
42 return (0);
43 }
44 return (params.sectors);
45 }
46
47 static struct edd_packet packet;
48
49 int
drvread(struct dsk * dskp,void * buf,daddr_t lba,unsigned nblk)50 drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
51 {
52 static unsigned c = 0x2d5c7c2f;
53
54 if (!OPT_CHECK(RBX_QUIET))
55 printf("%c\b", c = c << 8 | c >> 24);
56 packet.len = sizeof(struct edd_packet);
57 packet.count = nblk;
58 packet.off = VTOPOFF(buf);
59 packet.seg = VTOPSEG(buf);
60 packet.lba = lba;
61 v86.ctl = V86_FLAGS;
62 v86.addr = 0x13;
63 v86.eax = 0x4200;
64 v86.edx = dskp->drive;
65 v86.ds = VTOPSEG(&packet);
66 v86.esi = VTOPOFF(&packet);
67 v86int();
68 if (V86_CY(v86.efl)) {
69 printf("%s: error %u lba %llu\n",
70 BOOTPROG, v86.eax >> 8 & 0xff, lba);
71 return (-1);
72 }
73 return (0);
74 }
75
76 #if defined(GPT) || defined(ZFS)
77 int
drvwrite(struct dsk * dskp,void * buf,daddr_t lba,unsigned nblk)78 drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
79 {
80
81 packet.len = sizeof(struct edd_packet);
82 packet.count = nblk;
83 packet.off = VTOPOFF(buf);
84 packet.seg = VTOPSEG(buf);
85 packet.lba = lba;
86 v86.ctl = V86_FLAGS;
87 v86.addr = 0x13;
88 v86.eax = 0x4300;
89 v86.edx = dskp->drive;
90 v86.ds = VTOPSEG(&packet);
91 v86.esi = VTOPOFF(&packet);
92 v86int();
93 if (V86_CY(v86.efl)) {
94 printf("error %u lba %llu\n", v86.eax >> 8 & 0xff, lba);
95 return (-1);
96 }
97 return (0);
98 }
99 #endif /* GPT || ZFS */
100