Commit fc01f7e7f902ce96d985f44dc16f7c020b94f02b

Authored by bellard
1 parent 3b0dca51

IDE emulation


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@291 c046a42c-6fe2-441c-8c8c-71466251a162
Showing 3 changed files with 900 additions and 86 deletions
block.c 0 → 100644
  1 +/*
  2 + * QEMU System Emulator block driver
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#include <stdlib.h>
  25 +#include <stdio.h>
  26 +#include <stdarg.h>
  27 +#include <string.h>
  28 +#include <getopt.h>
  29 +#include <inttypes.h>
  30 +#include <unistd.h>
  31 +#include <sys/mman.h>
  32 +#include <fcntl.h>
  33 +#include <signal.h>
  34 +#include <time.h>
  35 +#include <sys/time.h>
  36 +#include <malloc.h>
  37 +#include <termios.h>
  38 +#include <sys/poll.h>
  39 +#include <errno.h>
  40 +#include <sys/wait.h>
  41 +
  42 +#include "vl.h"
  43 +
  44 +struct BlockDriverState {
  45 + int fd;
  46 + int64_t total_sectors;
  47 +};
  48 +
  49 +BlockDriverState *bdrv_open(const char *filename)
  50 +{
  51 + BlockDriverState *bs;
  52 + int fd;
  53 + int64_t size;
  54 +
  55 + bs = malloc(sizeof(BlockDriverState));
  56 + if(!bs)
  57 + return NULL;
  58 + fd = open(filename, O_RDWR);
  59 + if (fd < 0) {
  60 + close(fd);
  61 + free(bs);
  62 + return NULL;
  63 + }
  64 + size = lseek64(fd, 0, SEEK_END);
  65 + bs->total_sectors = size / 512;
  66 + bs->fd = fd;
  67 + return bs;
  68 +}
  69 +
  70 +void bdrv_close(BlockDriverState *bs)
  71 +{
  72 + close(bs->fd);
  73 + free(bs);
  74 +}
  75 +
  76 +/* return -1 if error */
  77 +int bdrv_read(BlockDriverState *bs, int64_t sector_num,
  78 + uint8_t *buf, int nb_sectors)
  79 +{
  80 + int ret;
  81 +
  82 + lseek64(bs->fd, sector_num * 512, SEEK_SET);
  83 + ret = read(bs->fd, buf, nb_sectors * 512);
  84 + if (ret != nb_sectors * 512)
  85 + return -1;
  86 + else
  87 + return 0;
  88 +}
  89 +
  90 +/* return -1 if error */
  91 +int bdrv_write(BlockDriverState *bs, int64_t sector_num,
  92 + const uint8_t *buf, int nb_sectors)
  93 +{
  94 + int ret;
  95 +
  96 + lseek64(bs->fd, sector_num * 512, SEEK_SET);
  97 + ret = write(bs->fd, buf, nb_sectors * 512);
  98 + if (ret != nb_sectors * 512)
  99 + return -1;
  100 + else
  101 + return 0;
  102 +}
  103 +
  104 +void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr)
  105 +{
  106 + *nb_sectors_ptr = bs->total_sectors;
  107 +}
... ...
... ... @@ -46,6 +46,9 @@
46 46  
47 47 #include "cpu-i386.h"
48 48 #include "disas.h"
  49 +#include "thunk.h"
  50 +
  51 +#include "vl.h"
49 52  
50 53 #define DEBUG_LOGFILE "/tmp/vl.log"
51 54 #define DEFAULT_NETWORK_SCRIPT "/etc/vl-ifup"
... ... @@ -175,17 +178,15 @@ struct __attribute__ ((packed)) linux_params {
175 178 typedef void (IOPortWriteFunc)(CPUX86State *env, uint32_t address, uint32_t data);
176 179 typedef uint32_t (IOPortReadFunc)(CPUX86State *env, uint32_t address);
177 180  
178   -#define MAX_IOPORTS 1024
  181 +#define MAX_IOPORTS 4096
179 182  
180 183 char phys_ram_file[1024];
181 184 CPUX86State *global_env;
182 185 CPUX86State *cpu_single_env;
183 186 FILE *logfile = NULL;
184 187 int loglevel;
185   -IOPortReadFunc *ioport_readb_table[MAX_IOPORTS];
186   -IOPortWriteFunc *ioport_writeb_table[MAX_IOPORTS];
187   -IOPortReadFunc *ioport_readw_table[MAX_IOPORTS];
188   -IOPortWriteFunc *ioport_writew_table[MAX_IOPORTS];
  188 +IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
  189 +IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
189 190  
190 191 /***********************************************************/
191 192 /* x86 io ports */
... ... @@ -195,7 +196,7 @@ uint32_t default_ioport_readb(CPUX86State *env, uint32_t address)
195 196 #ifdef DEBUG_UNUSED_IOPORT
196 197 fprintf(stderr, "inb: port=0x%04x\n", address);
197 198 #endif
198   - return 0;
  199 + return 0xff;
199 200 }
200 201  
201 202 void default_ioport_writeb(CPUX86State *env, uint32_t address, uint32_t data)
... ... @@ -209,62 +210,79 @@ void default_ioport_writeb(CPUX86State *env, uint32_t address, uint32_t data)
209 210 uint32_t default_ioport_readw(CPUX86State *env, uint32_t address)
210 211 {
211 212 uint32_t data;
212   - data = ioport_readb_table[address](env, address);
213   - data |= ioport_readb_table[address + 1](env, address + 1) << 8;
  213 + data = ioport_read_table[0][address](env, address);
  214 + data |= ioport_read_table[0][address + 1](env, address + 1) << 8;
214 215 return data;
215 216 }
216 217  
217 218 void default_ioport_writew(CPUX86State *env, uint32_t address, uint32_t data)
218 219 {
219   - ioport_writeb_table[address](env, address, data & 0xff);
220   - ioport_writeb_table[address + 1](env, address + 1, (data >> 8) & 0xff);
  220 + ioport_write_table[0][address](env, address, data & 0xff);
  221 + ioport_write_table[0][address + 1](env, address + 1, (data >> 8) & 0xff);
221 222 }
222 223  
223   -void init_ioports(void)
  224 +uint32_t default_ioport_readl(CPUX86State *env, uint32_t address)
224 225 {
225   - int i;
226   -
227   - for(i = 0; i < MAX_IOPORTS; i++) {
228   - ioport_readb_table[i] = default_ioport_readb;
229   - ioport_writeb_table[i] = default_ioport_writeb;
230   - ioport_readw_table[i] = default_ioport_readw;
231   - ioport_writew_table[i] = default_ioport_writew;
232   - }
  226 +#ifdef DEBUG_UNUSED_IOPORT
  227 + fprintf(stderr, "inl: port=0x%04x\n", address);
  228 +#endif
  229 + return 0xffffffff;
233 230 }
234 231  
235   -int register_ioport_readb(int start, int length, IOPortReadFunc *func)
  232 +void default_ioport_writel(CPUX86State *env, uint32_t address, uint32_t data)
236 233 {
237   - int i;
238   -
239   - for(i = start; i < start + length; i++)
240   - ioport_readb_table[i] = func;
241   - return 0;
  234 +#ifdef DEBUG_UNUSED_IOPORT
  235 + fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
  236 +#endif
242 237 }
243 238  
244   -int register_ioport_writeb(int start, int length, IOPortWriteFunc *func)
  239 +void init_ioports(void)
245 240 {
246 241 int i;
247 242  
248   - for(i = start; i < start + length; i++)
249   - ioport_writeb_table[i] = func;
250   - return 0;
  243 + for(i = 0; i < MAX_IOPORTS; i++) {
  244 + ioport_read_table[0][i] = default_ioport_readb;
  245 + ioport_write_table[0][i] = default_ioport_writeb;
  246 + ioport_read_table[1][i] = default_ioport_readw;
  247 + ioport_write_table[1][i] = default_ioport_writew;
  248 + ioport_read_table[2][i] = default_ioport_readl;
  249 + ioport_write_table[2][i] = default_ioport_writel;
  250 + }
251 251 }
252 252  
253   -int register_ioport_readw(int start, int length, IOPortReadFunc *func)
  253 +/* size is the word size in byte */
  254 +int register_ioport_read(int start, int length, IOPortReadFunc *func, int size)
254 255 {
255   - int i;
  256 + int i, bsize;
256 257  
257   - for(i = start; i < start + length; i += 2)
258   - ioport_readw_table[i] = func;
  258 + if (size == 1)
  259 + bsize = 0;
  260 + else if (size == 2)
  261 + bsize = 1;
  262 + else if (size == 4)
  263 + bsize = 2;
  264 + else
  265 + return -1;
  266 + for(i = start; i < start + length; i += size)
  267 + ioport_read_table[bsize][i] = func;
259 268 return 0;
260 269 }
261 270  
262   -int register_ioport_writew(int start, int length, IOPortWriteFunc *func)
  271 +/* size is the word size in byte */
  272 +int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size)
263 273 {
264   - int i;
  274 + int i, bsize;
265 275  
266   - for(i = start; i < start + length; i += 2)
267   - ioport_writew_table[i] = func;
  276 + if (size == 1)
  277 + bsize = 0;
  278 + else if (size == 2)
  279 + bsize = 1;
  280 + else if (size == 4)
  281 + bsize = 2;
  282 + else
  283 + return -1;
  284 + for(i = start; i < start + length; i += size)
  285 + ioport_write_table[bsize][i] = func;
268 286 return 0;
269 287 }
270 288  
... ... @@ -339,33 +357,32 @@ int load_image(const char *filename, uint8_t *addr)
339 357  
340 358 void cpu_x86_outb(CPUX86State *env, int addr, int val)
341 359 {
342   - ioport_writeb_table[addr & (MAX_IOPORTS - 1)](env, addr, val);
  360 + ioport_write_table[0][addr & (MAX_IOPORTS - 1)](env, addr, val);
343 361 }
344 362  
345 363 void cpu_x86_outw(CPUX86State *env, int addr, int val)
346 364 {
347   - ioport_writew_table[addr & (MAX_IOPORTS - 1)](env, addr, val);
  365 + ioport_write_table[1][addr & (MAX_IOPORTS - 1)](env, addr, val);
348 366 }
349 367  
350 368 void cpu_x86_outl(CPUX86State *env, int addr, int val)
351 369 {
352   - fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);
  370 + ioport_write_table[2][addr & (MAX_IOPORTS - 1)](env, addr, val);
353 371 }
354 372  
355 373 int cpu_x86_inb(CPUX86State *env, int addr)
356 374 {
357   - return ioport_readb_table[addr & (MAX_IOPORTS - 1)](env, addr);
  375 + return ioport_read_table[0][addr & (MAX_IOPORTS - 1)](env, addr);
358 376 }
359 377  
360 378 int cpu_x86_inw(CPUX86State *env, int addr)
361 379 {
362   - return ioport_readw_table[addr & (MAX_IOPORTS - 1)](env, addr);
  380 + return ioport_read_table[1][addr & (MAX_IOPORTS - 1)](env, addr);
363 381 }
364 382  
365 383 int cpu_x86_inl(CPUX86State *env, int addr)
366 384 {
367   - fprintf(stderr, "inl: port=0x%04x\n", addr);
368   - return 0;
  385 + return ioport_read_table[2][addr & (MAX_IOPORTS - 1)](env, addr);
369 386 }
370 387  
371 388 /***********************************************************/
... ... @@ -511,8 +528,8 @@ void cmos_init(void)
511 528  
512 529 cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
513 530  
514   - register_ioport_writeb(0x70, 2, cmos_ioport_write);
515   - register_ioport_readb(0x70, 2, cmos_ioport_read);
  531 + register_ioport_write(0x70, 2, cmos_ioport_write, 1);
  532 + register_ioport_read(0x70, 2, cmos_ioport_read, 1);
516 533 }
517 534  
518 535 /***********************************************************/
... ... @@ -726,10 +743,10 @@ uint32_t pic_ioport_read(CPUX86State *env, uint32_t addr)
726 743  
727 744 void pic_init(void)
728 745 {
729   - register_ioport_writeb(0x20, 2, pic_ioport_write);
730   - register_ioport_readb(0x20, 2, pic_ioport_read);
731   - register_ioport_writeb(0xa0, 2, pic_ioport_write);
732   - register_ioport_readb(0xa0, 2, pic_ioport_read);
  746 + register_ioport_write(0x20, 2, pic_ioport_write, 1);
  747 + register_ioport_read(0x20, 2, pic_ioport_read, 1);
  748 + register_ioport_write(0xa0, 2, pic_ioport_write, 1);
  749 + register_ioport_read(0xa0, 2, pic_ioport_read, 1);
733 750 }
734 751  
735 752 /***********************************************************/
... ... @@ -1031,11 +1048,11 @@ void pit_init(void)
1031 1048 pit_load_count(s, 0);
1032 1049 }
1033 1050  
1034   - register_ioport_writeb(0x40, 4, pit_ioport_write);
1035   - register_ioport_readb(0x40, 3, pit_ioport_read);
  1051 + register_ioport_write(0x40, 4, pit_ioport_write, 1);
  1052 + register_ioport_read(0x40, 3, pit_ioport_read, 1);
1036 1053  
1037   - register_ioport_readb(0x61, 1, speaker_ioport_read);
1038   - register_ioport_writeb(0x61, 1, speaker_ioport_write);
  1054 + register_ioport_read(0x61, 1, speaker_ioport_read, 1);
  1055 + register_ioport_write(0x61, 1, speaker_ioport_write, 1);
1039 1056 }
1040 1057  
1041 1058 /***********************************************************/
... ... @@ -1277,8 +1294,8 @@ void serial_init(void)
1277 1294  
1278 1295 s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
1279 1296  
1280   - register_ioport_writeb(0x3f8, 8, serial_ioport_write);
1281   - register_ioport_readb(0x3f8, 8, serial_ioport_read);
  1297 + register_ioport_write(0x3f8, 8, serial_ioport_write, 1);
  1298 + register_ioport_read(0x3f8, 8, serial_ioport_read, 1);
1282 1299  
1283 1300 term_init();
1284 1301 }
... ... @@ -1444,7 +1461,7 @@ int net_init(void)
1444 1461 close(fd);
1445 1462 return -1;
1446 1463 }
1447   - printf("connected to host network interface: %s\n", ifr.ifr_name);
  1464 + printf("Connected to host network interface: %s\n", ifr.ifr_name);
1448 1465 fcntl(fd, F_SETFL, O_NONBLOCK);
1449 1466 net_fd = fd;
1450 1467  
... ... @@ -1739,20 +1756,625 @@ uint32_t ne2000_reset_ioport_read(CPUX86State *env, uint32_t addr)
1739 1756  
1740 1757 void ne2000_init(void)
1741 1758 {
1742   - register_ioport_writeb(NE2000_IOPORT, 16, ne2000_ioport_write);
1743   - register_ioport_readb(NE2000_IOPORT, 16, ne2000_ioport_read);
  1759 + register_ioport_write(NE2000_IOPORT, 16, ne2000_ioport_write, 1);
  1760 + register_ioport_read(NE2000_IOPORT, 16, ne2000_ioport_read, 1);
1744 1761  
1745   - register_ioport_writeb(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_write);
1746   - register_ioport_readb(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_read);
1747   - register_ioport_writew(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_write);
1748   - register_ioport_readw(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_read);
  1762 + register_ioport_write(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_write, 1);
  1763 + register_ioport_read(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_read, 1);
  1764 + register_ioport_write(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_write, 2);
  1765 + register_ioport_read(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_read, 2);
1749 1766  
1750   - register_ioport_writeb(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_write);
1751   - register_ioport_readb(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_read);
  1767 + register_ioport_write(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_write, 1);
  1768 + register_ioport_read(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_read, 1);
1752 1769 ne2000_reset();
1753 1770 }
1754 1771  
1755 1772 /***********************************************************/
  1773 +/* ide emulation */
  1774 +
  1775 +//#define DEBUG_IDE
  1776 +
  1777 +/* Bits of HD_STATUS */
  1778 +#define ERR_STAT 0x01
  1779 +#define INDEX_STAT 0x02
  1780 +#define ECC_STAT 0x04 /* Corrected error */
  1781 +#define DRQ_STAT 0x08
  1782 +#define SEEK_STAT 0x10
  1783 +#define SRV_STAT 0x10
  1784 +#define WRERR_STAT 0x20
  1785 +#define READY_STAT 0x40
  1786 +#define BUSY_STAT 0x80
  1787 +
  1788 +/* Bits for HD_ERROR */
  1789 +#define MARK_ERR 0x01 /* Bad address mark */
  1790 +#define TRK0_ERR 0x02 /* couldn't find track 0 */
  1791 +#define ABRT_ERR 0x04 /* Command aborted */
  1792 +#define MCR_ERR 0x08 /* media change request */
  1793 +#define ID_ERR 0x10 /* ID field not found */
  1794 +#define MC_ERR 0x20 /* media changed */
  1795 +#define ECC_ERR 0x40 /* Uncorrectable ECC error */
  1796 +#define BBD_ERR 0x80 /* pre-EIDE meaning: block marked bad */
  1797 +#define ICRC_ERR 0x80 /* new meaning: CRC error during transfer */
  1798 +
  1799 +/* Bits of HD_NSECTOR */
  1800 +#define CD 0x01
  1801 +#define IO 0x02
  1802 +#define REL 0x04
  1803 +#define TAG_MASK 0xf8
  1804 +
  1805 +#define IDE_CMD_RESET 0x04
  1806 +#define IDE_CMD_DISABLE_IRQ 0x02
  1807 +
  1808 +/* ATA/ATAPI Commands pre T13 Spec */
  1809 +#define WIN_NOP 0x00
  1810 +/*
  1811 + * 0x01->0x02 Reserved
  1812 + */
  1813 +#define CFA_REQ_EXT_ERROR_CODE 0x03 /* CFA Request Extended Error Code */
  1814 +/*
  1815 + * 0x04->0x07 Reserved
  1816 + */
  1817 +#define WIN_SRST 0x08 /* ATAPI soft reset command */
  1818 +#define WIN_DEVICE_RESET 0x08
  1819 +/*
  1820 + * 0x09->0x0F Reserved
  1821 + */
  1822 +#define WIN_RECAL 0x10
  1823 +#define WIN_RESTORE WIN_RECAL
  1824 +/*
  1825 + * 0x10->0x1F Reserved
  1826 + */
  1827 +#define WIN_READ 0x20 /* 28-Bit */
  1828 +#define WIN_READ_ONCE 0x21 /* 28-Bit without retries */
  1829 +#define WIN_READ_LONG 0x22 /* 28-Bit */
  1830 +#define WIN_READ_LONG_ONCE 0x23 /* 28-Bit without retries */
  1831 +#define WIN_READ_EXT 0x24 /* 48-Bit */
  1832 +#define WIN_READDMA_EXT 0x25 /* 48-Bit */
  1833 +#define WIN_READDMA_QUEUED_EXT 0x26 /* 48-Bit */
  1834 +#define WIN_READ_NATIVE_MAX_EXT 0x27 /* 48-Bit */
  1835 +/*
  1836 + * 0x28
  1837 + */
  1838 +#define WIN_MULTREAD_EXT 0x29 /* 48-Bit */
  1839 +/*
  1840 + * 0x2A->0x2F Reserved
  1841 + */
  1842 +#define WIN_WRITE 0x30 /* 28-Bit */
  1843 +#define WIN_WRITE_ONCE 0x31 /* 28-Bit without retries */
  1844 +#define WIN_WRITE_LONG 0x32 /* 28-Bit */
  1845 +#define WIN_WRITE_LONG_ONCE 0x33 /* 28-Bit without retries */
  1846 +#define WIN_WRITE_EXT 0x34 /* 48-Bit */
  1847 +#define WIN_WRITEDMA_EXT 0x35 /* 48-Bit */
  1848 +#define WIN_WRITEDMA_QUEUED_EXT 0x36 /* 48-Bit */
  1849 +#define WIN_SET_MAX_EXT 0x37 /* 48-Bit */
  1850 +#define CFA_WRITE_SECT_WO_ERASE 0x38 /* CFA Write Sectors without erase */
  1851 +#define WIN_MULTWRITE_EXT 0x39 /* 48-Bit */
  1852 +/*
  1853 + * 0x3A->0x3B Reserved
  1854 + */
  1855 +#define WIN_WRITE_VERIFY 0x3C /* 28-Bit */
  1856 +/*
  1857 + * 0x3D->0x3F Reserved
  1858 + */
  1859 +#define WIN_VERIFY 0x40 /* 28-Bit - Read Verify Sectors */
  1860 +#define WIN_VERIFY_ONCE 0x41 /* 28-Bit - without retries */
  1861 +#define WIN_VERIFY_EXT 0x42 /* 48-Bit */
  1862 +/*
  1863 + * 0x43->0x4F Reserved
  1864 + */
  1865 +#define WIN_FORMAT 0x50
  1866 +/*
  1867 + * 0x51->0x5F Reserved
  1868 + */
  1869 +#define WIN_INIT 0x60
  1870 +/*
  1871 + * 0x61->0x5F Reserved
  1872 + */
  1873 +#define WIN_SEEK 0x70 /* 0x70-0x7F Reserved */
  1874 +#define CFA_TRANSLATE_SECTOR 0x87 /* CFA Translate Sector */
  1875 +#define WIN_DIAGNOSE 0x90
  1876 +#define WIN_SPECIFY 0x91 /* set drive geometry translation */
  1877 +#define WIN_DOWNLOAD_MICROCODE 0x92
  1878 +#define WIN_STANDBYNOW2 0x94
  1879 +#define WIN_STANDBY2 0x96
  1880 +#define WIN_SETIDLE2 0x97
  1881 +#define WIN_CHECKPOWERMODE2 0x98
  1882 +#define WIN_SLEEPNOW2 0x99
  1883 +/*
  1884 + * 0x9A VENDOR
  1885 + */
  1886 +#define WIN_PACKETCMD 0xA0 /* Send a packet command. */
  1887 +#define WIN_PIDENTIFY 0xA1 /* identify ATAPI device */
  1888 +#define WIN_QUEUED_SERVICE 0xA2
  1889 +#define WIN_SMART 0xB0 /* self-monitoring and reporting */
  1890 +#define CFA_ERASE_SECTORS 0xC0
  1891 +#define WIN_MULTREAD 0xC4 /* read sectors using multiple mode*/
  1892 +#define WIN_MULTWRITE 0xC5 /* write sectors using multiple mode */
  1893 +#define WIN_SETMULT 0xC6 /* enable/disable multiple mode */
  1894 +#define WIN_READDMA_QUEUED 0xC7 /* read sectors using Queued DMA transfers */
  1895 +#define WIN_READDMA 0xC8 /* read sectors using DMA transfers */
  1896 +#define WIN_READDMA_ONCE 0xC9 /* 28-Bit - without retries */
  1897 +#define WIN_WRITEDMA 0xCA /* write sectors using DMA transfers */
  1898 +#define WIN_WRITEDMA_ONCE 0xCB /* 28-Bit - without retries */
  1899 +#define WIN_WRITEDMA_QUEUED 0xCC /* write sectors using Queued DMA transfers */
  1900 +#define CFA_WRITE_MULTI_WO_ERASE 0xCD /* CFA Write multiple without erase */
  1901 +#define WIN_GETMEDIASTATUS 0xDA
  1902 +#define WIN_ACKMEDIACHANGE 0xDB /* ATA-1, ATA-2 vendor */
  1903 +#define WIN_POSTBOOT 0xDC
  1904 +#define WIN_PREBOOT 0xDD
  1905 +#define WIN_DOORLOCK 0xDE /* lock door on removable drives */
  1906 +#define WIN_DOORUNLOCK 0xDF /* unlock door on removable drives */
  1907 +#define WIN_STANDBYNOW1 0xE0
  1908 +#define WIN_IDLEIMMEDIATE 0xE1 /* force drive to become "ready" */
  1909 +#define WIN_STANDBY 0xE2 /* Set device in Standby Mode */
  1910 +#define WIN_SETIDLE1 0xE3
  1911 +#define WIN_READ_BUFFER 0xE4 /* force read only 1 sector */
  1912 +#define WIN_CHECKPOWERMODE1 0xE5
  1913 +#define WIN_SLEEPNOW1 0xE6
  1914 +#define WIN_FLUSH_CACHE 0xE7
  1915 +#define WIN_WRITE_BUFFER 0xE8 /* force write only 1 sector */
  1916 +#define WIN_WRITE_SAME 0xE9 /* read ata-2 to use */
  1917 + /* SET_FEATURES 0x22 or 0xDD */
  1918 +#define WIN_FLUSH_CACHE_EXT 0xEA /* 48-Bit */
  1919 +#define WIN_IDENTIFY 0xEC /* ask drive to identify itself */
  1920 +#define WIN_MEDIAEJECT 0xED
  1921 +#define WIN_IDENTIFY_DMA 0xEE /* same as WIN_IDENTIFY, but DMA */
  1922 +#define WIN_SETFEATURES 0xEF /* set special drive features */
  1923 +#define EXABYTE_ENABLE_NEST 0xF0
  1924 +#define WIN_SECURITY_SET_PASS 0xF1
  1925 +#define WIN_SECURITY_UNLOCK 0xF2
  1926 +#define WIN_SECURITY_ERASE_PREPARE 0xF3
  1927 +#define WIN_SECURITY_ERASE_UNIT 0xF4
  1928 +#define WIN_SECURITY_FREEZE_LOCK 0xF5
  1929 +#define WIN_SECURITY_DISABLE 0xF6
  1930 +#define WIN_READ_NATIVE_MAX 0xF8 /* return the native maximum address */
  1931 +#define WIN_SET_MAX 0xF9
  1932 +#define DISABLE_SEAGATE 0xFB
  1933 +
  1934 +#define MAX_MULT_SECTORS 16
  1935 +
  1936 +#define MAX_DISKS 2
  1937 +
  1938 +struct IDEState;
  1939 +
  1940 +typedef void EndTransferFunc(struct IDEState *);
  1941 +
  1942 +typedef struct IDEState {
  1943 + /* ide config */
  1944 + int cylinders, heads, sectors;
  1945 + int64_t nb_sectors;
  1946 + int mult_sectors;
  1947 + int irq;
  1948 + /* ide regs */
  1949 + uint8_t feature;
  1950 + uint8_t error;
  1951 + uint8_t nsector;
  1952 + uint8_t sector;
  1953 + uint8_t lcyl;
  1954 + uint8_t hcyl;
  1955 + uint8_t select;
  1956 + uint8_t status;
  1957 + /* 0x3f6 command, only meaningful for drive 0 */
  1958 + uint8_t cmd;
  1959 + /* depends on bit 4 in select, only meaningful for drive 0 */
  1960 + struct IDEState *cur_drive;
  1961 + BlockDriverState *bs;
  1962 + EndTransferFunc *end_transfer_func;
  1963 + uint8_t *data_ptr;
  1964 + uint8_t *data_end;
  1965 + uint8_t io_buffer[MAX_MULT_SECTORS*512 + 4];
  1966 +} IDEState;
  1967 +
  1968 +BlockDriverState *bs_table[MAX_DISKS];
  1969 +IDEState ide_state[MAX_DISKS];
  1970 +
  1971 +static void padstr(char *str, const char *src, int len)
  1972 +{
  1973 + int i, v;
  1974 + for(i = 0; i < len; i++) {
  1975 + if (*src)
  1976 + v = *src++;
  1977 + else
  1978 + v = ' ';
  1979 + *(char *)((long)str ^ 1) = v;
  1980 + str++;
  1981 + }
  1982 +}
  1983 +
  1984 +static void ide_identify(IDEState *s)
  1985 +{
  1986 + uint16_t *p;
  1987 + unsigned int oldsize;
  1988 +
  1989 + memset(s->io_buffer, 0, 512);
  1990 + p = (uint16_t *)s->io_buffer;
  1991 + stw(p + 0, 0x0040);
  1992 + stw(p + 1, s->cylinders);
  1993 + stw(p + 3, s->heads);
  1994 + stw(p + 4, 512 * s->sectors); /* sectors */
  1995 + stw(p + 5, 512); /* sector size */
  1996 + stw(p + 6, s->sectors);
  1997 + stw(p + 20, 3); /* buffer type */
  1998 + stw(p + 21, 512); /* cache size in sectors */
  1999 + stw(p + 22, 4); /* ecc bytes */
  2000 + padstr((uint8_t *)(p + 27), "QEMU HARDDISK", 40);
  2001 + // stw(p + 47, MAX_MULT_SECTORS);
  2002 + stw(p + 48, 1); /* dword I/O */
  2003 + stw(p + 49, 1 << 9); /* LBA supported, no DMA */
  2004 + stw(p + 51, 0x200); /* PIO transfer cycle */
  2005 + stw(p + 52, 0x200); /* DMA transfer cycle */
  2006 + stw(p + 54, s->cylinders);
  2007 + stw(p + 55, s->heads);
  2008 + stw(p + 56, s->sectors);
  2009 + oldsize = s->cylinders * s->heads * s->sectors;
  2010 + stw(p + 57, oldsize);
  2011 + stw(p + 58, oldsize >> 16);
  2012 + if (s->mult_sectors)
  2013 + stw(p + 59, 0x100 | s->mult_sectors);
  2014 + stw(p + 60, s->nb_sectors);
  2015 + stw(p + 61, s->nb_sectors >> 16);
  2016 + stw(p + 80, (1 << 1) | (1 << 2));
  2017 + stw(p + 82, (1 << 14));
  2018 + stw(p + 83, (1 << 14));
  2019 + stw(p + 84, (1 << 14));
  2020 + stw(p + 85, (1 << 14));
  2021 + stw(p + 86, 0);
  2022 + stw(p + 87, (1 << 14));
  2023 +}
  2024 +
  2025 +static inline void ide_abort_command(IDEState *s)
  2026 +{
  2027 + s->status = READY_STAT | ERR_STAT;
  2028 + s->error = ABRT_ERR;
  2029 +}
  2030 +
  2031 +static inline void ide_set_irq(IDEState *s)
  2032 +{
  2033 + if (!(ide_state[0].cmd & IDE_CMD_DISABLE_IRQ)) {
  2034 + pic_set_irq(s->irq, 1);
  2035 + cpu_x86_interrupt(global_env);
  2036 + }
  2037 +}
  2038 +
  2039 +/* prepare data transfer and tell what to do after */
  2040 +static void ide_transfer_start(IDEState *s, int size,
  2041 + EndTransferFunc *end_transfer_func)
  2042 +{
  2043 + s->end_transfer_func = end_transfer_func;
  2044 + s->data_ptr = s->io_buffer;
  2045 + s->data_end = s->io_buffer + size;
  2046 + s->status |= DRQ_STAT;
  2047 +}
  2048 +
  2049 +static void ide_transfer_stop(IDEState *s)
  2050 +{
  2051 + s->end_transfer_func = ide_transfer_stop;
  2052 + s->data_ptr = s->io_buffer;
  2053 + s->data_end = s->io_buffer;
  2054 + s->status &= ~DRQ_STAT;
  2055 +}
  2056 +
  2057 +static int64_t ide_get_sector(IDEState *s)
  2058 +{
  2059 + int64_t sector_num;
  2060 + if (s->select & 0x40) {
  2061 + /* lba */
  2062 + sector_num = ((s->select & 0x0f) << 24) | (s->hcyl << 16) |
  2063 + (s->lcyl << 8) | s->sector;
  2064 + } else {
  2065 + sector_num = ((s->hcyl << 8) | s->lcyl) * s->heads * s->sectors +
  2066 + (s->select & 0x0f) * s->sectors +
  2067 + (s->sector - 1);
  2068 + }
  2069 + return sector_num;
  2070 +}
  2071 +
  2072 +static void ide_set_sector(IDEState *s, int64_t sector_num)
  2073 +{
  2074 + unsigned int cyl, r;
  2075 + if (s->select & 0x40) {
  2076 + s->select = (s->select & 0xf0) | (sector_num >> 24);
  2077 + s->hcyl = (sector_num >> 16);
  2078 + s->lcyl = (sector_num >> 8);
  2079 + s->sector = (sector_num);
  2080 + } else {
  2081 + cyl = sector_num / (s->heads * s->sectors);
  2082 + r = sector_num % (s->heads * s->sectors);
  2083 + s->hcyl = cyl >> 8;
  2084 + s->lcyl = cyl;
  2085 + s->select = (s->select & 0xf0) | (r / s->sectors);
  2086 + s->sector = (r % s->sectors) + 1;
  2087 + }
  2088 +}
  2089 +
  2090 +static void ide_sector_read(IDEState *s)
  2091 +{
  2092 + int64_t sector_num;
  2093 + int ret;
  2094 +
  2095 + s->status = READY_STAT | SEEK_STAT;
  2096 + sector_num = ide_get_sector(s);
  2097 + s->nsector--;
  2098 + if (s->nsector == 0xff) {
  2099 + /* no more sector to read from disk */
  2100 + ide_transfer_stop(s);
  2101 + } else {
  2102 +#if defined(DEBUG_IDE)
  2103 + printf("read sector=%Ld\n", sector_num);
  2104 +#endif
  2105 + ret = bdrv_read(s->bs, sector_num, s->io_buffer, 1);
  2106 + ide_transfer_start(s, 512, ide_sector_read);
  2107 + ide_set_irq(s);
  2108 + }
  2109 + ide_set_sector(s, sector_num + 1);
  2110 +}
  2111 +
  2112 +static void ide_sector_write(IDEState *s)
  2113 +{
  2114 + int64_t sector_num;
  2115 + int ret;
  2116 +
  2117 + s->status = READY_STAT | SEEK_STAT;
  2118 + sector_num = ide_get_sector(s);
  2119 +#if defined(DEBUG_IDE)
  2120 + printf("write sector=%Ld\n", sector_num);
  2121 +#endif
  2122 + ret = bdrv_write(s->bs, sector_num, s->io_buffer, 1);
  2123 + s->nsector--;
  2124 + if (s->nsector == 0) {
  2125 + /* no more sector to write */
  2126 + ide_transfer_stop(s);
  2127 + } else {
  2128 + ide_transfer_start(s, 512, ide_sector_write);
  2129 + }
  2130 + ide_set_sector(s, sector_num + 1);
  2131 + ide_set_irq(s);
  2132 +}
  2133 +
  2134 +void ide_ioport_write(CPUX86State *env, uint32_t addr, uint32_t val)
  2135 +{
  2136 + IDEState *s = ide_state[0].cur_drive;
  2137 + int unit;
  2138 +
  2139 + addr &= 7;
  2140 +#ifdef DEBUG_IDE
  2141 + printf("IDE: write addr=0x%x val=0x%02x\n", addr, val);
  2142 +#endif
  2143 + switch(addr) {
  2144 + case 0:
  2145 + break;
  2146 + case 1:
  2147 + s->feature = val;
  2148 + break;
  2149 + case 2:
  2150 + s->nsector = val;
  2151 + break;
  2152 + case 3:
  2153 + s->sector = val;
  2154 + break;
  2155 + case 4:
  2156 + s->lcyl = val;
  2157 + break;
  2158 + case 5:
  2159 + s->hcyl = val;
  2160 + break;
  2161 + case 6:
  2162 + /* select drive */
  2163 + unit = (val >> 4) & 1;
  2164 + s = &ide_state[unit];
  2165 + ide_state[0].cur_drive = s;
  2166 + s->select = val;
  2167 + break;
  2168 + default:
  2169 + case 7:
  2170 + /* command */
  2171 +#if defined(DEBUG_IDE)
  2172 + printf("ide: CMD=%02x\n", val);
  2173 +#endif
  2174 + switch(val) {
  2175 + case WIN_PIDENTIFY:
  2176 + case WIN_IDENTIFY:
  2177 + if (s->bs) {
  2178 + ide_identify(s);
  2179 + s->status = READY_STAT;
  2180 + ide_transfer_start(s, 512, ide_transfer_stop);
  2181 + } else {
  2182 + ide_abort_command(s);
  2183 + }
  2184 + ide_set_irq(s);
  2185 + break;
  2186 + case WIN_SPECIFY:
  2187 + case WIN_RECAL:
  2188 + s->status = READY_STAT;
  2189 + ide_set_irq(s);
  2190 + break;
  2191 + case WIN_SETMULT:
  2192 + if (s->nsector > MAX_MULT_SECTORS ||
  2193 + s->nsector == 0 ||
  2194 + (s->nsector & (s->nsector - 1)) != 0) {
  2195 + ide_abort_command(s);
  2196 + } else {
  2197 + s->mult_sectors = s->nsector;
  2198 + s->status = READY_STAT;
  2199 + }
  2200 + ide_set_irq(s);
  2201 + break;
  2202 + case WIN_READ:
  2203 + case WIN_READ_ONCE:
  2204 + ide_sector_read(s);
  2205 + break;
  2206 + case WIN_WRITE:
  2207 + case WIN_WRITE_ONCE:
  2208 + s->status = SEEK_STAT;
  2209 + ide_transfer_start(s, 512, ide_sector_write);
  2210 + break;
  2211 + default:
  2212 + ide_abort_command(s);
  2213 + ide_set_irq(s);
  2214 + break;
  2215 + }
  2216 + }
  2217 +}
  2218 +
  2219 +uint32_t ide_ioport_read(CPUX86State *env, uint32_t addr)
  2220 +{
  2221 + IDEState *s = ide_state[0].cur_drive;
  2222 + int ret;
  2223 +
  2224 + addr &= 7;
  2225 + switch(addr) {
  2226 + case 0:
  2227 + ret = 0xff;
  2228 + break;
  2229 + case 1:
  2230 + ret = s->error;
  2231 + break;
  2232 + case 2:
  2233 + ret = s->nsector;
  2234 + break;
  2235 + case 3:
  2236 + ret = s->sector;
  2237 + break;
  2238 + case 4:
  2239 + ret = s->lcyl;
  2240 + break;
  2241 + case 5:
  2242 + ret = s->hcyl;
  2243 + break;
  2244 + case 6:
  2245 + ret = s->select;
  2246 + break;
  2247 + default:
  2248 + case 7:
  2249 + ret = s->status;
  2250 + pic_set_irq(s->irq, 0);
  2251 + break;
  2252 + }
  2253 +#ifdef DEBUG_IDE
  2254 + printf("ide: read addr=0x%x val=%02x\n", addr, ret);
  2255 +#endif
  2256 + return ret;
  2257 +}
  2258 +
  2259 +uint32_t ide_status_read(CPUX86State *env, uint32_t addr)
  2260 +{
  2261 + IDEState *s = ide_state[0].cur_drive;
  2262 + int ret;
  2263 + ret = s->status;
  2264 +#ifdef DEBUG_IDE
  2265 + printf("ide: read addr=0x%x val=%02x\n", addr, ret);
  2266 +#endif
  2267 + return ret;
  2268 +}
  2269 +
  2270 +void ide_cmd_write(CPUX86State *env, uint32_t addr, uint32_t val)
  2271 +{
  2272 + IDEState *s = &ide_state[0];
  2273 + /* common for both drives */
  2274 + s->cmd = val;
  2275 +}
  2276 +
  2277 +void ide_data_writew(CPUX86State *env, uint32_t addr, uint32_t val)
  2278 +{
  2279 + IDEState *s = ide_state[0].cur_drive;
  2280 + uint8_t *p;
  2281 +
  2282 + p = s->data_ptr;
  2283 + *(uint16_t *)p = tswap16(val);
  2284 + p += 2;
  2285 + s->data_ptr = p;
  2286 + if (p >= s->data_end)
  2287 + s->end_transfer_func(s);
  2288 +}
  2289 +
  2290 +uint32_t ide_data_readw(CPUX86State *env, uint32_t addr)
  2291 +{
  2292 + IDEState *s = ide_state[0].cur_drive;
  2293 + uint8_t *p;
  2294 + int ret;
  2295 +
  2296 + p = s->data_ptr;
  2297 + ret = tswap16(*(uint16_t *)p);
  2298 + p += 2;
  2299 + s->data_ptr = p;
  2300 + if (p >= s->data_end)
  2301 + s->end_transfer_func(s);
  2302 + return ret;
  2303 +}
  2304 +
  2305 +void ide_data_writel(CPUX86State *env, uint32_t addr, uint32_t val)
  2306 +{
  2307 + IDEState *s = ide_state[0].cur_drive;
  2308 + uint8_t *p;
  2309 +
  2310 + p = s->data_ptr;
  2311 + *(uint32_t *)p = tswap32(val);
  2312 + p += 4;
  2313 + s->data_ptr = p;
  2314 + if (p >= s->data_end)
  2315 + s->end_transfer_func(s);
  2316 +}
  2317 +
  2318 +uint32_t ide_data_readl(CPUX86State *env, uint32_t addr)
  2319 +{
  2320 + IDEState *s = ide_state[0].cur_drive;
  2321 + uint8_t *p;
  2322 + int ret;
  2323 +
  2324 + p = s->data_ptr;
  2325 + ret = tswap32(*(uint32_t *)p);
  2326 + p += 4;
  2327 + s->data_ptr = p;
  2328 + if (p >= s->data_end)
  2329 + s->end_transfer_func(s);
  2330 + return ret;
  2331 +}
  2332 +
  2333 +void ide_reset(IDEState *s)
  2334 +{
  2335 + s->mult_sectors = MAX_MULT_SECTORS;
  2336 + s->status = READY_STAT;
  2337 + s->cur_drive = s;
  2338 + s->select = 0xa0;
  2339 +}
  2340 +
  2341 +void ide_init(void)
  2342 +{
  2343 + IDEState *s;
  2344 + int i, cylinders;
  2345 + int64_t nb_sectors;
  2346 +
  2347 + for(i = 0; i < MAX_DISKS; i++) {
  2348 + s = &ide_state[i];
  2349 + s->bs = bs_table[i];
  2350 + if (s->bs) {
  2351 + bdrv_get_geometry(s->bs, &nb_sectors);
  2352 + cylinders = nb_sectors / (16 * 63);
  2353 + if (cylinders > 16383)
  2354 + cylinders = 16383;
  2355 + else if (cylinders < 2)
  2356 + cylinders = 2;
  2357 + s->cylinders = cylinders;
  2358 + s->heads = 16;
  2359 + s->sectors = 63;
  2360 + s->nb_sectors = nb_sectors;
  2361 + }
  2362 + s->irq = 14;
  2363 + ide_reset(s);
  2364 + }
  2365 + register_ioport_write(0x1f0, 8, ide_ioport_write, 1);
  2366 + register_ioport_read(0x1f0, 8, ide_ioport_read, 1);
  2367 + register_ioport_read(0x3f6, 1, ide_status_read, 1);
  2368 + register_ioport_write(0x3f6, 1, ide_cmd_write, 1);
  2369 +
  2370 + /* data ports */
  2371 + register_ioport_write(0x1f0, 2, ide_data_writew, 2);
  2372 + register_ioport_read(0x1f0, 2, ide_data_readw, 2);
  2373 + register_ioport_write(0x1f0, 4, ide_data_writel, 4);
  2374 + register_ioport_read(0x1f0, 4, ide_data_readl, 4);
  2375 +}
  2376 +
  2377 +/***********************************************************/
1756 2378 /* cpu signal handler */
1757 2379 static void host_segv_handler(int host_signum, siginfo_t *info,
1758 2380 void *puc)
... ... @@ -1873,16 +2495,22 @@ void main_loop(void *opaque)
1873 2495 void help(void)
1874 2496 {
1875 2497 printf("Virtual Linux version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
1876   - "usage: vl [options] bzImage initrd [kernel parameters...]\n"
  2498 + "usage: vl [options] bzImage [kernel parameters...]\n"
1877 2499 "\n"
1878 2500 "'bzImage' is a Linux kernel image (PAGE_OFFSET must be defined\n"
1879 2501 "to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"
1880   - "'initrd' is an initrd image\n"
1881   - "-m megs set virtual RAM size to megs MB\n"
1882   - "-n script set network init script [default=%s]\n"
1883   - "-s wait gdb connection to port %d\n"
1884   - "-p port change gdb connection port\n"
1885   - "-d output log in /tmp/vl.log\n"
  2502 + "\n"
  2503 + "General options:\n"
  2504 + "-initrd file use 'file' as initial ram disk\n"
  2505 + "-hda file use 'file' as hard disk 0 image\n"
  2506 + "-hdb file use 'file' as hard disk 1 image\n"
  2507 + "-m megs set virtual RAM size to megs MB\n"
  2508 + "-n script set network init script [default=%s]\n"
  2509 + "\n"
  2510 + "Debug options:\n"
  2511 + "-s wait gdb connection to port %d\n"
  2512 + "-p port change gdb connection port\n"
  2513 + "-d output log in /tmp/vl.log\n"
1886 2514 "\n"
1887 2515 "During emulation, use C-a h to get terminal commands:\n",
1888 2516 DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT);
... ... @@ -1890,27 +2518,50 @@ void help(void)
1890 2518 exit(1);
1891 2519 }
1892 2520  
  2521 +struct option long_options[] = {
  2522 + { "initrd", 1, NULL, 0, },
  2523 + { "hda", 1, NULL, 0, },
  2524 + { "hdb", 1, NULL, 0, },
  2525 + { NULL, 0, NULL, 0 },
  2526 +};
  2527 +
1893 2528 int main(int argc, char **argv)
1894 2529 {
1895   - int c, ret, initrd_size, i, use_gdbstub, gdbstub_port;
  2530 + int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
1896 2531 struct linux_params *params;
1897 2532 struct sigaction act;
1898 2533 struct itimerval itv;
1899 2534 CPUX86State *env;
1900   - const char *tmpdir;
  2535 + const char *tmpdir, *initrd_filename;
  2536 + const char *hd_filename[MAX_DISKS];
1901 2537  
1902 2538 /* we never want that malloc() uses mmap() */
1903 2539 mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
1904   -
  2540 + initrd_filename = NULL;
  2541 + for(i = 0; i < MAX_DISKS; i++)
  2542 + hd_filename[i] = NULL;
1905 2543 phys_ram_size = 32 * 1024 * 1024;
1906 2544 pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
1907 2545 use_gdbstub = 0;
1908 2546 gdbstub_port = DEFAULT_GDBSTUB_PORT;
1909 2547 for(;;) {
1910   - c = getopt(argc, argv, "hm:dn:sp:");
  2548 + c = getopt_long_only(argc, argv, "hm:dn:sp:", long_options, &long_index);
1911 2549 if (c == -1)
1912 2550 break;
1913 2551 switch(c) {
  2552 + case 0:
  2553 + switch(long_index) {
  2554 + case 0:
  2555 + initrd_filename = optarg;
  2556 + break;
  2557 + case 1:
  2558 + hd_filename[0] = optarg;
  2559 + break;
  2560 + case 2:
  2561 + hd_filename[1] = optarg;
  2562 + break;
  2563 + }
  2564 + break;
1914 2565 case 'h':
1915 2566 help();
1916 2567 break;
... ... @@ -1933,7 +2584,7 @@ int main(int argc, char **argv)
1933 2584 break;
1934 2585 }
1935 2586 }
1936   - if (optind + 1 >= argc)
  2587 + if (optind >= argc)
1937 2588 help();
1938 2589  
1939 2590 /* init debug */
... ... @@ -1946,6 +2597,18 @@ int main(int argc, char **argv)
1946 2597 setvbuf(logfile, NULL, _IOLBF, 0);
1947 2598 }
1948 2599  
  2600 + /* open the virtual block devices */
  2601 + for(i = 0; i < MAX_DISKS; i++) {
  2602 + if (hd_filename[i]) {
  2603 + bs_table[i] = bdrv_open(hd_filename[i]);
  2604 + if (!bs_table[i]) {
  2605 + fprintf(stderr, "vl: could not open hard disk image '%s\n",
  2606 + hd_filename[i]);
  2607 + exit(1);
  2608 + }
  2609 + }
  2610 + }
  2611 +
1949 2612 /* init network tun interface */
1950 2613 net_init();
1951 2614  
... ... @@ -1978,15 +2641,19 @@ int main(int argc, char **argv)
1978 2641 /* now we can load the kernel */
1979 2642 ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);
1980 2643 if (ret < 0) {
1981   - fprintf(stderr, "%s: could not load kernel\n", argv[optind]);
  2644 + fprintf(stderr, "vl: could not load kernel '%s'\n", argv[optind]);
1982 2645 exit(1);
1983 2646 }
1984 2647  
1985 2648 /* load initrd */
1986   - initrd_size = load_image(argv[optind + 1], phys_ram_base + INITRD_LOAD_ADDR);
1987   - if (initrd_size < 0) {
1988   - fprintf(stderr, "%s: could not load initrd\n", argv[optind + 1]);
1989   - exit(1);
  2649 + initrd_size = 0;
  2650 + if (initrd_filename) {
  2651 + initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
  2652 + if (initrd_size < 0) {
  2653 + fprintf(stderr, "vl: could not load initial ram disk '%s'\n",
  2654 + initrd_filename);
  2655 + exit(1);
  2656 + }
1990 2657 }
1991 2658  
1992 2659 /* init kernel params */
... ... @@ -1996,8 +2663,8 @@ int main(int argc, char **argv)
1996 2663 params->cl_magic = 0xA33F;
1997 2664 params->cl_offset = params->commandline - (uint8_t *)params;
1998 2665 params->ext_mem_k = (phys_ram_size / 1024) - 1024;
1999   - for(i = optind + 2; i < argc; i++) {
2000   - if (i != optind + 2)
  2666 + for(i = optind + 1; i < argc; i++) {
  2667 + if (i != optind + 1)
2001 2668 pstrcat(params->commandline, sizeof(params->commandline), " ");
2002 2669 pstrcat(params->commandline, sizeof(params->commandline), argv[i]);
2003 2670 }
... ... @@ -2011,15 +2678,16 @@ int main(int argc, char **argv)
2011 2678  
2012 2679 /* init basic PC hardware */
2013 2680 init_ioports();
2014   - register_ioport_writeb(0x80, 1, ioport80_write);
  2681 + register_ioport_write(0x80, 1, ioport80_write, 1);
2015 2682  
2016   - register_ioport_writeb(0x3d4, 2, vga_ioport_write);
  2683 + register_ioport_write(0x3d4, 2, vga_ioport_write, 1);
2017 2684  
2018 2685 cmos_init();
2019 2686 pic_init();
2020 2687 pit_init();
2021 2688 serial_init();
2022 2689 ne2000_init();
  2690 + ide_init();
2023 2691  
2024 2692 /* setup cpu signal handlers for MMU / self modifying code handling */
2025 2693 sigfillset(&act.sa_mask);
... ...
vl.h 0 → 100644
  1 +/*
  2 + * QEMU System Emulator header
  3 + *
  4 + * Copyright (c) 2003 Fabrice Bellard
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +#ifndef VL_H
  25 +#define VL_H
  26 +
  27 +/* block.c */
  28 +typedef struct BlockDriverState BlockDriverState;
  29 +
  30 +BlockDriverState *bdrv_open(const char *filename);
  31 +void bdrv_close(BlockDriverState *bs);
  32 +int bdrv_read(BlockDriverState *bs, int64_t sector_num,
  33 + uint8_t *buf, int nb_sectors);
  34 +int bdrv_write(BlockDriverState *bs, int64_t sector_num,
  35 + const uint8_t *buf, int nb_sectors);
  36 +void bdrv_get_geometry(BlockDriverState *bs, int64_t *nb_sectors_ptr);
  37 +
  38 +
  39 +#endif /* VL_H */
... ...