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