Commit ba6c23778cd886688c7aef4fcdc53128816f566a

Authored by bellard
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
... ... @@ -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, &sectors);
  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, &sectors);
  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 */
... ...