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

Diff of /qemu/vl.c

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

revision 1.15 by bellard, Sun Jul 27 22:19:00 2003 UTC revision 1.16 by bellard, Sun Aug 10 21:52:11 2003 UTC
# Line 74  Line 74 
74  /* debug PC keyboard */  /* debug PC keyboard */
75  //#define DEBUG_KBD  //#define DEBUG_KBD
76    
77    /* debug PC keyboard : only mouse */
78    //#define DEBUG_MOUSE
79    
80  #define PHYS_RAM_BASE     0xac000000  #define PHYS_RAM_BASE     0xac000000
81  #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)  #define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
82    
# Line 81  Line 84 
84  #define INITRD_LOAD_ADDR   0x00400000  #define INITRD_LOAD_ADDR   0x00400000
85  #define KERNEL_PARAMS_ADDR 0x00090000  #define KERNEL_PARAMS_ADDR 0x00090000
86    
87    #define GUI_REFRESH_INTERVAL 30
88    
89  #define MAX_DISKS 2  #define MAX_DISKS 2
90    
91  /* from plex86 (BSD license) */  /* from plex86 (BSD license) */
# Line 198  struct  __attribute__ ((packed)) linux_p Line 203  struct  __attribute__ ((packed)) linux_p
203  #define KERNEL_CS     0x10  #define KERNEL_CS     0x10
204  #define KERNEL_DS     0x18  #define KERNEL_DS     0x18
205    
 typedef void (IOPortWriteFunc)(CPUX86State *env, uint32_t address, uint32_t data);  
 typedef uint32_t (IOPortReadFunc)(CPUX86State *env, uint32_t address);  
   
206  #define MAX_IOPORTS 4096  #define MAX_IOPORTS 4096
207    
208  static const char *interp_prefix = CONFIG_QEMU_PREFIX;  static const char *interp_prefix = CONFIG_QEMU_PREFIX;
# Line 212  int loglevel; Line 214  int loglevel;
214  IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];  IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
215  IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];  IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
216  BlockDriverState *bs_table[MAX_DISKS];  BlockDriverState *bs_table[MAX_DISKS];
217    int vga_ram_size;
218    static DisplayState display_state;
219    int nodisp;
220    int term_inited;
221    int64_t ticks_per_sec;
222    
223  /***********************************************************/  /***********************************************************/
224  /* x86 io ports */  /* x86 io ports */
# Line 431  void hw_error(const char *fmt, ...) Line 438  void hw_error(const char *fmt, ...)
438  }  }
439    
440  /***********************************************************/  /***********************************************************/
 /* vga emulation */  
 static uint8_t vga_index;  
 static uint8_t vga_regs[256];  
 static int last_cursor_pos;  
   
 void update_console_messages(void)  
 {  
     int c, i, cursor_pos, eol;  
   
     cursor_pos = vga_regs[0x0f] | (vga_regs[0x0e] << 8);  
     eol = 0;  
     for(i = last_cursor_pos; i < cursor_pos; i++) {  
         c = phys_ram_base[0xb8000 + (i) * 2];  
         if (c >= ' ') {  
             putchar(c);  
             eol = 0;  
         } else {  
             if (!eol)  
                 putchar('\n');  
             eol = 1;  
         }  
     }  
     fflush(stdout);  
     last_cursor_pos = cursor_pos;  
 }  
   
 /* just to see first Linux console messages, we intercept cursor position */  
 void vga_ioport_write(CPUX86State *env, uint32_t addr, uint32_t data)  
 {  
     switch(addr) {  
     case 0x3d4:  
         vga_index = data;  
         break;  
     case 0x3d5:  
         vga_regs[vga_index] = data;  
         if (vga_index == 0x0f)  
             update_console_messages();  
         break;  
     }  
               
 }  
   
 /***********************************************************/  
441  /* cmos emulation */  /* cmos emulation */
442    
443  #define RTC_SECONDS             0  #define RTC_SECONDS             0
# Line 555  void cmos_init(void) Line 519  void cmos_init(void)
519      /* various important CMOS locations needed by PC/Bochs bios */      /* various important CMOS locations needed by PC/Bochs bios */
520    
521      cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */      cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
522        cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
523    
524      /* memory size */      /* memory size */
525      val = (phys_ram_size / 1024) - 1024;      val = (phys_ram_size / 1024) - 1024;
# Line 674  static void pic_update_irq(void) Line 639  static void pic_update_irq(void)
639  int64_t irq_time[16];  int64_t irq_time[16];
640  int64_t cpu_get_ticks(void);  int64_t cpu_get_ticks(void);
641  #endif  #endif
642  #ifdef DEBUG_PIC  #if defined(DEBUG_PIC)
643  int irq_level[16];  int irq_level[16];
644  #endif  #endif
645    
646  void pic_set_irq(int irq, int level)  void pic_set_irq(int irq, int level)
647  {  {
648  #ifdef DEBUG_PIC  #if defined(DEBUG_PIC)
649      if (level != irq_level[irq]) {      if (level != irq_level[irq]) {
650          printf("pic_set_irq: irq=%d level=%d\n", irq, level);          printf("pic_set_irq: irq=%d level=%d\n", irq, level);
651          irq_level[irq] = level;          irq_level[irq] = level;
# Line 702  int cpu_x86_get_pic_interrupt(CPUX86Stat Line 667  int cpu_x86_get_pic_interrupt(CPUX86Stat
667      /* signal the pic that the irq was acked by the CPU */      /* signal the pic that the irq was acked by the CPU */
668      irq = pic_irq_requested;      irq = pic_irq_requested;
669  #ifdef DEBUG_IRQ_LATENCY  #ifdef DEBUG_IRQ_LATENCY
670      printf("IRQ%d latency=%Ld\n", irq, cpu_get_ticks() - irq_time[irq]);      printf("IRQ%d latency=%0.3fus\n",
671               irq,
672               (double)(cpu_get_ticks() - irq_time[irq]) * 1000000.0 / ticks_per_sec);
673  #endif  #endif
674  #ifdef DEBUG_PIC  #ifdef DEBUG_PIC
675      printf("pic_interrupt: irq=%d\n", irq);      printf("pic_interrupt: irq=%d\n", irq);
# Line 761  void pic_ioport_write(CPUX86State *env, Line 728  void pic_ioport_write(CPUX86State *env,
728                  }                  }
729                  if (val == 0xa0)                  if (val == 0xa0)
730                      s->priority_add = (s->priority_add + 1) & 7;                      s->priority_add = (s->priority_add + 1) & 7;
731                    pic_update_irq();
732                  break;                  break;
733              case 0x60 ... 0x67:              case 0x60 ... 0x67:
734                  priority = val & 7;                  priority = val & 7;
735                  s->isr &= ~(1 << priority);                  s->isr &= ~(1 << priority);
736                    pic_update_irq();
737                  break;                  break;
738              case 0xc0 ... 0xc7:              case 0xc0 ... 0xc7:
739                  s->priority_add = (val + 1) & 7;                  s->priority_add = (val + 1) & 7;
740                    pic_update_irq();
741                  break;                  break;
742              case 0xe0 ... 0xe7:              case 0xe0 ... 0xe7:
743                  priority = val & 7;                  priority = val & 7;
744                  s->isr &= ~(1 << priority);                  s->isr &= ~(1 << priority);
745                  s->priority_add = (priority + 1) & 7;                  s->priority_add = (priority + 1) & 7;
746                    pic_update_irq();
747                  break;                  break;
748              }              }
749          }          }
# Line 861  int speaker_data_on; Line 832  int speaker_data_on;
832  int dummy_refresh_clock;  int dummy_refresh_clock;
833  int pit_min_timer_count = 0;  int pit_min_timer_count = 0;
834    
 int64_t ticks_per_sec;  
   
835  int64_t get_clock(void)  int64_t get_clock(void)
836  {  {
837      struct timeval tv;      struct timeval tv;
# Line 1354  void serial_received_byte(SerialState *s Line 1323  void serial_received_byte(SerialState *s
1323      }      }
1324  }  }
1325    
 /* init terminal so that we can grab keys */  
 static struct termios oldtty;  
   
 static void term_exit(void)  
 {  
     tcsetattr (0, TCSANOW, &oldtty);  
 }  
   
 static void term_init(void)  
 {  
     struct termios tty;  
   
     tcgetattr (0, &tty);  
     oldtty = tty;  
   
     tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP  
                           |INLCR|IGNCR|ICRNL|IXON);  
     tty.c_oflag |= OPOST;  
     tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);  
     tty.c_cflag &= ~(CSIZE|PARENB);  
     tty.c_cflag |= CS8;  
     tty.c_cc[VMIN] = 1;  
     tty.c_cc[VTIME] = 0;  
       
     tcsetattr (0, TCSANOW, &tty);  
   
     atexit(term_exit);  
   
     fcntl(0, F_SETFL, O_NONBLOCK);  
 }  
   
1326  void serial_init(void)  void serial_init(void)
1327  {  {
1328      SerialState *s = &serial_ports[0];      SerialState *s = &serial_ports[0];
# Line 1393  void serial_init(void) Line 1331  void serial_init(void)
1331    
1332      register_ioport_write(0x3f8, 8, serial_ioport_write, 1);      register_ioport_write(0x3f8, 8, serial_ioport_write, 1);
1333      register_ioport_read(0x3f8, 8, serial_ioport_read, 1);      register_ioport_read(0x3f8, 8, serial_ioport_read, 1);
   
     term_init();  
1334  }  }
1335    
1336  /***********************************************************/  /***********************************************************/
# Line 2597  void ide_init(void) Line 2533  void ide_init(void)
2533  #define KBD_MODE_RFU            0x80  #define KBD_MODE_RFU            0x80
2534    
2535  /* Mouse Commands */  /* Mouse Commands */
 #define AUX_SET_RES             0xE8    /* Set resolution */  
2536  #define AUX_SET_SCALE11         0xE6    /* Set 1:1 scaling */  #define AUX_SET_SCALE11         0xE6    /* Set 1:1 scaling */
2537  #define AUX_SET_SCALE21         0xE7    /* Set 2:1 scaling */  #define AUX_SET_SCALE21         0xE7    /* Set 2:1 scaling */
2538    #define AUX_SET_RES             0xE8    /* Set resolution */
2539  #define AUX_GET_SCALE           0xE9    /* Get scaling factor */  #define AUX_GET_SCALE           0xE9    /* Get scaling factor */
2540  #define AUX_SET_STREAM          0xEA    /* Set stream mode */  #define AUX_SET_STREAM          0xEA    /* Set stream mode */
2541    #define AUX_POLL                0xEB    /* Poll */
2542    #define AUX_RESET_WRAP          0xEC    /* Reset wrap mode */
2543    #define AUX_SET_WRAP            0xEE    /* Set wrap mode */
2544    #define AUX_SET_REMOTE          0xF0    /* Set remote mode */
2545    #define AUX_GET_TYPE            0xF2    /* Get type */
2546  #define AUX_SET_SAMPLE          0xF3    /* Set sample rate */  #define AUX_SET_SAMPLE          0xF3    /* Set sample rate */
2547  #define AUX_ENABLE_DEV          0xF4    /* Enable aux device */  #define AUX_ENABLE_DEV          0xF4    /* Enable aux device */
2548  #define AUX_DISABLE_DEV         0xF5    /* Disable aux device */  #define AUX_DISABLE_DEV         0xF5    /* Disable aux device */
2549    #define AUX_SET_DEFAULT         0xF6
2550  #define AUX_RESET               0xFF    /* Reset aux device */  #define AUX_RESET               0xFF    /* Reset aux device */
2551  #define AUX_ACK                 0xFA    /* Command byte ACK. */  #define AUX_ACK                 0xFA    /* Command byte ACK. */
2552    
2553  #define KBD_QUEUE_SIZE 64  #define MOUSE_STATUS_REMOTE     0x40
2554    #define MOUSE_STATUS_ENABLED    0x20
2555    #define MOUSE_STATUS_SCALE21    0x10
2556    
2557    #define KBD_QUEUE_SIZE 256
2558    
2559  typedef struct {  typedef struct {
2560      uint8_t data[KBD_QUEUE_SIZE];      uint8_t data[KBD_QUEUE_SIZE];
2561      int rptr, wptr, count;      int rptr, wptr, count;
2562  } KBDQueue;  } KBDQueue;
2563    
 enum KBDWriteState {  
     KBD_STATE_CMD = 0,  
     KBD_STATE_LED,  
 };  
   
2564  typedef struct KBDState {  typedef struct KBDState {
2565      KBDQueue queues[2];      KBDQueue queues[2];
2566      uint8_t write_cmd; /* if non zero, write data to port 60 is expected */      uint8_t write_cmd; /* if non zero, write data to port 60 is expected */
2567      uint8_t status;      uint8_t status;
2568      uint8_t mode;      uint8_t mode;
2569        /* keyboard state */
2570      int kbd_write_cmd;      int kbd_write_cmd;
2571      int scan_enabled;      int scan_enabled;
2572        /* mouse state */
2573        int mouse_write_cmd;
2574        uint8_t mouse_status;
2575        uint8_t mouse_resolution;
2576        uint8_t mouse_sample_rate;
2577        uint8_t mouse_wrap;
2578        uint8_t mouse_type; /* 0 = PS2, 3 = IMPS/2, 4 = IMEX */
2579        uint8_t mouse_detect_state;
2580        int mouse_dx; /* current values, needed for 'poll' mode */
2581        int mouse_dy;
2582        int mouse_dz;
2583        uint8_t mouse_buttons;
2584  } KBDState;  } KBDState;
2585    
2586  KBDState kbd_state;  KBDState kbd_state;
2587  int reset_requested;  int reset_requested;
2588  int a20_enabled;  int a20_enabled;
2589    
2590    /* update irq and KBD_STAT_[MOUSE_]OBF */
2591  static void kbd_update_irq(KBDState *s)  static void kbd_update_irq(KBDState *s)
2592  {  {
2593      int level;      int irq12_level, irq1_level;
2594        
2595      level = ((s->status & KBD_STAT_OBF) && (s->mode & KBD_MODE_KBD_INT));      irq1_level = 0;    
2596      pic_set_irq(1, level);      irq12_level = 0;    
2597            s->status &= ~(KBD_STAT_OBF | KBD_STAT_MOUSE_OBF);
2598      level = ((s->status & KBD_STAT_MOUSE_OBF) && (s->mode & KBD_MODE_MOUSE_INT));      if (s->queues[0].count != 0 ||
2599      pic_set_irq(12, level);          s->queues[1].count != 0) {
2600            s->status |= KBD_STAT_OBF;
2601            if (s->queues[1].count != 0) {
2602                s->status |= KBD_STAT_MOUSE_OBF;
2603                if (s->mode & KBD_MODE_MOUSE_INT)
2604                    irq12_level = 1;
2605            } else {
2606                if (s->mode & KBD_MODE_KBD_INT)
2607                    irq1_level = 1;
2608            }
2609        }
2610        pic_set_irq(1, irq1_level);
2611        pic_set_irq(12, irq12_level);
2612  }  }
2613    
2614  static void kbd_queue(KBDState *s, int b, int aux)  static void kbd_queue(KBDState *s, int b, int aux)
2615  {  {
2616      KBDQueue *q = &kbd_state.queues[aux];      KBDQueue *q = &kbd_state.queues[aux];
2617    
2618    #if defined(DEBUG_MOUSE) || defined(DEBUG_KBD)
2619        if (aux)
2620            printf("mouse event: 0x%02x\n", b);
2621    #ifdef DEBUG_KBD
2622        else
2623            printf("kbd event: 0x%02x\n", b);
2624    #endif
2625    #endif
2626      if (q->count >= KBD_QUEUE_SIZE)      if (q->count >= KBD_QUEUE_SIZE)
2627          return;          return;
2628      q->data[q->wptr] = b;      q->data[q->wptr] = b;
2629      if (++q->wptr == KBD_QUEUE_SIZE)      if (++q->wptr == KBD_QUEUE_SIZE)
2630          q->wptr = 0;          q->wptr = 0;
2631      q->count++;      q->count++;
     s->status |= KBD_STAT_OBF;  
     if (aux)  
         s->status |= KBD_STAT_MOUSE_OBF;  
2632      kbd_update_irq(s);      kbd_update_irq(s);
2633  }  }
2634    
2635    void kbd_put_keycode(int keycode)
2636    {
2637        KBDState *s = &kbd_state;
2638        kbd_queue(s, keycode, 0);
2639    }
2640    
2641  uint32_t kbd_read_status(CPUX86State *env, uint32_t addr)  uint32_t kbd_read_status(CPUX86State *env, uint32_t addr)
2642  {  {
2643      KBDState *s = &kbd_state;      KBDState *s = &kbd_state;
# Line 2745  uint32_t kbd_read_data(CPUX86State *env, Line 2723  uint32_t kbd_read_data(CPUX86State *env,
2723      KBDQueue *q;      KBDQueue *q;
2724      int val;      int val;
2725            
2726      q = &s->queues[1]; /* first check AUX data */      q = &s->queues[0]; /* first check KBD data */
2727      if (q->count == 0)      if (q->count == 0)
2728          q = &s->queues[0]; /* then check KBD data */          q = &s->queues[1]; /* then check AUX data */
2729      if (q->count == 0) {      if (q->count == 0) {
2730          /* XXX: return something else ? */          /* XXX: return something else ? */
2731          val = 0;          val = 0;
# Line 2756  uint32_t kbd_read_data(CPUX86State *env, Line 2734  uint32_t kbd_read_data(CPUX86State *env,
2734          if (++q->rptr == KBD_QUEUE_SIZE)          if (++q->rptr == KBD_QUEUE_SIZE)
2735              q->rptr = 0;              q->rptr = 0;
2736          q->count--;          q->count--;
2737            /* reading deasserts IRQ */
2738            if (q == &s->queues[0])
2739                pic_set_irq(1, 0);
2740            else
2741                pic_set_irq(12, 0);
2742      }      }
2743      if (s->queues[1].count == 0) {      /* reassert IRQs if data left */
2744          s->status &= ~KBD_STAT_MOUSE_OBF;      kbd_update_irq(s);
         if (s->queues[0].count == 0)  
             s->status &= ~KBD_STAT_OBF;  
         kbd_update_irq(s);  
     }  
   
2745  #ifdef DEBUG_KBD  #ifdef DEBUG_KBD
2746      printf("kbd: read data=0x%02x\n", val);      printf("kbd: read data=0x%02x\n", val);
2747  #endif  #endif
# Line 2820  static void kbd_write_keyboard(KBDState Line 2798  static void kbd_write_keyboard(KBDState
2798          break;          break;
2799      case KBD_CMD_SET_LEDS:      case KBD_CMD_SET_LEDS:
2800          kbd_queue(s, KBD_REPLY_ACK, 0);          kbd_queue(s, KBD_REPLY_ACK, 0);
2801            s->kbd_write_cmd = -1;
2802          break;          break;
2803      case KBD_CMD_SET_RATE:      case KBD_CMD_SET_RATE:
2804          kbd_queue(s, KBD_REPLY_ACK, 0);          kbd_queue(s, KBD_REPLY_ACK, 0);
2805            s->kbd_write_cmd = -1;
2806            break;
2807        }
2808    }
2809    
2810    static void kbd_mouse_send_packet(KBDState *s)
2811    {
2812        unsigned int b;
2813        int dx1, dy1, dz1;
2814    
2815        dx1 = s->mouse_dx;
2816        dy1 = s->mouse_dy;
2817        dz1 = s->mouse_dz;
2818        /* XXX: increase range to 8 bits ? */
2819        if (dx1 > 127)
2820            dx1 = 127;
2821        else if (dx1 < -127)
2822            dx1 = -127;
2823        if (dy1 > 127)
2824            dy1 = 127;
2825        else if (dy1 < -127)
2826            dy1 = -127;
2827        b = 0x08 | ((dx1 < 0) << 4) | ((dy1 < 0) << 5) | (s->mouse_buttons & 0x07);
2828        kbd_queue(s, b, 1);
2829        kbd_queue(s, dx1 & 0xff, 1);
2830        kbd_queue(s, dy1 & 0xff, 1);
2831        /* extra byte for IMPS/2 or IMEX */
2832        switch(s->mouse_type) {
2833        default:
2834            break;
2835        case 3:
2836            if (dz1 > 127)
2837                dz1 = 127;
2838            else if (dz1 < -127)
2839                    dz1 = -127;
2840            kbd_queue(s, dz1 & 0xff, 1);
2841            break;
2842        case 4:
2843            if (dz1 > 7)
2844                dz1 = 7;
2845            else if (dz1 < -7)
2846                dz1 = -7;
2847            b = (dz1 & 0x0f) | ((s->mouse_buttons & 0x18) << 1);
2848            kbd_queue(s, b, 1);
2849            break;
2850        }
2851    
2852        /* update deltas */
2853        s->mouse_dx -= dx1;
2854        s->mouse_dy -= dy1;
2855        s->mouse_dz -= dz1;
2856    }
2857    
2858    void kbd_mouse_event(int dx, int dy, int dz, int buttons_state)
2859    {
2860        KBDState *s = &kbd_state;
2861    
2862        /* check if deltas are recorded when disabled */
2863        if (!(s->mouse_status & MOUSE_STATUS_ENABLED))
2864            return;
2865    
2866        s->mouse_dx += dx;
2867        s->mouse_dy -= dy;
2868        s->mouse_dz += dz;
2869        s->mouse_buttons = buttons_state;
2870        
2871        if (!(s->mouse_status & MOUSE_STATUS_REMOTE) &&
2872            (s->queues[1].count < (KBD_QUEUE_SIZE - 16))) {
2873            for(;;) {
2874                /* if not remote, send event. Multiple events are sent if
2875                   too big deltas */
2876                kbd_mouse_send_packet(s);
2877                if (s->mouse_dx == 0 && s->mouse_dy == 0 && s->mouse_dz == 0)
2878                    break;
2879            }
2880        }
2881    }
2882    
2883    static void kbd_write_mouse(KBDState *s, int val)
2884    {
2885    #ifdef DEBUG_MOUSE
2886        printf("kbd: write mouse 0x%02x\n", val);
2887    #endif
2888        switch(s->mouse_write_cmd) {
2889        default:
2890        case -1:
2891            /* mouse command */
2892            if (s->mouse_wrap) {
2893                if (val == AUX_RESET_WRAP) {
2894                    s->mouse_wrap = 0;
2895                    kbd_queue(s, AUX_ACK, 1);
2896                    return;
2897                } else if (val != AUX_RESET) {
2898                    kbd_queue(s, val, 1);
2899                    return;
2900                }
2901            }
2902            switch(val) {
2903            case AUX_SET_SCALE11:
2904                s->mouse_status &= ~MOUSE_STATUS_SCALE21;
2905                kbd_queue(s, AUX_ACK, 1);
2906                break;
2907            case AUX_SET_SCALE21:
2908                s->mouse_status |= MOUSE_STATUS_SCALE21;
2909                kbd_queue(s, AUX_ACK, 1);
2910                break;
2911            case AUX_SET_STREAM:
2912                s->mouse_status &= ~MOUSE_STATUS_REMOTE;
2913                kbd_queue(s, AUX_ACK, 1);
2914                break;
2915            case AUX_SET_WRAP:
2916                s->mouse_wrap = 1;
2917                kbd_queue(s, AUX_ACK, 1);
2918                break;
2919            case AUX_SET_REMOTE:
2920                s->mouse_status |= MOUSE_STATUS_REMOTE;
2921                kbd_queue(s, AUX_ACK, 1);
2922                break;
2923            case AUX_GET_TYPE:
2924                kbd_queue(s, AUX_ACK, 1);
2925                kbd_queue(s, s->mouse_type, 1);
2926                break;
2927            case AUX_SET_RES:
2928            case AUX_SET_SAMPLE:
2929                s->mouse_write_cmd = val;
2930                kbd_queue(s, AUX_ACK, 1);
2931                break;
2932            case AUX_GET_SCALE:
2933                kbd_queue(s, AUX_ACK, 1);
2934                kbd_queue(s, s->mouse_status, 1);
2935                kbd_queue(s, s->mouse_resolution, 1);
2936                kbd_queue(s, s->mouse_sample_rate, 1);
2937                break;
2938            case AUX_POLL:
2939                kbd_queue(s, AUX_ACK, 1);
2940                kbd_mouse_send_packet(s);
2941                break;
2942            case AUX_ENABLE_DEV:
2943                s->mouse_status |= MOUSE_STATUS_ENABLED;
2944                kbd_queue(s, AUX_ACK, 1);
2945                break;
2946            case AUX_DISABLE_DEV:
2947                s->mouse_status &= ~MOUSE_STATUS_ENABLED;
2948                kbd_queue(s, AUX_ACK, 1);
2949                break;
2950            case AUX_SET_DEFAULT:
2951                s->mouse_sample_rate = 100;
2952                s->mouse_resolution = 2;
2953                s->mouse_status = 0;
2954                kbd_queue(s, AUX_ACK, 1);
2955                break;
2956            case AUX_RESET:
2957                s->mouse_sample_rate = 100;
2958                s->mouse_resolution = 2;
2959                s->mouse_status = 0;
2960                kbd_queue(s, AUX_ACK, 1);
2961                kbd_queue(s, 0xaa, 1);
2962                kbd_queue(s, s->mouse_type, 1);
2963                break;
2964            default:
2965                break;
2966            }
2967            break;
2968        case AUX_SET_SAMPLE:
2969            s->mouse_sample_rate = val;
2970    #if 0
2971            /* detect IMPS/2 or IMEX */
2972            switch(s->mouse_detect_state) {
2973            default:
2974            case 0:
2975                if (val == 200)
2976                    s->mouse_detect_state = 1;
2977                break;
2978            case 1:
2979                if (val == 100)
2980                    s->mouse_detect_state = 2;
2981                else if (val == 200)
2982                    s->mouse_detect_state = 3;
2983                else
2984                    s->mouse_detect_state = 0;
2985                break;
2986            case 2:
2987                if (val == 80)
2988                    s->mouse_type = 3; /* IMPS/2 */
2989                s->mouse_detect_state = 0;
2990                break;
2991            case 3:
2992                if (val == 80)
2993                    s->mouse_type = 4; /* IMEX */
2994                s->mouse_detect_state = 0;
2995                break;
2996            }
2997    #endif
2998            kbd_queue(s, AUX_ACK, 1);
2999            s->mouse_write_cmd = -1;
3000            break;
3001        case AUX_SET_RES:
3002            s->mouse_resolution = val;
3003            kbd_queue(s, AUX_ACK, 1);
3004            s->mouse_write_cmd = -1;
3005          break;          break;
3006      }      }
     s->kbd_write_cmd = -1;  
3007  }  }
3008    
3009  void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val)  void kbd_write_data(CPUX86State *env, uint32_t addr, uint32_t val)
# Line 2857  void kbd_write_data(CPUX86State *env, ui Line 3035  void kbd_write_data(CPUX86State *env, ui
3035              cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);              cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
3036          }          }
3037          break;          break;
3038        case KBD_CCMD_WRITE_MOUSE:
3039            kbd_write_mouse(s, val);
3040            break;
3041      default:      default:
3042          break;          break;
3043      }      }
# Line 2869  void kbd_reset(KBDState *s) Line 3050  void kbd_reset(KBDState *s)
3050      int i;      int i;
3051    
3052      s->kbd_write_cmd = -1;      s->kbd_write_cmd = -1;
3053        s->mouse_write_cmd = -1;
3054      s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;      s->mode = KBD_MODE_KBD_INT | KBD_MODE_MOUSE_INT;
3055      s->status = KBD_MODE_SYS | KBD_MODE_NO_KEYLOCK;      s->status = KBD_STAT_CMD | KBD_STAT_UNLOCKED;
3056      for(i = 0; i < 2; i++) {      for(i = 0; i < 2; i++) {
3057          q = &s->queues[i];          q = &s->queues[i];
3058          q->rptr = 0;          q->rptr = 0;
# Line 2934  void bochs_bios_init(void) Line 3116  void bochs_bios_init(void)
3116  }  }
3117    
3118  /***********************************************************/  /***********************************************************/
3119    /* dumb display */
3120    
3121    /* init terminal so that we can grab keys */
3122    static struct termios oldtty;
3123    
3124    static void term_exit(void)
3125    {
3126        tcsetattr (0, TCSANOW, &oldtty);
3127    }
3128    
3129    static void term_init(void)
3130    {
3131        struct termios tty;
3132    
3133        tcgetattr (0, &tty);
3134        oldtty = tty;
3135    
3136        tty.c_iflag &= ~(IGNBRK|BRKINT|PARMRK|ISTRIP
3137                              |INLCR|IGNCR|ICRNL|IXON);
3138        tty.c_oflag |= OPOST;
3139        tty.c_lflag &= ~(ECHO|ECHONL|ICANON|IEXTEN|ISIG);
3140        tty.c_cflag &= ~(CSIZE|PARENB);
3141        tty.c_cflag |= CS8;
3142        tty.c_cc[VMIN] = 1;
3143        tty.c_cc[VTIME] = 0;
3144        
3145        tcsetattr (0, TCSANOW, &tty);
3146    
3147        atexit(term_exit);
3148    
3149        fcntl(0, F_SETFL, O_NONBLOCK);
3150    }
3151    
3152    static void dumb_update(DisplayState *ds, int x, int y, int w, int h)
3153    {
3154    }
3155    
3156    static void dumb_resize(DisplayState *ds, int w, int h)
3157    {
3158    }
3159    
3160    static void dumb_refresh(DisplayState *ds)
3161    {
3162        vga_update_display();
3163    }
3164    
3165    void dumb_display_init(DisplayState *ds)
3166    {
3167        ds->data = NULL;
3168        ds->linesize = 0;
3169        ds->depth = 0;
3170        ds->dpy_update = dumb_update;
3171        ds->dpy_resize = dumb_resize;
3172        ds->dpy_refresh = dumb_refresh;
3173    }
3174    
3175    /***********************************************************/
3176  /* cpu signal handler */  /* cpu signal handler */
3177  static void host_segv_handler(int host_signum, siginfo_t *info,  static void host_segv_handler(int host_signum, siginfo_t *info,
3178                                void *puc)                                void *puc)
# Line 2947  static void host_segv_handler(int host_s Line 3186  static void host_segv_handler(int host_s
3186  static int timer_irq_pending;  static int timer_irq_pending;
3187  static int timer_irq_count;  static int timer_irq_count;
3188    
3189    static int timer_ms;
3190    static int gui_refresh_pending, gui_refresh_count;
3191    
3192  static void host_alarm_handler(int host_signum, siginfo_t *info,  static void host_alarm_handler(int host_signum, siginfo_t *info,
3193                                 void *puc)                                 void *puc)
3194  {  {
# Line 2958  static void host_alarm_handler(int host_ Line 3200  static void host_alarm_handler(int host_
3200          if (timer_irq_count > 2)          if (timer_irq_count > 2)
3201              timer_irq_count = 2;              timer_irq_count = 2;
3202          timer_irq_count--;          timer_irq_count--;
3203            timer_irq_pending = 1;
3204        }
3205        gui_refresh_count += timer_ms;
3206        if (gui_refresh_count >= GUI_REFRESH_INTERVAL) {
3207            gui_refresh_count = 0;
3208            gui_refresh_pending = 1;
3209        }
3210    
3211        if (gui_refresh_pending || timer_irq_pending) {
3212          /* just exit from the cpu to have a chance to handle timers */          /* just exit from the cpu to have a chance to handle timers */
3213          cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);          cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
         timer_irq_pending = 1;  
3214      }      }
3215  }  }
3216    
# Line 2988  int main_loop(void *opaque) Line 3238  int main_loop(void *opaque)
3238      uint8_t ch;      uint8_t ch;
3239      CPUState *env = global_env;      CPUState *env = global_env;
3240    
3241        if (nodisp && !term_inited) {
3242            /* initialize terminal only there so that the user has a
3243               chance to stop QEMU with Ctrl-C before the gdb connection
3244               is launched */
3245            term_inited = 1;
3246            term_init();
3247        }
3248    
3249      for(;;) {      for(;;) {
3250    
3251          ret = cpu_x86_exec(env);          ret = cpu_x86_exec(env);
# Line 3059  int main_loop(void *opaque) Line 3317  int main_loop(void *opaque)
3317              pic_set_irq(0, 0);              pic_set_irq(0, 0);
3318              timer_irq_pending = 0;              timer_irq_pending = 0;
3319          }          }
3320    
3321            /* VGA */
3322            if (gui_refresh_pending) {
3323                display_state.dpy_refresh(&display_state);
3324                gui_refresh_pending = 0;
3325            }
3326      }      }
3327      return EXCP_INTERRUPT;      return EXCP_INTERRUPT;
3328  }  }
# Line 3098  struct option long_options[] = { Line 3362  struct option long_options[] = {
3362      { "hdb", 1, NULL, 0, },      { "hdb", 1, NULL, 0, },
3363      { "snapshot", 0, NULL, 0, },      { "snapshot", 0, NULL, 0, },
3364      { "hdachs", 1, NULL, 0, },      { "hdachs", 1, NULL, 0, },
3365        { "nodisp", 0, NULL, 0, },
3366      { NULL, 0, NULL, 0 },      { NULL, 0, NULL, 0 },
3367  };  };
3368    
3369  int main(int argc, char **argv)  int main(int argc, char **argv)
3370  {  {
3371      int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;      int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
3372      int snapshot, linux_boot;      int snapshot, linux_boot, total_ram_size;
3373      struct linux_params *params;      struct linux_params *params;
3374      struct sigaction act;      struct sigaction act;
3375      struct itimerval itv;      struct itimerval itv;
3376      CPUX86State *env;      CPUX86State *env;
3377      const char *tmpdir, *initrd_filename;      const char *tmpdir, *initrd_filename;
3378      const char *hd_filename[MAX_DISKS];      const char *hd_filename[MAX_DISKS];
3379            DisplayState *ds = &display_state;
3380    
3381      /* we never want that malloc() uses mmap() */      /* we never want that malloc() uses mmap() */
3382      mallopt(M_MMAP_THRESHOLD, 4096 * 1024);      mallopt(M_MMAP_THRESHOLD, 4096 * 1024);
3383      initrd_filename = NULL;      initrd_filename = NULL;
3384      for(i = 0; i < MAX_DISKS; i++)      for(i = 0; i < MAX_DISKS; i++)
3385          hd_filename[i] = NULL;          hd_filename[i] = NULL;
3386      phys_ram_size = 32 * 1024 * 1024;      phys_ram_size = 32 * 1024 * 1024;
3387        vga_ram_size = VGA_RAM_SIZE;
3388      pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);      pstrcpy(network_script, sizeof(network_script), DEFAULT_NETWORK_SCRIPT);
3389      use_gdbstub = 0;      use_gdbstub = 0;
3390      gdbstub_port = DEFAULT_GDBSTUB_PORT;      gdbstub_port = DEFAULT_GDBSTUB_PORT;
3391      snapshot = 0;      snapshot = 0;
3392      linux_boot = 0;      linux_boot = 0;
3393        nodisp = 0;
3394      for(;;) {      for(;;) {
3395          c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index);          c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index);
3396          if (c == -1)          if (c == -1)
# Line 3164  int main(int argc, char **argv) Line 3432  int main(int argc, char **argv)
3432                  chs_fail: ;                  chs_fail: ;
3433                  }                  }
3434                  break;                  break;
3435                case 5:
3436                    nodisp = 1;
3437                    break;
3438              }              }
3439              break;              break;
3440          case 'h':          case 'h':
# Line 3232  int main(int argc, char **argv) Line 3503  int main(int argc, char **argv)
3503                  phys_ram_file);                  phys_ram_file);
3504          exit(1);          exit(1);
3505      }      }
3506      ftruncate(phys_ram_fd, phys_ram_size);      total_ram_size = phys_ram_size + vga_ram_size;
3507        ftruncate(phys_ram_fd, total_ram_size);
3508      unlink(phys_ram_file);      unlink(phys_ram_file);
3509      phys_ram_base = mmap(get_mmap_addr(phys_ram_size), phys_ram_size,      phys_ram_base = mmap(get_mmap_addr(total_ram_size),
3510                             total_ram_size,
3511                           PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED,                           PROT_WRITE | PROT_READ, MAP_SHARED | MAP_FIXED,
3512                           phys_ram_fd, 0);                           phys_ram_fd, 0);
3513      if (phys_ram_base == MAP_FAILED) {      if (phys_ram_base == MAP_FAILED) {
# Line 3261  int main(int argc, char **argv) Line 3534  int main(int argc, char **argv)
3534    
3535      init_ioports();      init_ioports();
3536    
3537        /* allocate RAM */
3538        cpu_register_physical_memory(0, phys_ram_size, 0);
3539    
3540      if (linux_boot) {      if (linux_boot) {
3541          /* now we can load the kernel */          /* now we can load the kernel */
3542          ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);          ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);
# Line 3366  int main(int argc, char **argv) Line 3642  int main(int argc, char **argv)
3642          bochs_bios_init();          bochs_bios_init();
3643      }      }
3644    
3645        /* terminal init */
3646        if (nodisp) {
3647            dumb_display_init(ds);
3648        } else {
3649    #ifdef CONFIG_SDL
3650            sdl_display_init(ds);
3651            /* the pthreads modify sigaction. We don't want that. */
3652    #define sigaction __sigaction
3653    #else
3654            dumb_display_init(ds);
3655    #endif
3656        }
3657      /* init basic PC hardware */      /* init basic PC hardware */
3658      register_ioport_write(0x80, 1, ioport80_write, 1);      register_ioport_write(0x80, 1, ioport80_write, 1);
3659    
3660      register_ioport_write(0x3d4, 2, vga_ioport_write, 1);      vga_init(ds, phys_ram_base + phys_ram_size, phys_ram_size,
3661                 vga_ram_size);
3662      cmos_init();      cmos_init();
3663      pic_init();      pic_init();
3664      pit_init();      pit_init();
# Line 3378  int main(int argc, char **argv) Line 3666  int main(int argc, char **argv)
3666      ne2000_init();      ne2000_init();
3667      ide_init();      ide_init();
3668      kbd_init();      kbd_init();
3669        
3670      /* setup cpu signal handlers for MMU / self modifying code handling */      /* setup cpu signal handlers for MMU / self modifying code handling */
3671      sigfillset(&act.sa_mask);      sigfillset(&act.sa_mask);
3672      act.sa_flags = SA_SIGINFO;      act.sa_flags = SA_SIGINFO;
# Line 3397  int main(int argc, char **argv) Line 3685  int main(int argc, char **argv)
3685      /* we probe the tick duration of the kernel to inform the user if      /* we probe the tick duration of the kernel to inform the user if
3686         the emulated kernel requested a too high timer frequency */         the emulated kernel requested a too high timer frequency */
3687      getitimer(ITIMER_REAL, &itv);      getitimer(ITIMER_REAL, &itv);
3688        timer_ms = itv.it_interval.tv_usec / 1000;
3689      pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) /      pit_min_timer_count = ((uint64_t)itv.it_interval.tv_usec * PIT_FREQ) /
3690          1000000;          1000000;
3691            

Legend:
Removed from v.1.15  
changed lines
  Added in v.1.16

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