2 * QEMU JAZZ RC4030 chipset
4 * Copyright (c) 2007-2009 Herve Poussineau
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:
13 * The above copyright notice and this permission notice shall be included in
14 * all copies or substantial portions of the Software.
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
26 #include "hw/mips/mips.h"
27 #include "qemu/timer.h"
28 #include "exec/address-spaces.h"
31 /********************************************************/
32 /* rc4030 emulation */
34 #define MAX_TL_ENTRIES 512
36 typedef struct dma_pagetable_entry
{
39 } QEMU_PACKED dma_pagetable_entry
;
41 #define DMA_PAGESIZE 4096
42 #define DMA_REG_ENABLE 1
43 #define DMA_REG_COUNT 2
44 #define DMA_REG_ADDRESS 3
46 #define DMA_FLAG_ENABLE 0x0001
47 #define DMA_FLAG_MEM_TO_DEV 0x0002
48 #define DMA_FLAG_TC_INTR 0x0100
49 #define DMA_FLAG_MEM_INTR 0x0200
50 #define DMA_FLAG_ADDR_INTR 0x0400
52 typedef struct rc4030State
54 uint32_t config
; /* 0x0000: RC4030 config register */
55 uint32_t revision
; /* 0x0008: RC4030 Revision register */
56 uint32_t invalid_address_register
; /* 0x0010: Invalid Address register */
59 uint32_t dma_regs
[8][4];
60 uint32_t dma_tl_base
; /* 0x0018: DMA transl. table base */
61 uint32_t dma_tl_limit
; /* 0x0020: DMA transl. table limit */
64 uint32_t cache_maint
; /* 0x0030: Cache Maintenance */
65 uint32_t remote_failed_address
; /* 0x0038: Remote Failed Address */
66 uint32_t memory_failed_address
; /* 0x0040: Memory Failed Address */
67 uint32_t cache_ptag
; /* 0x0048: I/O Cache Physical Tag */
68 uint32_t cache_ltag
; /* 0x0050: I/O Cache Logical Tag */
69 uint32_t cache_bmask
; /* 0x0058: I/O Cache Byte Mask */
71 uint32_t nmi_interrupt
; /* 0x0200: interrupt source */
72 uint32_t memory_refresh_rate
; /* 0x0210: memory refresh rate */
73 uint32_t nvram_protect
; /* 0x0220: NV ram protect register */
74 uint32_t rem_speed
[16];
75 uint32_t imr_jazz
; /* Local bus int enable mask */
76 uint32_t isr_jazz
; /* Local bus int source */
79 QEMUTimer
*periodic_timer
;
80 uint32_t itr
; /* Interval timer reload */
83 qemu_irq jazz_bus_irq
;
85 /* biggest translation table */
87 /* translation table memory region alias, added to system RAM */
88 MemoryRegion dma_tt_alias
;
89 /* whole DMA memory region, root of DMA address space */
91 /* translation table entry aliases, added to DMA memory region */
92 MemoryRegion dma_mrs
[MAX_TL_ENTRIES
];
95 MemoryRegion iomem_chipset
;
96 MemoryRegion iomem_jazzio
;
99 static void set_next_tick(rc4030State
*s
)
101 qemu_irq_lower(s
->timer_irq
);
104 tm_hz
= 1000 / (s
->itr
+ 1);
106 timer_mod(s
->periodic_timer
, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL
) +
107 get_ticks_per_sec() / tm_hz
);
110 /* called for accesses to rc4030 */
111 static uint64_t rc4030_read(void *opaque
, hwaddr addr
, unsigned int size
)
113 rc4030State
*s
= opaque
;
117 switch (addr
& ~0x3) {
118 /* Global config register */
122 /* Revision register */
126 /* Invalid Address register */
128 val
= s
->invalid_address_register
;
130 /* DMA transl. table base */
132 val
= s
->dma_tl_base
;
134 /* DMA transl. table limit */
136 val
= s
->dma_tl_limit
;
138 /* Remote Failed Address */
140 val
= s
->remote_failed_address
;
142 /* Memory Failed Address */
144 val
= s
->memory_failed_address
;
146 /* I/O Cache Byte Mask */
148 val
= s
->cache_bmask
;
150 if (s
->cache_bmask
== (uint32_t)-1)
153 /* Remote Speed Registers */
170 val
= s
->rem_speed
[(addr
- 0x0070) >> 3];
172 /* DMA channel base address */
206 int entry
= (addr
- 0x0100) >> 5;
207 int idx
= (addr
& 0x1f) >> 3;
208 val
= s
->dma_regs
[entry
][idx
];
211 /* Interrupt source */
213 val
= s
->nmi_interrupt
;
219 /* Memory refresh rate */
221 val
= s
->memory_refresh_rate
;
223 /* NV ram protect register */
225 val
= s
->nvram_protect
;
227 /* Interval timer count */
230 qemu_irq_lower(s
->timer_irq
);
234 val
= 7; /* FIXME: should be read from EISA controller */
237 qemu_log_mask(LOG_GUEST_ERROR
,
238 "rc4030: invalid read at 0x%x", (int)addr
);
243 if ((addr
& ~3) != 0x230) {
244 trace_rc4030_read(addr
, val
);
250 static void rc4030_dma_as_update_one(rc4030State
*s
, int index
, uint32_t frame
)
252 if (index
< MAX_TL_ENTRIES
) {
253 memory_region_set_enabled(&s
->dma_mrs
[index
], false);
260 if (index
>= MAX_TL_ENTRIES
) {
261 qemu_log_mask(LOG_UNIMP
,
262 "rc4030: trying to use too high "
263 "translation table entry %d (max allowed=%d)",
264 index
, MAX_TL_ENTRIES
);
267 memory_region_set_alias_offset(&s
->dma_mrs
[index
], frame
);
268 memory_region_set_enabled(&s
->dma_mrs
[index
], true);
271 static void rc4030_dma_tt_write(void *opaque
, hwaddr addr
, uint64_t data
,
274 rc4030State
*s
= opaque
;
277 memcpy(memory_region_get_ram_ptr(&s
->dma_tt
) + addr
, &data
, size
);
279 /* update dma address space (only if frame field has been written) */
280 if (addr
% sizeof(dma_pagetable_entry
) == 0) {
281 int index
= addr
/ sizeof(dma_pagetable_entry
);
282 memory_region_transaction_begin();
283 rc4030_dma_as_update_one(s
, index
, (uint32_t)data
);
284 memory_region_transaction_commit();
288 static const MemoryRegionOps rc4030_dma_tt_ops
= {
289 .write
= rc4030_dma_tt_write
,
290 .impl
.min_access_size
= 4,
291 .impl
.max_access_size
= 4,
294 static void rc4030_dma_tt_update(rc4030State
*s
, uint32_t new_tl_base
,
295 uint32_t new_tl_limit
)
298 dma_pagetable_entry
*dma_tl_contents
;
300 if (s
->dma_tl_limit
) {
301 /* write old dma tl table to physical memory */
302 memory_region_del_subregion(get_system_memory(), &s
->dma_tt_alias
);
303 cpu_physical_memory_write(s
->dma_tl_limit
& 0x7fffffff,
304 memory_region_get_ram_ptr(&s
->dma_tt
),
305 memory_region_size(&s
->dma_tt_alias
));
307 object_unparent(OBJECT(&s
->dma_tt_alias
));
309 s
->dma_tl_base
= new_tl_base
;
310 s
->dma_tl_limit
= new_tl_limit
;
311 new_tl_base
&= 0x7fffffff;
313 if (s
->dma_tl_limit
) {
314 uint64_t dma_tt_size
;
315 if (s
->dma_tl_limit
<= memory_region_size(&s
->dma_tt
)) {
316 dma_tt_size
= s
->dma_tl_limit
;
318 dma_tt_size
= memory_region_size(&s
->dma_tt
);
320 memory_region_init_alias(&s
->dma_tt_alias
, NULL
,
322 &s
->dma_tt
, 0, dma_tt_size
);
323 dma_tl_contents
= memory_region_get_ram_ptr(&s
->dma_tt
);
324 cpu_physical_memory_read(new_tl_base
, dma_tl_contents
, dma_tt_size
);
326 memory_region_transaction_begin();
327 entries
= dma_tt_size
/ sizeof(dma_pagetable_entry
);
328 for (i
= 0; i
< entries
; i
++) {
329 rc4030_dma_as_update_one(s
, i
, dma_tl_contents
[i
].frame
);
331 memory_region_add_subregion(get_system_memory(), new_tl_base
,
333 memory_region_transaction_commit();
335 memory_region_init(&s
->dma_tt_alias
, NULL
,
336 "dma-table-alias", 0);
340 static void rc4030_write(void *opaque
, hwaddr addr
, uint64_t data
,
343 rc4030State
*s
= opaque
;
347 trace_rc4030_write(addr
, val
);
349 switch (addr
& ~0x3) {
350 /* Global config register */
354 /* DMA transl. table base */
356 rc4030_dma_tt_update(s
, val
, s
->dma_tl_limit
);
358 /* DMA transl. table limit */
360 rc4030_dma_tt_update(s
, s
->dma_tl_base
, val
);
362 /* DMA transl. table invalidated */
365 /* Cache Maintenance */
367 s
->cache_maint
= val
;
369 /* I/O Cache Physical Tag */
373 /* I/O Cache Logical Tag */
377 /* I/O Cache Byte Mask */
379 s
->cache_bmask
|= val
; /* HACK */
381 /* I/O Cache Buffer Window */
384 if (s
->cache_ltag
== 0x80000001 && s
->cache_bmask
== 0xf0f0f0f) {
385 hwaddr dest
= s
->cache_ptag
& ~0x1;
386 dest
+= (s
->cache_maint
& 0x3) << 3;
387 cpu_physical_memory_write(dest
, &val
, 4);
390 /* Remote Speed Registers */
407 s
->rem_speed
[(addr
- 0x0070) >> 3] = val
;
409 /* DMA channel base address */
443 int entry
= (addr
- 0x0100) >> 5;
444 int idx
= (addr
& 0x1f) >> 3;
445 s
->dma_regs
[entry
][idx
] = val
;
448 /* Memory refresh rate */
450 s
->memory_refresh_rate
= val
;
452 /* Interval timer reload */
455 qemu_irq_lower(s
->timer_irq
);
462 qemu_log_mask(LOG_GUEST_ERROR
,
463 "rc4030: invalid write of 0x%02x at 0x%x",
469 static const MemoryRegionOps rc4030_ops
= {
471 .write
= rc4030_write
,
472 .impl
.min_access_size
= 4,
473 .impl
.max_access_size
= 4,
474 .endianness
= DEVICE_NATIVE_ENDIAN
,
477 static void update_jazz_irq(rc4030State
*s
)
481 pending
= s
->isr_jazz
& s
->imr_jazz
;
484 qemu_irq_raise(s
->jazz_bus_irq
);
486 qemu_irq_lower(s
->jazz_bus_irq
);
489 static void rc4030_irq_jazz_request(void *opaque
, int irq
, int level
)
491 rc4030State
*s
= opaque
;
494 s
->isr_jazz
|= 1 << irq
;
496 s
->isr_jazz
&= ~(1 << irq
);
502 static void rc4030_periodic_timer(void *opaque
)
504 rc4030State
*s
= opaque
;
507 qemu_irq_raise(s
->timer_irq
);
510 static uint64_t jazzio_read(void *opaque
, hwaddr addr
, unsigned int size
)
512 rc4030State
*s
= opaque
;
518 /* Local bus int source */
520 uint32_t pending
= s
->isr_jazz
& s
->imr_jazz
;
525 val
= (irq
+ 1) << 2;
533 /* Local bus int enable mask */
538 qemu_log_mask(LOG_GUEST_ERROR
,
539 "rc4030/jazzio: invalid read at 0x%x", (int)addr
);
544 trace_jazzio_read(addr
, val
);
549 static void jazzio_write(void *opaque
, hwaddr addr
, uint64_t data
,
552 rc4030State
*s
= opaque
;
556 trace_jazzio_write(addr
, val
);
559 /* Local bus int enable mask */
565 qemu_log_mask(LOG_GUEST_ERROR
,
566 "rc4030/jazzio: invalid write of 0x%02x at 0x%x",
572 static const MemoryRegionOps jazzio_ops
= {
574 .write
= jazzio_write
,
575 .impl
.min_access_size
= 2,
576 .impl
.max_access_size
= 2,
577 .endianness
= DEVICE_NATIVE_ENDIAN
,
580 static void rc4030_reset(void *opaque
)
582 rc4030State
*s
= opaque
;
585 s
->config
= 0x410; /* some boards seem to accept 0x104 too */
587 s
->invalid_address_register
= 0;
589 memset(s
->dma_regs
, 0, sizeof(s
->dma_regs
));
590 rc4030_dma_tt_update(s
, 0, 0);
592 s
->remote_failed_address
= s
->memory_failed_address
= 0;
594 s
->cache_ptag
= s
->cache_ltag
= 0;
597 s
->memory_refresh_rate
= 0x18186;
598 s
->nvram_protect
= 7;
599 for (i
= 0; i
< 15; i
++)
601 s
->imr_jazz
= 0x10; /* XXX: required by firmware, but why? */
606 qemu_irq_lower(s
->timer_irq
);
607 qemu_irq_lower(s
->jazz_bus_irq
);
610 static int rc4030_load(QEMUFile
*f
, void *opaque
, int version_id
)
612 rc4030State
* s
= opaque
;
618 s
->config
= qemu_get_be32(f
);
619 s
->invalid_address_register
= qemu_get_be32(f
);
620 for (i
= 0; i
< 8; i
++)
621 for (j
= 0; j
< 4; j
++)
622 s
->dma_regs
[i
][j
] = qemu_get_be32(f
);
623 s
->dma_tl_base
= qemu_get_be32(f
);
624 s
->dma_tl_limit
= qemu_get_be32(f
);
625 s
->cache_maint
= qemu_get_be32(f
);
626 s
->remote_failed_address
= qemu_get_be32(f
);
627 s
->memory_failed_address
= qemu_get_be32(f
);
628 s
->cache_ptag
= qemu_get_be32(f
);
629 s
->cache_ltag
= qemu_get_be32(f
);
630 s
->cache_bmask
= qemu_get_be32(f
);
631 s
->memory_refresh_rate
= qemu_get_be32(f
);
632 s
->nvram_protect
= qemu_get_be32(f
);
633 for (i
= 0; i
< 15; i
++)
634 s
->rem_speed
[i
] = qemu_get_be32(f
);
635 s
->imr_jazz
= qemu_get_be32(f
);
636 s
->isr_jazz
= qemu_get_be32(f
);
637 s
->itr
= qemu_get_be32(f
);
645 static void rc4030_save(QEMUFile
*f
, void *opaque
)
647 rc4030State
* s
= opaque
;
650 qemu_put_be32(f
, s
->config
);
651 qemu_put_be32(f
, s
->invalid_address_register
);
652 for (i
= 0; i
< 8; i
++)
653 for (j
= 0; j
< 4; j
++)
654 qemu_put_be32(f
, s
->dma_regs
[i
][j
]);
655 qemu_put_be32(f
, s
->dma_tl_base
);
656 qemu_put_be32(f
, s
->dma_tl_limit
);
657 qemu_put_be32(f
, s
->cache_maint
);
658 qemu_put_be32(f
, s
->remote_failed_address
);
659 qemu_put_be32(f
, s
->memory_failed_address
);
660 qemu_put_be32(f
, s
->cache_ptag
);
661 qemu_put_be32(f
, s
->cache_ltag
);
662 qemu_put_be32(f
, s
->cache_bmask
);
663 qemu_put_be32(f
, s
->memory_refresh_rate
);
664 qemu_put_be32(f
, s
->nvram_protect
);
665 for (i
= 0; i
< 15; i
++)
666 qemu_put_be32(f
, s
->rem_speed
[i
]);
667 qemu_put_be32(f
, s
->imr_jazz
);
668 qemu_put_be32(f
, s
->isr_jazz
);
669 qemu_put_be32(f
, s
->itr
);
672 static void rc4030_do_dma(void *opaque
, int n
, uint8_t *buf
, int len
, int is_write
)
674 rc4030State
*s
= opaque
;
678 s
->dma_regs
[n
][DMA_REG_ENABLE
] &= ~(DMA_FLAG_TC_INTR
| DMA_FLAG_MEM_INTR
| DMA_FLAG_ADDR_INTR
);
680 /* Check DMA channel consistency */
681 dev_to_mem
= (s
->dma_regs
[n
][DMA_REG_ENABLE
] & DMA_FLAG_MEM_TO_DEV
) ? 0 : 1;
682 if (!(s
->dma_regs
[n
][DMA_REG_ENABLE
] & DMA_FLAG_ENABLE
) ||
683 (is_write
!= dev_to_mem
)) {
684 s
->dma_regs
[n
][DMA_REG_ENABLE
] |= DMA_FLAG_MEM_INTR
;
685 s
->nmi_interrupt
|= 1 << n
;
689 /* Get start address and len */
690 if (len
> s
->dma_regs
[n
][DMA_REG_COUNT
])
691 len
= s
->dma_regs
[n
][DMA_REG_COUNT
];
692 dma_addr
= s
->dma_regs
[n
][DMA_REG_ADDRESS
];
694 /* Read/write data at right place */
695 address_space_rw(&s
->dma_as
, dma_addr
, MEMTXATTRS_UNSPECIFIED
,
698 s
->dma_regs
[n
][DMA_REG_ENABLE
] |= DMA_FLAG_TC_INTR
;
699 s
->dma_regs
[n
][DMA_REG_COUNT
] -= len
;
702 struct rc4030DMAState
{
707 void rc4030_dma_read(void *dma
, uint8_t *buf
, int len
)
710 rc4030_do_dma(s
->opaque
, s
->n
, buf
, len
, 0);
713 void rc4030_dma_write(void *dma
, uint8_t *buf
, int len
)
716 rc4030_do_dma(s
->opaque
, s
->n
, buf
, len
, 1);
719 static rc4030_dma
*rc4030_allocate_dmas(void *opaque
, int n
)
722 struct rc4030DMAState
*p
;
725 s
= (rc4030_dma
*)g_malloc0(sizeof(rc4030_dma
) * n
);
726 p
= (struct rc4030DMAState
*)g_malloc0(sizeof(struct rc4030DMAState
) * n
);
727 for (i
= 0; i
< n
; i
++) {
736 MemoryRegion
*rc4030_init(qemu_irq timer
, qemu_irq jazz_bus
,
737 qemu_irq
**irqs
, rc4030_dma
**dmas
,
738 MemoryRegion
*sysmem
)
743 s
= g_malloc0(sizeof(rc4030State
));
745 *irqs
= qemu_allocate_irqs(rc4030_irq_jazz_request
, s
, 16);
746 *dmas
= rc4030_allocate_dmas(s
, 4);
748 s
->periodic_timer
= timer_new_ns(QEMU_CLOCK_VIRTUAL
, rc4030_periodic_timer
, s
);
749 s
->timer_irq
= timer
;
750 s
->jazz_bus_irq
= jazz_bus
;
752 qemu_register_reset(rc4030_reset
, s
);
753 register_savevm(NULL
, "rc4030", 0, 2, rc4030_save
, rc4030_load
, s
);
756 memory_region_init_io(&s
->iomem_chipset
, NULL
, &rc4030_ops
, s
,
757 "rc4030.chipset", 0x300);
758 memory_region_add_subregion(sysmem
, 0x80000000, &s
->iomem_chipset
);
759 memory_region_init_io(&s
->iomem_jazzio
, NULL
, &jazzio_ops
, s
,
760 "rc4030.jazzio", 0x00001000);
761 memory_region_add_subregion(sysmem
, 0xf0000000, &s
->iomem_jazzio
);
763 memory_region_init_rom_device(&s
->dma_tt
, NULL
,
764 &rc4030_dma_tt_ops
, s
, "dma-table",
765 MAX_TL_ENTRIES
* sizeof(dma_pagetable_entry
),
767 memory_region_init(&s
->dma_tt_alias
, NULL
, "dma-table-alias", 0);
768 memory_region_init(&s
->dma_mr
, NULL
, "dma", INT32_MAX
);
769 for (i
= 0; i
< MAX_TL_ENTRIES
; ++i
) {
770 memory_region_init_alias(&s
->dma_mrs
[i
], NULL
, "dma-alias",
771 get_system_memory(), 0, DMA_PAGESIZE
);
772 memory_region_set_enabled(&s
->dma_mrs
[i
], false);
773 memory_region_add_subregion(&s
->dma_mr
, i
* DMA_PAGESIZE
,
776 address_space_init(&s
->dma_as
, &s
->dma_mr
, "rc4030-dma");