Commit 46d4767d93bcb2e84869ba6d2344ebff4382be86

Authored by bellard
1 parent e35c55fe

better BIOS ATA translation support


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@1153 c046a42c-6fe2-441c-8c8c-71466251a162
... ... @@ -348,6 +348,11 @@ void bdrv_set_type_hint(BlockDriverState *bs, int type)
348 348 type == BDRV_TYPE_FLOPPY));
349 349 }
350 350  
  351 +void bdrv_set_translation_hint(BlockDriverState *bs, int translation)
  352 +{
  353 + bs->translation = translation;
  354 +}
  355 +
351 356 void bdrv_get_geometry_hint(BlockDriverState *bs,
352 357 int *pcyls, int *pheads, int *psecs)
353 358 {
... ... @@ -361,6 +366,11 @@ int bdrv_get_type_hint(BlockDriverState *bs)
361 366 return bs->type;
362 367 }
363 368  
  369 +int bdrv_get_translation_hint(BlockDriverState *bs)
  370 +{
  371 + return bs->translation;
  372 +}
  373 +
364 374 int bdrv_is_removable(BlockDriverState *bs)
365 375 {
366 376 return bs->removable;
... ...
block_int.h
... ... @@ -68,7 +68,7 @@ struct BlockDriverState {
68 68  
69 69 /* NOTE: the following infos are only hints for real hardware
70 70 drivers. They are not used by the block driver */
71   - int cyls, heads, secs;
  71 + int cyls, heads, secs, translation;
72 72 int type;
73 73 char device_name[32];
74 74 BlockDriverState *next;
... ...
hw/ide.c
... ... @@ -1826,11 +1826,11 @@ struct partition {
1826 1826 uint32_t nr_sects; /* nr of sectors in partition */
1827 1827 } __attribute__((packed));
1828 1828  
1829   -/* try to guess the IDE geometry from the MSDOS partition table */
  1829 +/* try to guess the IDE physical geometry from the MSDOS partition table */
1830 1830 static void ide_guess_geometry(IDEState *s)
1831 1831 {
1832 1832 uint8_t buf[512];
1833   - int ret, i;
  1833 + int ret, i, heads, sectors, cylinders;
1834 1834 struct partition *p;
1835 1835 uint32_t nr_sects;
1836 1836  
... ... @@ -1848,9 +1848,18 @@ static void ide_guess_geometry(IDEState *s)
1848 1848 if (nr_sects && p->end_head) {
1849 1849 /* We make the assumption that the partition terminates on
1850 1850 a cylinder boundary */
1851   - s->heads = p->end_head + 1;
1852   - s->sectors = p->end_sector & 63;
1853   - s->cylinders = s->nb_sectors / (s->heads * s->sectors);
  1851 + heads = p->end_head + 1;
  1852 + if (heads < 1 || heads > 16)
  1853 + continue;
  1854 + sectors = p->end_sector & 63;
  1855 + if (sectors == 0)
  1856 + continue;
  1857 + cylinders = s->nb_sectors / (heads * sectors);
  1858 + if (cylinders < 1 || cylinders > 16383)
  1859 + continue;
  1860 + s->heads = heads;
  1861 + s->sectors = sectors;
  1862 + s->cylinders = cylinders;
1854 1863 #if 0
1855 1864 printf("guessed partition: CHS=%d %d %d\n",
1856 1865 s->cylinders, s->heads, s->sectors);
... ... @@ -1885,7 +1894,7 @@ static void ide_init2(IDEState *ide_state, int irq,
1885 1894 } else {
1886 1895 ide_guess_geometry(s);
1887 1896 if (s->cylinders == 0) {
1888   - /* if no geometry, use a LBA compatible one */
  1897 + /* if no geometry, use a standard physical disk geometry */
1889 1898 cylinders = nb_sectors / (16 * 63);
1890 1899 if (cylinders > 16383)
1891 1900 cylinders = 16383;
... ...
... ... @@ -217,19 +217,23 @@ static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table
217 217 val = 0;
218 218 for (i = 0; i < 4; i++) {
219 219 if (hd_table[i]) {
220   - int cylinders, heads, sectors;
221   - uint8_t translation;
222   - /* NOTE: bdrv_get_geometry_hint() returns the geometry
223   - that the hard disk returns. It is always such that: 1 <=
224   - sects <= 63, 1 <= heads <= 16, 1 <= cylinders <=
225   - 16383. The BIOS geometry can be different. */
226   - bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
227   - if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
228   - /* No translation. */
229   - translation = 0;
  220 + int cylinders, heads, sectors, translation;
  221 + /* NOTE: bdrv_get_geometry_hint() returns the physical
  222 + geometry. It is always such that: 1 <= sects <= 63, 1
  223 + <= heads <= 16, 1 <= cylinders <= 16383. The BIOS
  224 + geometry can be different if a translation is done. */
  225 + translation = bdrv_get_translation_hint(hd_table[i]);
  226 + if (translation == BIOS_ATA_TRANSLATION_AUTO) {
  227 + bdrv_get_geometry_hint(hd_table[i], &cylinders, &heads, &sectors);
  228 + if (cylinders <= 1024 && heads <= 16 && sectors <= 63) {
  229 + /* No translation. */
  230 + translation = 0;
  231 + } else {
  232 + /* LBA translation. */
  233 + translation = 1;
  234 + }
230 235 } else {
231   - /* LBA translation. */
232   - translation = 1;
  236 + translation--;
233 237 }
234 238 val |= translation << (i * 2);
235 239 }
... ...
qemu-doc.texi
... ... @@ -343,6 +343,12 @@ Change gdb connection port.
343 343 Do not start CPU at startup (you must type 'c' in the monitor).
344 344 @item -d
345 345 Output log in /tmp/qemu.log
  346 +@item -hdachs c,h,s,[,t]
  347 +Force hard disk 0 physical geometry (1 <= @var{c} <= 16383, 1 <=
  348 +@var{h} <= 16, 1 <= @var{s} <= 63) and optionally force the BIOS
  349 +translation mode (@var{t}=none, lba or auto). Usually QEMU can guess
  350 +all thoses parameters. This option is useful for old MS-DOS disk
  351 +images.
346 352 @item -isa
347 353 Simulate an ISA-only system (default is PCI system).
348 354 @item -std-vga
... ...
... ... @@ -2537,7 +2537,8 @@ void help(void)
2537 2537 "-s wait gdb connection to port %d\n"
2538 2538 "-p port change gdb connection port\n"
2539 2539 "-d item1,... output log to %s (use -d ? for a list of log items)\n"
2540   - "-hdachs c,h,s force hard disk 0 geometry (usually qemu can guess it)\n"
  2540 + "-hdachs c,h,s[,t] force hard disk 0 physical geometry and the optional BIOS\n"
  2541 + " translation (t=none or lba) (usually qemu can guess them)\n"
2541 2542 "-L path set the directory for the BIOS and VGA BIOS\n"
2542 2543 #ifdef USE_CODE_COPY
2543 2544 "-no-code-copy disable code copy acceleration\n"
... ... @@ -2753,7 +2754,7 @@ int main(int argc, char **argv)
2753 2754 const char *hd_filename[MAX_DISKS], *fd_filename[MAX_FD];
2754 2755 const char *kernel_filename, *kernel_cmdline;
2755 2756 DisplayState *ds = &display_state;
2756   - int cyls, heads, secs;
  2757 + int cyls, heads, secs, translation;
2757 2758 int start_emulation = 1;
2758 2759 uint8_t macaddr[6];
2759 2760 int net_if_type, nb_tun_fds, tun_fds[MAX_NICS];
... ... @@ -2788,6 +2789,7 @@ int main(int argc, char **argv)
2788 2789 kernel_cmdline = "";
2789 2790 has_cdrom = 1;
2790 2791 cyls = heads = secs = 0;
  2792 + translation = BIOS_ATA_TRANSLATION_AUTO;
2791 2793 pstrcpy(monitor_device, sizeof(monitor_device), "vc");
2792 2794  
2793 2795 pstrcpy(serial_devices[0], sizeof(serial_devices[0]), "vc");
... ... @@ -2857,17 +2859,34 @@ int main(int argc, char **argv)
2857 2859 const char *p;
2858 2860 p = optarg;
2859 2861 cyls = strtol(p, (char **)&p, 0);
  2862 + if (cyls < 1 || cyls > 16383)
  2863 + goto chs_fail;
2860 2864 if (*p != ',')
2861 2865 goto chs_fail;
2862 2866 p++;
2863 2867 heads = strtol(p, (char **)&p, 0);
  2868 + if (heads < 1 || heads > 16)
  2869 + goto chs_fail;
2864 2870 if (*p != ',')
2865 2871 goto chs_fail;
2866 2872 p++;
2867 2873 secs = strtol(p, (char **)&p, 0);
2868   - if (*p != '\0') {
  2874 + if (secs < 1 || secs > 63)
  2875 + goto chs_fail;
  2876 + if (*p == ',') {
  2877 + p++;
  2878 + if (!strcmp(p, "none"))
  2879 + translation = BIOS_ATA_TRANSLATION_NONE;
  2880 + else if (!strcmp(p, "lba"))
  2881 + translation = BIOS_ATA_TRANSLATION_LBA;
  2882 + else if (!strcmp(p, "auto"))
  2883 + translation = BIOS_ATA_TRANSLATION_AUTO;
  2884 + else
  2885 + goto chs_fail;
  2886 + } else if (*p != '\0') {
2869 2887 chs_fail:
2870   - cyls = 0;
  2888 + fprintf(stderr, "qemu: invalid physical CHS format\n");
  2889 + exit(1);
2871 2890 }
2872 2891 }
2873 2892 break;
... ... @@ -3230,8 +3249,10 @@ int main(int argc, char **argv)
3230 3249 hd_filename[i]);
3231 3250 exit(1);
3232 3251 }
3233   - if (i == 0 && cyls != 0)
  3252 + if (i == 0 && cyls != 0) {
3234 3253 bdrv_set_geometry_hint(bs_table[i], cyls, heads, secs);
  3254 + bdrv_set_translation_hint(bs_table[i], translation);
  3255 + }
3235 3256 }
3236 3257 }
3237 3258  
... ...
... ... @@ -383,13 +383,18 @@ void bdrv_set_boot_sector(BlockDriverState *bs, const uint8_t *data, int size);
383 383 #define BDRV_TYPE_HD 0
384 384 #define BDRV_TYPE_CDROM 1
385 385 #define BDRV_TYPE_FLOPPY 2
  386 +#define BIOS_ATA_TRANSLATION_AUTO 0
  387 +#define BIOS_ATA_TRANSLATION_NONE 1
  388 +#define BIOS_ATA_TRANSLATION_LBA 2
386 389  
387 390 void bdrv_set_geometry_hint(BlockDriverState *bs,
388 391 int cyls, int heads, int secs);
389 392 void bdrv_set_type_hint(BlockDriverState *bs, int type);
  393 +void bdrv_set_translation_hint(BlockDriverState *bs, int translation);
390 394 void bdrv_get_geometry_hint(BlockDriverState *bs,
391 395 int *pcyls, int *pheads, int *psecs);
392 396 int bdrv_get_type_hint(BlockDriverState *bs);
  397 +int bdrv_get_translation_hint(BlockDriverState *bs);
393 398 int bdrv_is_removable(BlockDriverState *bs);
394 399 int bdrv_is_read_only(BlockDriverState *bs);
395 400 int bdrv_is_inserted(BlockDriverState *bs);
... ...