/[qemu]/qemu/vl.c
ViewVC logotype

Diff of /qemu/vl.c

Parent Directory Parent Directory | Revision Log Revision Log | View Patch Patch

revision 1.5 by bellard, Fri Jun 27 17:34:32 2003 UTC revision 1.6 by bellard, Mon Jun 30 10:03:06 2003 UTC
# Line 46  Line 46 
46    
47  #include "cpu-i386.h"  #include "cpu-i386.h"
48  #include "disas.h"  #include "disas.h"
49    #include "thunk.h"
50    
51    #include "vl.h"
52    
53  #define DEBUG_LOGFILE "/tmp/vl.log"  #define DEBUG_LOGFILE "/tmp/vl.log"
54  #define DEFAULT_NETWORK_SCRIPT "/etc/vl-ifup"  #define DEFAULT_NETWORK_SCRIPT "/etc/vl-ifup"
# Line 175  struct  __attribute__ ((packed)) linux_p Line 178  struct  __attribute__ ((packed)) linux_p
178  typedef void (IOPortWriteFunc)(CPUX86State *env, uint32_t address, uint32_t data);  typedef void (IOPortWriteFunc)(CPUX86State *env, uint32_t address, uint32_t data);
179  typedef uint32_t (IOPortReadFunc)(CPUX86State *env, uint32_t address);  typedef uint32_t (IOPortReadFunc)(CPUX86State *env, uint32_t address);
180    
181  #define MAX_IOPORTS 1024  #define MAX_IOPORTS 4096
182    
183  char phys_ram_file[1024];  char phys_ram_file[1024];
184  CPUX86State *global_env;  CPUX86State *global_env;
185  CPUX86State *cpu_single_env;  CPUX86State *cpu_single_env;
186  FILE *logfile = NULL;  FILE *logfile = NULL;
187  int loglevel;  int loglevel;
188  IOPortReadFunc *ioport_readb_table[MAX_IOPORTS];  IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
189  IOPortWriteFunc *ioport_writeb_table[MAX_IOPORTS];  IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
 IOPortReadFunc *ioport_readw_table[MAX_IOPORTS];  
 IOPortWriteFunc *ioport_writew_table[MAX_IOPORTS];  
190    
191  /***********************************************************/  /***********************************************************/
192  /* x86 io ports */  /* x86 io ports */
# Line 195  uint32_t default_ioport_readb(CPUX86Stat Line 196  uint32_t default_ioport_readb(CPUX86Stat
196  #ifdef DEBUG_UNUSED_IOPORT  #ifdef DEBUG_UNUSED_IOPORT
197      fprintf(stderr, "inb: port=0x%04x\n", address);      fprintf(stderr, "inb: port=0x%04x\n", address);
198  #endif  #endif
199      return 0;      return 0xff;
200  }  }
201    
202  void default_ioport_writeb(CPUX86State *env, uint32_t address, uint32_t data)  void default_ioport_writeb(CPUX86State *env, uint32_t address, uint32_t data)
# Line 209  void default_ioport_writeb(CPUX86State * Line 210  void default_ioport_writeb(CPUX86State *
210  uint32_t default_ioport_readw(CPUX86State *env, uint32_t address)  uint32_t default_ioport_readw(CPUX86State *env, uint32_t address)
211  {  {
212      uint32_t data;      uint32_t data;
213      data = ioport_readb_table[address](env, address);      data = ioport_read_table[0][address](env, address);
214      data |= ioport_readb_table[address + 1](env, address + 1) << 8;      data |= ioport_read_table[0][address + 1](env, address + 1) << 8;
215      return data;      return data;
216  }  }
217    
218  void default_ioport_writew(CPUX86State *env, uint32_t address, uint32_t data)  void default_ioport_writew(CPUX86State *env, uint32_t address, uint32_t data)
219  {  {
220      ioport_writeb_table[address](env, address, data & 0xff);      ioport_write_table[0][address](env, address, data & 0xff);
221      ioport_writeb_table[address + 1](env, address + 1, (data >> 8) & 0xff);      ioport_write_table[0][address + 1](env, address + 1, (data >> 8) & 0xff);
222  }  }
223    
224  void init_ioports(void)  uint32_t default_ioport_readl(CPUX86State *env, uint32_t address)
225  {  {
226      int i;  #ifdef DEBUG_UNUSED_IOPORT
227        fprintf(stderr, "inl: port=0x%04x\n", address);
228      for(i = 0; i < MAX_IOPORTS; i++) {  #endif
229          ioport_readb_table[i] = default_ioport_readb;      return 0xffffffff;
         ioport_writeb_table[i] = default_ioport_writeb;  
         ioport_readw_table[i] = default_ioport_readw;  
         ioport_writew_table[i] = default_ioport_writew;  
     }  
230  }  }
231    
232  int register_ioport_readb(int start, int length, IOPortReadFunc *func)  void default_ioport_writel(CPUX86State *env, uint32_t address, uint32_t data)
233  {  {
234      int i;  #ifdef DEBUG_UNUSED_IOPORT
235        fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
236      for(i = start; i < start + length; i++)  #endif
         ioport_readb_table[i] = func;  
     return 0;  
237  }  }
238    
239  int register_ioport_writeb(int start, int length, IOPortWriteFunc *func)  void init_ioports(void)
240  {  {
241      int i;      int i;
242    
243      for(i = start; i < start + length; i++)      for(i = 0; i < MAX_IOPORTS; i++) {
244          ioport_writeb_table[i] = func;          ioport_read_table[0][i] = default_ioport_readb;
245      return 0;          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  }  }
252    
253  int register_ioport_readw(int start, int length, IOPortReadFunc *func)  /* size is the word size in byte */
254  {  int register_ioport_read(int start, int length, IOPortReadFunc *func, int size)
255      int i;  {
256        int i, bsize;
257      for(i = start; i < start + length; i += 2)  
258          ioport_readw_table[i] = func;      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;
268      return 0;      return 0;
269  }  }
270    
271  int register_ioport_writew(int start, int length, IOPortWriteFunc *func)  /* size is the word size in byte */
272    int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size)
273  {  {
274      int i;      int i, bsize;
275    
276      for(i = start; i < start + length; i += 2)      if (size == 1)
277          ioport_writew_table[i] = func;          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;
286      return 0;      return 0;
287  }  }
288    
# Line 339  int load_image(const char *filename, uin Line 357  int load_image(const char *filename, uin
357    
358  void cpu_x86_outb(CPUX86State *env, int addr, int val)  void cpu_x86_outb(CPUX86State *env, int addr, int val)
359  {  {
360      ioport_writeb_table[addr & (MAX_IOPORTS - 1)](env, addr, val);      ioport_write_table[0][addr & (MAX_IOPORTS - 1)](env, addr, val);
361  }  }
362    
363  void cpu_x86_outw(CPUX86State *env, int addr, int val)  void cpu_x86_outw(CPUX86State *env, int addr, int val)
364  {  {
365      ioport_writew_table[addr & (MAX_IOPORTS - 1)](env, addr, val);      ioport_write_table[1][addr & (MAX_IOPORTS - 1)](env, addr, val);
366  }  }
367    
368  void cpu_x86_outl(CPUX86State *env, int addr, int val)  void cpu_x86_outl(CPUX86State *env, int addr, int val)
369  {  {
370      fprintf(stderr, "outl: port=0x%04x, data=%08x\n", addr, val);      ioport_write_table[2][addr & (MAX_IOPORTS - 1)](env, addr, val);
371  }  }
372    
373  int cpu_x86_inb(CPUX86State *env, int addr)  int cpu_x86_inb(CPUX86State *env, int addr)
374  {  {
375      return ioport_readb_table[addr & (MAX_IOPORTS - 1)](env, addr);      return ioport_read_table[0][addr & (MAX_IOPORTS - 1)](env, addr);
376  }  }
377    
378  int cpu_x86_inw(CPUX86State *env, int addr)  int cpu_x86_inw(CPUX86State *env, int addr)
379  {  {
380      return ioport_readw_table[addr & (MAX_IOPORTS - 1)](env, addr);      return ioport_read_table[1][addr & (MAX_IOPORTS - 1)](env, addr);
381  }  }
382    
383  int cpu_x86_inl(CPUX86State *env, int addr)  int cpu_x86_inl(CPUX86State *env, int addr)
384  {  {
385      fprintf(stderr, "inl: port=0x%04x\n", addr);      return ioport_read_table[2][addr & (MAX_IOPORTS - 1)](env, addr);
     return 0;  
386  }  }
387    
388  /***********************************************************/  /***********************************************************/
# Line 511  void cmos_init(void) Line 528  void cmos_init(void)
528    
529      cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */      cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
530    
531      register_ioport_writeb(0x70, 2, cmos_ioport_write);      register_ioport_write(0x70, 2, cmos_ioport_write, 1);
532      register_ioport_readb(0x70, 2, cmos_ioport_read);      register_ioport_read(0x70, 2, cmos_ioport_read, 1);
533  }  }
534    
535  /***********************************************************/  /***********************************************************/
# Line 726  uint32_t pic_ioport_read(CPUX86State *en Line 743  uint32_t pic_ioport_read(CPUX86State *en
743    
744  void pic_init(void)  void pic_init(void)
745  {  {
746      register_ioport_writeb(0x20, 2, pic_ioport_write);      register_ioport_write(0x20, 2, pic_ioport_write, 1);
747      register_ioport_readb(0x20, 2, pic_ioport_read);      register_ioport_read(0x20, 2, pic_ioport_read, 1);
748      register_ioport_writeb(0xa0, 2, pic_ioport_write);      register_ioport_write(0xa0, 2, pic_ioport_write, 1);
749      register_ioport_readb(0xa0, 2, pic_ioport_read);      register_ioport_read(0xa0, 2, pic_ioport_read, 1);
750  }  }
751    
752  /***********************************************************/  /***********************************************************/
# Line 1031  void pit_init(void) Line 1048  void pit_init(void)
1048          pit_load_count(s, 0);          pit_load_count(s, 0);
1049      }      }
1050    
1051      register_ioport_writeb(0x40, 4, pit_ioport_write);      register_ioport_write(0x40, 4, pit_ioport_write, 1);
1052      register_ioport_readb(0x40, 3, pit_ioport_read);      register_ioport_read(0x40, 3, pit_ioport_read, 1);
1053    
1054      register_ioport_readb(0x61, 1, speaker_ioport_read);      register_ioport_read(0x61, 1, speaker_ioport_read, 1);
1055      register_ioport_writeb(0x61, 1, speaker_ioport_write);      register_ioport_write(0x61, 1, speaker_ioport_write, 1);
1056  }  }
1057    
1058  /***********************************************************/  /***********************************************************/
# Line 1277  void serial_init(void) Line 1294  void serial_init(void)
1294    
1295      s->lsr = UART_LSR_TEMT | UART_LSR_THRE;      s->lsr = UART_LSR_TEMT | UART_LSR_THRE;
1296    
1297      register_ioport_writeb(0x3f8, 8, serial_ioport_write);      register_ioport_write(0x3f8, 8, serial_ioport_write, 1);
1298      register_ioport_readb(0x3f8, 8, serial_ioport_read);      register_ioport_read(0x3f8, 8, serial_ioport_read, 1);
1299    
1300      term_init();      term_init();
1301  }  }
# Line 1444  int net_init(void) Line 1461  int net_init(void)
1461          close(fd);          close(fd);
1462          return -1;          return -1;
1463      }      }
1464      printf("connected to host network interface: %s\n", ifr.ifr_name);      printf("Connected to host network interface: %s\n", ifr.ifr_name);
1465      fcntl(fd, F_SETFL, O_NONBLOCK);      fcntl(fd, F_SETFL, O_NONBLOCK);
1466      net_fd = fd;      net_fd = fd;
1467    
# Line 1739  uint32_t ne2000_reset_ioport_read(CPUX86 Line 1756  uint32_t ne2000_reset_ioport_read(CPUX86
1756    
1757  void ne2000_init(void)  void ne2000_init(void)
1758  {  {
1759      register_ioport_writeb(NE2000_IOPORT, 16, ne2000_ioport_write);      register_ioport_write(NE2000_IOPORT, 16, ne2000_ioport_write, 1);
1760      register_ioport_readb(NE2000_IOPORT, 16, ne2000_ioport_read);      register_ioport_read(NE2000_IOPORT, 16, ne2000_ioport_read, 1);
1761    
1762      register_ioport_writeb(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_write);      register_ioport_write(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_write, 1);
1763      register_ioport_readb(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_read);      register_ioport_read(NE2000_IOPORT + 0x10, 1, ne2000_asic_ioport_read, 1);
1764      register_ioport_writew(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_write);      register_ioport_write(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_write, 2);
1765      register_ioport_readw(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_read);      register_ioport_read(NE2000_IOPORT + 0x10, 2, ne2000_asic_ioport_read, 2);
1766    
1767      register_ioport_writeb(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_write);      register_ioport_write(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_write, 1);
1768      register_ioport_readb(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_read);      register_ioport_read(NE2000_IOPORT + 0x1f, 1, ne2000_reset_ioport_read, 1);
1769      ne2000_reset();      ne2000_reset();
1770  }  }
1771    
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    /***********************************************************/
2378  /* cpu signal handler */  /* cpu signal handler */
2379  static void host_segv_handler(int host_signum, siginfo_t *info,  static void host_segv_handler(int host_signum, siginfo_t *info,
2380                                void *puc)                                void *puc)
# Line 1873  void main_loop(void *opaque) Line 2495  void main_loop(void *opaque)
2495  void help(void)  void help(void)
2496  {  {
2497      printf("Virtual Linux version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"      printf("Virtual Linux version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
2498             "usage: vl [options] bzImage initrd [kernel parameters...]\n"             "usage: vl [options] bzImage [kernel parameters...]\n"
2499             "\n"             "\n"
2500             "'bzImage' is a Linux kernel image (PAGE_OFFSET must be defined\n"             "'bzImage' is a Linux kernel image (PAGE_OFFSET must be defined\n"
2501             "to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"             "to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"
2502             "'initrd' is an initrd image\n"             "\n"
2503             "-m megs   set virtual RAM size to megs MB\n"             "General options:\n"
2504             "-n script set network init script [default=%s]\n"             "-initrd file   use 'file' as initial ram disk\n"
2505             "-s        wait gdb connection to port %d\n"             "-hda file      use 'file' as hard disk 0 image\n"
2506             "-p port   change gdb connection port\n"             "-hdb file      use 'file' as hard disk 1 image\n"
2507             "-d        output log in /tmp/vl.log\n"             "-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"
2514             "\n"             "\n"
2515             "During emulation, use C-a h to get terminal commands:\n",             "During emulation, use C-a h to get terminal commands:\n",
2516             DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT);             DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT);
# Line 1890  void help(void) Line 2518  void help(void)
2518      exit(1);      exit(1);
2519  }  }
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    
2528  int main(int argc, char **argv)  int main(int argc, char **argv)
2529  {  {
2530      int c, ret, initrd_size, i, use_gdbstub, gdbstub_port;      int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
2531      struct linux_params *params;      struct linux_params *params;
2532      struct sigaction act;      struct sigaction act;
2533      struct itimerval itv;      struct itimerval itv;
2534      CPUX86State *env;      CPUX86State *env;
2535      const char *tmpdir;      const char *tmpdir, *initrd_filename;
2536        const char *hd_filename[MAX_DISKS];
2537            
2538      /* we never want that malloc() uses mmap() */      /* we never want that malloc() uses mmap() */
2539      mallopt(M_MMAP_THRESHOLD, 4096 * 1024);      mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
2540            initrd_filename = NULL;
2541        for(i = 0; i < MAX_DISKS; i++)
2542            hd_filename[i] = NULL;
2543      phys_ram_size = 32 * 1024 * 1024;      phys_ram_size = 32 * 1024 * 1024;
2544      pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);      pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
2545      use_gdbstub = 0;      use_gdbstub = 0;
2546      gdbstub_port = DEFAULT_GDBSTUB_PORT;      gdbstub_port = DEFAULT_GDBSTUB_PORT;
2547      for(;;) {      for(;;) {
2548          c = getopt(argc, argv, "hm:dn:sp:");          c = getopt_long_only(argc, argv, "hm:dn:sp:", long_options, &long_index);
2549          if (c == -1)          if (c == -1)
2550              break;              break;
2551          switch(c) {          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;
2565          case 'h':          case 'h':
2566              help();              help();
2567              break;              break;
# Line 1933  int main(int argc, char **argv) Line 2584  int main(int argc, char **argv)
2584              break;              break;
2585          }          }
2586      }      }
2587      if (optind + 1 >= argc)      if (optind >= argc)
2588          help();          help();
2589    
2590      /* init debug */      /* init debug */
# Line 1946  int main(int argc, char **argv) Line 2597  int main(int argc, char **argv)
2597          setvbuf(logfile, NULL, _IOLBF, 0);          setvbuf(logfile, NULL, _IOLBF, 0);
2598      }      }
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    
2612      /* init network tun interface */      /* init network tun interface */
2613      net_init();      net_init();
2614    
# Line 1978  int main(int argc, char **argv) Line 2641  int main(int argc, char **argv)
2641      /* now we can load the kernel */      /* now we can load the kernel */
2642      ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);      ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);
2643      if (ret < 0) {      if (ret < 0) {
2644          fprintf(stderr, "%s: could not load kernel\n", argv[optind]);          fprintf(stderr, "vl: could not load kernel '%s'\n", argv[optind]);
2645          exit(1);          exit(1);
2646      }      }
2647    
2648      /* load initrd */      /* load initrd */
2649      initrd_size = load_image(argv[optind + 1], phys_ram_base + INITRD_LOAD_ADDR);      initrd_size = 0;
2650      if (initrd_size < 0) {      if (initrd_filename) {
2651          fprintf(stderr, "%s: could not load initrd\n", argv[optind + 1]);          initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
2652          exit(1);          if (initrd_size < 0) {
2653                fprintf(stderr, "vl: could not load initial ram disk '%s'\n",
2654                        initrd_filename);
2655                exit(1);
2656            }
2657      }      }
2658    
2659      /* init kernel params */      /* init kernel params */
# Line 1996  int main(int argc, char **argv) Line 2663  int main(int argc, char **argv)
2663      params->cl_magic = 0xA33F;      params->cl_magic = 0xA33F;
2664      params->cl_offset = params->commandline - (uint8_t *)params;      params->cl_offset = params->commandline - (uint8_t *)params;
2665      params->ext_mem_k = (phys_ram_size / 1024) - 1024;      params->ext_mem_k = (phys_ram_size / 1024) - 1024;
2666      for(i = optind + 2; i < argc; i++) {      for(i = optind + 1; i < argc; i++) {
2667          if (i != optind + 2)          if (i != optind + 1)
2668              pstrcat(params->commandline, sizeof(params->commandline), " ");              pstrcat(params->commandline, sizeof(params->commandline), " ");
2669          pstrcat(params->commandline, sizeof(params->commandline), argv[i]);          pstrcat(params->commandline, sizeof(params->commandline), argv[i]);
2670      }      }
# Line 2011  int main(int argc, char **argv) Line 2678  int main(int argc, char **argv)
2678    
2679      /* init basic PC hardware */      /* init basic PC hardware */
2680      init_ioports();      init_ioports();
2681      register_ioport_writeb(0x80, 1, ioport80_write);      register_ioport_write(0x80, 1, ioport80_write, 1);
2682    
2683      register_ioport_writeb(0x3d4, 2, vga_ioport_write);      register_ioport_write(0x3d4, 2, vga_ioport_write, 1);
2684    
2685      cmos_init();      cmos_init();
2686      pic_init();      pic_init();
2687      pit_init();      pit_init();
2688      serial_init();      serial_init();
2689      ne2000_init();      ne2000_init();
2690        ide_init();
2691    
2692      /* setup cpu signal handlers for MMU / self modifying code handling */      /* setup cpu signal handlers for MMU / self modifying code handling */
2693      sigfillset(&act.sa_mask);      sigfillset(&act.sa_mask);

Legend:
Removed from v.1.5  
changed lines
  Added in v.1.6

savannah-hackers-public@gnu.org
ViewVC Help
Powered by ViewVC 1.1.26