From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailman by lists.gnu.org with tmda-scanned (Exim 4.43) id 1FBdPd-0003UP-0v for qemu-devel@nongnu.org; Tue, 21 Feb 2006 14:43:05 -0500 Received: from exim by lists.gnu.org with spam-scanned (Exim 4.43) id 1FBdH1-0000Vr-9l for qemu-devel@nongnu.org; Tue, 21 Feb 2006 14:34:11 -0500 Received: from [199.232.76.173] (helo=monty-python.gnu.org) by lists.gnu.org with esmtp (Exim 4.43) id 1FBcuZ-0001E9-G4 for qemu-devel@nongnu.org; Tue, 21 Feb 2006 14:11:00 -0500 Received: from [193.7.176.20] (helo=bender.bawue.de) by monty-python.gnu.org with esmtps (TLS-1.0:DHE_RSA_3DES_EDE_CBC_SHA:24) (Exim 4.52) id 1FBd0t-0004SQ-1q for qemu-devel@nongnu.org; Tue, 21 Feb 2006 14:17:31 -0500 Received: from lagash (unknown [194.74.144.146]) (using TLSv1 with cipher DES-CBC3-SHA (168/168 bits)) (No client certificate requested) by bender.bawue.de (Postfix) with ESMTP id EAEBB44202 for ; Tue, 21 Feb 2006 20:10:56 +0100 (MET) Received: from ths by lagash with local (Exim 4.60) (envelope-from ) id 1FBcus-0004hi-Pz for qemu-devel@nongnu.org; Tue, 21 Feb 2006 19:11:18 +0000 Date: Tue, 21 Feb 2006 19:11:18 +0000 Message-ID: <20060221191118.GA4110@networkno.de> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline From: Thiemo Seufer Subject: [Qemu-devel] [PATCH] Add more devices for MIPS system emulation Reply-To: qemu-devel@nongnu.org List-Id: qemu-devel.nongnu.org List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Hello All, this adds to the MIPS system emulation: - Harddisk emulation, including MSDOS partition labels. - RTC support. - (Untested) Audio, PC Keyboard, and PS/2 suport. Thiemo diff -urpN qemu-work/Makefile.target qemu/Makefile.target --- qemu-work/Makefile.target 2006-02-18 00:40:53.000000000 +0000 +++ qemu/Makefile.target 2006-02-16 00:24:40.000000000 +0000 @@ -333,8 +333,11 @@ VL_OBJS+= ppc_prep.o ppc_chrp.o cuda.o a DEFINES += -DHAS_AUDIO endif ifeq ($(TARGET_ARCH), mips) -VL_OBJS+= mips_r4k.o dma.o vga.o serial.o i8254.o i8259.o -#VL_OBJS+= #ide.o pckbd.o fdc.o m48t59.o +VL_OBJS+= ide.o pckbd.o ps2.o vga.o $(SOUND_HW) dma.o $(AUDIODRV) +VL_OBJS+= mc146818rtc.o serial.o i8259.o i8254.o mips_r4k.o +VL_OBJS+= mixeng.o +#VL_OBJS+= #fdc.o +DEFINES += -DHAS_AUDIO endif ifeq ($(TARGET_BASE_ARCH), sparc) ifeq ($(TARGET_ARCH), sparc64) diff -urpN qemu-work/hw/mips_r4k.c qemu/hw/mips_r4k.c --- qemu-work/hw/mips_r4k.c 2006-02-17 23:55:13.000000000 +0000 +++ qemu/hw/mips_r4k.c 2006-02-12 21:06:22.000000000 +0000 @@ -2,11 +2,13 @@ #define BIOS_FILENAME "mips_bios.bin" -//#define BIOS_FILENAME "system.bin" +#define LINUX_BOOT_FILENAME "linux_boot.bin" + #define KERNEL_LOAD_ADDR 0x80010000 #define INITRD_LOAD_ADDR 0x80800000 extern FILE *logfile; +static RTCState *rtc_state; static PITState *pit; static void pic_irq_request(void *opaque, int level) @@ -101,6 +104,35 @@ void cpu_mips_clock_init (CPUState *env) cpu_mips_update_count(env, 1, 0); } +#define REG_EQUIPMENT_BYTE 0x14 +#define REG_IBM_CENTURY_BYTE 0x32 +#define REG_IBM_PS2_CENTURY_BYTE 0x37 + +static inline int to_bcd(RTCState *s, int a) +{ + return ((a / 10) << 4) | (a % 10); +} + +static void cmos_init(int ram_size, int boot_device, BlockDriverState **hd_table) +{ + RTCState *s = rtc_state; + int val; + time_t ti; + struct tm *tm; + + /* set the CMOS date */ + time(&ti); + if (rtc_utc) + tm = gmtime(&ti); + else + tm = localtime(&ti); + rtc_set_date(s, tm); + + val = to_bcd(s, (tm->tm_year / 100) + 19); + rtc_set_memory(s, REG_IBM_CENTURY_BYTE, val); + rtc_set_memory(s, REG_IBM_PS2_CENTURY_BYTE, val); +} + static void io_writeb (void *opaque, target_phys_addr_t addr, uint32_t value) { #if 0 @@ -183,6 +215,10 @@ CPUReadMemoryFunc *io_read[] = { &io_readl, }; +static const int ide_iobase[2] = { 0x1f0, 0x170 }; +static const int ide_iobase2[2] = { 0x3f6, 0x376 }; +static const int ide_irq[2] = { 14, 15 }; + void mips_r4k_init (int ram_size, int vga_ram_size, int boot_device, DisplayState *ds, const char **fd_filename, int snapshot, const char *kernel_filename, const char *kernel_cmdline, @@ -195,16 +231,18 @@ void mips_r4k_init (int ram_size, int vg int linux_boot; int ret; CPUState *env; + int i; printf("%s: start\n", __func__); linux_boot = (kernel_filename != NULL); env = cpu_init(); register_savevm("cpu", 0, 3, cpu_save, cpu_load, env); /* allocate RAM */ cpu_register_physical_memory(0, ram_size, IO_MEM_RAM); bios_offset = ram_size + vga_ram_size; + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME); printf("%s: load BIOS '%s' size %d\n", __func__, buf, BIOS_SIZE); ret = load_image(buf, phys_ram_base + bios_offset); @@ -221,6 +260,28 @@ void mips_r4k_init (int ram_size, int vg env->PC = 0xBFC00004; #endif if (linux_boot) { + uint8_t bootsect[512]; + uint8_t old_bootsect[512]; + + if (bs_table[0] == NULL) { + fprintf(stderr, "A disk image must be given for 'hda' when booting a Linux kernel\n"); + exit(1); + } + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, LINUX_BOOT_FILENAME); + ret = load_image(buf, bootsect); + if (ret != sizeof(bootsect)) { + fprintf(stderr, "qemu: could not load linux boot sector '%s'\n", + buf); + exit(1); + } + + if (bdrv_read(bs_table[0], 0, old_bootsect, 1) >= 0) { + /* copy the MSDOS partition table */ + memcpy(bootsect + 0x1be, old_bootsect + 0x1be, 0x40); + } + + bdrv_set_boot_sector(bs_table[0], bootsect, sizeof(bootsect)); + kernel_base = KERNEL_LOAD_ADDR; /* now we can load the kernel */ kernel_size = load_image(kernel_filename, @@ -230,6 +291,7 @@ void mips_r4k_init (int ram_size, int vg kernel_filename); exit(1); } + /* load initrd */ if (initrd_filename) { initrd_base = INITRD_LOAD_ADDR; @@ -244,6 +306,7 @@ void mips_r4k_init (int ram_size, int vg initrd_base = 0; initrd_size = 0; } + env->PC = KERNEL_LOAD_ADDR; /* Store command line. */ strcpy (phys_ram_base + (16 << 20) - 256, kernel_cmdline); @@ -261,6 +324,8 @@ void mips_r4k_init (int ram_size, int vg cpu_mips_clock_init(env); cpu_mips_irqctrl_init(); + rtc_state = rtc_init(0x70, 8); + /* Register 64 KB of ISA IO space at 0x14000000 */ io_memory = cpu_register_io_memory(0, io_read, io_write, NULL); cpu_register_physical_memory(0x14000000, 0x00010000, io_memory); @@ -268,6 +333,7 @@ void mips_r4k_init (int ram_size, int vg isa_pic = pic_init(pic_irq_request, env); pit = pit_init(0x40, 0); + serial_init(&pic_set_irq_new, isa_pic, 0x3f8, 4, serial_hds[0]); vga_initialize(NULL, ds, phys_ram_base + ram_size, ram_size, vga_ram_size, 0, 0); @@ -281,6 +347,16 @@ void mips_r4k_init (int ram_size, int vg exit (1); } } + + for(i = 0; i < 2; i++) + isa_ide_init(ide_iobase[i], ide_iobase2[i], ide_irq[i], + bs_table[2 * i], bs_table[2 * i + 1]); + + kbd_init(); + DMA_init(1); + + cmos_init(ram_size, boot_device, bs_table); + } QEMUMachine mips_machine = {