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