Revision 330d0414 vl.c

b/vl.c
52 52

  
53 53
#define DEBUG_LOGFILE "/tmp/vl.log"
54 54
#define DEFAULT_NETWORK_SCRIPT "/etc/vl-ifup"
55
#define BIOS_FILENAME "bios.bin"
56
#define VGABIOS_FILENAME "vgabios.bin"
55 57

  
56 58
//#define DEBUG_UNUSED_IOPORT
59

  
57 60
//#define DEBUG_IRQ_LATENCY
58 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

  
59 77
#define PHYS_RAM_BASE     0xac000000
60 78
#define PHYS_RAM_MAX_SIZE (256 * 1024 * 1024)
61 79

  
......
185 203

  
186 204
#define MAX_IOPORTS 4096
187 205

  
206
static const char *interp_prefix = CONFIG_QEMU_PREFIX;
188 207
char phys_ram_file[1024];
189 208
CPUX86State *global_env;
190 209
CPUX86State *cpu_single_env;
......
216 235
uint32_t default_ioport_readw(CPUX86State *env, uint32_t address)
217 236
{
218 237
    uint32_t data;
219
    data = ioport_read_table[0][address](env, address);
220
    data |= ioport_read_table[0][address + 1](env, address + 1) << 8;
238
    data = ioport_read_table[0][address & (MAX_IOPORTS - 1)](env, address);
239
    data |= ioport_read_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1) << 8;
221 240
    return data;
222 241
}
223 242

  
224 243
void default_ioport_writew(CPUX86State *env, uint32_t address, uint32_t data)
225 244
{
226
    ioport_write_table[0][address](env, address, data & 0xff);
227
    ioport_write_table[0][address + 1](env, address + 1, (data >> 8) & 0xff);
245
    ioport_write_table[0][address & (MAX_IOPORTS - 1)](env, address, data & 0xff);
246
    ioport_write_table[0][(address + 1) & (MAX_IOPORTS - 1)](env, address + 1, (data >> 8) & 0xff);
228 247
}
229 248

  
230 249
uint32_t default_ioport_readl(CPUX86State *env, uint32_t address)
......
516 535
{
517 536
    struct tm *tm;
518 537
    time_t ti;
538
    int val;
519 539

  
520 540
    ti = time(NULL);
521 541
    tm = gmtime(&ti);
......
532 552
    cmos_data[RTC_REG_C] = 0x00;
533 553
    cmos_data[RTC_REG_D] = 0x80;
534 554

  
555
    /* various important CMOS locations needed by PC/Bochs bios */
556

  
535 557
    cmos_data[REG_EQUIPMENT_BYTE] = 0x02; /* FPU is there */
536 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
    
537 576
    register_ioport_write(0x70, 2, cmos_ioport_write, 1);
538 577
    register_ioport_read(0x70, 2, cmos_ioport_read, 1);
539 578
}
......
541 580
/***********************************************************/
542 581
/* 8259 pic emulation */
543 582

  
544
//#define DEBUG_PIC
545

  
546 583
typedef struct PicState {
547 584
    uint8_t last_irr; /* edge detection */
548 585
    uint8_t irr; /* interrupt request register */
......
1360 1397
/***********************************************************/
1361 1398
/* ne2000 emulation */
1362 1399

  
1363
//#define DEBUG_NE2000
1364

  
1365 1400
#define NE2000_IOPORT   0x300
1366 1401
#define NE2000_IRQ      9
1367 1402

  
......
1827 1862
/***********************************************************/
1828 1863
/* ide emulation */
1829 1864

  
1830
//#define DEBUG_IDE
1831

  
1832 1865
/* Bits of HD_STATUS */
1833 1866
#define ERR_STAT		0x01
1834 1867
#define INDEX_STAT		0x02
......
2352 2385
    int ret;
2353 2386
    ret = s->status;
2354 2387
#ifdef DEBUG_IDE
2355
    printf("ide: read addr=0x%x val=%02x\n", addr, ret);
2388
    printf("ide: read status val=%02x\n", ret);
2356 2389
#endif
2357 2390
    return ret;
2358 2391
}
2359 2392

  
2360 2393
void ide_cmd_write(CPUX86State *env, uint32_t addr, uint32_t val)
2361 2394
{
2362
    IDEState *s = &ide_state[0];
2395
    IDEState *s;
2396
    int i;
2397

  
2398
#ifdef DEBUG_IDE
2399
    printf("ide: write control val=%02x\n", val);
2400
#endif
2363 2401
    /* common for both drives */
2364
    s->cmd = val;
2402
    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;
2365 2432
}
2366 2433

  
2367 2434
void ide_data_writew(CPUX86State *env, uint32_t addr, uint32_t val)
......
2439 2506
        s->bs = bs_table[i];
2440 2507
        if (s->bs) {
2441 2508
            bdrv_get_geometry(s->bs, &nb_sectors);
2442
            cylinders = nb_sectors / (16 * 63);
2443
            if (cylinders > 16383)
2444
                cylinders = 16383;
2445
            else if (cylinders < 2)
2446
                cylinders = 2;
2447
            s->cylinders = cylinders;
2448
            s->heads = 16;
2449
            s->sectors = 63;
2509
            if (s->cylinders == 0) {
2510
                /* if no geometry, use a LBA compatible one */
2511
                cylinders = nb_sectors / (16 * 63);
2512
                if (cylinders > 16383)
2513
                    cylinders = 16383;
2514
                else if (cylinders < 2)
2515
                    cylinders = 2;
2516
                s->cylinders = cylinders;
2517
                s->heads = 16;
2518
                s->sectors = 63;
2519
            }
2450 2520
            s->nb_sectors = nb_sectors;
2451 2521
        }
2452 2522
        s->irq = 14;
......
2465 2535
}
2466 2536

  
2467 2537
/***********************************************************/
2468
/* simulate reset (stop qemu) */
2538
/* 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
};
2469 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;
2470 2630
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
}
2471 2659

  
2472 2660
uint32_t kbd_read_status(CPUX86State *env, uint32_t addr)
2473 2661
{
2474
    return 0;
2662
    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;
2475 2669
}
2476 2670

  
2477 2671
void kbd_write_command(CPUX86State *env, uint32_t addr, uint32_t val)
2478 2672
{
2673
    KBDState *s = &kbd_state;
2674

  
2675
#ifdef DEBUG_KBD
2676
    printf("kbd: write cmd=0x%02x\n", val);
2677
#endif
2479 2678
    switch(val) {
2480
    case 0xfe:
2679
    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:
2481 2730
        reset_requested = 1;
2482 2731
        cpu_x86_interrupt(global_env, CPU_INTERRUPT_EXIT);
2483 2732
        break;
2484 2733
    default:
2734
        fprintf(stderr, "vl: unsupported keyboard cmd=0x%02x\n", val);
2735
        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:
2485 2858
        break;
2486 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
    }
2487 2877
}
2488 2878

  
2489 2879
void kbd_init(void)
2490 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);
2491 2884
    register_ioport_read(0x64, 1, kbd_read_status, 1);
2492 2885
    register_ioport_write(0x64, 1, kbd_write_command, 1);
2493 2886
}
2494 2887

  
2495 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
/***********************************************************/
2496 2934
/* cpu signal handler */
2497 2935
static void host_segv_handler(int host_signum, siginfo_t *info, 
2498 2936
                              void *puc)
......
2625 3063
void help(void)
2626 3064
{
2627 3065
    printf("Virtual Linux version " QEMU_VERSION ", Copyright (c) 2003 Fabrice Bellard\n"
2628
           "usage: vl [options] bzImage [kernel parameters...]\n"
3066
           "usage: vl [options] [bzImage [kernel parameters...]]\n"
2629 3067
           "\n"
2630 3068
           "'bzImage' is a Linux kernel image (PAGE_OFFSET must be defined\n"
2631 3069
           "to 0x90000000 in asm/page.h and arch/i386/vmlinux.lds)\n"
......
2638 3076
           "-m megs        set virtual RAM size to megs MB\n"
2639 3077
           "-n script      set network init script [default=%s]\n"
2640 3078
           "\n"
2641
           "Debug options:\n"
3079
           "Debug/Expert options:\n"
2642 3080
           "-s             wait gdb connection to port %d\n"
2643 3081
           "-p port        change gdb connection port\n"
2644 3082
           "-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"
2645 3085
           "\n"
2646 3086
           "During emulation, use C-a h to get terminal commands:\n",
2647 3087
           DEFAULT_NETWORK_SCRIPT, DEFAULT_GDBSTUB_PORT);
......
2654 3094
    { "hda", 1, NULL, 0, },
2655 3095
    { "hdb", 1, NULL, 0, },
2656 3096
    { "snapshot", 0, NULL, 0, },
3097
    { "hdachs", 1, NULL, 0, },
2657 3098
    { NULL, 0, NULL, 0 },
2658 3099
};
2659 3100

  
2660 3101
int main(int argc, char **argv)
2661 3102
{
2662 3103
    int c, ret, initrd_size, i, use_gdbstub, gdbstub_port, long_index;
2663
    int snapshot;
3104
    int snapshot, linux_boot;
2664 3105
    struct linux_params *params;
2665 3106
    struct sigaction act;
2666 3107
    struct itimerval itv;
......
2678 3119
    use_gdbstub = 0;
2679 3120
    gdbstub_port = DEFAULT_GDBSTUB_PORT;
2680 3121
    snapshot = 0;
3122
    linux_boot = 0;
2681 3123
    for(;;) {
2682
        c = getopt_long_only(argc, argv, "hm:dn:sp:", long_options, &long_index);
3124
        c = getopt_long_only(argc, argv, "hm:dn:sp:L:", long_options, &long_index);
2683 3125
        if (c == -1)
2684 3126
            break;
2685 3127
        switch(c) {
......
2697 3139
            case 3:
2698 3140
                snapshot = 1;
2699 3141
                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;
2700 3164
            }
2701 3165
            break;
2702 3166
        case 'h':
......
2724 3188
        case 'p':
2725 3189
            gdbstub_port = atoi(optarg);
2726 3190
            break;
3191
        case 'L':
3192
            interp_prefix = optarg;
3193
            break;
2727 3194
        }
2728 3195
    }
2729
    if (optind >= argc)
3196

  
3197
    linux_boot = (optind < argc);
3198
        
3199
    if (!linux_boot && hd_filename[0] == '\0')
2730 3200
        help();
2731 3201

  
2732 3202
    /* init debug */
......
2781 3251
        }
2782 3252
    }
2783 3253

  
2784
    /* now we can load the kernel */
2785
    ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);
2786
    if (ret < 0) {
2787
        fprintf(stderr, "vl: could not load kernel '%s'\n", argv[optind]);
2788
        exit(1);
2789
    }
3254
    /* init CPU state */
3255
    env = cpu_init();
3256
    global_env = env;
3257
    cpu_single_env = env;
3258

  
3259
    init_ioports();
2790 3260

  
2791
    /* load initrd */
2792
    initrd_size = 0;
2793
    if (initrd_filename) {
2794
        initrd_size = load_image(initrd_filename, phys_ram_base + INITRD_LOAD_ADDR);
2795
        if (initrd_size < 0) {
2796
            fprintf(stderr, "vl: could not load initial ram disk '%s'\n", 
2797
                    initrd_filename);
3261
    if (linux_boot) {
3262
        /* now we can load the kernel */
3263
        ret = load_kernel(argv[optind], phys_ram_base + KERNEL_LOAD_ADDR);
3264
        if (ret < 0) {
3265
            fprintf(stderr, "vl: could not load kernel '%s'\n", argv[optind]);
2798 3266
            exit(1);
2799 3267
        }
2800
    }
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;
2801 3324

  
2802
    /* init kernel params */
2803
    params = (void *)(phys_ram_base + KERNEL_PARAMS_ADDR);
2804
    memset(params, 0, sizeof(struct linux_params));
2805
    params->mount_root_rdonly = 0;
2806
    params->cl_magic = 0xA33F;
2807
    params->cl_offset = params->commandline - (uint8_t *)params;
2808
    params->alt_mem_k = (phys_ram_size / 1024) - 1024;
2809
    for(i = optind + 1; i < argc; i++) {
2810
        if (i != optind + 1)
2811
            pstrcat(params->commandline, sizeof(params->commandline), " ");
2812
        pstrcat(params->commandline, sizeof(params->commandline), argv[i]);
2813
    }
2814
    params->loader_type = 0x01;
2815
    if (initrd_size > 0) {
2816
        params->initrd_start = INITRD_LOAD_ADDR;
2817
        params->initrd_size = initrd_size;
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
        env->eflags = 0x2;
3362

  
3363
        bochs_bios_init();
2818 3364
    }
2819
    params->orig_video_lines = 25;
2820
    params->orig_video_cols = 80;
2821 3365

  
2822 3366
    /* init basic PC hardware */
2823
    init_ioports();
2824 3367
    register_ioport_write(0x80, 1, ioport80_write, 1);
2825 3368

  
2826 3369
    register_ioport_write(0x3d4, 2, vga_ioport_write, 1);
......
2843 3386
    act.sa_sigaction = host_alarm_handler;
2844 3387
    sigaction(SIGALRM, &act, NULL);
2845 3388

  
2846
    /* init CPU state */
2847
    env = cpu_init();
2848
    global_env = env;
2849
    cpu_single_env = env;
2850

  
2851
    /* setup basic memory access */
2852
    env->cr[0] = 0x00000033;
2853
    cpu_x86_init_mmu(env);
2854
    
2855
    memset(params->idt_table, 0, sizeof(params->idt_table));
2856

  
2857
    params->gdt_table[2] = 0x00cf9a000000ffffLL; /* KERNEL_CS */
2858
    params->gdt_table[3] = 0x00cf92000000ffffLL; /* KERNEL_DS */
2859
    
2860
    env->idt.base = (void *)params->idt_table;
2861
    env->idt.limit = sizeof(params->idt_table) - 1;
2862
    env->gdt.base = (void *)params->gdt_table;
2863
    env->gdt.limit = sizeof(params->gdt_table) - 1;
2864

  
2865
    cpu_x86_load_seg(env, R_CS, KERNEL_CS);
2866
    cpu_x86_load_seg(env, R_DS, KERNEL_DS);
2867
    cpu_x86_load_seg(env, R_ES, KERNEL_DS);
2868
    cpu_x86_load_seg(env, R_SS, KERNEL_DS);
2869
    cpu_x86_load_seg(env, R_FS, KERNEL_DS);
2870
    cpu_x86_load_seg(env, R_GS, KERNEL_DS);
2871
    
2872
    env->eip = KERNEL_LOAD_ADDR;
2873
    env->regs[R_ESI] = KERNEL_PARAMS_ADDR;
2874
    env->eflags = 0x2;
2875

  
2876 3389
    itv.it_interval.tv_sec = 0;
2877 3390
    itv.it_interval.tv_usec = 1000;
2878 3391
    itv.it_value.tv_sec = 0;

Also available in: Unified diff