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(&params);
45226748Sjhb	v86.esi = VTOPOFF(&params);
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