vl.c 96.8 KB
Newer Older
1
/*
bellard's avatar
bellard committed
2
 * QEMU PC System Emulator
3
 * 
bellard's avatar
bellard committed
4
 * Copyright (c) 2003 Fabrice Bellard
5
 * 
bellard's avatar
bellard committed
6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in
 * all copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
 * THE SOFTWARE.
23 24 25
 */
#include <stdlib.h>
#include <stdio.h>
bellard's avatar
bellard committed
26
#include <stdarg.h>
27
#include <string.h>
28
#include <ctype.h>
29 30 31 32 33 34 35 36 37 38 39 40
#include <getopt.h>
#include <inttypes.h>
#include <unistd.h>
#include <sys/mman.h>
#include <fcntl.h>
#include <signal.h>
#include <time.h>
#include <sys/time.h>
#include <malloc.h>
#include <termios.h>
#include <sys/poll.h>
#include <errno.h>
bellard's avatar
bellard committed
41 42 43 44 45 46
#include <sys/wait.h>

#include <sys/ioctl.h>
#include <sys/socket.h>
#include <linux/if.h>
#include <linux/if_tun.h>
47 48

#include "disas.h"
bellard's avatar
bellard committed
49 50 51
#include "thunk.h"

#include "vl.h"
52

53
#define DEFAULT_NETWORK_SCRIPT "/etc/qemu-ifup"
54 55
#define BIOS_FILENAME "bios.bin"
#define VGABIOS_FILENAME "vgabios.bin"
bellard's avatar
bellard committed
56
#define LINUX_BOOT_FILENAME "linux_boot.bin"
bellard's avatar
bellard committed
57

58
//#define DEBUG_UNUSED_IOPORT
59

60
//#define DEBUG_IRQ_LATENCY
61

62 63 64
/* output Bochs bios info messages */
//#define DEBUG_BIOS

65 66
//#define DEBUG_CMOS

67 68 69 70 71 72 73 74 75
/* debug PIC */
//#define DEBUG_PIC

/* debug NE2000 card */
//#define DEBUG_NE2000

/* debug PC keyboard */
//#define DEBUG_KBD

76 77 78
/* debug PC keyboard : only mouse */
//#define DEBUG_MOUSE

79 80
//#define DEBUG_SERIAL

81
#if !defined(CONFIG_SOFTMMU)
bellard's avatar
bellard committed
82
#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
83 84 85
#else
#define PHYS_RAM_MAX_SIZE (2047 * 1024 * 1024)
#endif
bellard's avatar
bellard committed
86

87
#if defined (TARGET_I386)
88
#define KERNEL_LOAD_ADDR   0x00100000
89 90
#elif defined (TARGET_PPC)
//#define USE_OPEN_FIRMWARE
bellard's avatar
bellard committed
91
#if !defined (USE_OPEN_FIRMWARE)
92 93 94 95 96 97 98
#define KERNEL_LOAD_ADDR    0x01000000
#define KERNEL_STACK_ADDR   0x01200000
#else
#define KERNEL_LOAD_ADDR    0x00000000
#define KERNEL_STACK_ADDR   0x00400000
#endif
#endif
99 100 101
#define INITRD_LOAD_ADDR     0x00400000
#define KERNEL_PARAMS_ADDR   0x00090000
#define KERNEL_CMDLINE_ADDR  0x00099000
102

103 104
#define GUI_REFRESH_INTERVAL 30 

105 106
/* XXX: use a two level table to limit memory usage */
#define MAX_IOPORTS 65536
107

108
static const char *bios_dir = CONFIG_QEMU_SHAREDIR;
109
char phys_ram_file[1024];
110 111
CPUState *global_env;
CPUState *cpu_single_env;
bellard's avatar
bellard committed
112 113
IOPortReadFunc *ioport_read_table[3][MAX_IOPORTS];
IOPortWriteFunc *ioport_write_table[3][MAX_IOPORTS];
114
BlockDriverState *bs_table[MAX_DISKS], *fd_table[MAX_FD];
115 116
int vga_ram_size;
static DisplayState display_state;
117
int nographic;
118 119
int term_inited;
int64_t ticks_per_sec;
120
int boot_device = 'c';
121
static int ram_size;
122 123 124 125

/***********************************************************/
/* x86 io ports */

126
uint32_t default_ioport_readb(CPUState *env, uint32_t address)
127 128 129 130
{
#ifdef DEBUG_UNUSED_IOPORT
    fprintf(stderr, "inb: port=0x%04x\n", address);
#endif
bellard's avatar
bellard committed
131
    return 0xff;
132 133
}

134
void default_ioport_writeb(CPUState *env, uint32_t address, uint32_t data)
135 136 137 138 139 140 141
{
#ifdef DEBUG_UNUSED_IOPORT
    fprintf(stderr, "outb: port=0x%04x data=0x%02x\n", address, data);
#endif
}

/* default is to make two byte accesses */
142
uint32_t default_ioport_readw(CPUState *env, uint32_t address)
143 144
{
    uint32_t data;
145 146
    data = ioport_read_table[0][address & (MAX_IOPORTS - 1)](env, address);
    data |= ioport_read_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1) << 8;
147 148 149
    return data;
}

150
void default_ioport_writew(CPUState *env, uint32_t address, uint32_t data)
151
{
152 153
    ioport_write_table[0][address & (MAX_IOPORTS - 1)](env, address, data & 0xff);
    ioport_write_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1, (data >> 8) & 0xff);
154 155
}

156
uint32_t default_ioport_readl(CPUState *env, uint32_t address)
157
{
bellard's avatar
bellard committed
158 159 160 161
#ifdef DEBUG_UNUSED_IOPORT
    fprintf(stderr, "inl: port=0x%04x\n", address);
#endif
    return 0xffffffff;
162 163
}

164
void default_ioport_writel(CPUState *env, uint32_t address, uint32_t data)
165
{
bellard's avatar
bellard committed
166 167 168
#ifdef DEBUG_UNUSED_IOPORT
    fprintf(stderr, "outl: port=0x%04x data=0x%02x\n", address, data);
#endif
169 170
}

bellard's avatar
bellard committed
171
void init_ioports(void)
172 173 174
{
    int i;

bellard's avatar
bellard committed
175 176 177 178 179 180 181 182
    for(i = 0; i < MAX_IOPORTS; i++) {
        ioport_read_table[0][i] = default_ioport_readb;
        ioport_write_table[0][i] = default_ioport_writeb;
        ioport_read_table[1][i] = default_ioport_readw;
        ioport_write_table[1][i] = default_ioport_writew;
        ioport_read_table[2][i] = default_ioport_readl;
        ioport_write_table[2][i] = default_ioport_writel;
    }
183 184
}

bellard's avatar
bellard committed
185 186
/* size is the word size in byte */
int register_ioport_read(int start, int length, IOPortReadFunc *func, int size)
bellard's avatar
bellard committed
187
{
bellard's avatar
bellard committed
188
    int i, bsize;
bellard's avatar
bellard committed
189

bellard's avatar
bellard committed
190 191 192 193 194 195 196 197 198 199
    if (size == 1)
        bsize = 0;
    else if (size == 2)
        bsize = 1;
    else if (size == 4)
        bsize = 2;
    else
        return -1;
    for(i = start; i < start + length; i += size)
        ioport_read_table[bsize][i] = func;
bellard's avatar
bellard committed
200 201 202
    return 0;
}

bellard's avatar
bellard committed
203 204
/* size is the word size in byte */
int register_ioport_write(int start, int length, IOPortWriteFunc *func, int size)
bellard's avatar
bellard committed
205
{
bellard's avatar
bellard committed
206
    int i, bsize;
bellard's avatar
bellard committed
207

bellard's avatar
bellard committed
208 209 210 211 212 213 214 215 216 217
    if (size == 1)
        bsize = 0;
    else if (size == 2)
        bsize = 1;
    else if (size == 4)
        bsize = 2;
    else
        return -1;
    for(i = start; i < start + length; i += size)
        ioport_write_table[bsize][i] = func;
bellard's avatar
bellard committed
218 219 220
    return 0;
}

221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247
void pstrcpy(char *buf, int buf_size, const char *str)
{
    int c;
    char *q = buf;

    if (buf_size <= 0)
        return;

    for(;;) {
        c = *str++;
        if (c == 0 || q >= buf + buf_size - 1)
            break;
        *q++ = c;
    }
    *q = '\0';
}

/* strcat and truncate. */
char *pstrcat(char *buf, int buf_size, const char *s)
{
    int len;
    len = strlen(buf);
    if (len < buf_size) 
        pstrcpy(buf + len, buf_size - len, s);
    return buf;
}

248 249 250
#if defined (TARGET_I386)
int load_kernel(const char *filename, uint8_t *addr, 
                uint8_t *real_addr)
251
{
252 253
    int fd, size;
    int setup_sects;
254 255 256 257

    fd = open(filename, O_RDONLY);
    if (fd < 0)
        return -1;
258 259 260

    /* load 16 bit code */
    if (read(fd, real_addr, 512) != 512)
261
        goto fail;
262
    setup_sects = real_addr[0x1F1];
263 264
    if (!setup_sects)
        setup_sects = 4;
265 266 267 268 269
    if (read(fd, real_addr + 512, setup_sects * 512) != 
        setup_sects * 512)
        goto fail;
    
    /* load 32 bit code */
270 271 272 273 274 275 276 277 278
    size = read(fd, addr, 16 * 1024 * 1024);
    if (size < 0)
        goto fail;
    close(fd);
    return size;
 fail:
    close(fd);
    return -1;
}
279
#endif
280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297

/* return the size or -1 if error */
int load_image(const char *filename, uint8_t *addr)
{
    int fd, size;
    fd = open(filename, O_RDONLY);
    if (fd < 0)
        return -1;
    size = lseek(fd, 0, SEEK_END);
    lseek(fd, 0, SEEK_SET);
    if (read(fd, addr, size) != size) {
        close(fd);
        return -1;
    }
    close(fd);
    return size;
}

298
void cpu_outb(CPUState *env, int addr, int val)
299
{
bellard's avatar
bellard committed
300
    ioport_write_table[0][addr & (MAX_IOPORTS - 1)](env, addr, val);
301 302
}

303
void cpu_outw(CPUState *env, int addr, int val)
304
{
bellard's avatar
bellard committed
305
    ioport_write_table[1][addr & (MAX_IOPORTS - 1)](env, addr, val);
306 307
}

308
void cpu_outl(CPUState *env, int addr, int val)
309
{
bellard's avatar
bellard committed
310
    ioport_write_table[2][addr & (MAX_IOPORTS - 1)](env, addr, val);
311 312
}

313
int cpu_inb(CPUState *env, int addr)
314
{
bellard's avatar
bellard committed
315
    return ioport_read_table[0][addr & (MAX_IOPORTS - 1)](env, addr);
316 317
}

318
int cpu_inw(CPUState *env, int addr)
319
{
bellard's avatar
bellard committed
320
    return ioport_read_table[1][addr & (MAX_IOPORTS - 1)](env, addr);
321 322
}

323
int cpu_inl(CPUState *env, int addr)
324
{
bellard's avatar
bellard committed
325
    return ioport_read_table[2][addr & (MAX_IOPORTS - 1)](env, addr);
326 327 328
}

/***********************************************************/
329
void ioport80_write(CPUState *env, uint32_t addr, uint32_t data)
330 331 332 333 334 335 336 337 338 339 340 341 342
{
}

void hw_error(const char *fmt, ...)
{
    va_list ap;

    va_start(ap, fmt);
    fprintf(stderr, "qemu: hardware error: ");
    vfprintf(stderr, fmt, ap);
    fprintf(stderr, "\n");
#ifdef TARGET_I386
    cpu_x86_dump_state(global_env, stderr, X86_DUMP_FPU | X86_DUMP_CCOP);
343 344
#else
    cpu_dump_state(global_env, stderr, 0);
345 346 347 348 349 350 351 352
#endif
    va_end(ap);
    abort();
}

/***********************************************************/
/* cmos emulation */

353
#if defined (TARGET_I386)
354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373
#define RTC_SECONDS             0
#define RTC_SECONDS_ALARM       1
#define RTC_MINUTES             2
#define RTC_MINUTES_ALARM       3
#define RTC_HOURS               4
#define RTC_HOURS_ALARM         5
#define RTC_ALARM_DONT_CARE    0xC0

#define RTC_DAY_OF_WEEK         6
#define RTC_DAY_OF_MONTH        7
#define RTC_MONTH               8
#define RTC_YEAR                9

#define RTC_REG_A               10
#define RTC_REG_B               11
#define RTC_REG_C               12
#define RTC_REG_D               13

/* PC cmos mappings */
#define REG_EQUIPMENT_BYTE          0x14
374
#define REG_IBM_CENTURY_BYTE        0x32
375
#define REG_IBM_PS2_CENTURY_BYTE    0x37
376 377 378 379

uint8_t cmos_data[128];
uint8_t cmos_index;

380
void cmos_ioport_write(CPUState *env, uint32_t addr, uint32_t data)
381 382 383
{
    if (addr == 0x70) {
        cmos_index = data & 0x7f;
384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416
    } else {
#ifdef DEBUG_CMOS
        printf("cmos: write index=0x%02x val=0x%02x\n",
               cmos_index, data);
#endif        
        switch(addr) {
        case RTC_SECONDS_ALARM:
        case RTC_MINUTES_ALARM:
        case RTC_HOURS_ALARM:
            /* XXX: not supported */
            cmos_data[cmos_index] = data;
            break;
        case RTC_SECONDS:
        case RTC_MINUTES:
        case RTC_HOURS:
        case RTC_DAY_OF_WEEK:
        case RTC_DAY_OF_MONTH:
        case RTC_MONTH:
        case RTC_YEAR:
            cmos_data[cmos_index] = data;
            break;
        case RTC_REG_A:
        case RTC_REG_B:
            cmos_data[cmos_index] = data;
            break;
        case RTC_REG_C:
        case RTC_REG_D:
            /* cannot write to them */
            break;
        default:
            cmos_data[cmos_index] = data;
            break;
        }
417 418 419
    }
}

420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439
static inline int to_bcd(int a)
{
    return ((a / 10) << 4) | (a % 10);
}

static void cmos_update_time(void)
{
    struct tm *tm;
    time_t ti;

    ti = time(NULL);
    tm = gmtime(&ti);
    cmos_data[RTC_SECONDS] = to_bcd(tm->tm_sec);
    cmos_data[RTC_MINUTES] = to_bcd(tm->tm_min);
    cmos_data[RTC_HOURS] = to_bcd(tm->tm_hour);
    cmos_data[RTC_DAY_OF_WEEK] = to_bcd(tm->tm_wday);
    cmos_data[RTC_DAY_OF_MONTH] = to_bcd(tm->tm_mday);
    cmos_data[RTC_MONTH] = to_bcd(tm->tm_mon + 1);
    cmos_data[RTC_YEAR] = to_bcd(tm->tm_year % 100);
    cmos_data[REG_IBM_CENTURY_BYTE] = to_bcd((tm->tm_year / 100) + 19);
440
    cmos_data[REG_IBM_PS2_CENTURY_BYTE] = cmos_data[REG_IBM_CENTURY_BYTE];
441 442
}

443
uint32_t cmos_ioport_read(CPUState *env, uint32_t addr)
444 445 446 447 448 449
{
    int ret;

    if (addr == 0x70) {
        return 0xff;
    } else {
450
        switch(cmos_index) {
451 452 453 454 455 456 457 458
        case RTC_SECONDS:
        case RTC_MINUTES:
        case RTC_HOURS:
        case RTC_DAY_OF_WEEK:
        case RTC_DAY_OF_MONTH:
        case RTC_MONTH:
        case RTC_YEAR:
        case REG_IBM_CENTURY_BYTE:
459
        case REG_IBM_PS2_CENTURY_BYTE:
460 461 462
            cmos_update_time();
            ret = cmos_data[cmos_index];
            break;
463
        case RTC_REG_A:
464
            ret = cmos_data[cmos_index];
465 466
            /* toggle update-in-progress bit for Linux (same hack as
               plex86) */
467
            cmos_data[RTC_REG_A] ^= 0x80; 
468 469
            break;
        case RTC_REG_C:
470
            ret = cmos_data[cmos_index];
471
            pic_set_irq(8, 0);
472
            cmos_data[RTC_REG_C] = 0x00; 
473
            break;
474 475 476
        default:
            ret = cmos_data[cmos_index];
            break;
477 478 479 480 481
        }
#ifdef DEBUG_CMOS
        printf("cmos: read index=0x%02x val=0x%02x\n",
               cmos_index, ret);
#endif
482 483 484 485 486 487
        return ret;
    }
}

void cmos_init(void)
{
488
    int val;
489

490
    cmos_update_time();
491 492 493 494 495 496

    cmos_data[RTC_REG_A] = 0x26;
    cmos_data[RTC_REG_B] = 0x02;
    cmos_data[RTC_REG_C] = 0x00;
    cmos_data[RTC_REG_D] = 0x80;

497 498
    /* various important CMOS locations needed by PC/Bochs bios */

499
    cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
500
    cmos_data[REG_EQUIPMENT_BYTE] |= 0x04; /* PS/2 mouse installed */
501

502
    /* memory size */
503
    val = (ram_size / 1024) - 1024;
504 505 506 507 508 509 510
    if (val > 65535)
        val = 65535;
    cmos_data[0x17] = val;
    cmos_data[0x18] = val >> 8;
    cmos_data[0x30] = val;
    cmos_data[0x31] = val >> 8;

511
    val = (ram_size / 65536) - ((16 * 1024 * 1024) / 65536);
512 513 514 515 516
    if (val > 65535)
        val = 65535;
    cmos_data[0x34] = val;
    cmos_data[0x35] = val >> 8;
    
517 518
    switch(boot_device) {
    case 'a':
519
    case 'b':
520 521 522 523 524 525 526 527 528 529 530
        cmos_data[0x3d] = 0x01; /* floppy boot */
        break;
    default:
    case 'c':
        cmos_data[0x3d] = 0x02; /* hard drive boot */
        break;
    case 'd':
        cmos_data[0x3d] = 0x03; /* CD-ROM boot */
        break;
    }

bellard's avatar
bellard committed
531 532
    register_ioport_write(0x70, 2, cmos_ioport_write, 1);
    register_ioport_read(0x70, 2, cmos_ioport_read, 1);
533 534
}

535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561 562 563 564 565 566 567 568 569 570 571 572 573 574 575 576 577 578 579 580 581 582 583 584
void cmos_register_fd (uint8_t fd0, uint8_t fd1)
{
    int nb = 0;

    cmos_data[0x10] = 0;
    switch (fd0) {
    case 0:
        /* 1.44 Mb 3"5 drive */
        cmos_data[0x10] |= 0x40;
        break;
    case 1:
        /* 2.88 Mb 3"5 drive */
        cmos_data[0x10] |= 0x60;
        break;
    case 2:
        /* 1.2 Mb 5"5 drive */
        cmos_data[0x10] |= 0x20;
        break;
    }
    switch (fd1) {
    case 0:
        /* 1.44 Mb 3"5 drive */
        cmos_data[0x10] |= 0x04;
        break;
    case 1:
        /* 2.88 Mb 3"5 drive */
        cmos_data[0x10] |= 0x06;
        break;
    case 2:
        /* 1.2 Mb 5"5 drive */
        cmos_data[0x10] |= 0x02;
        break;
    }
    if (fd0 < 3)
        nb++;
    if (fd1 < 3)
        nb++;
    switch (nb) {
    case 0:
        break;
    case 1:
        cmos_data[REG_EQUIPMENT_BYTE] |= 0x01; /* 1 drive, ready for boot */
        break;
    case 2:
        cmos_data[REG_EQUIPMENT_BYTE] |= 0x41; /* 2 drives, ready for boot */
        break;
    }
}
#endif /* TARGET_I386 */

585 586 587 588 589 590 591 592
/***********************************************************/
/* 8259 pic emulation */

typedef struct PicState {
    uint8_t last_irr; /* edge detection */
    uint8_t irr; /* interrupt request register */
    uint8_t imr; /* interrupt mask register */
    uint8_t isr; /* interrupt service register */
593
    uint8_t priority_add; /* highest irq priority */
594 595
    uint8_t irq_base;
    uint8_t read_reg_select;
596
    uint8_t poll;
597 598 599
    uint8_t special_mask;
    uint8_t init_state;
    uint8_t auto_eoi;
600 601
    uint8_t rotate_on_auto_eoi;
    uint8_t special_fully_nested_mode;
602 603 604 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622
    uint8_t init4; /* true if 4 byte init */
} PicState;

/* 0 is master pic, 1 is slave pic */
PicState pics[2];
int pic_irq_requested;

/* set irq level. If an edge is detected, then the IRR is set to 1 */
static inline void pic_set_irq1(PicState *s, int irq, int level)
{
    int mask;
    mask = 1 << irq;
    if (level) {
        if ((s->last_irr & mask) == 0)
            s->irr |= mask;
        s->last_irr |= mask;
    } else {
        s->last_irr &= ~mask;
    }
}

623 624
/* return the highest priority found in mask (highest = smallest
   number). Return 8 if no irq */
625 626 627 628
static inline int get_priority(PicState *s, int mask)
{
    int priority;
    if (mask == 0)
629 630
        return 8;
    priority = 0;
631
    while ((mask & (1 << ((priority + s->priority_add) & 7))) == 0)
632
        priority++;
633 634 635 636 637 638 639 640 641 642
    return priority;
}

/* return the pic wanted interrupt. return -1 if none */
static int pic_get_irq(PicState *s)
{
    int mask, cur_priority, priority;

    mask = s->irr & ~s->imr;
    priority = get_priority(s, mask);
643
    if (priority == 8)
644
        return -1;
645 646 647 648 649 650 651 652
    /* compute current priority. If special fully nested mode on the
       master, the IRQ coming from the slave is not taken into account
       for the priority computation. */
    mask = s->isr;
    if (s->special_fully_nested_mode && s == &pics[0])
        mask &= ~(1 << 2);
    cur_priority = get_priority(s, mask);
    if (priority < cur_priority) {
653
        /* higher priority found: an irq should be generated */
654
        return (priority + s->priority_add) & 7;
655 656 657 658 659
    } else {
        return -1;
    }
}

660 661
/* raise irq to CPU if necessary. must be called every time the active
   irq may change */
662
void pic_update_irq(void)
663 664 665 666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682
{
    int irq2, irq;

    /* first look at slave pic */
    irq2 = pic_get_irq(&pics[1]);
    if (irq2 >= 0) {
        /* if irq request by slave pic, signal master PIC */
        pic_set_irq1(&pics[0], 2, 1);
        pic_set_irq1(&pics[0], 2, 0);
    }
    /* look at requested irq */
    irq = pic_get_irq(&pics[0]);
    if (irq >= 0) {
        if (irq == 2) {
            /* from slave pic */
            pic_irq_requested = 8 + irq2;
        } else {
            /* from master pic */
            pic_irq_requested = irq;
        }
683 684 685 686 687 688 689 690 691 692 693
#if defined(DEBUG_PIC)
        {
            int i;
            for(i = 0; i < 2; i++) {
                printf("pic%d: imr=%x irr=%x padd=%d\n", 
                       i, pics[i].imr, pics[i].irr, pics[i].priority_add);
                
            }
        }
        printf("pic: cpu_interrupt req=%d\n", pic_irq_requested);
#endif
694
        cpu_interrupt(global_env, CPU_INTERRUPT_HARD);
695 696 697
    }
}

698 699 700 701
#ifdef DEBUG_IRQ_LATENCY
int64_t irq_time[16];
int64_t cpu_get_ticks(void);
#endif
702
#if defined(DEBUG_PIC)
bellard's avatar
bellard committed
703 704
int irq_level[16];
#endif
705 706 707

void pic_set_irq(int irq, int level)
{
708
#if defined(DEBUG_PIC)
bellard's avatar
bellard committed
709 710 711 712 713
    if (level != irq_level[irq]) {
        printf("pic_set_irq: irq=%d level=%d\n", irq, level);
        irq_level[irq] = level;
    }
#endif
714 715 716 717 718 719 720 721 722
#ifdef DEBUG_IRQ_LATENCY
    if (level) {
        irq_time[irq] = cpu_get_ticks();
    }
#endif
    pic_set_irq1(&pics[irq >> 3], irq & 7, level);
    pic_update_irq();
}

723 724 725 726 727 728 729 730 731 732 733 734
/* acknowledge interrupt 'irq' */
static inline void pic_intack(PicState *s, int irq)
{
    if (s->auto_eoi) {
        if (s->rotate_on_auto_eoi)
            s->priority_add = (irq + 1) & 7;
    } else {
        s->isr |= (1 << irq);
    }
    s->irr &= ~(1 << irq);
}

735
int cpu_x86_get_pic_interrupt(CPUState *env)
736 737 738 739 740
{
    int irq, irq2, intno;

    /* signal the pic that the irq was acked by the CPU */
    irq = pic_irq_requested;
741
#ifdef DEBUG_IRQ_LATENCY
742 743 744
    printf("IRQ%d latency=%0.3fus\n", 
           irq, 
           (double)(cpu_get_ticks() - irq_time[irq]) * 1000000.0 / ticks_per_sec);
745
#endif
746
#if defined(DEBUG_PIC)
bellard's avatar
bellard committed
747 748
    printf("pic_interrupt: irq=%d\n", irq);
#endif
749

750 751
    if (irq >= 8) {
        irq2 = irq & 7;
752
        pic_intack(&pics[1], irq2);
753 754 755 756 757
        irq = 2;
        intno = pics[1].irq_base + irq2;
    } else {
        intno = pics[0].irq_base + irq;
    }
758
    pic_intack(&pics[0], irq);
759 760 761
    return intno;
}

762
void pic_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
763 764
{
    PicState *s;
765
    int priority, cmd, irq;
766

bellard's avatar
bellard committed
767 768 769
#ifdef DEBUG_PIC
    printf("pic_write: addr=0x%02x val=0x%02x\n", addr, val);
#endif
770 771 772 773 774 775 776 777 778 779 780 781 782
    s = &pics[addr >> 7];
    addr &= 1;
    if (addr == 0) {
        if (val & 0x10) {
            /* init */
            memset(s, 0, sizeof(PicState));
            s->init_state = 1;
            s->init4 = val & 1;
            if (val & 0x02)
                hw_error("single mode not supported");
            if (val & 0x08)
                hw_error("level sensitive irq not supported");
        } else if (val & 0x08) {
783
            if (val & 0x04)
784
                s->poll = 1;
785 786 787 788 789
            if (val & 0x02)
                s->read_reg_select = val & 1;
            if (val & 0x40)
                s->special_mask = (val >> 5) & 1;
        } else {
790 791 792 793 794
            cmd = val >> 5;
            switch(cmd) {
            case 0:
            case 4:
                s->rotate_on_auto_eoi = cmd >> 2;
795
                break;
796 797
            case 1: /* end of interrupt */
            case 5:
798
                priority = get_priority(s, s->isr);
799 800 801 802 803 804
                if (priority != 8) {
                    irq = (priority + s->priority_add) & 7;
                    s->isr &= ~(1 << irq);
                    if (cmd == 5)
                        s->priority_add = (irq + 1) & 7;
                    pic_update_irq();
805 806
                }
                break;
807 808 809
            case 3:
                irq = val & 7;
                s->isr &= ~(1 << irq);
810
                pic_update_irq();
811
                break;
812
            case 6:
813
                s->priority_add = (val + 1) & 7;
814
                pic_update_irq();
815
                break;
816 817 818 819
            case 7:
                irq = val & 7;
                s->isr &= ~(1 << irq);
                s->priority_add = (irq + 1) & 7;
820
                pic_update_irq();
821
                break;
822 823 824
            default:
                /* no operation */
                break;
825 826 827 828 829 830 831
            }
        }
    } else {
        switch(s->init_state) {
        case 0:
            /* normal mode */
            s->imr = val;
832
            pic_update_irq();
833 834 835 836 837 838 839 840 841 842 843 844 845
            break;
        case 1:
            s->irq_base = val & 0xf8;
            s->init_state = 2;
            break;
        case 2:
            if (s->init4) {
                s->init_state = 3;
            } else {
                s->init_state = 0;
            }
            break;
        case 3:
846
            s->special_fully_nested_mode = (val >> 4) & 1;
847 848 849 850 851 852 853
            s->auto_eoi = (val >> 1) & 1;
            s->init_state = 0;
            break;
        }
    }
}

854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876
static uint32_t pic_poll_read (PicState *s, uint32_t addr1)
{
    int ret;

    ret = pic_get_irq(s);
    if (ret >= 0) {
        if (addr1 >> 7) {
            pics[0].isr &= ~(1 << 2);
            pics[0].irr &= ~(1 << 2);
        }
        s->irr &= ~(1 << ret);
        s->isr &= ~(1 << ret);
        if (addr1 >> 7 || ret != 2)
            pic_update_irq();
    } else {
        ret = 0x07;
        pic_update_irq();
    }

    return ret;
}

uint32_t pic_ioport_read(CPUState *env, uint32_t addr1)
877 878
{
    PicState *s;
bellard's avatar
bellard committed
879 880 881 882
    unsigned int addr;
    int ret;

    addr = addr1;
883 884
    s = &pics[addr >> 7];
    addr &= 1;
885
    if (s->poll) {
886 887 888
        ret = pic_poll_read(s, addr1);
        s->poll = 0;
    } else {
889 890 891 892 893 894 895 896
        if (addr == 0) {
            if (s->read_reg_select)
                ret = s->isr;
            else
                ret = s->irr;
        } else {
            ret = s->imr;
        }
897
    }
bellard's avatar
bellard committed
898 899 900 901
#ifdef DEBUG_PIC
    printf("pic_read: addr=0x%02x val=0x%02x\n", addr1, ret);
#endif
    return ret;
902 903
}

904 905 906 907 908 909 910 911 912 913 914 915 916 917
/* memory mapped interrupt status */
uint32_t pic_intack_read(CPUState *env)
{
    int ret;

    ret = pic_poll_read(&pics[0], 0x00);
    if (ret == 2)
        ret = pic_poll_read(&pics[1], 0x80) + 8;
    /* Prepare for ISR read */
    pics[0].read_reg_select = 1;
    
    return ret;
}

918 919
void pic_init(void)
{
920
#if defined (TARGET_I386) || defined (TARGET_PPC)
bellard's avatar
bellard committed
921 922 923 924
    register_ioport_write(0x20, 2, pic_ioport_write, 1);
    register_ioport_read(0x20, 2, pic_ioport_read, 1);
    register_ioport_write(0xa0, 2, pic_ioport_write, 1);
    register_ioport_read(0xa0, 2, pic_ioport_read, 1);
925
#endif
926 927 928 929 930 931 932 933 934 935 936 937 938 939 940
}

/***********************************************************/
/* 8253 PIT emulation */

#define PIT_FREQ 1193182

#define RW_STATE_LSB 0
#define RW_STATE_MSB 1
#define RW_STATE_WORD0 2
#define RW_STATE_WORD1 3
#define RW_STATE_LATCHED_WORD0 4
#define RW_STATE_LATCHED_WORD1 5

typedef struct PITChannelState {
941
    int count; /* can be 65536 */
942 943 944 945 946 947
    uint16_t latched_count;
    uint8_t rw_state;
    uint8_t mode;
    uint8_t bcd; /* not supported */
    uint8_t gate; /* timer start */
    int64_t count_load_time;
948
    int64_t count_last_edge_check_time;
949 950 951 952
} PITChannelState;

PITChannelState pit_channels[3];
int speaker_data_on;
953
int dummy_refresh_clock;
954
int pit_min_timer_count = 0;
955

956 957 958 959

#if defined(__powerpc__)

static inline uint32_t get_tbl(void) 
960
{
961 962 963
    uint32_t tbl;
    asm volatile("mftb %0" : "=r" (tbl));
    return tbl;
964 965
}

966 967 968 969 970 971 972 973 974 975 976 977 978 979 980 981 982 983 984 985 986 987
static inline uint32_t get_tbu(void) 
{
	uint32_t tbl;
	asm volatile("mftbu %0" : "=r" (tbl));
	return tbl;
}

int64_t cpu_get_real_ticks(void)
{
    uint32_t l, h, h1;
    /* NOTE: we test if wrapping has occurred */
    do {
        h = get_tbu();
        l = get_tbl();
        h1 = get_tbu();
    } while (h != h1);
    return ((int64_t)h << 32) | l;
}

#elif defined(__i386__)

int64_t cpu_get_real_ticks(void)
988 989 990 991 992 993
{
    int64_t val;
    asm("rdtsc" : "=A" (val));
    return val;
}

994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025
#else
#error unsupported CPU
#endif

static int64_t cpu_ticks_offset;
static int64_t cpu_ticks_last;

int64_t cpu_get_ticks(void)
{
    return cpu_get_real_ticks() + cpu_ticks_offset;
}

/* enable cpu_get_ticks() */
void cpu_enable_ticks(void)
{
    cpu_ticks_offset = cpu_ticks_last - cpu_get_real_ticks();
}

/* disable cpu_get_ticks() : the clock is stopped. You must not call
   cpu_get_ticks() after that.  */
void cpu_disable_ticks(void)
{
    cpu_ticks_last = cpu_get_ticks();
}

int64_t get_clock(void)
{
    struct timeval tv;
    gettimeofday(&tv, NULL);
    return tv.tv_sec * 1000000LL + tv.tv_usec;
}

1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037
void cpu_calibrate_ticks(void)
{
    int64_t usec, ticks;

    usec = get_clock();
    ticks = cpu_get_ticks();
    usleep(50 * 1000);
    usec = get_clock() - usec;
    ticks = cpu_get_ticks() - ticks;
    ticks_per_sec = (ticks * 1000000LL + (usec >> 1)) / usec;
}

1038 1039 1040 1041 1042 1043 1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061
/* compute with 96 bit intermediate result: (a*b)/c */
static uint64_t muldiv64(uint64_t a, uint32_t b, uint32_t c)
{
    union {
        uint64_t ll;
        struct {
#ifdef WORDS_BIGENDIAN
            uint32_t high, low;
#else
            uint32_t low, high;
#endif            
        } l;
    } u, res;
    uint64_t rl, rh;

    u.ll = a;
    rl = (uint64_t)u.l.low * (uint64_t)b;
    rh = (uint64_t)u.l.high * (uint64_t)b;
    rh += (rl >> 32);
    res.l.high = rh / c;
    res.l.low = (((rh % c) << 32) + (rl & 0xffffffff)) / c;
    return res.ll;
}

1062 1063
static int pit_get_count(PITChannelState *s)
{
1064
    uint64_t d;
1065 1066
    int counter;

1067
    d = muldiv64(cpu_get_ticks() - s->count_load_time, PIT_FREQ, ticks_per_sec);
1068 1069 1070 1071 1072 1073 1074
    switch(s->mode) {
    case 0:
    case 1:
    case 4:
    case 5:
        counter = (s->count - d) & 0xffff;
        break;
bellard's avatar
bellard committed
1075 1076 1077 1078
    case 3:
        /* XXX: may be incorrect for odd counts */
        counter = s->count - ((2 * d) % s->count);
        break;
1079 1080 1081 1082 1083 1084 1085 1086 1087 1088
    default:
        counter = s->count - (d % s->count);
        break;
    }
    return counter;
}

/* get pit output bit */
static int pit_get_out(PITChannelState *s)
{
1089
    uint64_t d;
1090 1091
    int out;

1092
    d = muldiv64(cpu_get_ticks() - s->count_load_time, PIT_FREQ, ticks_per_sec);
1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107
    switch(s->mode) {
    default:
    case 0:
        out = (d >= s->count);
        break;
    case 1:
        out = (d < s->count);
        break;
    case 2:
        if ((d % s->count) == 0 && d != 0)
            out = 1;
        else
            out = 0;
        break;
    case 3:
bellard's avatar
bellard committed
1108
        out = (d % s->count) < ((s->count + 1) >> 1);
1109 1110 1111 1112 1113 1114 1115 1116 1117
        break;
    case 4:
    case 5:
        out = (d == s->count);
        break;
    }
    return out;
}

1118 1119 1120 1121 1122 1123 1124 1125 1126 1127 1128 1129 1130 1131 1132 1133 1134 1135 1136 1137 1138 1139 1140 1141 1142 1143 1144 1145 1146 1147 1148 1149 1150
/* get the number of 0 to 1 transitions we had since we call this
   function */
/* XXX: maybe better to use ticks precision to avoid getting edges
   twice if checks are done at very small intervals */
static int pit_get_out_edges(PITChannelState *s)
{
    uint64_t d1, d2;
    int64_t ticks;
    int ret, v;

    ticks = cpu_get_ticks();
    d1 = muldiv64(s->count_last_edge_check_time - s->count_load_time, 
                 PIT_FREQ, ticks_per_sec);
    d2 = muldiv64(ticks - s->count_load_time, 
                  PIT_FREQ, ticks_per_sec);
    s->count_last_edge_check_time = ticks;
    switch(s->mode) {
    default:
    case 0:
        if (d1 < s->count && d2 >= s->count)
            ret = 1;
        else
            ret = 0;
        break;
    case 1:
        ret = 0;
        break;
    case 2:
        d1 /= s->count;
        d2 /= s->count;
        ret = d2 - d1;
        break;
    case 3:
bellard's avatar
bellard committed
1151
        v = s->count - ((s->count + 1) >> 1);
1152 1153 1154 1155 1156 1157 1158 1159 1160 1161 1162 1163 1164 1165 1166
        d1 = (d1 + v) / s->count;
        d2 = (d2 + v) / s->count;
        ret = d2 - d1;
        break;
    case 4:
    case 5:
        if (d1 < s->count && d2 >= s->count)
            ret = 1;
        else
            ret = 0;
        break;
    }
    return ret;
}

bellard's avatar
bellard committed
1167 1168 1169 1170 1171 1172 1173 1174 1175 1176 1177 1178 1179 1180 1181 1182 1183 1184 1185 1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196
/* val must be 0 or 1 */
static inline void pit_set_gate(PITChannelState *s, int val)
{
    switch(s->mode) {
    default:
    case 0:
    case 4:
        /* XXX: just disable/enable counting */
        break;
    case 1:
    case 5:
        if (s->gate < val) {
            /* restart counting on rising edge */
            s->count_load_time = cpu_get_ticks();
            s->count_last_edge_check_time = s->count_load_time;
        }
        break;
    case 2:
    case 3:
        if (s->gate < val) {
            /* restart counting on rising edge */
            s->count_load_time = cpu_get_ticks();
            s->count_last_edge_check_time = s->count_load_time;
        }
        /* XXX: disable/enable counting */
        break;
    }
    s->gate = val;
}

1197 1198 1199 1200 1201 1202 1203 1204 1205
static inline void pit_load_count(PITChannelState *s, int val)
{
    if (val == 0)
        val = 0x10000;
    s->count_load_time = cpu_get_ticks();
    s->count_last_edge_check_time = s->count_load_time;
    s->count = val;
    if (s == &pit_channels[0] && val <= pit_min_timer_count) {
        fprintf(stderr, 
1206
                "\nWARNING: qemu: on your system, accurate timer emulation is impossible if its frequency is more than %d Hz. If using a 2.6 guest Linux kernel, you must patch asm/param.h to change HZ from 1000 to 100.\n\n", 
1207 1208 1209 1210
                PIT_FREQ / pit_min_timer_count);
    }
}

1211
void pit_ioport_write(CPUState *env, uint32_t addr, uint32_t val)
1212 1213 1214
{
    int channel, access;
    PITChannelState *s;
1215

1216 1217 1218 1219 1220 1221 1222 1223 1224 1225 1226 1227