qed: Consistency check support
[qemu-kvm/stefanha.git] / hw / extboot.c
blob8ada21bf54dfc9eab4281cf6d88f7466e6b7df1a
1 /*
2 * Extended boot option ROM support.
4 * Copyright IBM, Corp. 2007
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2. See
10 * the COPYING file in the top-level directory.
14 #include "hw.h"
15 #include "pc.h"
16 #include "isa.h"
17 #include "block.h"
19 /* Extended Boot ROM suport */
21 union extboot_cmd
23 uint16_t type;
24 struct {
25 uint16_t type;
26 uint16_t cylinders;
27 uint16_t heads;
28 uint16_t sectors;
29 uint64_t nb_sectors;
30 } query_geometry;
31 struct {
32 uint16_t type;
33 uint16_t nb_sectors;
34 uint16_t segment;
35 uint16_t offset;
36 uint64_t sector;
37 } xfer;
40 static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s)
42 bdrv_get_geometry_hint(bs, c, h, s);
44 if (*c <= 1024) {
45 *c >>= 0;
46 *h <<= 0;
47 } else if (*c <= 2048) {
48 *c >>= 1;
49 *h <<= 1;
50 } else if (*c <= 4096) {
51 *c >>= 2;
52 *h <<= 2;
53 } else if (*c <= 8192) {
54 *c >>= 3;
55 *h <<= 3;
56 } else {
57 *c >>= 4;
58 *h <<= 4;
61 /* what is the correct algorithm for this?? */
62 if (*h == 256) {
63 *h = 255;
64 *c = *c + 1;
68 static void extboot_write_cmd(void *opaque, uint32_t addr, uint32_t value)
70 union extboot_cmd cmd;
71 BlockDriverState *bs = opaque;
72 int cylinders, heads, sectors, err;
73 uint64_t nb_sectors;
74 target_phys_addr_t pa = 0;
75 int blen = 0;
76 void *buf = NULL;
78 cpu_physical_memory_read((value & 0xFFFF) << 4, (uint8_t *)&cmd,
79 sizeof(cmd));
81 if (cmd.type == 0x01 || cmd.type == 0x02) {
82 pa = cmd.xfer.segment * 16 + cmd.xfer.offset;
83 blen = cmd.xfer.nb_sectors * 512;
84 buf = qemu_memalign(512, blen);
87 switch (cmd.type) {
88 case 0x00:
89 get_translated_chs(bs, &cylinders, &heads, &sectors);
90 bdrv_get_geometry(bs, &nb_sectors);
91 cmd.query_geometry.cylinders = cylinders;
92 cmd.query_geometry.heads = heads;
93 cmd.query_geometry.sectors = sectors;
94 cmd.query_geometry.nb_sectors = nb_sectors;
95 break;
96 case 0x01:
97 err = bdrv_read(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
98 if (err)
99 printf("Read failed\n");
101 cpu_physical_memory_write(pa, buf, blen);
103 break;
104 case 0x02:
105 cpu_physical_memory_read(pa, buf, blen);
107 err = bdrv_write(bs, cmd.xfer.sector, buf, cmd.xfer.nb_sectors);
108 if (err)
109 printf("Write failed\n");
111 break;
114 cpu_physical_memory_write((value & 0xFFFF) << 4, (uint8_t *)&cmd,
115 sizeof(cmd));
116 if (buf)
117 qemu_free(buf);
120 void extboot_init(BlockDriverState *bs)
122 register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs);