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

Diff of /qemu/vl.c

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

revision 1.13 by bellard, Sat Jul 26 12:06:08 2003 UTC revision 1.14 by bellard, Sat Jul 26 18:11:40 2003 UTC
# Line 52  Line 52 
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"
55    #define BIOS_FILENAME "bios.bin"
56    #define VGABIOS_FILENAME "vgabios.bin"
57    
58  //#define DEBUG_UNUSED_IOPORT  //#define DEBUG_UNUSED_IOPORT
59    
60  //#define DEBUG_IRQ_LATENCY  //#define DEBUG_IRQ_LATENCY
61    
62    /* output Bochs bios info messages */
63    //#define DEBUG_BIOS
64    
65    /* debug IDE devices */
66    //#define DEBUG_IDE
67    
68    /* debug PIC */
69    //#define DEBUG_PIC
70    
71    /* debug NE2000 card */
72    //#define DEBUG_NE2000
73    
74    /* debug PC keyboard */
75    //#define DEBUG_KBD
76    
77  #define PHYS_RAM_BASE     0xac000000  #define PHYS_RAM_BASE     0xac000000
78  #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)  #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
79    
# Line 185  typedef uint32_t (IOPortReadFunc)(CPUX86 Line 203  typedef uint32_t (IOPortReadFunc)(CPUX86
203    
204  #define MAX_IOPORTS 4096  #define MAX_IOPORTS 4096
205    
206    static const char *interp_prefix = CONFIG_QEMU_PREFIX;
207  char phys_ram_file[1024];  char phys_ram_file[1024];
208  CPUX86State *global_env;  CPUX86State *global_env;
209  CPUX86State *cpu_single_env;  CPUX86State *cpu_single_env;
# Line 216  void default_ioport_writeb(CPUX86State * Line 235  void default_ioport_writeb(CPUX86State *
235  uint32_t default_ioport_readw(CPUX86State *env, uint32_t address)  uint32_t default_ioport_readw(CPUX86State *env, uint32_t address)
236  {  {
237      uint32_t data;      uint32_t data;
238      data = ioport_read_table[0][address](env, address);      data = ioport_read_table[0][address & (MAX_IOPORTS - 1)](env, address);
239      data |= ioport_read_table[0][address + 1](env, address + 1) << 8;      data |= ioport_read_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1) << 8;
240      return data;      return data;
241  }  }
242    
243  void default_ioport_writew(CPUX86State *env, uint32_t address, uint32_t data)  void default_ioport_writew(CPUX86State *env, uint32_t address, uint32_t data)
244  {  {
245      ioport_write_table[0][address](env, address, data & 0xff);      ioport_write_table[0][address & (MAX_IOPORTS - 1)](env, address, data & 0xff);
246      ioport_write_table[0][address + 1](env, address + 1, (data >> 8) & 0xff);      ioport_write_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1, (data >> 8) & 0xff);
247  }  }
248    
249  uint32_t default_ioport_readl(CPUX86State *env, uint32_t address)  uint32_t default_ioport_readl(CPUX86State *env, uint32_t address)
# Line 516  void cmos_init(void) Line 535  void cmos_init(void)
535  {  {
536      struct tm *tm;      struct tm *tm;
537      time_t ti;      time_t ti;
538        int val;
539    
540      ti = time(NULL);      ti = time(NULL);
541      tm = gmtime(&ti);      tm = gmtime(&ti);
# Line 532  void cmos_init(void) Line 552  void cmos_init(void)
552      cmos_data[RTC_REG_C] = 0x00;      cmos_data[RTC_REG_C] = 0x00;
553      cmos_data[RTC_REG_D] = 0x80;      cmos_data[RTC_REG_D] = 0x80;
554    
555        /* various important CMOS locations needed by PC/Bochs bios */
556    
557      cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */      cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
558    
559        /* memory size */
560        val = (phys_ram_size / 1024) - 1024;
561        if (val > 65535)
562            val = 65535;
563        cmos_data[0x17] = val;
564        cmos_data[0x18] = val >> 8;
565        cmos_data[0x30] = val;
566        cmos_data[0x31] = val >> 8;
567    
568        val = (phys_ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
569        if (val > 65535)
570            val = 65535;
571        cmos_data[0x34] = val;
572        cmos_data[0x35] = val >> 8;
573        
574        cmos_data[0x3d] = 0x02; /* hard drive boot */
575        
576      register_ioport_write(0x70, 2, cmos_ioport_write, 1);      register_ioport_write(0x70, 2, cmos_ioport_write, 1);
577      register_ioport_read(0x70, 2, cmos_ioport_read, 1);      register_ioport_read(0x70, 2, cmos_ioport_read, 1);
578  }  }
# Line 541  void cmos_init(void) Line 580  void cmos_init(void)
580  /***********************************************************/  /***********************************************************/
581  /* 8259 pic emulation */  /* 8259 pic emulation */
582    
 //#define DEBUG_PIC  
   
583  typedef struct PicState {  typedef struct PicState {
584      uint8_t last_irr; /* edge detection */      uint8_t last_irr; /* edge detection */
585      uint8_t irr; /* interrupt request register */      uint8_t irr; /* interrupt request register */
# Line 1360  void serial_init(void) Line 1397  void serial_init(void)
1397  /***********************************************************/  /***********************************************************/
1398  /* ne2000 emulation */  /* ne2000 emulation */
1399    
 //#define DEBUG_NE2000  
   
1400  #define NE2000_IOPORT   0x300  #define NE2000_IOPORT   0x300
1401  #define NE2000_IRQ      9  #define NE2000_IRQ      9
1402    
# Line 1827  void ne2000_init(void) Line 1862  void ne2000_init(void)
1862  /***********************************************************/  /***********************************************************/
1863  /* ide emulation */  /* ide emulation */
1864    
 //#define DEBUG_IDE  
   
1865  /* Bits of HD_STATUS */  /* Bits of HD_STATUS */
1866  #define ERR_STAT                0x01  #define ERR_STAT                0x01
1867  #define INDEX_STAT              0x02  #define INDEX_STAT              0x02
# Line 2352  uint32_t ide_status_read(CPUX86State *en Line 2385  uint32_t ide_status_read(CPUX86State *en
2385      int ret;      int ret;
2386      ret = s->status;      ret = s->status;
2387  #ifdef DEBUG_IDE  #ifdef DEBUG_IDE
2388      printf("ide: read addr=0x%x val=%02x\n", addr, ret);      printf("ide: read status val=%02x\n", ret);
2389  #endif  #endif
2390      return ret;      return ret;
2391  }  }
2392    
2393  void ide_cmd_write(CPUX86State *env, uint32_t addr, uint32_t val)  void ide_cmd_write(CPUX86State *env, uint32_t addr, uint32_t val)
2394  {  {
2395      IDEState *s = &ide_state[0];      IDEState *s;
2396        int i;
2397    
2398    #ifdef DEBUG_IDE
2399        printf("ide: write control val=%02x\n", val);
2400    #endif
2401      /* common for both drives */      /* common for both drives */
2402      s->cmd = val;      if (!(ide_state[0].cmd & IDE_CMD_RESET) &&
2403            (val & IDE_CMD_RESET)) {
2404            /* reset low to high */
2405            for(i = 0;i < 2; i++) {
2406                s = &ide_state[i];
2407                s->status = BUSY_STAT | SEEK_STAT;
2408                s->error = 0x01;
2409            }
2410        } else if ((ide_state[0].cmd & IDE_CMD_RESET) &&
2411                   !(val & IDE_CMD_RESET)) {
2412            /* high to low */
2413            for(i = 0;i < 2; i++) {
2414                s = &ide_state[i];
2415                s->status = READY_STAT;
2416                /* set hard disk drive ID */
2417                s->select &= 0xf0; /* clear head */
2418                s->nsector = 1;
2419                s->sector = 1;
2420                if (s->nb_sectors == 0) {
2421                    /* no disk present */
2422                    s->lcyl = 0x12;
2423                    s->hcyl = 0x34;
2424                } else {
2425                    s->lcyl = 0;
2426                    s->hcyl = 0;
2427                }
2428            }
2429        }
2430    
2431        ide_state[0].cmd = val;
2432  }  }
2433    
2434  void ide_data_writew(CPUX86State *env, uint32_t addr, uint32_t val)  void ide_data_writew(CPUX86State *env, uint32_t addr, uint32_t val)
# Line 2439  void ide_init(void) Line 2506  void ide_init(void)
2506          s->bs = bs_table[i];          s->bs = bs_table[i];
2507          if (s->bs) {          if (s->bs) {
2508              bdrv_get_geometry(s->bs, &nb_sectors);              bdrv_get_geometry(s->bs, &nb_sectors);
2509              cylinders = nb_sectors / (16 * 63);              if (s->cylinders == 0) {
2510              if (cylinders > 16383)                  /* if no geometry, use a LBA compatible one */
2511                  cylinders = 16383;                  cylinders = nb_sectors / (16 * 63);
2512              else if (cylinders < 2)                  if (cylinders > 16383)
2513                  cylinders = 2;                      cylinders = 16383;
2514              s->cylinders = cylinders;                  else if (cylinders < 2)
2515              s->heads = 16;                      cylinders = 2;
2516              s->sectors = 63;                  s->cylinders = cylinders;
2517                    s->heads = 16;
2518                    s->sectors = 63;
2519                }
2520              s->nb_sectors = nb_sectors;              s->nb_sectors = nb_sectors;
2521          }          }
2522          s->irq = 14;          s->irq = 14;
# Line 2465  void ide_init(void) Line 2535  void ide_init(void)
2535  }  }
2536    
2537  /***********************************************************/  /***********************************************************/
2538  /* simulate reset (stop qemu) */  /* keyboard emulation */
2539    
2540    /*      Keyboard Controller Commands */
2541    #define KBD_CCMD_READ_MODE      0x20    /* Read mode bits */
2542    #define KBD_CCMD_WRITE_MODE     0x60    /* Write mode bits */
2543    #define KBD_CCMD_GET_VERSION    0xA1    /* Get controller version */
2544    #define KBD_CCMD_MOUSE_DISABLE  0xA7    /* Disable mouse interface */
2545    #define KBD_CCMD_MOUSE_ENABLE   0xA8    /* Enable mouse interface */
2546    #define KBD_CCMD_TEST_MOUSE     0xA9    /* Mouse interface test */
2547    #define KBD_CCMD_SELF_TEST      0xAA    /* Controller self test */
2548    #define KBD_CCMD_KBD_TEST       0xAB    /* Keyboard interface test */
2549    #define KBD_CCMD_KBD_DISABLE    0xAD    /* Keyboard interface disable */
2550    #define KBD_CCMD_KBD_ENABLE     0xAE    /* Keyboard interface enable */
2551    #define KBD_CCMD_READ_INPORT    0xC0    /* read input port */
2552    #define KBD_CCMD_READ_OUTPORT   0xD0    /* read output port */
2553    #define KBD_CCMD_WRITE_OUTPORT  0xD1    /* write output port */
2554    #define KBD_CCMD_WRITE_OBUF     0xD2
2555    #define KBD_CCMD_WRITE_AUX_OBUF 0xD3    /* Write to output buffer as if
2556                                               initiated by the auxiliary device */
2557    #define KBD_CCMD_WRITE_MOUSE    0xD4    /* Write the following byte to the mouse */
2558    #define KBD_CCMD_ENABLE_A20     0xDD
2559    #define KBD_CCMD_DISABLE_A20    0xDF
2560    #define KBD_CCMD_RESET          0xFE
2561    
2562    /* Keyboard Commands */
2563    #define KBD_CMD_SET_LEDS        0xED    /* Set keyboard leds */
2564    #define KBD_CMD_ECHO            0xEE
2565    #define KBD_CMD_SET_RATE        0xF3    /* Set typematic rate */
2566    #define KBD_CMD_ENABLE          0xF4    /* Enable scanning */
2567    #define KBD_CMD_RESET_DISABLE   0xF5    /* reset and disable scanning */
2568    #define KBD_CMD_RESET_ENABLE    0xF6    /* reset and enable scanning */
2569    #define KBD_CMD_RESET           0xFF    /* Reset */
2570    
2571    /* Keyboard Replies */
2572    #define KBD_REPLY_POR           0xAA    /* Power on reset */
2573    #define KBD_REPLY_ACK           0xFA    /* Command ACK */
2574    #define KBD_REPLY_RESEND        0xFE    /* Command NACK, send the cmd again */
2575    
2576    /* Status Register Bits */
2577    #define KBD_STAT_OBF            0x01    /* Keyboard output buffer full */
2578    #define KBD_STAT_IBF            0x02    /* Keyboard input buffer full */
2579    #define KBD_STAT_SELFTEST       0x04    /* Self test successful */
2580    #define KBD_STAT_CMD            0x08    /* Last write was a command write (0=data) */
2581    #define KBD_STAT_UNLOCKED       0x10    /* Zero if keyboard locked */
2582    #define KBD_STAT_MOUSE_OBF      0x20    /* Mouse output buffer full */
2583    #define KBD_STAT_GTO            0x40    /* General receive/xmit timeout */
2584    #define KBD_STAT_PERR           0x80    /* Parity error */
2585    
2586    /* Controller Mode Register Bits */
2587    #define KBD_MODE_KBD_INT        0x01    /* Keyboard data generate IRQ1 */
2588    #define KBD_MODE_MOUSE_INT      0x02    /* Mouse data generate IRQ12 */
2589    #define KBD_MODE_SYS            0x04    /* The system flag (?) */
2590    #define KBD_MODE_NO_KEYLOCK     0x08    /* The keylock doesn't affect the keyboard if set */
2591    #define KBD_MODE_DISABLE_KBD    0x10    /* Disable keyboard interface */
2592    #define KBD_MODE_DISABLE_MOUSE  0x20    /* Disable mouse interface */
2593    #define KBD_MODE_KCC            0x40    /* Scan code conversion to PC format */
2594    #define KBD_MODE_RFU            0x80
2595    
2596    /* Mouse Commands */
2597    #define AUX_SET_RES             0xE8    /* Set resolution */
2598    #define AUX_SET_SCALE11         0xE6    /* Set 1:1 scaling */
2599    #define AUX_SET_SCALE21         0xE7    /* Set 2:1 scaling */
2600    #define AUX_GET_SCALE           0xE9    /* Get scaling factor */
2601    #define AUX_SET_STREAM          0xEA    /* Set stream mode */
2602    #define AUX_SET_SAMPLE          0xF3    /* Set sample rate */
2603    #define AUX_ENABLE_DEV          0xF4    /* Enable aux device */
2604    #define AUX_DISABLE_DEV         0xF5    /* Disable aux device */
2605    #define AUX_RESET               0xFF    /* Reset aux device */
2606    #define AUX_ACK                 0xFA    /* Command byte ACK. */
2607    
2608    #define KBD_QUEUE_SIZE 64
2609    
2610    typedef struct {
2611        uint8_t data[KBD_QUEUE_SIZE];
2612        int rptr, wptr, count;
2613    } KBDQueue;
2614    
2615    enum KBDWriteState {
2616        KBD_STATE_CMD = 0,
2617        KBD_STATE_LED,
2618    };
2619    
2620    typedef struct KBDState {
2621        KBDQueue queues[2];
2622        uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
2623        uint8_t status;
2624        uint8_t mode;
2625        int kbd_write_cmd;
2626        int scan_enabled;
2627    } KBDState;
2628    
2629    KBDState kbd_state;
2630  int reset_requested;  int reset_requested;
2631    int a20_enabled;
2632    
2633    static void kbd_update_irq(KBDState *s)
2634    {
2635        int level;
2636        
2637        level = ((s->status & KBD_STAT_OBF) && (s->mode & KBD_MODE_KBD_INT));
2638        pic_set_irq(1, level);
2639        
2640        level = ((s->status & KBD_STAT_MOUSE_OBF) && (s->mode & KBD_MODE_MOUSE_INT));
2641        pic_set_irq(12, level);
2642    }
2643    
2644    static void kbd_queue(KBDState *s, int b, int aux)
2645    {
2646        KBDQueue *q = &kbd_state.queues[aux];
2647    
2648        if (q->count >= KBD_QUEUE_SIZE)
2649            return;
2650        q->data[q->wptr] = b;
2651        if (++q->wptr == KBD_QUEUE_SIZE)
2652            q->wptr = 0;
2653        q->count++;
2654        s->status |= KBD_STAT_OBF;
2655        if (aux)
2656            s->status |= KBD_STAT_MOUSE_OBF;
2657        kbd_update_irq(s);
2658    }
2659    
2660  uint32_t kbd_read_status(CPUX86State *env, uint32_t addr)  uint32_t kbd_read_status(CPUX86State *env, uint32_t addr)
2661  {  {
2662      return 0;      KBDState *s = &kbd_state;
2663        int val;
2664        val = s->status;
2665    #if defined(DEBUG_KBD) && 0
2666        printf("kbd: read status=0x%02x\n", val);
2667    #endif
2668        return val;
2669  }  }
2670    
2671  void kbd_write_command(CPUX86State *env, uint32_t addr, uint32_t val)  void kbd_write_command(CPUX86State *env, uint32_t addr, uint32_t val)
2672  {  {
2673        KBDState *s = &kbd_state;
2674    
2675    #ifdef DEBUG_KBD
2676        printf("kbd: write cmd=0x%02x\n", val);
2677    #endif
2678      switch(val) {      switch(val) {
2679      case 0xfe:      case KBD_CCMD_READ_MODE:
2680            kbd_queue(s, s->mode, 0);
2681            break;
2682        case KBD_CCMD_WRITE_MODE:
2683        case KBD_CCMD_WRITE_OBUF:
2684        case KBD_CCMD_WRITE_AUX_OBUF:
2685        case KBD_CCMD_WRITE_MOUSE:
2686        case KBD_CCMD_WRITE_OUTPORT:
2687            s->write_cmd = val;
2688            break;
2689        case KBD_CCMD_MOUSE_DISABLE:
2690            s->mode |= KBD_MODE_DISABLE_MOUSE;
2691            break;
2692        case KBD_CCMD_MOUSE_ENABLE:
2693            s->mode &= ~KBD_MODE_DISABLE_MOUSE;
2694            break;
2695        case KBD_CCMD_TEST_MOUSE:
2696            kbd_queue(s, 0x00, 0);
2697            break;
2698        case KBD_CCMD_SELF_TEST:
2699            s->status |= KBD_STAT_SELFTEST;
2700            kbd_queue(s, 0x55, 0);
2701            break;
2702        case KBD_CCMD_KBD_TEST:
2703            kbd_queue(s, 0x00, 0);
2704            break;
2705        case KBD_CCMD_KBD_DISABLE:
2706            s->mode |= KBD_MODE_DISABLE_KBD;
2707            break;
2708        case KBD_CCMD_KBD_ENABLE:
2709            s->mode &= ~KBD_MODE_DISABLE_KBD;
2710            break;
2711        case KBD_CCMD_READ_INPORT:
2712            kbd_queue(s, 0x00, 0);
2713            break;
2714        case KBD_CCMD_READ_OUTPORT:
2715            /* XXX: check that */
2716            val = 0x01 | (a20_enabled << 1);
2717            if (s->status & KBD_STAT_OBF)
2718                val |= 0x10;
2719            if (s->status & KBD_STAT_MOUSE_OBF)
2720                val |= 0x20;
2721            kbd_queue(s, val, 0);
2722            break;
2723        case KBD_CCMD_ENABLE_A20:
2724            a20_enabled = 1;
2725            break;
2726        case KBD_CCMD_DISABLE_A20:
2727            a20_enabled = 0;
2728            break;
2729        case KBD_CCMD_RESET:
2730          reset_requested = 1;          reset_requested = 1;
2731          cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);          cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
2732          break;          break;
2733      default:      default:
2734            fprintf(stderr, "vl: unsupported keyboard cmd=0x%02x\n", val);
2735          break;          break;
2736      }      }
2737  }  }
2738    
2739    uint32_t kbd_read_data(CPUX86State *env, uint32_t addr)
2740    {
2741        KBDState *s = &kbd_state;
2742        KBDQueue *q;
2743        int val;
2744        
2745        q = &s->queues[1]; /* first check AUX data */
2746        if (q->count == 0)
2747            q = &s->queues[0]; /* then check KBD data */
2748        if (q->count == 0) {
2749            /* XXX: return something else ? */
2750            val = 0;
2751        } else {
2752            val = q->data[q->rptr];
2753            if (++q->rptr == KBD_QUEUE_SIZE)
2754                q->rptr = 0;
2755            q->count--;
2756        }
2757        if (s->queues[1].count == 0) {
2758            s->status &= ~KBD_STAT_MOUSE_OBF;
2759            if (s->queues[0].count == 0)
2760                s->status &= ~KBD_STAT_OBF;
2761            kbd_update_irq(s);
2762        }
2763    
2764    #ifdef DEBUG_KBD
2765        printf("kbd: read data=0x%02x\n", val);
2766    #endif
2767        return val;
2768    }
2769    
2770    static void kbd_reset_keyboard(KBDState *s)
2771    {
2772        s->scan_enabled = 1;
2773    }
2774    
2775    static void kbd_write_keyboard(KBDState *s, int val)
2776    {
2777        switch(s->kbd_write_cmd) {
2778        default:
2779        case -1:
2780            switch(val) {
2781            case 0x00:
2782                kbd_queue(s, KBD_REPLY_ACK, 0);
2783                break;
2784            case 0x05:
2785                kbd_queue(s, KBD_REPLY_RESEND, 0);
2786                break;
2787            case KBD_CMD_ECHO:
2788                kbd_queue(s, KBD_CMD_ECHO, 0);
2789                break;
2790            case KBD_CMD_ENABLE:
2791                s->scan_enabled = 1;
2792                kbd_queue(s, KBD_REPLY_ACK, 0);
2793                break;
2794            case KBD_CMD_SET_LEDS:
2795            case KBD_CMD_SET_RATE:
2796                s->kbd_write_cmd = val;
2797                break;
2798            case KBD_CMD_RESET_DISABLE:
2799                kbd_reset_keyboard(s);
2800                s->scan_enabled = 0;
2801                kbd_queue(s, KBD_REPLY_ACK, 0);
2802                break;
2803            case KBD_CMD_RESET_ENABLE:
2804                kbd_reset_keyboard(s);
2805                s->scan_enabled = 1;
2806                kbd_queue(s, KBD_REPLY_ACK, 0);
2807                break;
2808            case KBD_CMD_RESET:
2809                kbd_reset_keyboard(s);
2810                kbd_queue(s, KBD_REPLY_ACK, 0);
2811                kbd_queue(s, KBD_REPLY_POR, 0);
2812                break;
2813            default:
2814                kbd_queue(s, KBD_REPLY_ACK, 0);
2815                break;
2816            }
2817            break;
2818        case KBD_CMD_SET_LEDS:
2819            kbd_queue(s, KBD_REPLY_ACK, 0);
2820            break;
2821        case KBD_CMD_SET_RATE:
2822            kbd_queue(s, KBD_REPLY_ACK, 0);
2823            break;
2824        }
2825        s->kbd_write_cmd = -1;
2826    }
2827    
2828    void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val)
2829    {
2830        KBDState *s = &kbd_state;
2831    
2832    #ifdef DEBUG_KBD
2833        printf("kbd: write data=0x%02x\n", val);
2834    #endif
2835    
2836        switch(s->write_cmd) {
2837        case 0:
2838            kbd_write_keyboard(s, val);
2839            break;
2840        case KBD_CCMD_WRITE_MODE:
2841            s->mode = val;
2842            kbd_update_irq(s);
2843            break;
2844        case KBD_CCMD_WRITE_OBUF:
2845            kbd_queue(s, val, 0);
2846            break;
2847        case KBD_CCMD_WRITE_AUX_OBUF:
2848            kbd_queue(s, val, 1);
2849            break;
2850        case KBD_CCMD_WRITE_OUTPORT:
2851            a20_enabled = (val >> 1) & 1;
2852            if (!(val & 1)) {
2853                reset_requested = 1;
2854                cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
2855            }
2856            break;
2857        default:
2858            break;
2859        }
2860        s->write_cmd = 0;
2861    }
2862    
2863    void kbd_reset(KBDState *s)
2864    {
2865        KBDQueue *q;
2866        int i;
2867    
2868        s->kbd_write_cmd = -1;
2869        s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
2870        s->status = KBD_MODE_SYS | KBD_MODE_NO_KEYLOCK;
2871        for(i = 0; i < 2; i++) {
2872            q = &s->queues[i];
2873            q->rptr = 0;
2874            q->wptr = 0;
2875            q->count = 0;
2876        }
2877    }
2878    
2879  void kbd_init(void)  void kbd_init(void)
2880  {  {
2881        kbd_reset(&kbd_state);
2882        register_ioport_read(0x60, 1, kbd_read_data, 1);
2883        register_ioport_write(0x60, 1, kbd_write_data, 1);
2884      register_ioport_read(0x64, 1, kbd_read_status, 1);      register_ioport_read(0x64, 1, kbd_read_status, 1);
2885      register_ioport_write(0x64, 1, kbd_write_command, 1);      register_ioport_write(0x64, 1, kbd_write_command, 1);
2886  }  }
2887    
2888  /***********************************************************/  /***********************************************************/
2889    /* Bochs BIOS debug ports */
2890    
2891    void bochs_bios_write(CPUX86State *env, uint32_t addr, uint32_t val)
2892    {
2893        switch(addr) {
2894            /* Bochs BIOS messages */
2895        case 0x400:
2896        case 0x401:
2897            fprintf(stderr, "BIOS panic at rombios.c, line %d\n", val);
2898            exit(1);
2899        case 0x402:
2900        case 0x403:
2901    #ifdef DEBUG_BIOS
2902            fprintf(stderr, "%c", val);
2903    #endif
2904            break;
2905    
2906            /* LGPL'ed VGA BIOS messages */
2907        case 0x501:
2908        case 0x502:
2909            fprintf(stderr, "VGA BIOS panic, line %d\n", val);
2910            exit(1);
2911        case 0x500:
2912        case 0x503:
2913    #ifdef DEBUG_BIOS
2914            fprintf(stderr, "%c", val);
2915    #endif
2916            break;
2917        }
2918    }
2919    
2920    void bochs_bios_init(void)
2921    {
2922        register_ioport_write(0x400, 1, bochs_bios_write, 2);
2923        register_ioport_write(0x401, 1, bochs_bios_write, 2);
2924        register_ioport_write(0x402, 1, bochs_bios_write, 1);
2925        register_ioport_write(0x403, 1, bochs_bios_write, 1);
2926    
2927        register_ioport_write(0x501, 1, bochs_bios_write, 2);
2928        register_ioport_write(0x502, 1, bochs_bios_write, 2);
2929        register_ioport_write(0x500, 1, bochs_bios_write, 1);
2930        register_ioport_write(0x503, 1, bochs_bios_write, 1);
2931    }
2932    
2933    /***********************************************************/
2934  /* cpu signal handler */  /* cpu signal handler */
2935  static void host_segv_handler(int host_signum, siginfo_t *info,  static void host_segv_handler(int host_signum, siginfo_t *info,
2936                                void *puc)                                void *puc)
# Line 2625  int main_loop(void *opaque) Line 3063  int main_loop(void *opaque)
3063  void help(void)  void help(void)
3064  {  {
3065      printf("Virtual Linux version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"      printf("Virtual Linux version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
3066             "usage: vl [options] bzImage [kernel parameters...]\n"             "usage: vl [options] [bzImage [kernel parameters...]]\n"
3067             "\n"             "\n"
3068             "'bzImage' is a Linux kernel image (PAGE_OFFSET must be defined\n"             "'bzImage' is a Linux kernel image (PAGE_OFFSET must be defined\n"
3069             "to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"             "to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"
# Line 2638  void help(void) Line 3076  void help(void)
3076             "-m megs        set virtual RAM size to megs MB\n"             "-m megs        set virtual RAM size to megs MB\n"
3077             "-n script      set network init script [default=%s]\n"             "-n script      set network init script [default=%s]\n"
3078             "\n"             "\n"
3079             "Debug options:\n"             "Debug/Expert options:\n"
3080             "-s             wait gdb connection to port %d\n"             "-s             wait gdb connection to port %d\n"
3081             "-p port        change gdb connection port\n"             "-p port        change gdb connection port\n"
3082             "-d             output log in /tmp/vl.log\n"             "-d             output log in /tmp/vl.log\n"
3083               "-hdachs c,h,s  force hard disk 0 geometry for non LBA disk images\n"
3084               "-L path        set the directory for the BIOS and VGA BIOS\n"
3085             "\n"             "\n"
3086             "During emulation, use C-a h to get terminal commands:\n",             "During emulation, use C-a h to get terminal commands:\n",
3087             DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT);             DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT);
# Line 2654  struct option long_options[] = { Line 3094  struct option long_options[] = {
3094      { "hda", 1, NULL, 0, },      { "hda", 1, NULL, 0, },
3095      { "hdb", 1, NULL, 0, },      { "hdb", 1, NULL, 0, },
3096      { "snapshot", 0, NULL, 0, },      { "snapshot", 0, NULL, 0, },
3097        { "hdachs", 1, NULL, 0, },
3098      { NULL, 0, NULL, 0 },      { NULL, 0, NULL, 0 },
3099  };  };
3100    
3101  int main(int argc, char **argv)  int main(int argc, char **argv)
3102  {  {
3103      int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;      int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
3104      int snapshot;      int snapshot, linux_boot;
3105      struct linux_params *params;      struct linux_params *params;
3106      struct sigaction act;      struct sigaction act;
3107      struct itimerval itv;      struct itimerval itv;
# Line 2678  int main(int argc, char **argv) Line 3119  int main(int argc, char **argv)
3119      use_gdbstub = 0;      use_gdbstub = 0;
3120      gdbstub_port = DEFAULT_GDBSTUB_PORT;      gdbstub_port = DEFAULT_GDBSTUB_PORT;
3121      snapshot = 0;      snapshot = 0;
3122        linux_boot = 0;
3123      for(;;) {      for(;;) {
3124          c = getopt_long_only(argc, argv, "hm:dn:sp:", long_options, &long_index);          c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index);
3125          if (c == -1)          if (c == -1)
3126              break;              break;
3127          switch(c) {          switch(c) {
# Line 2697  int main(int argc, char **argv) Line 3139  int main(int argc, char **argv)
3139              case 3:              case 3:
3140                  snapshot = 1;                  snapshot = 1;
3141                  break;                  break;
3142                case 4:
3143                    {
3144                        int cyls, heads, secs;
3145                        const char *p;
3146                        p = optarg;
3147                        cyls = strtol(p, (char **)&p, 0);
3148                        if (*p != ',')
3149                            goto chs_fail;
3150                        p++;
3151                        heads = strtol(p, (char **)&p, 0);
3152                        if (*p != ',')
3153                            goto chs_fail;
3154                        p++;
3155                        secs = strtol(p, (char **)&p, 0);
3156                        if (*p != '\0')
3157                            goto chs_fail;
3158                        ide_state[0].cylinders = cyls;
3159                        ide_state[0].heads = heads;
3160                        ide_state[0].sectors = secs;
3161                    chs_fail: ;
3162                    }
3163                    break;
3164              }              }
3165              break;              break;
3166          case 'h':          case 'h':
# Line 2724  int main(int argc, char **argv) Line 3188  int main(int argc, char **argv)
3188          case 'p':          case 'p':
3189              gdbstub_port = atoi(optarg);              gdbstub_port = atoi(optarg);
3190              break;              break;
3191            case 'L':
3192                interp_prefix = optarg;
3193                break;
3194          }          }
3195      }      }
3196      if (optind >= argc)  
3197        linux_boot = (optind < argc);
3198            
3199        if (!linux_boot && hd_filename[0] == '\0')
3200          help();          help();
3201    
3202      /* init debug */      /* init debug */
# Line 2781  int main(int argc, char **argv) Line 3251  int main(int argc, char **argv)
3251          }          }
3252      }      }
3253    
3254      /* now we can load the kernel */      /* init CPU state */
3255      ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);      env = cpu_init();
3256      if (ret < 0) {      global_env = env;
3257          fprintf(stderr, "vl: could not load kernel '%s'\n", argv[optind]);      cpu_single_env = env;
3258          exit(1);  
3259      }      init_ioports();
3260    
3261      /* load initrd */      if (linux_boot) {
3262      initrd_size = 0;          /* now we can load the kernel */
3263      if (initrd_filename) {          ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);
3264          initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);          if (ret < 0) {
3265          if (initrd_size < 0) {              fprintf(stderr, "vl: could not load kernel '%s'\n", argv[optind]);
             fprintf(stderr, "vl: could not load initial ram disk '%s'\n",  
                     initrd_filename);  
3266              exit(1);              exit(1);
3267          }          }
3268      }          
3269            /* load initrd */
3270            initrd_size = 0;
3271            if (initrd_filename) {
3272                initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
3273                if (initrd_size < 0) {
3274                    fprintf(stderr, "vl: could not load initial ram disk '%s'\n",
3275                            initrd_filename);
3276                    exit(1);
3277                }
3278            }
3279            
3280            /* init kernel params */
3281            params = (void *)(phys_ram_base + KERNEL_PARAMS_ADDR);
3282            memset(params, 0, sizeof(struct linux_params));
3283            params->mount_root_rdonly = 0;
3284            params->cl_magic = 0xA33F;
3285            params->cl_offset = params->commandline - (uint8_t *)params;
3286            params->alt_mem_k = (phys_ram_size / 1024) - 1024;
3287            for(i = optind + 1; i < argc; i++) {
3288                if (i != optind + 1)
3289                    pstrcat(params->commandline, sizeof(params->commandline), " ");
3290                pstrcat(params->commandline, sizeof(params->commandline), argv[i]);
3291            }
3292            params->loader_type = 0x01;
3293            if (initrd_size > 0) {
3294                params->initrd_start = INITRD_LOAD_ADDR;
3295                params->initrd_size = initrd_size;
3296            }
3297            params->orig_video_lines = 25;
3298            params->orig_video_cols = 80;
3299    
3300            /* setup basic memory access */
3301            env->cr[0] = 0x00000033;
3302            cpu_x86_init_mmu(env);
3303            
3304            memset(params->idt_table, 0, sizeof(params->idt_table));
3305            
3306            params->gdt_table[2] = 0x00cf9a000000ffffLL; /* KERNEL_CS */
3307            params->gdt_table[3] = 0x00cf92000000ffffLL; /* KERNEL_DS */
3308            
3309            env->idt.base = (void *)params->idt_table;
3310            env->idt.limit = sizeof(params->idt_table) - 1;
3311            env->gdt.base = (void *)params->gdt_table;
3312            env->gdt.limit = sizeof(params->gdt_table) - 1;
3313            
3314            cpu_x86_load_seg(env, R_CS, KERNEL_CS);
3315            cpu_x86_load_seg(env, R_DS, KERNEL_DS);
3316            cpu_x86_load_seg(env, R_ES, KERNEL_DS);
3317            cpu_x86_load_seg(env, R_SS, KERNEL_DS);
3318            cpu_x86_load_seg(env, R_FS, KERNEL_DS);
3319            cpu_x86_load_seg(env, R_GS, KERNEL_DS);
3320            
3321            env->eip = KERNEL_LOAD_ADDR;
3322            env->regs[R_ESI] = KERNEL_PARAMS_ADDR;
3323            env->eflags = 0x2;
3324    
3325        } else {
3326            char buf[1024];
3327            
3328            /* RAW PC boot */
3329    
3330            /* BIOS load */
3331            snprintf(buf, sizeof(buf), "%s/%s", interp_prefix, BIOS_FILENAME);
3332            ret = load_image(buf, phys_ram_base + 0x000f0000);
3333            if (ret != 0x10000) {
3334                fprintf(stderr, "vl: could not load PC bios '%s'\n", BIOS_FILENAME);
3335                exit(1);
3336            }
3337    
3338            /* VGA BIOS load */
3339            snprintf(buf, sizeof(buf), "%s/%s", interp_prefix, VGABIOS_FILENAME);
3340            ret = load_image(buf, phys_ram_base + 0x000c0000);
3341    
3342            /* setup basic memory access */
3343            env->cr[0] = 0x60000010;
3344            cpu_x86_init_mmu(env);
3345            
3346            env->idt.limit = 0xffff;
3347            env->gdt.limit = 0xffff;
3348            env->ldt.limit = 0xffff;
3349    
3350            /* not correct (CS base=0xffff0000) */
3351            cpu_x86_load_seg(env, R_CS, 0xf000);
3352            cpu_x86_load_seg(env, R_DS, 0);
3353            cpu_x86_load_seg(env, R_ES, 0);
3354            cpu_x86_load_seg(env, R_SS, 0);
3355            cpu_x86_load_seg(env, R_FS, 0);
3356            cpu_x86_load_seg(env, R_GS, 0);
3357    
3358            env->eip = 0xfff0;
3359            env->regs[R_EDX] = 0x600; /* indicate P6 processor */
3360    
3361      /* init kernel params */          env->eflags = 0x2;
3362      params = (void *)(phys_ram_base + KERNEL_PARAMS_ADDR);  
3363      memset(params, 0, sizeof(struct linux_params));          bochs_bios_init();
     params->mount_root_rdonly = 0;  
     params->cl_magic = 0xA33F;  
     params->cl_offset = params->commandline - (uint8_t *)params;  
     params->alt_mem_k = (phys_ram_size / 1024) - 1024;  
     for(i = optind + 1; i < argc; i++) {  
         if (i != optind + 1)  
             pstrcat(params->commandline, sizeof(params->commandline), " ");  
         pstrcat(params->commandline, sizeof(params->commandline), argv[i]);  
     }  
     params->loader_type = 0x01;  
     if (initrd_size > 0) {  
         params->initrd_start = INITRD_LOAD_ADDR;  
         params->initrd_size = initrd_size;  
3364      }      }
     params->orig_video_lines = 25;  
     params->orig_video_cols = 80;  
3365    
3366      /* init basic PC hardware */      /* init basic PC hardware */
     init_ioports();  
3367      register_ioport_write(0x80, 1, ioport80_write, 1);      register_ioport_write(0x80, 1, ioport80_write, 1);
3368    
3369      register_ioport_write(0x3d4, 2, vga_ioport_write, 1);      register_ioport_write(0x3d4, 2, vga_ioport_write, 1);
# Line 2843  int main(int argc, char **argv) Line 3386  int main(int argc, char **argv)
3386      act.sa_sigaction = host_alarm_handler;      act.sa_sigaction = host_alarm_handler;
3387      sigaction(SIGALRM, &act, NULL);      sigaction(SIGALRM, &act, NULL);
3388    
     /* init CPU state */  
     env = cpu_init();  
     global_env = env;  
     cpu_single_env = env;  
   
     /* setup basic memory access */  
     env->cr[0] = 0x00000033;  
     cpu_x86_init_mmu(env);  
       
     memset(params->idt_table, 0, sizeof(params->idt_table));  
   
     params->gdt_table[2] = 0x00cf9a000000ffffLL; /* KERNEL_CS */  
     params->gdt_table[3] = 0x00cf92000000ffffLL; /* KERNEL_DS */  
       
     env->idt.base = (void *)params->idt_table;  
     env->idt.limit = sizeof(params->idt_table) - 1;  
     env->gdt.base = (void *)params->gdt_table;  
     env->gdt.limit = sizeof(params->gdt_table) - 1;  
   
     cpu_x86_load_seg(env, R_CS, KERNEL_CS);  
     cpu_x86_load_seg(env, R_DS, KERNEL_DS);  
     cpu_x86_load_seg(env, R_ES, KERNEL_DS);  
     cpu_x86_load_seg(env, R_SS, KERNEL_DS);  
     cpu_x86_load_seg(env, R_FS, KERNEL_DS);  
     cpu_x86_load_seg(env, R_GS, KERNEL_DS);  
       
     env->eip = KERNEL_LOAD_ADDR;  
     env->regs[R_ESI] = KERNEL_PARAMS_ADDR;  
     env->eflags = 0x2;  
   
3389      itv.it_interval.tv_sec = 0;      itv.it_interval.tv_sec = 0;
3390      itv.it_interval.tv_usec = 1000;      itv.it_interval.tv_usec = 1000;
3391      itv.it_value.tv_sec = 0;      itv.it_value.tv_sec = 0;

Legend:
Removed from v.1.13  
changed lines
  Added in v.1.14

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