Commit ba6c23778cd886688c7aef4fcdc53128816f566a
1 parent
4b19ec0c
cmos init for IDE (Ben Pfaf)
git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1105 c046a42c-6fe2-441c-8c8c-71466251a162
Showing
1 changed file
with
54 additions
and
2 deletions
hw/pc.c
| ... | ... | @@ -101,13 +101,32 @@ static int cmos_get_fd_drive_type(int fd0) |
| 101 | 101 | return val; |
| 102 | 102 | } |
| 103 | 103 | |
| 104 | -static void cmos_init(int ram_size, int boot_device) | |
| 104 | +static void cmos_init_hd(int type_ofs, int info_ofs, BlockDriverState *hd) | |
| 105 | +{ | |
| 106 | + RTCState *s = rtc_state; | |
| 107 | + int cylinders, heads, sectors; | |
| 108 | + bdrv_get_geometry_hint(hd, &cylinders, &heads, §ors); | |
| 109 | + rtc_set_memory(s, type_ofs, 47); | |
| 110 | + rtc_set_memory(s, info_ofs, cylinders); | |
| 111 | + rtc_set_memory(s, info_ofs + 1, cylinders >> 8); | |
| 112 | + rtc_set_memory(s, info_ofs + 2, heads); | |
| 113 | + rtc_set_memory(s, info_ofs + 3, 0xff); | |
| 114 | + rtc_set_memory(s, info_ofs + 4, 0xff); | |
| 115 | + rtc_set_memory(s, info_ofs + 5, 0xc0 | ((heads > 8) << 3)); | |
| 116 | + rtc_set_memory(s, info_ofs + 6, cylinders); | |
| 117 | + rtc_set_memory(s, info_ofs + 7, cylinders >> 8); | |
| 118 | + rtc_set_memory(s, info_ofs + 8, sectors); | |
| 119 | +} | |
| 120 | + | |
| 121 | +/* hd_table must contain 4 block drivers */ | |
| 122 | +static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table) | |
| 105 | 123 | { |
| 106 | 124 | RTCState *s = rtc_state; |
| 107 | 125 | int val; |
| 108 | 126 | int fd0, fd1, nb; |
| 109 | 127 | time_t ti; |
| 110 | 128 | struct tm *tm; |
| 129 | + int i; | |
| 111 | 130 | |
| 112 | 131 | /* set the CMOS date */ |
| 113 | 132 | time(&ti); |
| ... | ... | @@ -187,6 +206,39 @@ static void cmos_init(int ram_size, int boot_device) |
| 187 | 206 | val |= 0x04; /* PS/2 mouse installed */ |
| 188 | 207 | rtc_set_memory(s, REG_EQUIPMENT_BYTE, val); |
| 189 | 208 | |
| 209 | + /* hard drives */ | |
| 210 | + | |
| 211 | + rtc_set_memory(s, 0x12, (hd_table[0] ? 0xf0 : 0) | (hd_table[1] ? 0x0f : 0)); | |
| 212 | + if (hd_table[0]) | |
| 213 | + cmos_init_hd(0x19, 0x1b, hd_table[0]); | |
| 214 | + if (hd_table[1]) | |
| 215 | + cmos_init_hd(0x1a, 0x24, hd_table[1]); | |
| 216 | + | |
| 217 | + val = 0; | |
| 218 | + for (i = 0; i < 4; i++) | |
| 219 | + if (hd_table[i]) { | |
| 220 | + int cylinders, heads, sectors; | |
| 221 | + uint8_t translation; | |
| 222 | + | |
| 223 | + bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, §ors); | |
| 224 | + if (cylinders <= 1024 && heads <= 16 && sectors <= 63) { | |
| 225 | + /* No translation. */ | |
| 226 | + translation = 0; | |
| 227 | + } else if (cylinders * heads > 131072) { | |
| 228 | + /* LBA translation. */ | |
| 229 | + translation = 1; | |
| 230 | + } else { | |
| 231 | + /* LARGE translation. */ | |
| 232 | + translation = 2; | |
| 233 | + } | |
| 234 | + | |
| 235 | + val |= translation << (i * 2); | |
| 236 | + } | |
| 237 | + rtc_set_memory(s, 0x39, val); | |
| 238 | + | |
| 239 | + /* Disable check of 0x55AA signature on the last two bytes of | |
| 240 | + first sector of disk. XXX: make it the default ? */ | |
| 241 | + // rtc_set_memory(s, 0x38, 1); | |
| 190 | 242 | } |
| 191 | 243 | |
| 192 | 244 | static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val) |
| ... | ... | @@ -512,7 +564,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, |
| 512 | 564 | |
| 513 | 565 | floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); |
| 514 | 566 | |
| 515 | - cmos_init(ram_size, boot_device); | |
| 567 | + cmos_init(ram_size, boot_device, bs_table); | |
| 516 | 568 | |
| 517 | 569 | /* must be done after all PCI devices are instanciated */ |
| 518 | 570 | /* XXX: should be done in the Bochs BIOS */ | ... | ... |