]> CyberLeo.Net >> Repos - FreeBSD/releng/9.2.git/blob - sys/boot/i386/common/drv.c
- Copy stable/9 to releng/9.2 as part of the 9.2-RELEASE cycle.
[FreeBSD/releng/9.2.git] / sys / boot / i386 / common / drv.c
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 __FBSDID("$FreeBSD$");
19
20 #include <sys/param.h>
21
22 #include <btxv86.h>
23
24 #include "rbx.h"
25 #include "util.h"
26 #include "drv.h"
27 #include "edd.h"
28 #ifdef USE_XREAD
29 #include "xreadorg.h"
30 #endif
31
32 #ifdef GPT
33 static struct edd_params params;
34
35 uint64_t
36 drvsize(struct dsk *dskp)
37 {
38
39         params.len = sizeof(struct edd_params);
40         v86.ctl = V86_FLAGS;
41         v86.addr = 0x13;
42         v86.eax = 0x4800;
43         v86.edx = dskp->drive;
44         v86.ds = VTOPSEG(&params);
45         v86.esi = VTOPOFF(&params);
46         v86int();
47         if (V86_CY(v86.efl)) {
48                 printf("error %u\n", v86.eax >> 8 & 0xff);
49                 return (0);
50         }
51         return (params.sectors);
52 }
53 #endif  /* GPT */
54
55 #ifndef USE_XREAD
56 static struct edd_packet packet;
57 #endif
58
59 int
60 drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
61 {
62         static unsigned c = 0x2d5c7c2f;
63
64         if (!OPT_CHECK(RBX_QUIET))
65                 printf("%c\b", c = c << 8 | c >> 24);
66 #ifndef USE_XREAD
67         packet.len = sizeof(struct edd_packet);
68         packet.count = nblk;
69         packet.off = VTOPOFF(buf);
70         packet.seg = VTOPSEG(buf);
71         packet.lba = lba;
72         v86.ctl = V86_FLAGS;
73         v86.addr = 0x13;
74         v86.eax = 0x4200;
75         v86.edx = dskp->drive;
76         v86.ds = VTOPSEG(&packet);
77         v86.esi = VTOPOFF(&packet);
78 #else   /* USE_XREAD */
79         v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS;
80         v86.addr = XREADORG;            /* call to xread in boot1 */
81         v86.es = VTOPSEG(buf);
82         v86.eax = lba;
83         v86.ebx = VTOPOFF(buf);
84         v86.ecx = lba >> 32;
85         v86.edx = nblk << 8 | dskp->drive;
86 #endif  /* USE_XREAD */
87         v86int();
88         if (V86_CY(v86.efl)) {
89                 printf("%s: error %u lba %u\n",
90                     BOOTPROG, v86.eax >> 8 & 0xff, lba);
91                 return (-1);
92         }
93         return (0);
94 }
95
96 #ifdef GPT
97 int
98 drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
99 {
100
101         packet.len = sizeof(struct edd_packet);
102         packet.count = nblk;
103         packet.off = VTOPOFF(buf);
104         packet.seg = VTOPSEG(buf);
105         packet.lba = lba;
106         v86.ctl = V86_FLAGS;
107         v86.addr = 0x13;
108         v86.eax = 0x4300;
109         v86.edx = dskp->drive;
110         v86.ds = VTOPSEG(&packet);
111         v86.esi = VTOPOFF(&packet);
112         v86int();
113         if (V86_CY(v86.efl)) {
114                 printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba);
115                 return (-1);
116         }
117         return (0);
118 }
119 #endif  /* GPT */