]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - sys/boot/i386/common/drv.c
MFC Loader Fixes 2017q1: r311458,r312237,r312314,r312374,r312947,r313042,
[FreeBSD/FreeBSD.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
29 static struct edd_params params;
30
31 uint64_t
32 drvsize(struct dsk *dskp)
33 {
34
35         params.len = sizeof(struct edd_params);
36         v86.ctl = V86_FLAGS;
37         v86.addr = 0x13;
38         v86.eax = 0x4800;
39         v86.edx = dskp->drive;
40         v86.ds = VTOPSEG(&params);
41         v86.esi = VTOPOFF(&params);
42         v86int();
43         if (V86_CY(v86.efl)) {
44                 printf("error %u\n", v86.eax >> 8 & 0xff);
45                 return (0);
46         }
47         return (params.sectors);
48 }
49
50 static struct edd_packet packet;
51
52 int
53 drvread(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
54 {
55         static unsigned c = 0x2d5c7c2f;
56
57         if (!OPT_CHECK(RBX_QUIET))
58                 printf("%c\b", c = c << 8 | c >> 24);
59         packet.len = sizeof(struct edd_packet);
60         packet.count = nblk;
61         packet.off = VTOPOFF(buf);
62         packet.seg = VTOPSEG(buf);
63         packet.lba = lba;
64         v86.ctl = V86_FLAGS;
65         v86.addr = 0x13;
66         v86.eax = 0x4200;
67         v86.edx = dskp->drive;
68         v86.ds = VTOPSEG(&packet);
69         v86.esi = VTOPOFF(&packet);
70         v86int();
71         if (V86_CY(v86.efl)) {
72                 printf("%s: error %u lba %u\n",
73                     BOOTPROG, v86.eax >> 8 & 0xff, lba);
74                 return (-1);
75         }
76         return (0);
77 }
78
79 #if defined(GPT) || defined(ZFS)
80 int
81 drvwrite(struct dsk *dskp, void *buf, daddr_t lba, unsigned nblk)
82 {
83
84         packet.len = sizeof(struct edd_packet);
85         packet.count = nblk;
86         packet.off = VTOPOFF(buf);
87         packet.seg = VTOPSEG(buf);
88         packet.lba = lba;
89         v86.ctl = V86_FLAGS;
90         v86.addr = 0x13;
91         v86.eax = 0x4300;
92         v86.edx = dskp->drive;
93         v86.ds = VTOPSEG(&packet);
94         v86.esi = VTOPOFF(&packet);
95         v86int();
96         if (V86_CY(v86.efl)) {
97                 printf("error %u lba %u\n", v86.eax >> 8 & 0xff, lba);
98                 return (-1);
99         }
100         return (0);
101 }
102 #endif  /* GPT || ZFS */