Commit 4ce7ff6e68e9a13ff7da67d00cfc19e64e7aaef0

Authored by aurel32
1 parent b60aee00

MIPS Magnum R4000 machine


git-svn-id: svn://svn.savannah.nongnu.org/qemu/trunk@4164 c046a42c-6fe2-441c-8c8c-71466251a162
Makefile.target
... ... @@ -559,14 +559,14 @@ OBJS+= unin_pci.o ppc_chrp.o
559 559 OBJS+= pflash_cfi02.o ppc4xx_devs.o ppc405_uc.o ppc405_boards.o
560 560 endif
561 561 ifeq ($(TARGET_BASE_ARCH), mips)
562   -OBJS+= mips_r4k.o mips_malta.o mips_pica61.o mips_mipssim.o
563   -OBJS+= mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o
564   -OBJS+= jazz_led.o
  562 +OBJS+= mips_r4k.o mips_jazz.o mips_malta.o mips_pica61.o mips_mipssim.o
  563 +OBJS+= mips_timer.o mips_int.o dma.o vga.o serial.o i8254.o i8259.o rc4030.o
  564 +OBJS+= g364fb.o jazz_led.o
565 565 OBJS+= ide.o gt64xxx.o pckbd.o ps2.o fdc.o mc146818rtc.o usb-uhci.o acpi.o ds1225y.o
566   -OBJS+= piix_pci.o parallel.o cirrus_vga.o $(SOUND_HW)
  566 +OBJS+= piix_pci.o parallel.o cirrus_vga.o pcspk.o $(SOUND_HW)
567 567 OBJS+= mipsnet.o
568 568 OBJS+= pflash_cfi01.o
569   -CPPFLAGS += -DHAS_AUDIO
  569 +CPPFLAGS += -DHAS_AUDIO -DHAS_AUDIO_CHOICE
570 570 endif
571 571 ifeq ($(TARGET_BASE_ARCH), cris)
572 572 OBJS+= etraxfs.o
... ...
hw/boards.h
... ... @@ -36,6 +36,9 @@ extern QEMUMachine taihu_machine;
36 36 /* mips_r4k.c */
37 37 extern QEMUMachine mips_machine;
38 38  
  39 +/* mips_jazz.c */
  40 +extern QEMUMachine mips_magnum_machine;
  41 +
39 42 /* mips_malta.c */
40 43 extern QEMUMachine mips_malta_machine;
41 44  
... ...
hw/mips.h
... ... @@ -9,6 +9,11 @@ PCIBus *pci_gt64120_init(qemu_irq *pic);
9 9 void *ds1225y_init(target_phys_addr_t mem_base, const char *filename);
10 10 void ds1225y_set_protection(void *opaque, int protection);
11 11  
  12 +/* g364fb.c */
  13 +int g364fb_mm_init(DisplayState *ds,
  14 + int vram_size, int it_shift,
  15 + target_phys_addr_t vram_base, target_phys_addr_t ctrl_base);
  16 +
12 17 /* mipsnet.c */
13 18 void mipsnet_init(int base, qemu_irq irq, NICInfo *nd);
14 19  
... ... @@ -22,4 +27,7 @@ extern void cpu_mips_irq_init_cpu(CPUState *env);
22 27 extern void cpu_mips_clock_init(CPUState *);
23 28 extern void cpu_mips_irqctrl_init (void);
24 29  
  30 +/* rc4030.c */
  31 +qemu_irq *rc4030_init(qemu_irq timer, qemu_irq jazz_bus);
  32 +
25 33 #endif
... ...
hw/mips_jazz.c 0 → 100644
  1 +/*
  2 + * QEMU MIPS Jazz support
  3 + *
  4 + * Copyright (c) 2007-2008 Hervé Poussineau
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#include "hw.h"
  26 +#include "mips.h"
  27 +#include "pc.h"
  28 +#include "isa.h"
  29 +#include "fdc.h"
  30 +#include "sysemu.h"
  31 +#include "audio/audio.h"
  32 +#include "boards.h"
  33 +#include "net.h"
  34 +#include "scsi.h"
  35 +
  36 +extern int nographic;
  37 +
  38 +#ifdef TARGET_WORDS_BIGENDIAN
  39 +#define BIOS_FILENAME "mips_bios.bin"
  40 +#else
  41 +#define BIOS_FILENAME "mipsel_bios.bin"
  42 +#endif
  43 +
  44 +#ifdef TARGET_MIPS64
  45 +#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffULL)
  46 +#else
  47 +#define PHYS_TO_VIRT(x) ((x) | ~0x7fffffffU)
  48 +#endif
  49 +#define VIRT_TO_PHYS_ADDEND (-((int64_t)(int32_t)0x80000000))
  50 +
  51 +enum jazz_model_e
  52 +{
  53 + JAZZ_MAGNUM,
  54 +};
  55 +
  56 +static void main_cpu_reset(void *opaque)
  57 +{
  58 + CPUState *env = opaque;
  59 + cpu_reset(env);
  60 +}
  61 +
  62 +static uint32_t rtc_readb(void *opaque, target_phys_addr_t addr)
  63 +{
  64 + CPUState *env = opaque;
  65 + return cpu_inw(env, 0x71);
  66 +}
  67 +
  68 +static void rtc_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  69 +{
  70 + CPUState *env = opaque;
  71 + cpu_outw(env, 0x71, val & 0xff);
  72 +}
  73 +
  74 +static CPUReadMemoryFunc *rtc_read[3] = {
  75 + rtc_readb,
  76 + rtc_readb,
  77 + rtc_readb,
  78 +};
  79 +
  80 +static CPUWriteMemoryFunc *rtc_write[3] = {
  81 + rtc_writeb,
  82 + rtc_writeb,
  83 + rtc_writeb,
  84 +};
  85 +
  86 +#ifdef HAS_AUDIO
  87 +static void audio_init(qemu_irq *pic)
  88 +{
  89 + struct soundhw *c;
  90 + int audio_enabled = 0;
  91 +
  92 + for (c = soundhw; !audio_enabled && c->name; ++c) {
  93 + audio_enabled = c->enabled;
  94 + }
  95 +
  96 + if (audio_enabled) {
  97 + AudioState *s;
  98 +
  99 + s = AUD_init();
  100 + if (s) {
  101 + for (c = soundhw; c->name; ++c) {
  102 + if (c->enabled) {
  103 + if (c->isa) {
  104 + c->init.init_isa(s, pic);
  105 + }
  106 + }
  107 + }
  108 + }
  109 + }
  110 +}
  111 +#endif
  112 +
  113 +void espdma_memory_read(void *opaque, uint8_t *buf, int len)
  114 +{
  115 + printf("espdma_memory_read(buf %p, len %d) not implemented\n", buf, len);
  116 +}
  117 +
  118 +void espdma_memory_write(void *opaque, uint8_t *buf, int len)
  119 +{
  120 + printf("espdma_memory_write(buf %p, len %d) not implemented\n", buf, len);
  121 +}
  122 +
  123 +#define MAGNUM_BIOS_SIZE_MAX 0x7e000
  124 +#define MAGNUM_BIOS_SIZE (BIOS_SIZE < MAGNUM_BIOS_SIZE_MAX ? BIOS_SIZE : MAGNUM_BIOS_SIZE_MAX)
  125 +
  126 +static
  127 +void mips_jazz_init (int ram_size, int vga_ram_size,
  128 + DisplayState *ds, const char *cpu_model,
  129 + enum jazz_model_e jazz_model)
  130 +{
  131 + char buf[1024];
  132 + unsigned long bios_offset;
  133 + int bios_size, n;
  134 + CPUState *env;
  135 + qemu_irq *rc4030, *i8259;
  136 + void *scsi_hba;
  137 + int hd;
  138 + int s_rtc;
  139 + PITState *pit;
  140 + BlockDriverState *fds[MAX_FD];
  141 + qemu_irq esp_reset;
  142 +
  143 + /* init CPUs */
  144 + if (cpu_model == NULL) {
  145 +#ifdef TARGET_MIPS64
  146 + cpu_model = "R4000";
  147 +#else
  148 + /* FIXME: All wrong, this maybe should be R3000 for the older JAZZs. */
  149 + cpu_model = "24Kf";
  150 +#endif
  151 + }
  152 + env = cpu_init(cpu_model);
  153 + if (!env) {
  154 + fprintf(stderr, "Unable to find CPU definition\n");
  155 + exit(1);
  156 + }
  157 + register_savevm("cpu", 0, 3, cpu_save, cpu_load, env);
  158 + qemu_register_reset(main_cpu_reset, env);
  159 +
  160 + /* allocate RAM */
  161 + cpu_register_physical_memory(0, ram_size, IO_MEM_RAM);
  162 +
  163 + /* load the BIOS image. */
  164 + bios_offset = ram_size + vga_ram_size;
  165 + snprintf(buf, sizeof(buf), "%s/%s", bios_dir, BIOS_FILENAME);
  166 + bios_size = load_image(buf, phys_ram_base + bios_offset);
  167 + if (bios_size < 0 || bios_size > MAGNUM_BIOS_SIZE) {
  168 + fprintf(stderr, "qemu: Could not load MIPS bios '%s'\n",
  169 + buf);
  170 + exit(1);
  171 + }
  172 +
  173 + cpu_register_physical_memory(0x1fc00000LL,
  174 + MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM);
  175 + cpu_register_physical_memory(0xfff00000LL,
  176 + MAGNUM_BIOS_SIZE, bios_offset | IO_MEM_ROM);
  177 +
  178 + /* Init CPU internal devices */
  179 + cpu_mips_irq_init_cpu(env);
  180 + cpu_mips_clock_init(env);
  181 +
  182 + /* Chipset */
  183 + rc4030 = rc4030_init(env->irq[6], env->irq[3]);
  184 +
  185 + /* ISA devices */
  186 + i8259 = i8259_init(env->irq[4]);
  187 + pit = pit_init(0x40, i8259[0]);
  188 + pcspk_init(pit);
  189 +
  190 + /* ISA IO space at 0x90000000 */
  191 + isa_mmio_init(0x90000000, 0x01000000);
  192 + isa_mem_base = 0x11000000;
  193 +
  194 + /* Video card */
  195 + switch (jazz_model) {
  196 + case JAZZ_MAGNUM:
  197 + g364fb_mm_init(ds, vga_ram_size, 0, 0x40000000, 0x60000000);
  198 + break;
  199 + default:
  200 + break;
  201 + }
  202 +
  203 + /* Network controller */
  204 + /* FIXME: missing NS SONIC DP83932 */
  205 +
  206 + /* SCSI adapter */
  207 + scsi_hba = esp_init(0x80002000,
  208 + espdma_memory_read, espdma_memory_write, NULL,
  209 + rc4030[5], &esp_reset);
  210 + for (n = 0; n < ESP_MAX_DEVS; n++) {
  211 + hd = drive_get_index(IF_SCSI, 0, n);
  212 + if (hd != -1) {
  213 + esp_scsi_attach(scsi_hba, drives_table[hd].bdrv, n);
  214 + }
  215 + }
  216 +
  217 + /* Floppy */
  218 + if (drive_get_max_bus(IF_FLOPPY) >= MAX_FD) {
  219 + fprintf(stderr, "qemu: too many floppy drives\n");
  220 + exit(1);
  221 + }
  222 + for (n = 0; n < MAX_FD; n++) {
  223 + int fd = drive_get_index(IF_FLOPPY, 0, n);
  224 + if (fd != -1)
  225 + fds[n] = drives_table[fd].bdrv;
  226 + else
  227 + fds[n] = NULL;
  228 + }
  229 + fdctrl_init(rc4030[1], 0, 1, 0x80003000, fds);
  230 +
  231 + /* Real time clock */
  232 + rtc_init(0x70, i8259[8]);
  233 + s_rtc = cpu_register_io_memory(0, rtc_read, rtc_write, env);
  234 + cpu_register_physical_memory(0x80004000, 0x00001000, s_rtc);
  235 +
  236 + /* Keyboard (i8042) */
  237 + i8042_mm_init(rc4030[6], rc4030[7], 0x80005000, 0);
  238 +
  239 + /* Serial ports */
  240 + if (serial_hds[0])
  241 + serial_mm_init(0x80006000, 0, rc4030[8], serial_hds[0], 1);
  242 + if (serial_hds[1])
  243 + serial_mm_init(0x80007000, 0, rc4030[9], serial_hds[1], 1);
  244 +
  245 + /* Parallel port */
  246 + if (parallel_hds[0])
  247 + parallel_mm_init(0x80008000, 0, rc4030[0], parallel_hds[0]);
  248 +
  249 + /* Sound card */
  250 + /* FIXME: missing Jazz sound at 0x8000c000, rc4030[2] */
  251 +#ifdef HAS_AUDIO
  252 + audio_init(i8259);
  253 +#endif
  254 +
  255 + /* NVRAM: Unprotected at 0x9000, Protected at 0xa000, Read only at 0xb000 */
  256 + ds1225y_init(0x80009000, "nvram");
  257 +
  258 + /* LED indicator */
  259 + jazz_led_init(ds, 0x8000f000);
  260 +}
  261 +
  262 +static
  263 +void mips_magnum_init (int ram_size, int vga_ram_size,
  264 + const char *boot_device, DisplayState *ds,
  265 + const char *kernel_filename, const char *kernel_cmdline,
  266 + const char *initrd_filename, const char *cpu_model)
  267 +{
  268 + mips_jazz_init(ram_size, vga_ram_size, ds, cpu_model, JAZZ_MAGNUM);
  269 +}
  270 +
  271 +QEMUMachine mips_magnum_machine = {
  272 + "magnum",
  273 + "MIPS Magnum",
  274 + mips_magnum_init,
  275 +};
... ...
hw/rc4030.c 0 → 100644
  1 +/*
  2 + * QEMU JAZZ RC4030 chipset
  3 + *
  4 + * Copyright (c) 2007-2008 Hervé Poussineau
  5 + *
  6 + * Permission is hereby granted, free of charge, to any person obtaining a copy
  7 + * of this software and associated documentation files (the "Software"), to deal
  8 + * in the Software without restriction, including without limitation the rights
  9 + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10 + * copies of the Software, and to permit persons to whom the Software is
  11 + * furnished to do so, subject to the following conditions:
  12 + *
  13 + * The above copyright notice and this permission notice shall be included in
  14 + * all copies or substantial portions of the Software.
  15 + *
  16 + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17 + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18 + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
  19 + * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20 + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21 + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22 + * THE SOFTWARE.
  23 + */
  24 +
  25 +#include "hw.h"
  26 +#include "qemu-timer.h"
  27 +
  28 +//#define DEBUG_RC4030
  29 +
  30 +#ifdef DEBUG_RC4030
  31 +static const char* irq_names[] = { "parallel", "floppy", "sound", "video",
  32 + "network", "scsi", "keyboard", "mouse", "serial0", "serial1" };
  33 +#endif
  34 +
  35 +typedef struct rc4030State
  36 +{
  37 + uint32_t config; /* 0x0000: RC4030 config register */
  38 + uint32_t invalid_address_register; /* 0x0010: Invalid Address register */
  39 +
  40 + /* DMA */
  41 + uint32_t dma_regs[8][4];
  42 + uint32_t dma_tl_base; /* 0x0018: DMA transl. table base */
  43 + uint32_t dma_tl_limit; /* 0x0020: DMA transl. table limit */
  44 +
  45 + /* cache */
  46 + uint32_t remote_failed_address; /* 0x0038: Remote Failed Address */
  47 + uint32_t memory_failed_address; /* 0x0040: Memory Failed Address */
  48 + uint32_t cache_ptag; /* 0x0048: I/O Cache Physical Tag */
  49 + uint32_t cache_ltag; /* 0x0050: I/O Cache Logical Tag */
  50 + uint32_t cache_bmask; /* 0x0058: I/O Cache Byte Mask */
  51 + uint32_t cache_bwin; /* 0x0060: I/O Cache Buffer Window */
  52 +
  53 + uint32_t offset208;
  54 + uint32_t offset210;
  55 + uint32_t nvram_protect; /* 0x0220: NV ram protect register */
  56 + uint32_t offset238;
  57 + uint32_t rem_speed[15];
  58 + uint32_t imr_jazz; /* Local bus int enable mask */
  59 + uint32_t isr_jazz; /* Local bus int source */
  60 +
  61 + /* timer */
  62 + QEMUTimer *periodic_timer;
  63 + uint32_t itr; /* Interval timer reload */
  64 +
  65 + uint32_t dummy32;
  66 + qemu_irq timer_irq;
  67 + qemu_irq jazz_bus_irq;
  68 +} rc4030State;
  69 +
  70 +static void set_next_tick(rc4030State *s)
  71 +{
  72 + qemu_irq_lower(s->timer_irq);
  73 + uint32_t hz;
  74 +
  75 + hz = 1000 / (s->itr + 1);
  76 +
  77 + qemu_mod_timer(s->periodic_timer, qemu_get_clock(vm_clock) + ticks_per_sec / hz);
  78 +}
  79 +
  80 +/* called for accesses to rc4030 */
  81 +static uint32_t rc4030_readl(void *opaque, target_phys_addr_t addr)
  82 +{
  83 + rc4030State *s = opaque;
  84 + uint32_t val;
  85 +
  86 + addr &= 0x3fff;
  87 + switch (addr & ~0x3) {
  88 + /* Global config register */
  89 + case 0x0000:
  90 + val = s->config;
  91 + break;
  92 + /* Invalid Address register */
  93 + case 0x0010:
  94 + val = s->invalid_address_register;
  95 + break;
  96 + /* DMA transl. table base */
  97 + case 0x0018:
  98 + val = s->dma_tl_base;
  99 + break;
  100 + /* DMA transl. table limit */
  101 + case 0x0020:
  102 + val = s->dma_tl_limit;
  103 + break;
  104 + /* Remote Failed Address */
  105 + case 0x0038:
  106 + val = s->remote_failed_address;
  107 + break;
  108 + /* Memory Failed Address */
  109 + case 0x0040:
  110 + val = s->memory_failed_address;
  111 + break;
  112 + /* I/O Cache Byte Mask */
  113 + case 0x0058:
  114 + val = s->cache_bmask;
  115 + /* HACK */
  116 + if (s->cache_bmask == (uint32_t)-1)
  117 + s->cache_bmask = 0;
  118 + break;
  119 + /* Remote Speed Registers */
  120 + case 0x0070:
  121 + case 0x0078:
  122 + case 0x0080:
  123 + case 0x0088:
  124 + case 0x0090:
  125 + case 0x0098:
  126 + case 0x00a0:
  127 + case 0x00a8:
  128 + case 0x00b0:
  129 + case 0x00b8:
  130 + case 0x00c0:
  131 + case 0x00c8:
  132 + case 0x00d0:
  133 + case 0x00d8:
  134 + case 0x00e0:
  135 + val = s->rem_speed[(addr - 0x0070) >> 3];
  136 + break;
  137 + /* DMA channel base address */
  138 + case 0x0100:
  139 + case 0x0108:
  140 + case 0x0110:
  141 + case 0x0118:
  142 + case 0x0120:
  143 + case 0x0128:
  144 + case 0x0130:
  145 + case 0x0138:
  146 + case 0x0140:
  147 + case 0x0148:
  148 + case 0x0150:
  149 + case 0x0158:
  150 + case 0x0160:
  151 + case 0x0168:
  152 + case 0x0170:
  153 + case 0x0178:
  154 + case 0x0180:
  155 + case 0x0188:
  156 + case 0x0190:
  157 + case 0x0198:
  158 + case 0x01a0:
  159 + case 0x01a8:
  160 + case 0x01b0:
  161 + case 0x01b8:
  162 + case 0x01c0:
  163 + case 0x01c8:
  164 + case 0x01d0:
  165 + case 0x01d8:
  166 + case 0x01e0:
  167 + case 0x1e8:
  168 + case 0x01f0:
  169 + case 0x01f8:
  170 + {
  171 + int entry = (addr - 0x0100) >> 5;
  172 + int idx = (addr & 0x1f) >> 3;
  173 + val = s->dma_regs[entry][idx];
  174 + }
  175 + break;
  176 + /* Offset 0x0208 */
  177 + case 0x0208:
  178 + val = s->offset208;
  179 + break;
  180 + /* Offset 0x0210 */
  181 + case 0x0210:
  182 + val = s->offset210;
  183 + break;
  184 + /* NV ram protect register */
  185 + case 0x0220:
  186 + val = s->nvram_protect;
  187 + break;
  188 + /* Interval timer count */
  189 + case 0x0230:
  190 + val = s->dummy32;
  191 + qemu_irq_lower(s->timer_irq);
  192 + break;
  193 + /* Offset 0x0238 */
  194 + case 0x0238:
  195 + val = s->offset238;
  196 + break;
  197 + default:
  198 +#ifdef DEBUG_RC4030
  199 + printf("rc4030: invalid read [" TARGET_FMT_lx "]\n", addr);
  200 +#endif
  201 + val = 0;
  202 + break;
  203 + }
  204 +
  205 +#ifdef DEBUG_RC4030
  206 + if ((addr & ~3) != 0x230)
  207 + printf("rc4030: read 0x%02x at " TARGET_FMT_lx "\n", val, addr);
  208 +#endif
  209 +
  210 + return val;
  211 +}
  212 +
  213 +static uint32_t rc4030_readw(void *opaque, target_phys_addr_t addr)
  214 +{
  215 + uint32_t v = rc4030_readl(opaque, addr & ~0x3);
  216 + if (addr & 0x2)
  217 + return v >> 16;
  218 + else
  219 + return v & 0xffff;
  220 +}
  221 +
  222 +static uint32_t rc4030_readb(void *opaque, target_phys_addr_t addr)
  223 +{
  224 + uint32_t v = rc4030_readl(opaque, addr & ~0x3);
  225 + return (v >> (8 * (addr & 0x3))) & 0xff;
  226 +}
  227 +
  228 +static void rc4030_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  229 +{
  230 + rc4030State *s = opaque;
  231 + addr &= 0x3fff;
  232 +
  233 +#ifdef DEBUG_RC4030
  234 + printf("rc4030: write 0x%02x at " TARGET_FMT_lx "\n", val, addr);
  235 +#endif
  236 +
  237 + switch (addr & ~0x3) {
  238 + /* Global config register */
  239 + case 0x0000:
  240 + s->config = val;
  241 + break;
  242 + /* DMA transl. table base */
  243 + case 0x0018:
  244 + s->dma_tl_base = val;
  245 + break;
  246 + /* DMA transl. table limit */
  247 + case 0x0020:
  248 + s->dma_tl_limit = val;
  249 + break;
  250 + /* I/O Cache Physical Tag */
  251 + case 0x0048:
  252 + s->cache_ptag = val;
  253 + break;
  254 + /* I/O Cache Logical Tag */
  255 + case 0x0050:
  256 + s->cache_ltag = val;
  257 + break;
  258 + /* I/O Cache Byte Mask */
  259 + case 0x0058:
  260 + s->cache_bmask |= val; /* HACK */
  261 + break;
  262 + /* I/O Cache Buffer Window */
  263 + case 0x0060:
  264 + s->cache_bwin = val;
  265 + /* HACK */
  266 + if (s->cache_ltag == 0x80000001 && s->cache_bmask == 0xf0f0f0f) {
  267 + target_phys_addr_t dests[] = { 4, 0, 8, 0x10 };
  268 + static int current = 0;
  269 + target_phys_addr_t dest = 0 + dests[current];
  270 + uint8_t buf;
  271 + current = (current + 1) % (sizeof(dests)/sizeof(dests[0]));
  272 + buf = s->cache_bwin - 1;
  273 + cpu_physical_memory_rw(dest, &buf, 1, 1);
  274 + }
  275 + break;
  276 + /* Remote Speed Registers */
  277 + case 0x0070:
  278 + case 0x0078:
  279 + case 0x0080:
  280 + case 0x0088:
  281 + case 0x0090:
  282 + case 0x0098:
  283 + case 0x00a0:
  284 + case 0x00a8:
  285 + case 0x00b0:
  286 + case 0x00b8:
  287 + case 0x00c0:
  288 + case 0x00c8:
  289 + case 0x00d0:
  290 + case 0x00d8:
  291 + case 0x00e0:
  292 + s->rem_speed[(addr - 0x0070) >> 3] = val;
  293 + break;
  294 + /* DMA channel base address */
  295 + case 0x0100:
  296 + case 0x0108:
  297 + case 0x0110:
  298 + case 0x0118:
  299 + case 0x0120:
  300 + case 0x0128:
  301 + case 0x0130:
  302 + case 0x0138:
  303 + case 0x0140:
  304 + case 0x0148:
  305 + case 0x0150:
  306 + case 0x0158:
  307 + case 0x0160:
  308 + case 0x0168:
  309 + case 0x0170:
  310 + case 0x0178:
  311 + case 0x0180:
  312 + case 0x0188:
  313 + case 0x0190:
  314 + case 0x0198:
  315 + case 0x01a0:
  316 + case 0x01a8:
  317 + case 0x01b0:
  318 + case 0x01b8:
  319 + case 0x01c0:
  320 + case 0x01c8:
  321 + case 0x01d0:
  322 + case 0x01d8:
  323 + case 0x01e0:
  324 + case 0x1e8:
  325 + case 0x01f0:
  326 + case 0x01f8:
  327 + {
  328 + int entry = (addr - 0x0100) >> 5;
  329 + int idx = (addr & 0x1f) >> 3;
  330 + s->dma_regs[entry][idx] = val;
  331 + }
  332 + break;
  333 + /* Offset 0x0210 */
  334 + case 0x0210:
  335 + s->offset210 = val;
  336 + break;
  337 + /* Interval timer reload */
  338 + case 0x0228:
  339 + s->itr = val;
  340 + qemu_irq_lower(s->timer_irq);
  341 + set_next_tick(s);
  342 + break;
  343 + default:
  344 +#ifdef DEBUG_RC4030
  345 + printf("rc4030: invalid write of 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
  346 +#endif
  347 + break;
  348 + }
  349 +}
  350 +
  351 +static void rc4030_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
  352 +{
  353 + uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
  354 +
  355 + if (addr & 0x2)
  356 + val = (val << 16) | (old_val & 0x0000ffff);
  357 + else
  358 + val = val | (old_val & 0xffff0000);
  359 + rc4030_writel(opaque, addr & ~0x3, val);
  360 +}
  361 +
  362 +static void rc4030_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  363 +{
  364 + uint32_t old_val = rc4030_readl(opaque, addr & ~0x3);
  365 +
  366 + switch (addr & 3) {
  367 + case 0:
  368 + val = val | (old_val & 0xffffff00);
  369 + break;
  370 + case 1:
  371 + val = (val << 8) | (old_val & 0xffff00ff);
  372 + break;
  373 + case 2:
  374 + val = (val << 16) | (old_val & 0xff00ffff);
  375 + break;
  376 + case 3:
  377 + val = (val << 24) | (old_val & 0x00ffffff);
  378 + break;
  379 + }
  380 + rc4030_writel(opaque, addr & ~0x3, val);
  381 +}
  382 +
  383 +static CPUReadMemoryFunc *rc4030_read[3] = {
  384 + rc4030_readb,
  385 + rc4030_readw,
  386 + rc4030_readl,
  387 +};
  388 +
  389 +static CPUWriteMemoryFunc *rc4030_write[3] = {
  390 + rc4030_writeb,
  391 + rc4030_writew,
  392 + rc4030_writel,
  393 +};
  394 +
  395 +static void update_jazz_irq(rc4030State *s)
  396 +{
  397 + uint16_t pending;
  398 +
  399 + pending = s->isr_jazz & s->imr_jazz;
  400 +
  401 +#ifdef DEBUG_RC4030
  402 + if (s->isr_jazz != 0) {
  403 + uint32_t irq = 0;
  404 + printf("jazz pending:");
  405 + for (irq = 0; irq < sizeof(irq_names)/sizeof(irq_names[0]); irq++) {
  406 + if (s->isr_jazz & (1 << irq)) {
  407 + printf(" %s", irq_names[irq]);
  408 + if (!(s->imr_jazz & (1 << irq))) {
  409 + printf("(ignored)");
  410 + }
  411 + }
  412 + }
  413 + printf("\n");
  414 + }
  415 +#endif
  416 +
  417 + if (pending != 0)
  418 + qemu_irq_raise(s->jazz_bus_irq);
  419 + else
  420 + qemu_irq_lower(s->jazz_bus_irq);
  421 +}
  422 +
  423 +static void rc4030_irq_jazz_request(void *opaque, int irq, int level)
  424 +{
  425 + rc4030State *s = opaque;
  426 +
  427 + if (level) {
  428 + s->isr_jazz |= 1 << irq;
  429 + } else {
  430 + s->isr_jazz &= ~(1 << irq);
  431 + }
  432 +
  433 + update_jazz_irq(s);
  434 +}
  435 +
  436 +static void rc4030_periodic_timer(void *opaque)
  437 +{
  438 + rc4030State *s = opaque;
  439 +
  440 + set_next_tick(s);
  441 + qemu_irq_raise(s->timer_irq);
  442 +}
  443 +
  444 +static uint32_t int_readb(void *opaque, target_phys_addr_t addr)
  445 +{
  446 + rc4030State *s = opaque;
  447 + uint32_t val;
  448 + uint32_t irq;
  449 + addr &= 0xfff;
  450 +
  451 + switch (addr) {
  452 + case 0x00: {
  453 + /* Local bus int source */
  454 + uint32_t pending = s->isr_jazz & s->imr_jazz;
  455 + val = 0;
  456 + irq = 0;
  457 + while (pending) {
  458 + if (pending & 1) {
  459 + //printf("returning irq %s\n", irq_names[irq]);
  460 + val = (irq + 1) << 2;
  461 + break;
  462 + }
  463 + irq++;
  464 + pending >>= 1;
  465 + }
  466 + break;
  467 + }
  468 + default:
  469 +#ifdef DEBUG_RC4030
  470 + printf("rc4030: (interrupt controller) invalid read [" TARGET_FMT_lx "]\n", addr);
  471 +#endif
  472 + val = 0;
  473 + }
  474 +
  475 +#ifdef DEBUG_RC4030
  476 + printf("rc4030: (interrupt controller) read 0x%02x at " TARGET_FMT_lx "\n", val, addr);
  477 +#endif
  478 +
  479 + return val;
  480 +}
  481 +
  482 +static uint32_t int_readw(void *opaque, target_phys_addr_t addr)
  483 +{
  484 + uint32_t v;
  485 + v = int_readb(opaque, addr);
  486 + v |= int_readb(opaque, addr + 1) << 8;
  487 + return v;
  488 +}
  489 +
  490 +static uint32_t int_readl(void *opaque, target_phys_addr_t addr)
  491 +{
  492 + uint32_t v;
  493 + v = int_readb(opaque, addr);
  494 + v |= int_readb(opaque, addr + 1) << 8;
  495 + v |= int_readb(opaque, addr + 2) << 16;
  496 + v |= int_readb(opaque, addr + 3) << 24;
  497 + return v;
  498 +}
  499 +
  500 +static void int_writeb(void *opaque, target_phys_addr_t addr, uint32_t val)
  501 +{
  502 + rc4030State *s = opaque;
  503 + addr &= 0xfff;
  504 +
  505 +#ifdef DEBUG_RC4030
  506 + printf("rc4030: (interrupt controller) write 0x%02x at " TARGET_FMT_lx "\n", val, addr);
  507 +#endif
  508 +
  509 + switch (addr) {
  510 + /* Local bus int enable mask */
  511 + case 0x02:
  512 + s->imr_jazz = (s->imr_jazz & 0xff00) | (val << 0); update_jazz_irq(s);
  513 + break;
  514 + case 0x03:
  515 + s->imr_jazz = (s->imr_jazz & 0x00ff) | (val << 8); update_jazz_irq(s);
  516 + break;
  517 + default:
  518 +#ifdef DEBUG_RC4030
  519 + printf("rc4030: (interrupt controller) invalid write of 0x%02x at [" TARGET_FMT_lx "]\n", val, addr);
  520 +#endif
  521 + break;
  522 + }
  523 +}
  524 +
  525 +static void int_writew(void *opaque, target_phys_addr_t addr, uint32_t val)
  526 +{
  527 + int_writeb(opaque, addr, val & 0xff);
  528 + int_writeb(opaque, addr + 1, (val >> 8) & 0xff);
  529 +}
  530 +
  531 +static void int_writel(void *opaque, target_phys_addr_t addr, uint32_t val)
  532 +{
  533 + int_writeb(opaque, addr, val & 0xff);
  534 + int_writeb(opaque, addr + 1, (val >> 8) & 0xff);
  535 + int_writeb(opaque, addr + 2, (val >> 16) & 0xff);
  536 + int_writeb(opaque, addr + 3, (val >> 24) & 0xff);
  537 +}
  538 +
  539 +static CPUReadMemoryFunc *int_read[3] = {
  540 + int_readb,
  541 + int_readw,
  542 + int_readl,
  543 +};
  544 +
  545 +static CPUWriteMemoryFunc *int_write[3] = {
  546 + int_writeb,
  547 + int_writew,
  548 + int_writel,
  549 +};
  550 +
  551 +#define G364_512KB_RAM (0x0)
  552 +#define G364_2MB_RAM (0x1)
  553 +#define G364_8MB_RAM (0x2)
  554 +#define G364_32MB_RAM (0x3)
  555 +
  556 +static void rc4030_reset(void *opaque)
  557 +{
  558 + rc4030State *s = opaque;
  559 + int i;
  560 +
  561 + s->config = (G364_2MB_RAM << 8) | 0x04;
  562 + s->invalid_address_register = 0;
  563 +
  564 + memset(s->dma_regs, 0, sizeof(s->dma_regs));
  565 + s->dma_tl_base = s->dma_tl_limit = 0;
  566 +
  567 + s->remote_failed_address = s->memory_failed_address = 0;
  568 + s->cache_ptag = s->cache_ltag = 0;
  569 + s->cache_bmask = s->cache_bwin = 0;
  570 +
  571 + s->offset208 = 0;
  572 + s->offset210 = 0x18186;
  573 + s->nvram_protect = 7;
  574 + s->offset238 = 7;
  575 + for (i = 0; i < 15; i++)
  576 + s->rem_speed[i] = 7;
  577 + s->imr_jazz = s->isr_jazz = 0;
  578 +
  579 + s->itr = 0;
  580 + s->dummy32 = 0;
  581 +
  582 + qemu_irq_lower(s->timer_irq);
  583 + qemu_irq_lower(s->jazz_bus_irq);
  584 +}
  585 +
  586 +qemu_irq *rc4030_init(qemu_irq timer, qemu_irq jazz_bus)
  587 +{
  588 + rc4030State *s;
  589 + int s_chipset, s_int;
  590 +
  591 + s = qemu_mallocz(sizeof(rc4030State));
  592 + if (!s)
  593 + return NULL;
  594 +
  595 + s->periodic_timer = qemu_new_timer(vm_clock, rc4030_periodic_timer, s);
  596 + s->timer_irq = timer;
  597 + s->jazz_bus_irq = jazz_bus;
  598 +
  599 + qemu_register_reset(rc4030_reset, s);
  600 + rc4030_reset(s);
  601 +
  602 + s_chipset = cpu_register_io_memory(0, rc4030_read, rc4030_write, s);
  603 + cpu_register_physical_memory(0x80000000, 0x300, s_chipset);
  604 + s_int = cpu_register_io_memory(0, int_read, int_write, s);
  605 + cpu_register_physical_memory(0xf0000000, 0x00001000, s_int);
  606 +
  607 + return qemu_allocate_irqs(rc4030_irq_jazz_request, s, 16);
  608 +}
... ...
... ... @@ -26,7 +26,6 @@
26 26 #include "hw/usb.h"
27 27 #include "hw/pcmcia.h"
28 28 #include "hw/pc.h"
29   -#include "hw/fdc.h"
30 29 #include "hw/audiodev.h"
31 30 #include "hw/isa.h"
32 31 #include "net.h"
... ... @@ -8002,6 +8001,7 @@ static void register_machines(void)
8002 8001 qemu_register_machine(&taihu_machine);
8003 8002 #elif defined(TARGET_MIPS)
8004 8003 qemu_register_machine(&mips_machine);
  8004 + qemu_register_machine(&mips_magnum_machine);
8005 8005 qemu_register_machine(&mips_malta_machine);
8006 8006 qemu_register_machine(&mips_pica61_machine);
8007 8007 qemu_register_machine(&mips_mipssim_machine);
... ... @@ -8056,7 +8056,7 @@ static void register_machines(void)
8056 8056 #ifdef HAS_AUDIO
8057 8057 struct soundhw soundhw[] = {
8058 8058 #ifdef HAS_AUDIO_CHOICE
8059   -#ifdef TARGET_I386
  8059 +#if defined(TARGET_I386) || defined(TARGET_MIPS)
8060 8060 {
8061 8061 "pcspk",
8062 8062 "PC speaker",
... ...