Regenerate bios for ioapic id fix
[qemu-kvm/fedora.git] / hw / extboot.c
blob8759895bdd9172db6ece9ed54f63663b9c48a877
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 } query_geometry;
30 struct {
31 uint16_t type;
32 uint16_t nb_sectors;
33 uint16_t segment;
34 uint16_t offset;
35 uint64_t sector;
36 } xfer;
39 static void get_translated_chs(BlockDriverState *bs, int *c, int *h, int *s)
41 bdrv_get_geometry_hint(bs, c, h, s);
43 if (*c <= 1024) {
44 *c >>= 0;
45 *h <<= 0;
46 } else if (*c <= 2048) {
47 *c >>= 1;
48 *h <<= 1;
49 } else if (*c <= 4096) {
50 *c >>= 2;
51 *h <<= 2;
52 } else if (*c <= 8192) {
53 *c >>= 3;
54 *h <<= 3;
55 } else {
56 *c >>= 4;
57 *h <<= 4;
60 /* what is the correct algorithm for this?? */
61 if (*h == 256) {
62 *h = 255;
63 *c = *c + 1;
67 static uint32_t extboot_read(void *opaque, uint32_t addr)
69 int *pcmd = opaque;
70 return *pcmd;
73 static void extboot_write_cmd(void *opaque, uint32_t addr, uint32_t value)
75 union extboot_cmd *cmd = (void *)(phys_ram_base + ((value & 0xFFFF) << 4));
76 BlockDriverState *bs = opaque;
77 int cylinders, heads, sectors, err;
79 get_translated_chs(bs, &cylinders, &heads, &sectors);
81 if (cmd->type == 0x01 || cmd->type == 0x02) {
82 target_ulong pa = cmd->xfer.segment * 16 + cmd->xfer.segment;
84 /* possible buffer overflow */
85 if ((pa + cmd->xfer.nb_sectors * 512) > phys_ram_size)
86 return;
89 switch (cmd->type) {
90 case 0x00:
91 cmd->query_geometry.cylinders = cylinders;
92 cmd->query_geometry.heads = heads;
93 cmd->query_geometry.sectors = sectors;
94 cpu_physical_memory_set_dirty((value & 0xFFFF) << 4);
95 break;
96 case 0x01:
97 err = bdrv_read(bs, cmd->xfer.sector, phys_ram_base +
98 cmd->xfer.segment * 16 + cmd->xfer.offset,
99 cmd->xfer.nb_sectors);
100 if (err)
101 printf("Read failed\n");
102 break;
103 case 0x02:
104 err = bdrv_write(bs, cmd->xfer.sector, phys_ram_base +
105 cmd->xfer.segment * 16 + cmd->xfer.offset,
106 cmd->xfer.nb_sectors);
107 if (err)
108 printf("Write failed\n");
110 cpu_physical_memory_set_dirty(cmd->xfer.segment * 16 + cmd->xfer.offset);
111 break;
115 void extboot_init(BlockDriverState *bs, int cmd)
117 int *pcmd;
119 pcmd = qemu_mallocz(sizeof(int));
120 if (!pcmd) {
121 fprintf(stderr, "Error allocating memory\n");
122 exit(1);
125 *pcmd = cmd;
126 register_ioport_read(0x404, 1, 1, extboot_read, pcmd);
127 register_ioport_write(0x405, 1, 2, extboot_write_cmd, bs);