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,13 +101,32 @@ static int cmos_get_fd_drive_type(int fd0) | ||
101 | return val; | 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 | RTCState *s = rtc_state; | 124 | RTCState *s = rtc_state; |
107 | int val; | 125 | int val; |
108 | int fd0, fd1, nb; | 126 | int fd0, fd1, nb; |
109 | time_t ti; | 127 | time_t ti; |
110 | struct tm *tm; | 128 | struct tm *tm; |
129 | + int i; | ||
111 | 130 | ||
112 | /* set the CMOS date */ | 131 | /* set the CMOS date */ |
113 | time(&ti); | 132 | time(&ti); |
@@ -187,6 +206,39 @@ static void cmos_init(int ram_size, int boot_device) | @@ -187,6 +206,39 @@ static void cmos_init(int ram_size, int boot_device) | ||
187 | val |= 0x04; /* PS/2 mouse installed */ | 206 | val |= 0x04; /* PS/2 mouse installed */ |
188 | rtc_set_memory(s, REG_EQUIPMENT_BYTE, val); | 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 | static void speaker_ioport_write(void *opaque, uint32_t addr, uint32_t val) | 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,7 +564,7 @@ void pc_init(int ram_size, int vga_ram_size, int boot_device, | ||
512 | 564 | ||
513 | floppy_controller = fdctrl_init(6, 2, 0, 0x3f0, fd_table); | 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 | /* must be done after all PCI devices are instanciated */ | 569 | /* must be done after all PCI devices are instanciated */ |
518 | /* XXX: should be done in the Bochs BIOS */ | 570 | /* XXX: should be done in the Bochs BIOS */ |