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 */ | ... | ... |