xref: /illumos-gate/usr/src/boot/i386/common/drv.c (revision 22028508)
164f9afd1SToomas Soome /*
2199767f8SToomas Soome  * Copyright (c) 1998 Robert Nordier
3199767f8SToomas Soome  * Copyright (c) 2010 Pawel Jakub Dawidek <pjd@FreeBSD.org>
4199767f8SToomas Soome  * All rights reserved.
5199767f8SToomas Soome  *
6199767f8SToomas Soome  * Redistribution and use in source and binary forms are freely
7199767f8SToomas Soome  * permitted provided that the above copyright notice and this
8199767f8SToomas Soome  * paragraph and the following disclaimer are duplicated in all
9199767f8SToomas Soome  * such forms.
10199767f8SToomas Soome  *
11199767f8SToomas Soome  * This software is provided "AS IS" and without any express or
12199767f8SToomas Soome  * implied warranties, including, without limitation, the implied
13199767f8SToomas Soome  * warranties of merchantability and fitness for a particular
14199767f8SToomas Soome  * purpose.
15199767f8SToomas Soome  */
16199767f8SToomas Soome 
17199767f8SToomas Soome #include <sys/cdefs.h>
18199767f8SToomas Soome 
19199767f8SToomas Soome #include <sys/param.h>
20199767f8SToomas Soome 
21199767f8SToomas Soome #include <btxv86.h>
22199767f8SToomas Soome 
2364f9afd1SToomas Soome #include "stand.h"
24199767f8SToomas Soome #include "rbx.h"
25199767f8SToomas Soome #include "drv.h"
26199767f8SToomas Soome #include "edd.h"
27199767f8SToomas Soome 
28199767f8SToomas Soome static struct edd_params params;
29199767f8SToomas Soome 
30199767f8SToomas Soome uint64_t
drvsize(struct dsk * dskp)31199767f8SToomas Soome drvsize(struct dsk *dskp)
32199767f8SToomas Soome {
33199767f8SToomas Soome 
3464f9afd1SToomas Soome 	params.len = sizeof (struct edd_params);
35199767f8SToomas Soome 	v86.ctl = V86_FLAGS;
36199767f8SToomas Soome 	v86.addr = 0x13;
37199767f8SToomas Soome 	v86.eax = 0x4800;
38199767f8SToomas Soome 	v86.edx = dskp->drive;
39199767f8SToomas Soome 	v86.ds = VTOPSEG(&params);
40199767f8SToomas Soome 	v86.esi = VTOPOFF(&params);
41199767f8SToomas Soome 	v86int();
42199767f8SToomas Soome 	if (V86_CY(v86.efl)) {
43199767f8SToomas Soome 		printf("error %u\n", v86.eax >> 8 & 0xff);
44199767f8SToomas Soome 		return (0);
45199767f8SToomas Soome 	}
46199767f8SToomas Soome 	return (params.sectors);
47199767f8SToomas Soome }
48199767f8SToomas Soome 
49199767f8SToomas Soome static struct edd_packet packet;
50199767f8SToomas Soome 
51199767f8SToomas Soome int
drvread(struct dsk * dskp,void * buf,daddr_t lba,unsigned nblk)52199767f8SToomas Soome drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
53199767f8SToomas Soome {
54199767f8SToomas Soome 	static unsigned c = 0x2d5c7c2f;
55199767f8SToomas Soome 
56199767f8SToomas Soome 	if (!OPT_CHECK(RBX_QUIET))
57199767f8SToomas Soome 		printf("%c\b", c = c << 8 | c >> 24);
5864f9afd1SToomas Soome 	packet.len = sizeof (struct edd_packet);
59199767f8SToomas Soome 	packet.count = nblk;
60199767f8SToomas Soome 	packet.off = VTOPOFF(buf);
61199767f8SToomas Soome 	packet.seg = VTOPSEG(buf);
62199767f8SToomas Soome 	packet.lba = lba;
63199767f8SToomas Soome 	v86.ctl = V86_FLAGS;
64199767f8SToomas Soome 	v86.addr = 0x13;
65199767f8SToomas Soome 	v86.eax = 0x4200;
66199767f8SToomas Soome 	v86.edx = dskp->drive;
67199767f8SToomas Soome 	v86.ds = VTOPSEG(&packet);
68199767f8SToomas Soome 	v86.esi = VTOPOFF(&packet);
69199767f8SToomas Soome 	v86int();
70199767f8SToomas Soome 	if (V86_CY(v86.efl)) {
7164f9afd1SToomas Soome 		printf("%s: error %u lba %llu\n",
72199767f8SToomas Soome 		    BOOTPROG, v86.eax >> 8 & 0xff, lba);
73199767f8SToomas Soome 		return (-1);
74199767f8SToomas Soome 	}
75199767f8SToomas Soome 	return (0);
76199767f8SToomas Soome }
77199767f8SToomas Soome 
78199767f8SToomas Soome int
drvwrite(struct dsk * dskp,void * buf,daddr_t lba,unsigned nblk)79199767f8SToomas Soome drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
80199767f8SToomas Soome {
81199767f8SToomas Soome 
8264f9afd1SToomas Soome 	packet.len = sizeof (struct edd_packet);
83199767f8SToomas Soome 	packet.count = nblk;
84199767f8SToomas Soome 	packet.off = VTOPOFF(buf);
85199767f8SToomas Soome 	packet.seg = VTOPSEG(buf);
86199767f8SToomas Soome 	packet.lba = lba;
87199767f8SToomas Soome 	v86.ctl = V86_FLAGS;
88199767f8SToomas Soome 	v86.addr = 0x13;
89199767f8SToomas Soome 	v86.eax = 0x4300;
90199767f8SToomas Soome 	v86.edx = dskp->drive;
91199767f8SToomas Soome 	v86.ds = VTOPSEG(&packet);
92199767f8SToomas Soome 	v86.esi = VTOPOFF(&packet);
93199767f8SToomas Soome 	v86int();
94199767f8SToomas Soome 	if (V86_CY(v86.efl)) {
9564f9afd1SToomas Soome 		printf("error %u lba %llu\n", v86.eax >> 8 & 0xff, lba);
96199767f8SToomas Soome 		return (-1);
97199767f8SToomas Soome 	}
98199767f8SToomas Soome 	return (0);
99199767f8SToomas Soome }
100