mirror of https://github.com/xemu-project/xemu.git
MIPS (and few misc) patches
- MIPS - Remove obsolete "mips" board from target-mips.rst - Fix JALS32/J32/SWM32 instructions for microMIPS - Fix CP0.Config7.WII handling on pre-R6 cores - HW - Revert "Remove intermediate IRQ forwarder" commits - Implement legacy LTIM Edge/Level Bank Select in Intel 8259 INTC - Improve PCI IRQ routing in VT82C686 / Pegasos II - Basic implementation of VIA AC97 audio playback - Implement 'resume on connection status change' in USB OHCI - UI - Override windowDidResignKey - memory - Dump HPA and access type in HMP 'info ramblock' -----BEGIN PGP SIGNATURE----- iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmQHzH8ACgkQ4+MsLN6t wN4RbxAAtbsbJKHikHevCiE9Fi0E4HHI4su00m3anImogfU3CKIHA7WHgeUVCdVH aLoFKjvE3d45FA4YwMs13wIo89tv6btn1y8C9iy+yjktdABPUr8OJphuaDxU+yNf XhPm4WsS0tEg5KzzTHF7qotJGw7Zd0Aca8oezFVBSL8b73lqiJiWBEouFTK9j5Oi s1uvAOPG3oxSlT7IIbnLRIEff4hi5FZh+LxRDgE3ChcOyY2W/DhrpdVIazv9Cpki facQ0ozMG4uuZ+HvviuTkK1vLX1+BcS0P1fnDPkXEPAxqx9jdqsMqWHbbnseQPN3 xcVhw+GOZ67x8qAWIBKDG7nfChbcXgJ2sHxQmvb2XlxnOYw1oO5aRlrnn7ZPEWYA NbqUHB8G88wDcrms+Y+xCfO8idnr7Kzf4/1R1J1+5yEjg8Y1wu4t0asqZvhXA2HL F1yhHDCRY8w9pLYmPFGBrINBCoosiDn61g+JTngPffq1zJttmWjSLe9BYOF8Kiw+ 4YjkCx43wK6RLTZNhU8g7iuqoYbHCQcXx5ZnGEadk+UJcfGrLnOrQbtAhvysS2wo msyum0FNWhnx/IZ6bmhmbFC8F/hASgyiV9CDwU2oOZ2oAkRiFXYBfXruUAt+6uLT UnAihAEsyUjyg5YNb4r8ZNkdeCPN6p3s2xY8OHphqu717K6uJXw= =D/0W -----END PGP SIGNATURE----- Merge tag 'mips-misc-20230308' of https://github.com/philmd/qemu into staging MIPS (and few misc) patches - MIPS - Remove obsolete "mips" board from target-mips.rst - Fix JALS32/J32/SWM32 instructions for microMIPS - Fix CP0.Config7.WII handling on pre-R6 cores - HW - Revert "Remove intermediate IRQ forwarder" commits - Implement legacy LTIM Edge/Level Bank Select in Intel 8259 INTC - Improve PCI IRQ routing in VT82C686 / Pegasos II - Basic implementation of VIA AC97 audio playback - Implement 'resume on connection status change' in USB OHCI - UI - Override windowDidResignKey - memory - Dump HPA and access type in HMP 'info ramblock' # -----BEGIN PGP SIGNATURE----- # # iQIzBAABCAAdFiEE+qvnXhKRciHc/Wuy4+MsLN6twN4FAmQHzH8ACgkQ4+MsLN6t # wN4RbxAAtbsbJKHikHevCiE9Fi0E4HHI4su00m3anImogfU3CKIHA7WHgeUVCdVH # aLoFKjvE3d45FA4YwMs13wIo89tv6btn1y8C9iy+yjktdABPUr8OJphuaDxU+yNf # XhPm4WsS0tEg5KzzTHF7qotJGw7Zd0Aca8oezFVBSL8b73lqiJiWBEouFTK9j5Oi # s1uvAOPG3oxSlT7IIbnLRIEff4hi5FZh+LxRDgE3ChcOyY2W/DhrpdVIazv9Cpki # facQ0ozMG4uuZ+HvviuTkK1vLX1+BcS0P1fnDPkXEPAxqx9jdqsMqWHbbnseQPN3 # xcVhw+GOZ67x8qAWIBKDG7nfChbcXgJ2sHxQmvb2XlxnOYw1oO5aRlrnn7ZPEWYA # NbqUHB8G88wDcrms+Y+xCfO8idnr7Kzf4/1R1J1+5yEjg8Y1wu4t0asqZvhXA2HL # F1yhHDCRY8w9pLYmPFGBrINBCoosiDn61g+JTngPffq1zJttmWjSLe9BYOF8Kiw+ # 4YjkCx43wK6RLTZNhU8g7iuqoYbHCQcXx5ZnGEadk+UJcfGrLnOrQbtAhvysS2wo # msyum0FNWhnx/IZ6bmhmbFC8F/hASgyiV9CDwU2oOZ2oAkRiFXYBfXruUAt+6uLT # UnAihAEsyUjyg5YNb4r8ZNkdeCPN6p3s2xY8OHphqu717K6uJXw= # =D/0W # -----END PGP SIGNATURE----- # gpg: Signature made Tue 07 Mar 2023 23:45:03 GMT # gpg: using RSA key FAABE75E12917221DCFD6BB2E3E32C2CDEADC0DE # gpg: Good signature from "Philippe Mathieu-Daudé (F4BUG) <f4bug@amsat.org>" [unknown] # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: FAAB E75E 1291 7221 DCFD 6BB2 E3E3 2C2C DEAD C0DE * tag 'mips-misc-20230308' of https://github.com/philmd/qemu: log: Remove unneeded new line memory: Dump HPA and access type of ramblocks ui/cocoa: Override windowDidResignKey hw/usb/ohci: Implement resume on connection status change hw/audio/via-ac97: Basic implementation of audio playback hw/usb/vt82c686-uhci-pci: Use PCI IRQ routing hw/ppc/pegasos2: Fix PCI interrupt routing hw/isa/vt82c686: Implement PCI IRQ routing hw/intc/i8259: Implement legacy LTIM Edge/Level Bank Select hw/display/sm501: Add debug property to control pixman usage Revert "hw/isa/vt82c686: Remove intermediate IRQ forwarder" Revert "hw/isa/i82378: Remove intermediate IRQ forwarder" hw/mips/itu: Pass SAAR using QOM link property hw/mips: Declare all length properties as unsigned target/mips: Set correct CP0.Config[4, 5] values for M14K(c) target/mips: Implement CP0.Config7.WII bit support target/mips: Fix SWM32 handling for microMIPS target/mips: Fix JALS32/J32 instruction handling for microMIPS target/mips: Replace [g_]assert(0) -> g_assert_not_reached() docs/system: Remove "mips" board from target-mips.rst Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
commit
555ce1d855
|
@ -8,8 +8,6 @@ endian options, ``qemu-system-mips``, ``qemu-system-mipsel``
|
||||||
``qemu-system-mips64`` and ``qemu-system-mips64el``. Five different
|
``qemu-system-mips64`` and ``qemu-system-mips64el``. Five different
|
||||||
machine types are emulated:
|
machine types are emulated:
|
||||||
|
|
||||||
- A generic ISA PC-like machine \"mips\"
|
|
||||||
|
|
||||||
- The MIPS Malta prototype board \"malta\"
|
- The MIPS Malta prototype board \"malta\"
|
||||||
|
|
||||||
- An ACER Pica \"pica61\". This machine needs the 64-bit emulator.
|
- An ACER Pica \"pica61\". This machine needs the 64-bit emulator.
|
||||||
|
@ -19,18 +17,6 @@ machine types are emulated:
|
||||||
- A MIPS Magnum R4000 machine \"magnum\". This machine needs the
|
- A MIPS Magnum R4000 machine \"magnum\". This machine needs the
|
||||||
64-bit emulator.
|
64-bit emulator.
|
||||||
|
|
||||||
The generic emulation is supported by Debian 'Etch' and is able to
|
|
||||||
install Debian into a virtual disk image. The following devices are
|
|
||||||
emulated:
|
|
||||||
|
|
||||||
- A range of MIPS CPUs, default is the 24Kf
|
|
||||||
|
|
||||||
- PC style serial port
|
|
||||||
|
|
||||||
- PC style IDE disk
|
|
||||||
|
|
||||||
- NE2000 network card
|
|
||||||
|
|
||||||
The Malta emulation supports the following devices:
|
The Malta emulation supports the following devices:
|
||||||
|
|
||||||
- Core board with MIPS 24Kf CPU and Galileo system controller
|
- Core board with MIPS 24Kf CPU and Galileo system controller
|
||||||
|
|
|
@ -11,3 +11,9 @@ hda_audio_running(const char *stream, int nr, bool running) "st %s, nr %d, run %
|
||||||
hda_audio_format(const char *stream, int chan, const char *fmt, int freq) "st %s, %d x %s @ %d Hz"
|
hda_audio_format(const char *stream, int chan, const char *fmt, int freq) "st %s, %d x %s @ %d Hz"
|
||||||
hda_audio_adjust(const char *stream, int pos) "st %s, pos %d"
|
hda_audio_adjust(const char *stream, int pos) "st %s, pos %d"
|
||||||
hda_audio_overrun(const char *stream) "st %s"
|
hda_audio_overrun(const char *stream) "st %s"
|
||||||
|
|
||||||
|
#via-ac97.c
|
||||||
|
via_ac97_codec_write(uint8_t addr, uint16_t val) "0x%x <- 0x%x"
|
||||||
|
via_ac97_sgd_fetch(uint32_t curr, uint32_t addr, char stop, char eol, char flag, uint32_t len) "curr=0x%x addr=0x%x %c%c%c len=%d"
|
||||||
|
via_ac97_sgd_read(uint64_t addr, unsigned size, uint64_t val) "0x%"PRIx64" %d -> 0x%"PRIx64
|
||||||
|
via_ac97_sgd_write(uint64_t addr, unsigned size, uint64_t val) "0x%"PRIx64" %d <- 0x%"PRIx64
|
||||||
|
|
|
@ -1,39 +1,482 @@
|
||||||
/*
|
/*
|
||||||
* VIA south bridges sound support
|
* VIA south bridges sound support
|
||||||
*
|
*
|
||||||
|
* Copyright (c) 2022-2023 BALATON Zoltan
|
||||||
|
*
|
||||||
* This work is licensed under the GNU GPL license version 2 or later.
|
* This work is licensed under the GNU GPL license version 2 or later.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* TODO: This is entirely boiler plate just registering empty PCI devices
|
* TODO: This is only a basic implementation of one audio playback channel
|
||||||
* with the right ID guests expect, functionality should be added here.
|
* more functionality should be added here.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
|
#include "qemu/log.h"
|
||||||
#include "hw/isa/vt82c686.h"
|
#include "hw/isa/vt82c686.h"
|
||||||
#include "hw/pci/pci_device.h"
|
#include "ac97.h"
|
||||||
|
#include "trace.h"
|
||||||
|
|
||||||
|
#define CLEN_IS_EOL(x) ((x)->clen & BIT(31))
|
||||||
|
#define CLEN_IS_FLAG(x) ((x)->clen & BIT(30))
|
||||||
|
#define CLEN_IS_STOP(x) ((x)->clen & BIT(29))
|
||||||
|
#define CLEN_LEN(x) ((x)->clen & 0xffffff)
|
||||||
|
|
||||||
|
#define STAT_ACTIVE BIT(7)
|
||||||
|
#define STAT_PAUSED BIT(6)
|
||||||
|
#define STAT_TRIG BIT(3)
|
||||||
|
#define STAT_STOP BIT(2)
|
||||||
|
#define STAT_EOL BIT(1)
|
||||||
|
#define STAT_FLAG BIT(0)
|
||||||
|
|
||||||
|
#define CNTL_START BIT(7)
|
||||||
|
#define CNTL_TERM BIT(6)
|
||||||
|
#define CNTL_PAUSE BIT(3)
|
||||||
|
|
||||||
|
static void open_voice_out(ViaAC97State *s);
|
||||||
|
|
||||||
|
static uint16_t codec_rates[] = { 8000, 11025, 16000, 22050, 32000, 44100,
|
||||||
|
48000 };
|
||||||
|
|
||||||
|
#define CODEC_REG(s, o) ((s)->codec_regs[(o) / 2])
|
||||||
|
#define CODEC_VOL(vol, mask) ((255 * ((vol) & mask)) / mask)
|
||||||
|
|
||||||
|
static void codec_volume_set_out(ViaAC97State *s)
|
||||||
|
{
|
||||||
|
int lvol, rvol, mute;
|
||||||
|
|
||||||
|
lvol = 255 - CODEC_VOL(CODEC_REG(s, AC97_Master_Volume_Mute) >> 8, 0x1f);
|
||||||
|
lvol *= 255 - CODEC_VOL(CODEC_REG(s, AC97_PCM_Out_Volume_Mute) >> 8, 0x1f);
|
||||||
|
lvol /= 255;
|
||||||
|
rvol = 255 - CODEC_VOL(CODEC_REG(s, AC97_Master_Volume_Mute), 0x1f);
|
||||||
|
rvol *= 255 - CODEC_VOL(CODEC_REG(s, AC97_PCM_Out_Volume_Mute), 0x1f);
|
||||||
|
rvol /= 255;
|
||||||
|
mute = CODEC_REG(s, AC97_Master_Volume_Mute) >> MUTE_SHIFT;
|
||||||
|
mute |= CODEC_REG(s, AC97_PCM_Out_Volume_Mute) >> MUTE_SHIFT;
|
||||||
|
AUD_set_volume_out(s->vo, mute, lvol, rvol);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void codec_reset(ViaAC97State *s)
|
||||||
|
{
|
||||||
|
memset(s->codec_regs, 0, sizeof(s->codec_regs));
|
||||||
|
CODEC_REG(s, AC97_Reset) = 0x6a90;
|
||||||
|
CODEC_REG(s, AC97_Master_Volume_Mute) = 0x8000;
|
||||||
|
CODEC_REG(s, AC97_Headphone_Volume_Mute) = 0x8000;
|
||||||
|
CODEC_REG(s, AC97_Master_Volume_Mono_Mute) = 0x8000;
|
||||||
|
CODEC_REG(s, AC97_Phone_Volume_Mute) = 0x8008;
|
||||||
|
CODEC_REG(s, AC97_Mic_Volume_Mute) = 0x8008;
|
||||||
|
CODEC_REG(s, AC97_Line_In_Volume_Mute) = 0x8808;
|
||||||
|
CODEC_REG(s, AC97_CD_Volume_Mute) = 0x8808;
|
||||||
|
CODEC_REG(s, AC97_Video_Volume_Mute) = 0x8808;
|
||||||
|
CODEC_REG(s, AC97_Aux_Volume_Mute) = 0x8808;
|
||||||
|
CODEC_REG(s, AC97_PCM_Out_Volume_Mute) = 0x8808;
|
||||||
|
CODEC_REG(s, AC97_Record_Gain_Mute) = 0x8000;
|
||||||
|
CODEC_REG(s, AC97_Powerdown_Ctrl_Stat) = 0x000f;
|
||||||
|
CODEC_REG(s, AC97_Extended_Audio_ID) = 0x0a05;
|
||||||
|
CODEC_REG(s, AC97_Extended_Audio_Ctrl_Stat) = 0x0400;
|
||||||
|
CODEC_REG(s, AC97_PCM_Front_DAC_Rate) = 48000;
|
||||||
|
CODEC_REG(s, AC97_PCM_LR_ADC_Rate) = 48000;
|
||||||
|
/* Sigmatel 9766 (STAC9766) */
|
||||||
|
CODEC_REG(s, AC97_Vendor_ID1) = 0x8384;
|
||||||
|
CODEC_REG(s, AC97_Vendor_ID2) = 0x7666;
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint16_t codec_read(ViaAC97State *s, uint8_t addr)
|
||||||
|
{
|
||||||
|
return CODEC_REG(s, addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void codec_write(ViaAC97State *s, uint8_t addr, uint16_t val)
|
||||||
|
{
|
||||||
|
trace_via_ac97_codec_write(addr, val);
|
||||||
|
switch (addr) {
|
||||||
|
case AC97_Reset:
|
||||||
|
codec_reset(s);
|
||||||
|
return;
|
||||||
|
case AC97_Master_Volume_Mute:
|
||||||
|
case AC97_PCM_Out_Volume_Mute:
|
||||||
|
if (addr == AC97_Master_Volume_Mute) {
|
||||||
|
if (val & BIT(13)) {
|
||||||
|
val |= 0x1f00;
|
||||||
|
}
|
||||||
|
if (val & BIT(5)) {
|
||||||
|
val |= 0x1f;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
CODEC_REG(s, addr) = val & 0x9f1f;
|
||||||
|
codec_volume_set_out(s);
|
||||||
|
return;
|
||||||
|
case AC97_Extended_Audio_Ctrl_Stat:
|
||||||
|
CODEC_REG(s, addr) &= ~EACS_VRA;
|
||||||
|
CODEC_REG(s, addr) |= val & EACS_VRA;
|
||||||
|
if (!(val & EACS_VRA)) {
|
||||||
|
CODEC_REG(s, AC97_PCM_Front_DAC_Rate) = 48000;
|
||||||
|
CODEC_REG(s, AC97_PCM_LR_ADC_Rate) = 48000;
|
||||||
|
open_voice_out(s);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case AC97_PCM_Front_DAC_Rate:
|
||||||
|
case AC97_PCM_LR_ADC_Rate:
|
||||||
|
if (CODEC_REG(s, AC97_Extended_Audio_Ctrl_Stat) & EACS_VRA) {
|
||||||
|
int i;
|
||||||
|
uint16_t rate = val;
|
||||||
|
|
||||||
|
for (i = 0; i < ARRAY_SIZE(codec_rates) - 1; i++) {
|
||||||
|
if (rate < codec_rates[i] +
|
||||||
|
(codec_rates[i + 1] - codec_rates[i]) / 2) {
|
||||||
|
rate = codec_rates[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (rate > 48000) {
|
||||||
|
rate = 48000;
|
||||||
|
}
|
||||||
|
CODEC_REG(s, addr) = rate;
|
||||||
|
open_voice_out(s);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
case AC97_Powerdown_Ctrl_Stat:
|
||||||
|
CODEC_REG(s, addr) = (val & 0xff00) | (CODEC_REG(s, addr) & 0xff);
|
||||||
|
return;
|
||||||
|
case AC97_Extended_Audio_ID:
|
||||||
|
case AC97_Vendor_ID1:
|
||||||
|
case AC97_Vendor_ID2:
|
||||||
|
/* Read only registers */
|
||||||
|
return;
|
||||||
|
default:
|
||||||
|
qemu_log_mask(LOG_UNIMP,
|
||||||
|
"via-ac97: Unimplemented codec register 0x%x\n", addr);
|
||||||
|
CODEC_REG(s, addr) = val;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fetch_sgd(ViaAC97SGDChannel *c, PCIDevice *d)
|
||||||
|
{
|
||||||
|
uint32_t b[2];
|
||||||
|
|
||||||
|
if (c->curr < c->base) {
|
||||||
|
c->curr = c->base;
|
||||||
|
}
|
||||||
|
if (unlikely(pci_dma_read(d, c->curr, b, sizeof(b)) != MEMTX_OK)) {
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR,
|
||||||
|
"via-ac97: DMA error reading SGD table\n");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
c->addr = le32_to_cpu(b[0]);
|
||||||
|
c->clen = le32_to_cpu(b[1]);
|
||||||
|
trace_via_ac97_sgd_fetch(c->curr, c->addr, CLEN_IS_STOP(c) ? 'S' : '-',
|
||||||
|
CLEN_IS_EOL(c) ? 'E' : '-',
|
||||||
|
CLEN_IS_FLAG(c) ? 'F' : '-', CLEN_LEN(c));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void out_cb(void *opaque, int avail)
|
||||||
|
{
|
||||||
|
ViaAC97State *s = opaque;
|
||||||
|
ViaAC97SGDChannel *c = &s->aur;
|
||||||
|
int temp, to_copy, copied;
|
||||||
|
bool stop = false;
|
||||||
|
uint8_t tmpbuf[4096];
|
||||||
|
|
||||||
|
if (c->stat & STAT_PAUSED) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
c->stat |= STAT_ACTIVE;
|
||||||
|
while (avail && !stop) {
|
||||||
|
if (!c->clen) {
|
||||||
|
fetch_sgd(c, &s->dev);
|
||||||
|
}
|
||||||
|
temp = MIN(CLEN_LEN(c), avail);
|
||||||
|
while (temp) {
|
||||||
|
to_copy = MIN(temp, sizeof(tmpbuf));
|
||||||
|
pci_dma_read(&s->dev, c->addr, tmpbuf, to_copy);
|
||||||
|
copied = AUD_write(s->vo, tmpbuf, to_copy);
|
||||||
|
if (!copied) {
|
||||||
|
stop = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
temp -= copied;
|
||||||
|
avail -= copied;
|
||||||
|
c->addr += copied;
|
||||||
|
c->clen -= copied;
|
||||||
|
}
|
||||||
|
if (CLEN_LEN(c) == 0) {
|
||||||
|
c->curr += 8;
|
||||||
|
if (CLEN_IS_EOL(c)) {
|
||||||
|
c->stat |= STAT_EOL;
|
||||||
|
if (c->type & CNTL_START) {
|
||||||
|
c->curr = c->base;
|
||||||
|
c->stat |= STAT_PAUSED;
|
||||||
|
} else {
|
||||||
|
c->stat &= ~STAT_ACTIVE;
|
||||||
|
AUD_set_active_out(s->vo, 0);
|
||||||
|
}
|
||||||
|
if (c->type & STAT_EOL) {
|
||||||
|
pci_set_irq(&s->dev, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CLEN_IS_FLAG(c)) {
|
||||||
|
c->stat |= STAT_FLAG;
|
||||||
|
c->stat |= STAT_PAUSED;
|
||||||
|
if (c->type & STAT_FLAG) {
|
||||||
|
pci_set_irq(&s->dev, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (CLEN_IS_STOP(c)) {
|
||||||
|
c->stat |= STAT_STOP;
|
||||||
|
c->stat |= STAT_PAUSED;
|
||||||
|
}
|
||||||
|
c->clen = 0;
|
||||||
|
stop = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void open_voice_out(ViaAC97State *s)
|
||||||
|
{
|
||||||
|
struct audsettings as = {
|
||||||
|
.freq = CODEC_REG(s, AC97_PCM_Front_DAC_Rate),
|
||||||
|
.nchannels = s->aur.type & BIT(4) ? 2 : 1,
|
||||||
|
.fmt = s->aur.type & BIT(5) ? AUDIO_FORMAT_S16 : AUDIO_FORMAT_S8,
|
||||||
|
.endianness = 0,
|
||||||
|
};
|
||||||
|
s->vo = AUD_open_out(&s->card, s->vo, "via-ac97.out", s, out_cb, &as);
|
||||||
|
}
|
||||||
|
|
||||||
|
static uint64_t sgd_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
|
{
|
||||||
|
ViaAC97State *s = opaque;
|
||||||
|
uint64_t val = 0;
|
||||||
|
|
||||||
|
switch (addr) {
|
||||||
|
case 0:
|
||||||
|
val = s->aur.stat;
|
||||||
|
if (s->aur.type & CNTL_START) {
|
||||||
|
val |= STAT_TRIG;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
val = s->aur.stat & STAT_PAUSED ? BIT(3) : 0;
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
val = s->aur.type;
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
val = s->aur.curr;
|
||||||
|
break;
|
||||||
|
case 0xc:
|
||||||
|
val = CLEN_LEN(&s->aur);
|
||||||
|
break;
|
||||||
|
case 0x10:
|
||||||
|
/* silence unimplemented log message that happens at every IRQ */
|
||||||
|
break;
|
||||||
|
case 0x80:
|
||||||
|
val = s->ac97_cmd;
|
||||||
|
break;
|
||||||
|
case 0x84:
|
||||||
|
val = s->aur.stat & STAT_FLAG;
|
||||||
|
if (s->aur.stat & STAT_EOL) {
|
||||||
|
val |= BIT(4);
|
||||||
|
}
|
||||||
|
if (s->aur.stat & STAT_STOP) {
|
||||||
|
val |= BIT(8);
|
||||||
|
}
|
||||||
|
if (s->aur.stat & STAT_ACTIVE) {
|
||||||
|
val |= BIT(12);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "via-ac97: Unimplemented register read 0x%"
|
||||||
|
HWADDR_PRIx"\n", addr);
|
||||||
|
}
|
||||||
|
trace_via_ac97_sgd_read(addr, size, val);
|
||||||
|
return val;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void sgd_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||||
|
{
|
||||||
|
ViaAC97State *s = opaque;
|
||||||
|
|
||||||
|
trace_via_ac97_sgd_write(addr, size, val);
|
||||||
|
switch (addr) {
|
||||||
|
case 0:
|
||||||
|
if (val & STAT_STOP) {
|
||||||
|
s->aur.stat &= ~STAT_PAUSED;
|
||||||
|
}
|
||||||
|
if (val & STAT_EOL) {
|
||||||
|
s->aur.stat &= ~(STAT_EOL | STAT_PAUSED);
|
||||||
|
if (s->aur.type & STAT_EOL) {
|
||||||
|
pci_set_irq(&s->dev, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (val & STAT_FLAG) {
|
||||||
|
s->aur.stat &= ~(STAT_FLAG | STAT_PAUSED);
|
||||||
|
if (s->aur.type & STAT_FLAG) {
|
||||||
|
pci_set_irq(&s->dev, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 1:
|
||||||
|
if (val & CNTL_START) {
|
||||||
|
AUD_set_active_out(s->vo, 1);
|
||||||
|
s->aur.stat = STAT_ACTIVE;
|
||||||
|
}
|
||||||
|
if (val & CNTL_TERM) {
|
||||||
|
AUD_set_active_out(s->vo, 0);
|
||||||
|
s->aur.stat &= ~(STAT_ACTIVE | STAT_PAUSED);
|
||||||
|
s->aur.clen = 0;
|
||||||
|
}
|
||||||
|
if (val & CNTL_PAUSE) {
|
||||||
|
AUD_set_active_out(s->vo, 0);
|
||||||
|
s->aur.stat &= ~STAT_ACTIVE;
|
||||||
|
s->aur.stat |= STAT_PAUSED;
|
||||||
|
} else if (!(val & CNTL_PAUSE) && (s->aur.stat & STAT_PAUSED)) {
|
||||||
|
AUD_set_active_out(s->vo, 1);
|
||||||
|
s->aur.stat |= STAT_ACTIVE;
|
||||||
|
s->aur.stat &= ~STAT_PAUSED;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
{
|
||||||
|
uint32_t oldval = s->aur.type;
|
||||||
|
s->aur.type = val;
|
||||||
|
if ((oldval & 0x30) != (val & 0x30)) {
|
||||||
|
open_voice_out(s);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case 4:
|
||||||
|
s->aur.base = val & ~1ULL;
|
||||||
|
s->aur.curr = s->aur.base;
|
||||||
|
break;
|
||||||
|
case 0x80:
|
||||||
|
if (val >> 30) {
|
||||||
|
/* we only have primary codec */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (val & BIT(23)) { /* read reg */
|
||||||
|
s->ac97_cmd = val & 0xc0ff0000ULL;
|
||||||
|
s->ac97_cmd |= codec_read(s, (val >> 16) & 0x7f);
|
||||||
|
s->ac97_cmd |= BIT(25); /* data valid */
|
||||||
|
} else {
|
||||||
|
s->ac97_cmd = val & 0xc0ffffffULL;
|
||||||
|
codec_write(s, (val >> 16) & 0x7f, val);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
case 0xc:
|
||||||
|
case 0x84:
|
||||||
|
/* Read only */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
qemu_log_mask(LOG_UNIMP, "via-ac97: Unimplemented register write 0x%"
|
||||||
|
HWADDR_PRIx"\n", addr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static const MemoryRegionOps sgd_ops = {
|
||||||
|
.read = sgd_read,
|
||||||
|
.write = sgd_write,
|
||||||
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint64_t fm_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d\n", __func__, addr, size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void fm_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d <= 0x%"PRIX64"\n",
|
||||||
|
__func__, addr, size, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const MemoryRegionOps fm_ops = {
|
||||||
|
.read = fm_read,
|
||||||
|
.write = fm_write,
|
||||||
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static uint64_t midi_read(void *opaque, hwaddr addr, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d\n", __func__, addr, size);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void midi_write(void *opaque, hwaddr addr, uint64_t val, unsigned size)
|
||||||
|
{
|
||||||
|
qemu_log_mask(LOG_UNIMP, "%s: 0x%"HWADDR_PRIx" %d <= 0x%"PRIX64"\n",
|
||||||
|
__func__, addr, size, val);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const MemoryRegionOps midi_ops = {
|
||||||
|
.read = midi_read,
|
||||||
|
.write = midi_write,
|
||||||
|
.endianness = DEVICE_LITTLE_ENDIAN,
|
||||||
|
};
|
||||||
|
|
||||||
|
static void via_ac97_reset(DeviceState *dev)
|
||||||
|
{
|
||||||
|
ViaAC97State *s = VIA_AC97(dev);
|
||||||
|
|
||||||
|
codec_reset(s);
|
||||||
|
}
|
||||||
|
|
||||||
static void via_ac97_realize(PCIDevice *pci_dev, Error **errp)
|
static void via_ac97_realize(PCIDevice *pci_dev, Error **errp)
|
||||||
{
|
{
|
||||||
pci_set_word(pci_dev->config + PCI_COMMAND,
|
ViaAC97State *s = VIA_AC97(pci_dev);
|
||||||
PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
|
Object *o = OBJECT(s);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Command register Bus Master bit is documented to be fixed at 0 but it's
|
||||||
|
* needed for PCI DMA to work in QEMU. The pegasos2 firmware writes 0 here
|
||||||
|
* and the AmigaOS driver writes 1 only enabling IO bit which works on
|
||||||
|
* real hardware. So set it here and fix it to 1 to allow DMA.
|
||||||
|
*/
|
||||||
|
pci_set_word(pci_dev->config + PCI_COMMAND, PCI_COMMAND_MASTER);
|
||||||
|
pci_set_word(pci_dev->wmask + PCI_COMMAND, PCI_COMMAND_IO);
|
||||||
pci_set_word(pci_dev->config + PCI_STATUS,
|
pci_set_word(pci_dev->config + PCI_STATUS,
|
||||||
PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_MEDIUM);
|
PCI_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_MEDIUM);
|
||||||
pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03);
|
pci_set_long(pci_dev->config + PCI_INTERRUPT_PIN, 0x03);
|
||||||
|
pci_set_byte(pci_dev->config + 0x40, 1); /* codec ready */
|
||||||
|
|
||||||
|
memory_region_init_io(&s->sgd, o, &sgd_ops, s, "via-ac97.sgd", 256);
|
||||||
|
pci_register_bar(pci_dev, 0, PCI_BASE_ADDRESS_SPACE_IO, &s->sgd);
|
||||||
|
memory_region_init_io(&s->fm, o, &fm_ops, s, "via-ac97.fm", 4);
|
||||||
|
pci_register_bar(pci_dev, 1, PCI_BASE_ADDRESS_SPACE_IO, &s->fm);
|
||||||
|
memory_region_init_io(&s->midi, o, &midi_ops, s, "via-ac97.midi", 4);
|
||||||
|
pci_register_bar(pci_dev, 2, PCI_BASE_ADDRESS_SPACE_IO, &s->midi);
|
||||||
|
|
||||||
|
AUD_register_card ("via-ac97", &s->card);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void via_ac97_exit(PCIDevice *dev)
|
||||||
|
{
|
||||||
|
ViaAC97State *s = VIA_AC97(dev);
|
||||||
|
|
||||||
|
AUD_close_out(&s->card, s->vo);
|
||||||
|
AUD_remove_card(&s->card);
|
||||||
|
}
|
||||||
|
|
||||||
|
static Property via_ac97_properties[] = {
|
||||||
|
DEFINE_AUDIO_PROPERTIES(ViaAC97State, card),
|
||||||
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
|
};
|
||||||
|
|
||||||
static void via_ac97_class_init(ObjectClass *klass, void *data)
|
static void via_ac97_class_init(ObjectClass *klass, void *data)
|
||||||
{
|
{
|
||||||
DeviceClass *dc = DEVICE_CLASS(klass);
|
DeviceClass *dc = DEVICE_CLASS(klass);
|
||||||
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
|
||||||
|
|
||||||
k->realize = via_ac97_realize;
|
k->realize = via_ac97_realize;
|
||||||
|
k->exit = via_ac97_exit;
|
||||||
k->vendor_id = PCI_VENDOR_ID_VIA;
|
k->vendor_id = PCI_VENDOR_ID_VIA;
|
||||||
k->device_id = PCI_DEVICE_ID_VIA_AC97;
|
k->device_id = PCI_DEVICE_ID_VIA_AC97;
|
||||||
k->revision = 0x50;
|
k->revision = 0x50;
|
||||||
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
|
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
|
||||||
|
device_class_set_props(dc, via_ac97_properties);
|
||||||
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
|
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
|
||||||
dc->desc = "VIA AC97";
|
dc->desc = "VIA AC97";
|
||||||
|
dc->reset = via_ac97_reset;
|
||||||
/* Reason: Part of a south bridge chip */
|
/* Reason: Part of a south bridge chip */
|
||||||
dc->user_creatable = false;
|
dc->user_creatable = false;
|
||||||
}
|
}
|
||||||
|
@ -41,7 +484,7 @@ static void via_ac97_class_init(ObjectClass *klass, void *data)
|
||||||
static const TypeInfo via_ac97_info = {
|
static const TypeInfo via_ac97_info = {
|
||||||
.name = TYPE_VIA_AC97,
|
.name = TYPE_VIA_AC97,
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(PCIDevice),
|
.instance_size = sizeof(ViaAC97State),
|
||||||
.class_init = via_ac97_class_init,
|
.class_init = via_ac97_class_init,
|
||||||
.interfaces = (InterfaceInfo[]) {
|
.interfaces = (InterfaceInfo[]) {
|
||||||
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
|
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
|
||||||
|
|
|
@ -465,6 +465,7 @@ typedef struct SM501State {
|
||||||
uint32_t last_width;
|
uint32_t last_width;
|
||||||
uint32_t last_height;
|
uint32_t last_height;
|
||||||
bool do_full_update; /* perform a full update next time */
|
bool do_full_update; /* perform a full update next time */
|
||||||
|
uint8_t use_pixman;
|
||||||
I2CBus *i2c_bus;
|
I2CBus *i2c_bus;
|
||||||
|
|
||||||
/* mmio registers */
|
/* mmio registers */
|
||||||
|
@ -827,7 +828,7 @@ static void sm501_2d_operation(SM501State *s)
|
||||||
de = db + (width + (height - 1) * dst_pitch) * bypp;
|
de = db + (width + (height - 1) * dst_pitch) * bypp;
|
||||||
overlap = (db < se && sb < de);
|
overlap = (db < se && sb < de);
|
||||||
}
|
}
|
||||||
if (overlap) {
|
if (overlap && (s->use_pixman & BIT(2))) {
|
||||||
/* pixman can't do reverse blit: copy via temporary */
|
/* pixman can't do reverse blit: copy via temporary */
|
||||||
int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
|
int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
|
||||||
uint32_t *tmp = tmp_buf;
|
uint32_t *tmp = tmp_buf;
|
||||||
|
@ -852,13 +853,15 @@ static void sm501_2d_operation(SM501State *s)
|
||||||
if (tmp != tmp_buf) {
|
if (tmp != tmp_buf) {
|
||||||
g_free(tmp);
|
g_free(tmp);
|
||||||
}
|
}
|
||||||
} else {
|
} else if (!overlap && (s->use_pixman & BIT(1))) {
|
||||||
fallback = !pixman_blt((uint32_t *)&s->local_mem[src_base],
|
fallback = !pixman_blt((uint32_t *)&s->local_mem[src_base],
|
||||||
(uint32_t *)&s->local_mem[dst_base],
|
(uint32_t *)&s->local_mem[dst_base],
|
||||||
src_pitch * bypp / sizeof(uint32_t),
|
src_pitch * bypp / sizeof(uint32_t),
|
||||||
dst_pitch * bypp / sizeof(uint32_t),
|
dst_pitch * bypp / sizeof(uint32_t),
|
||||||
8 * bypp, 8 * bypp, src_x, src_y,
|
8 * bypp, 8 * bypp, src_x, src_y,
|
||||||
dst_x, dst_y, width, height);
|
dst_x, dst_y, width, height);
|
||||||
|
} else {
|
||||||
|
fallback = true;
|
||||||
}
|
}
|
||||||
if (fallback) {
|
if (fallback) {
|
||||||
uint8_t *sp = s->local_mem + src_base;
|
uint8_t *sp = s->local_mem + src_base;
|
||||||
|
@ -891,7 +894,7 @@ static void sm501_2d_operation(SM501State *s)
|
||||||
color = cpu_to_le16(color);
|
color = cpu_to_le16(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((width == 1 && height == 1) ||
|
if (!(s->use_pixman & BIT(0)) || (width == 1 && height == 1) ||
|
||||||
!pixman_fill((uint32_t *)&s->local_mem[dst_base],
|
!pixman_fill((uint32_t *)&s->local_mem[dst_base],
|
||||||
dst_pitch * bypp / sizeof(uint32_t), 8 * bypp,
|
dst_pitch * bypp / sizeof(uint32_t), 8 * bypp,
|
||||||
dst_x, dst_y, width, height, color)) {
|
dst_x, dst_y, width, height, color)) {
|
||||||
|
@ -2035,6 +2038,7 @@ static void sm501_realize_sysbus(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
static Property sm501_sysbus_properties[] = {
|
static Property sm501_sysbus_properties[] = {
|
||||||
DEFINE_PROP_UINT32("vram-size", SM501SysBusState, vram_size, 0),
|
DEFINE_PROP_UINT32("vram-size", SM501SysBusState, vram_size, 0),
|
||||||
|
DEFINE_PROP_UINT8("x-pixman", SM501SysBusState, state.use_pixman, 7),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2122,6 +2126,7 @@ static void sm501_realize_pci(PCIDevice *dev, Error **errp)
|
||||||
|
|
||||||
static Property sm501_pci_properties[] = {
|
static Property sm501_pci_properties[] = {
|
||||||
DEFINE_PROP_UINT32("vram-size", SM501PCIState, vram_size, 64 * MiB),
|
DEFINE_PROP_UINT32("vram-size", SM501PCIState, vram_size, 64 * MiB),
|
||||||
|
DEFINE_PROP_UINT8("x-pixman", SM501PCIState, state.use_pixman, 7),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -2162,11 +2167,18 @@ static void sm501_pci_class_init(ObjectClass *klass, void *data)
|
||||||
dc->vmsd = &vmstate_sm501_pci;
|
dc->vmsd = &vmstate_sm501_pci;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void sm501_pci_init(Object *o)
|
||||||
|
{
|
||||||
|
object_property_set_description(o, "x-pixman", "Use pixman for: "
|
||||||
|
"1: fill, 2: blit, 4: overlap blit");
|
||||||
|
}
|
||||||
|
|
||||||
static const TypeInfo sm501_pci_info = {
|
static const TypeInfo sm501_pci_info = {
|
||||||
.name = TYPE_PCI_SM501,
|
.name = TYPE_PCI_SM501,
|
||||||
.parent = TYPE_PCI_DEVICE,
|
.parent = TYPE_PCI_DEVICE,
|
||||||
.instance_size = sizeof(SM501PCIState),
|
.instance_size = sizeof(SM501PCIState),
|
||||||
.class_init = sm501_pci_class_init,
|
.class_init = sm501_pci_class_init,
|
||||||
|
.instance_init = sm501_pci_init,
|
||||||
.interfaces = (InterfaceInfo[]) {
|
.interfaces = (InterfaceInfo[]) {
|
||||||
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
|
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
|
||||||
{ },
|
{ },
|
||||||
|
|
|
@ -133,7 +133,7 @@ static void pic_set_irq(void *opaque, int irq, int level)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (s->elcr & mask) {
|
if (s->ltim || (s->elcr & mask)) {
|
||||||
/* level triggered */
|
/* level triggered */
|
||||||
if (level) {
|
if (level) {
|
||||||
s->irr |= mask;
|
s->irr |= mask;
|
||||||
|
@ -167,7 +167,7 @@ static void pic_intack(PICCommonState *s, int irq)
|
||||||
s->isr |= (1 << irq);
|
s->isr |= (1 << irq);
|
||||||
}
|
}
|
||||||
/* We don't clear a level sensitive interrupt here */
|
/* We don't clear a level sensitive interrupt here */
|
||||||
if (!(s->elcr & (1 << irq))) {
|
if (!s->ltim && !(s->elcr & (1 << irq))) {
|
||||||
s->irr &= ~(1 << irq);
|
s->irr &= ~(1 << irq);
|
||||||
}
|
}
|
||||||
pic_update_irq(s);
|
pic_update_irq(s);
|
||||||
|
@ -224,6 +224,7 @@ static void pic_reset(DeviceState *dev)
|
||||||
PICCommonState *s = PIC_COMMON(dev);
|
PICCommonState *s = PIC_COMMON(dev);
|
||||||
|
|
||||||
s->elcr = 0;
|
s->elcr = 0;
|
||||||
|
s->ltim = 0;
|
||||||
pic_init_reset(s);
|
pic_init_reset(s);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -243,10 +244,7 @@ static void pic_ioport_write(void *opaque, hwaddr addr64,
|
||||||
s->init_state = 1;
|
s->init_state = 1;
|
||||||
s->init4 = val & 1;
|
s->init4 = val & 1;
|
||||||
s->single_mode = val & 2;
|
s->single_mode = val & 2;
|
||||||
if (val & 0x08) {
|
s->ltim = val & 8;
|
||||||
qemu_log_mask(LOG_UNIMP,
|
|
||||||
"i8259: level sensitive irq not supported\n");
|
|
||||||
}
|
|
||||||
} else if (val & 0x08) {
|
} else if (val & 0x08) {
|
||||||
if (val & 0x04) {
|
if (val & 0x04) {
|
||||||
s->poll = 1;
|
s->poll = 1;
|
||||||
|
|
|
@ -51,7 +51,7 @@ void pic_reset_common(PICCommonState *s)
|
||||||
s->special_fully_nested_mode = 0;
|
s->special_fully_nested_mode = 0;
|
||||||
s->init4 = 0;
|
s->init4 = 0;
|
||||||
s->single_mode = 0;
|
s->single_mode = 0;
|
||||||
/* Note: ELCR is not reset */
|
/* Note: ELCR and LTIM are not reset */
|
||||||
}
|
}
|
||||||
|
|
||||||
static int pic_dispatch_pre_save(void *opaque)
|
static int pic_dispatch_pre_save(void *opaque)
|
||||||
|
@ -144,6 +144,24 @@ static void pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
|
||||||
s->special_fully_nested_mode);
|
s->special_fully_nested_mode);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static bool ltim_state_needed(void *opaque)
|
||||||
|
{
|
||||||
|
PICCommonState *s = PIC_COMMON(opaque);
|
||||||
|
|
||||||
|
return !!s->ltim;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const VMStateDescription vmstate_pic_ltim = {
|
||||||
|
.name = "i8259/ltim",
|
||||||
|
.version_id = 1,
|
||||||
|
.minimum_version_id = 1,
|
||||||
|
.needed = ltim_state_needed,
|
||||||
|
.fields = (VMStateField[]) {
|
||||||
|
VMSTATE_UINT8(ltim, PICCommonState),
|
||||||
|
VMSTATE_END_OF_LIST()
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static const VMStateDescription vmstate_pic_common = {
|
static const VMStateDescription vmstate_pic_common = {
|
||||||
.name = "i8259",
|
.name = "i8259",
|
||||||
.version_id = 1,
|
.version_id = 1,
|
||||||
|
@ -168,6 +186,10 @@ static const VMStateDescription vmstate_pic_common = {
|
||||||
VMSTATE_UINT8(single_mode, PICCommonState),
|
VMSTATE_UINT8(single_mode, PICCommonState),
|
||||||
VMSTATE_UINT8(elcr, PICCommonState),
|
VMSTATE_UINT8(elcr, PICCommonState),
|
||||||
VMSTATE_END_OF_LIST()
|
VMSTATE_END_OF_LIST()
|
||||||
|
},
|
||||||
|
.subsections = (const VMStateDescription*[]) {
|
||||||
|
&vmstate_pic_ltim,
|
||||||
|
NULL
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -439,8 +439,8 @@ static void mips_gic_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property mips_gic_properties[] = {
|
static Property mips_gic_properties[] = {
|
||||||
DEFINE_PROP_INT32("num-vp", MIPSGICState, num_vps, 1),
|
DEFINE_PROP_UINT32("num-vp", MIPSGICState, num_vps, 1),
|
||||||
DEFINE_PROP_INT32("num-irq", MIPSGICState, num_irq, 256),
|
DEFINE_PROP_UINT32("num-irq", MIPSGICState, num_irq, 256),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -47,6 +47,12 @@ static const VMStateDescription vmstate_i82378 = {
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void i82378_request_out0_irq(void *opaque, int irq, int level)
|
||||||
|
{
|
||||||
|
I82378State *s = opaque;
|
||||||
|
qemu_set_irq(s->cpu_intr, level);
|
||||||
|
}
|
||||||
|
|
||||||
static void i82378_request_pic_irq(void *opaque, int irq, int level)
|
static void i82378_request_pic_irq(void *opaque, int irq, int level)
|
||||||
{
|
{
|
||||||
DeviceState *dev = opaque;
|
DeviceState *dev = opaque;
|
||||||
|
@ -88,7 +94,9 @@ static void i82378_realize(PCIDevice *pci, Error **errp)
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* 2 82C59 (irq) */
|
/* 2 82C59 (irq) */
|
||||||
s->isa_irqs_in = i8259_init(isabus, s->cpu_intr);
|
s->isa_irqs_in = i8259_init(isabus,
|
||||||
|
qemu_allocate_irq(i82378_request_out0_irq,
|
||||||
|
s, 0));
|
||||||
isa_bus_register_input_irqs(isabus, s->isa_irqs_in);
|
isa_bus_register_input_irqs(isabus, s->isa_irqs_in);
|
||||||
|
|
||||||
/* 1 82C54 (pit) */
|
/* 1 82C54 (pit) */
|
||||||
|
|
|
@ -16,6 +16,7 @@ apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x"
|
||||||
|
|
||||||
# vt82c686.c
|
# vt82c686.c
|
||||||
via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
via_isa_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
||||||
|
via_pm_read(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
||||||
via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
via_pm_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
||||||
via_pm_io_read(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
via_pm_io_read(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
||||||
via_pm_io_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
via_pm_io_write(uint32_t addr, uint32_t val, int len) "addr 0x%x val 0x%x len 0x%x"
|
||||||
|
|
|
@ -554,7 +554,7 @@ struct ViaISAState {
|
||||||
PCIIDEState ide;
|
PCIIDEState ide;
|
||||||
UHCIState uhci[2];
|
UHCIState uhci[2];
|
||||||
ViaPMState pm;
|
ViaPMState pm;
|
||||||
PCIDevice ac97;
|
ViaAC97State ac97;
|
||||||
PCIDevice mc97;
|
PCIDevice mc97;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -598,15 +598,63 @@ void via_isa_set_irq(PCIDevice *d, int n, int level)
|
||||||
qemu_set_irq(s->isa_irqs_in[n], level);
|
qemu_set_irq(s->isa_irqs_in[n], level);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void via_isa_request_i8259_irq(void *opaque, int irq, int level)
|
||||||
|
{
|
||||||
|
ViaISAState *s = opaque;
|
||||||
|
qemu_set_irq(s->cpu_intr, level);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int via_isa_get_pci_irq(const ViaISAState *s, int irq_num)
|
||||||
|
{
|
||||||
|
switch (irq_num) {
|
||||||
|
case 0:
|
||||||
|
return s->dev.config[0x55] >> 4;
|
||||||
|
case 1:
|
||||||
|
return s->dev.config[0x56] & 0xf;
|
||||||
|
case 2:
|
||||||
|
return s->dev.config[0x56] >> 4;
|
||||||
|
case 3:
|
||||||
|
return s->dev.config[0x57] >> 4;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void via_isa_set_pci_irq(void *opaque, int irq_num, int level)
|
||||||
|
{
|
||||||
|
ViaISAState *s = opaque;
|
||||||
|
PCIBus *bus = pci_get_bus(&s->dev);
|
||||||
|
int i, pic_level, pic_irq = via_isa_get_pci_irq(s, irq_num);
|
||||||
|
|
||||||
|
/* IRQ 0: disabled, IRQ 2,8,13: reserved */
|
||||||
|
if (!pic_irq) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (unlikely(pic_irq == 2 || pic_irq == 8 || pic_irq == 13)) {
|
||||||
|
qemu_log_mask(LOG_GUEST_ERROR, "Invalid ISA IRQ routing");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* The pic level is the logical OR of all the PCI irqs mapped to it. */
|
||||||
|
pic_level = 0;
|
||||||
|
for (i = 0; i < PCI_NUM_PINS; i++) {
|
||||||
|
if (pic_irq == via_isa_get_pci_irq(s, i)) {
|
||||||
|
pic_level |= pci_bus_get_irq_level(bus, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/* Now we change the pic irq level according to the via irq mappings. */
|
||||||
|
qemu_set_irq(s->isa_irqs_in[pic_irq], pic_level);
|
||||||
|
}
|
||||||
|
|
||||||
static void via_isa_realize(PCIDevice *d, Error **errp)
|
static void via_isa_realize(PCIDevice *d, Error **errp)
|
||||||
{
|
{
|
||||||
ViaISAState *s = VIA_ISA(d);
|
ViaISAState *s = VIA_ISA(d);
|
||||||
DeviceState *dev = DEVICE(d);
|
DeviceState *dev = DEVICE(d);
|
||||||
PCIBus *pci_bus = pci_get_bus(d);
|
PCIBus *pci_bus = pci_get_bus(d);
|
||||||
|
qemu_irq *isa_irq;
|
||||||
ISABus *isa_bus;
|
ISABus *isa_bus;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
qdev_init_gpio_out(dev, &s->cpu_intr, 1);
|
qdev_init_gpio_out(dev, &s->cpu_intr, 1);
|
||||||
|
isa_irq = qemu_allocate_irqs(via_isa_request_i8259_irq, s, 1);
|
||||||
isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
|
isa_bus = isa_bus_new(dev, pci_address_space(d), pci_address_space_io(d),
|
||||||
errp);
|
errp);
|
||||||
|
|
||||||
|
@ -614,11 +662,13 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
s->isa_irqs_in = i8259_init(isa_bus, s->cpu_intr);
|
s->isa_irqs_in = i8259_init(isa_bus, *isa_irq);
|
||||||
isa_bus_register_input_irqs(isa_bus, s->isa_irqs_in);
|
isa_bus_register_input_irqs(isa_bus, s->isa_irqs_in);
|
||||||
i8254_pit_init(isa_bus, 0x40, 0, NULL);
|
i8254_pit_init(isa_bus, 0x40, 0, NULL);
|
||||||
i8257_dma_init(isa_bus, 0);
|
i8257_dma_init(isa_bus, 0);
|
||||||
|
|
||||||
|
qdev_init_gpio_in_named(dev, via_isa_set_pci_irq, "pirq", PCI_NUM_PINS);
|
||||||
|
|
||||||
/* RTC */
|
/* RTC */
|
||||||
qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000);
|
qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000);
|
||||||
if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {
|
if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {
|
||||||
|
|
|
@ -702,7 +702,7 @@ static void boston_mach_init(MachineState *machine)
|
||||||
object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_MIPS_CPS);
|
object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_MIPS_CPS);
|
||||||
object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type,
|
object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type,
|
||||||
&error_fatal);
|
&error_fatal);
|
||||||
object_property_set_int(OBJECT(&s->cps), "num-vp", machine->smp.cpus,
|
object_property_set_uint(OBJECT(&s->cps), "num-vp", machine->smp.cpus,
|
||||||
&error_fatal);
|
&error_fatal);
|
||||||
qdev_connect_clock_in(DEVICE(&s->cps), "clk-in",
|
qdev_connect_clock_in(DEVICE(&s->cps), "clk-in",
|
||||||
qdev_get_clock_out(dev, "cpu-refclk"));
|
qdev_get_clock_out(dev, "cpu-refclk"));
|
||||||
|
|
|
@ -66,20 +66,17 @@ static bool cpu_mips_itu_supported(CPUMIPSState *env)
|
||||||
static void mips_cps_realize(DeviceState *dev, Error **errp)
|
static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
MIPSCPSState *s = MIPS_CPS(dev);
|
MIPSCPSState *s = MIPS_CPS(dev);
|
||||||
CPUMIPSState *env;
|
|
||||||
MIPSCPU *cpu;
|
|
||||||
int i;
|
|
||||||
target_ulong gcr_base;
|
target_ulong gcr_base;
|
||||||
bool itu_present = false;
|
bool itu_present = false;
|
||||||
bool saar_present = false;
|
|
||||||
|
|
||||||
if (!clock_get(s->clock)) {
|
if (!clock_get(s->clock)) {
|
||||||
error_setg(errp, "CPS input clock is not connected to an output clock");
|
error_setg(errp, "CPS input clock is not connected to an output clock");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < s->num_vp; i++) {
|
for (int i = 0; i < s->num_vp; i++) {
|
||||||
cpu = MIPS_CPU(object_new(s->cpu_type));
|
MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
|
||||||
|
CPUMIPSState *env = &cpu->env;
|
||||||
|
|
||||||
/* All VPs are halted on reset. Leave powering up to CPC. */
|
/* All VPs are halted on reset. Leave powering up to CPC. */
|
||||||
if (!object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
|
if (!object_property_set_bool(OBJECT(cpu), "start-powered-off", true,
|
||||||
|
@ -97,7 +94,6 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
cpu_mips_irq_init_cpu(cpu);
|
cpu_mips_irq_init_cpu(cpu);
|
||||||
cpu_mips_clock_init(cpu);
|
cpu_mips_clock_init(cpu);
|
||||||
|
|
||||||
env = &cpu->env;
|
|
||||||
if (cpu_mips_itu_supported(env)) {
|
if (cpu_mips_itu_supported(env)) {
|
||||||
itu_present = true;
|
itu_present = true;
|
||||||
/* Attach ITC Tag to the VP */
|
/* Attach ITC Tag to the VP */
|
||||||
|
@ -107,22 +103,15 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
qemu_register_reset(main_cpu_reset, cpu);
|
qemu_register_reset(main_cpu_reset, cpu);
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu = MIPS_CPU(first_cpu);
|
|
||||||
env = &cpu->env;
|
|
||||||
saar_present = (bool)env->saarp;
|
|
||||||
|
|
||||||
/* Inter-Thread Communication Unit */
|
/* Inter-Thread Communication Unit */
|
||||||
if (itu_present) {
|
if (itu_present) {
|
||||||
object_initialize_child(OBJECT(dev), "itu", &s->itu, TYPE_MIPS_ITU);
|
object_initialize_child(OBJECT(dev), "itu", &s->itu, TYPE_MIPS_ITU);
|
||||||
object_property_set_int(OBJECT(&s->itu), "num-fifo", 16,
|
object_property_set_link(OBJECT(&s->itu), "cpu[0]",
|
||||||
|
OBJECT(first_cpu), &error_abort);
|
||||||
|
object_property_set_uint(OBJECT(&s->itu), "num-fifo", 16,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
object_property_set_int(OBJECT(&s->itu), "num-semaphores", 16,
|
object_property_set_uint(OBJECT(&s->itu), "num-semaphores", 16,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
object_property_set_bool(OBJECT(&s->itu), "saar-present", saar_present,
|
|
||||||
&error_abort);
|
|
||||||
if (saar_present) {
|
|
||||||
s->itu.saar = &env->CP0_SAAR;
|
|
||||||
}
|
|
||||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->itu), errp)) {
|
if (!sysbus_realize(SYS_BUS_DEVICE(&s->itu), errp)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -133,7 +122,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
/* Cluster Power Controller */
|
/* Cluster Power Controller */
|
||||||
object_initialize_child(OBJECT(dev), "cpc", &s->cpc, TYPE_MIPS_CPC);
|
object_initialize_child(OBJECT(dev), "cpc", &s->cpc, TYPE_MIPS_CPC);
|
||||||
object_property_set_int(OBJECT(&s->cpc), "num-vp", s->num_vp,
|
object_property_set_uint(OBJECT(&s->cpc), "num-vp", s->num_vp,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1,
|
object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
|
@ -146,9 +135,9 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
|
|
||||||
/* Global Interrupt Controller */
|
/* Global Interrupt Controller */
|
||||||
object_initialize_child(OBJECT(dev), "gic", &s->gic, TYPE_MIPS_GIC);
|
object_initialize_child(OBJECT(dev), "gic", &s->gic, TYPE_MIPS_GIC);
|
||||||
object_property_set_int(OBJECT(&s->gic), "num-vp", s->num_vp,
|
object_property_set_uint(OBJECT(&s->gic), "num-vp", s->num_vp,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
object_property_set_int(OBJECT(&s->gic), "num-irq", 128,
|
object_property_set_uint(OBJECT(&s->gic), "num-irq", 128,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
|
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
|
||||||
return;
|
return;
|
||||||
|
@ -158,10 +147,10 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
|
||||||
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0));
|
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0));
|
||||||
|
|
||||||
/* Global Configuration Registers */
|
/* Global Configuration Registers */
|
||||||
gcr_base = env->CP0_CMGCRBase << 4;
|
gcr_base = MIPS_CPU(first_cpu)->env.CP0_CMGCRBase << 4;
|
||||||
|
|
||||||
object_initialize_child(OBJECT(dev), "gcr", &s->gcr, TYPE_MIPS_GCR);
|
object_initialize_child(OBJECT(dev), "gcr", &s->gcr, TYPE_MIPS_GCR);
|
||||||
object_property_set_int(OBJECT(&s->gcr), "num-vp", s->num_vp,
|
object_property_set_uint(OBJECT(&s->gcr), "num-vp", s->num_vp,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
object_property_set_int(OBJECT(&s->gcr), "gcr-rev", 0x800,
|
object_property_set_int(OBJECT(&s->gcr), "gcr-rev", 0x800,
|
||||||
&error_abort);
|
&error_abort);
|
||||||
|
|
|
@ -1066,7 +1066,7 @@ static void create_cps(MachineState *ms, MaltaState *s,
|
||||||
object_initialize_child(OBJECT(s), "cps", &s->cps, TYPE_MIPS_CPS);
|
object_initialize_child(OBJECT(s), "cps", &s->cps, TYPE_MIPS_CPS);
|
||||||
object_property_set_str(OBJECT(&s->cps), "cpu-type", ms->cpu_type,
|
object_property_set_str(OBJECT(&s->cps), "cpu-type", ms->cpu_type,
|
||||||
&error_fatal);
|
&error_fatal);
|
||||||
object_property_set_int(OBJECT(&s->cps), "num-vp", ms->smp.cpus,
|
object_property_set_uint(OBJECT(&s->cps), "num-vp", ms->smp.cpus,
|
||||||
&error_fatal);
|
&error_fatal);
|
||||||
qdev_connect_clock_in(DEVICE(&s->cps), "clk-in", s->cpuclk);
|
qdev_connect_clock_in(DEVICE(&s->cps), "clk-in", s->cpuclk);
|
||||||
sysbus_realize(SYS_BUS_DEVICE(&s->cps), &error_fatal);
|
sysbus_realize(SYS_BUS_DEVICE(&s->cps), &error_fatal);
|
||||||
|
|
|
@ -212,7 +212,7 @@ static const VMStateDescription vmstate_mips_gcr = {
|
||||||
};
|
};
|
||||||
|
|
||||||
static Property mips_gcr_properties[] = {
|
static Property mips_gcr_properties[] = {
|
||||||
DEFINE_PROP_INT32("num-vp", MIPSGCRState, num_vps, 1),
|
DEFINE_PROP_UINT32("num-vp", MIPSGCRState, num_vps, 1),
|
||||||
DEFINE_PROP_INT32("gcr-rev", MIPSGCRState, gcr_rev, 0x800),
|
DEFINE_PROP_INT32("gcr-rev", MIPSGCRState, gcr_rev, 0x800),
|
||||||
DEFINE_PROP_UINT64("gcr-base", MIPSGCRState, gcr_base, GCR_BASE_ADDR),
|
DEFINE_PROP_UINT64("gcr-base", MIPSGCRState, gcr_base, GCR_BASE_ADDR),
|
||||||
DEFINE_PROP_LINK("gic", MIPSGCRState, gic_mr, TYPE_MEMORY_REGION,
|
DEFINE_PROP_LINK("gic", MIPSGCRState, gic_mr, TYPE_MEMORY_REGION,
|
||||||
|
|
|
@ -93,10 +93,10 @@ void itc_reconfigure(MIPSITUState *tag)
|
||||||
uint64_t size = (1 * KiB) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
|
uint64_t size = (1 * KiB) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
|
||||||
bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;
|
bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;
|
||||||
|
|
||||||
if (tag->saar_present) {
|
if (tag->saar) {
|
||||||
address = ((*(uint64_t *) tag->saar) & 0xFFFFFFFFE000ULL) << 4;
|
address = (tag->saar[0] & 0xFFFFFFFFE000ULL) << 4;
|
||||||
size = 1ULL << ((*(uint64_t *) tag->saar >> 1) & 0x1f);
|
size = 1ULL << ((tag->saar[0] >> 1) & 0x1f);
|
||||||
is_enabled = *(uint64_t *) tag->saar & 1;
|
is_enabled = tag->saar[0] & 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
memory_region_transaction_begin();
|
memory_region_transaction_begin();
|
||||||
|
@ -157,7 +157,7 @@ static inline ITCView get_itc_view(hwaddr addr)
|
||||||
static inline int get_cell_stride_shift(const MIPSITUState *s)
|
static inline int get_cell_stride_shift(const MIPSITUState *s)
|
||||||
{
|
{
|
||||||
/* Minimum interval (for EntryGain = 0) is 128 B */
|
/* Minimum interval (for EntryGain = 0) is 128 B */
|
||||||
if (s->saar_present) {
|
if (s->saar) {
|
||||||
return 7 + ((s->icr0 >> ITC_ICR0_BLK_GRAIN) &
|
return 7 + ((s->icr0 >> ITC_ICR0_BLK_GRAIN) &
|
||||||
ITC_ICR0_BLK_GRAIN_MASK);
|
ITC_ICR0_BLK_GRAIN_MASK);
|
||||||
} else {
|
} else {
|
||||||
|
@ -515,6 +515,7 @@ static void mips_itu_init(Object *obj)
|
||||||
static void mips_itu_realize(DeviceState *dev, Error **errp)
|
static void mips_itu_realize(DeviceState *dev, Error **errp)
|
||||||
{
|
{
|
||||||
MIPSITUState *s = MIPS_ITU(dev);
|
MIPSITUState *s = MIPS_ITU(dev);
|
||||||
|
CPUMIPSState *env;
|
||||||
|
|
||||||
if (s->num_fifo > ITC_FIFO_NUM_MAX) {
|
if (s->num_fifo > ITC_FIFO_NUM_MAX) {
|
||||||
error_setg(errp, "Exceed maximum number of FIFO cells: %d",
|
error_setg(errp, "Exceed maximum number of FIFO cells: %d",
|
||||||
|
@ -526,6 +527,15 @@ static void mips_itu_realize(DeviceState *dev, Error **errp)
|
||||||
s->num_semaphores);
|
s->num_semaphores);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
if (!s->cpu0) {
|
||||||
|
error_setg(errp, "Missing 'cpu[0]' property");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
env = &s->cpu0->env;
|
||||||
|
if (env->saarp) {
|
||||||
|
s->saar = env->CP0_SAAR;
|
||||||
|
}
|
||||||
|
|
||||||
s->cell = g_new(ITCStorageCell, get_num_cells(s));
|
s->cell = g_new(ITCStorageCell, get_num_cells(s));
|
||||||
}
|
}
|
||||||
|
@ -534,8 +544,8 @@ static void mips_itu_reset(DeviceState *dev)
|
||||||
{
|
{
|
||||||
MIPSITUState *s = MIPS_ITU(dev);
|
MIPSITUState *s = MIPS_ITU(dev);
|
||||||
|
|
||||||
if (s->saar_present) {
|
if (s->saar) {
|
||||||
*(uint64_t *) s->saar = 0x11 << 1;
|
s->saar[0] = 0x11 << 1;
|
||||||
s->icr0 = get_num_cells(s) << ITC_ICR0_CELL_NUM;
|
s->icr0 = get_num_cells(s) << ITC_ICR0_CELL_NUM;
|
||||||
} else {
|
} else {
|
||||||
s->ITCAddressMap[0] = 0;
|
s->ITCAddressMap[0] = 0;
|
||||||
|
@ -549,11 +559,11 @@ static void mips_itu_reset(DeviceState *dev)
|
||||||
}
|
}
|
||||||
|
|
||||||
static Property mips_itu_properties[] = {
|
static Property mips_itu_properties[] = {
|
||||||
DEFINE_PROP_INT32("num-fifo", MIPSITUState, num_fifo,
|
DEFINE_PROP_UINT32("num-fifo", MIPSITUState, num_fifo,
|
||||||
ITC_FIFO_NUM_MAX),
|
ITC_FIFO_NUM_MAX),
|
||||||
DEFINE_PROP_INT32("num-semaphores", MIPSITUState, num_semaphores,
|
DEFINE_PROP_UINT32("num-semaphores", MIPSITUState, num_semaphores,
|
||||||
ITC_SEMAPH_NUM_MAX),
|
ITC_SEMAPH_NUM_MAX),
|
||||||
DEFINE_PROP_BOOL("saar-present", MIPSITUState, saar_present, false),
|
DEFINE_PROP_LINK("cpu[0]", MIPSITUState, cpu0, TYPE_MIPS_CPU, MIPSCPU *),
|
||||||
DEFINE_PROP_END_OF_LIST(),
|
DEFINE_PROP_END_OF_LIST(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -873,10 +873,6 @@ static void mv64361_realize(DeviceState *dev, Error **errp)
|
||||||
}
|
}
|
||||||
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
|
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
|
||||||
qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
|
qdev_init_gpio_in_named(dev, mv64361_gpp_irq, "gpp", 32);
|
||||||
/* FIXME: PCI IRQ connections may be board specific */
|
|
||||||
for (i = 0; i < PCI_NUM_PINS; i++) {
|
|
||||||
s->pci[1].irq[i] = qdev_get_gpio_in_named(dev, "gpp", 12 + i);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void mv64361_reset(DeviceState *dev)
|
static void mv64361_reset(DeviceState *dev)
|
||||||
|
|
|
@ -73,6 +73,8 @@ struct Pegasos2MachineState {
|
||||||
MachineState parent_obj;
|
MachineState parent_obj;
|
||||||
PowerPCCPU *cpu;
|
PowerPCCPU *cpu;
|
||||||
DeviceState *mv;
|
DeviceState *mv;
|
||||||
|
qemu_irq mv_pirq[PCI_NUM_PINS];
|
||||||
|
qemu_irq via_pirq[PCI_NUM_PINS];
|
||||||
Vof *vof;
|
Vof *vof;
|
||||||
void *fdt_blob;
|
void *fdt_blob;
|
||||||
uint64_t kernel_addr;
|
uint64_t kernel_addr;
|
||||||
|
@ -95,6 +97,15 @@ static void pegasos2_cpu_reset(void *opaque)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void pegasos2_pci_irq(void *opaque, int n, int level)
|
||||||
|
{
|
||||||
|
Pegasos2MachineState *pm = opaque;
|
||||||
|
|
||||||
|
/* PCI interrupt lines are connected to both MV64361 and VT8231 */
|
||||||
|
qemu_set_irq(pm->mv_pirq[n], level);
|
||||||
|
qemu_set_irq(pm->via_pirq[n], level);
|
||||||
|
}
|
||||||
|
|
||||||
static void pegasos2_init(MachineState *machine)
|
static void pegasos2_init(MachineState *machine)
|
||||||
{
|
{
|
||||||
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
|
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
|
||||||
|
@ -106,7 +117,7 @@ static void pegasos2_init(MachineState *machine)
|
||||||
I2CBus *i2c_bus;
|
I2CBus *i2c_bus;
|
||||||
const char *fwname = machine->firmware ?: PROM_FILENAME;
|
const char *fwname = machine->firmware ?: PROM_FILENAME;
|
||||||
char *filename;
|
char *filename;
|
||||||
int sz;
|
int i, sz;
|
||||||
uint8_t *spd_data;
|
uint8_t *spd_data;
|
||||||
|
|
||||||
/* init CPU */
|
/* init CPU */
|
||||||
|
@ -156,11 +167,18 @@ static void pegasos2_init(MachineState *machine)
|
||||||
/* Marvell Discovery II system controller */
|
/* Marvell Discovery II system controller */
|
||||||
pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
|
pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
|
||||||
qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
|
qdev_get_gpio_in(DEVICE(pm->cpu), PPC6xx_INPUT_INT)));
|
||||||
|
for (i = 0; i < PCI_NUM_PINS; i++) {
|
||||||
|
pm->mv_pirq[i] = qdev_get_gpio_in_named(pm->mv, "gpp", 12 + i);
|
||||||
|
}
|
||||||
pci_bus = mv64361_get_pci_bus(pm->mv, 1);
|
pci_bus = mv64361_get_pci_bus(pm->mv, 1);
|
||||||
|
pci_bus_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
|
||||||
|
|
||||||
/* VIA VT8231 South Bridge (multifunction PCI device) */
|
/* VIA VT8231 South Bridge (multifunction PCI device) */
|
||||||
via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
|
via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
|
||||||
true, TYPE_VT8231_ISA));
|
true, TYPE_VT8231_ISA));
|
||||||
|
for (i = 0; i < PCI_NUM_PINS; i++) {
|
||||||
|
pm->via_pirq[i] = qdev_get_gpio_in_named(DEVICE(via), "pirq", i);
|
||||||
|
}
|
||||||
object_property_add_alias(OBJECT(machine), "rtc-time",
|
object_property_add_alias(OBJECT(machine), "rtc-time",
|
||||||
object_resolve_path_component(via, "rtc"),
|
object_resolve_path_component(via, "rtc"),
|
||||||
"date");
|
"date");
|
||||||
|
@ -267,6 +285,12 @@ static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
|
||||||
PCI_INTERRUPT_LINE, 2, 0x9);
|
PCI_INTERRUPT_LINE, 2, 0x9);
|
||||||
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
|
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
|
||||||
0x50, 1, 0x2);
|
0x50, 1, 0x2);
|
||||||
|
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
|
||||||
|
0x55, 1, 0x90);
|
||||||
|
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
|
||||||
|
0x56, 1, 0x99);
|
||||||
|
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
|
||||||
|
0x57, 1, 0x90);
|
||||||
|
|
||||||
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
|
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 1) << 8) |
|
||||||
PCI_INTERRUPT_LINE, 2, 0x109);
|
PCI_INTERRUPT_LINE, 2, 0x109);
|
||||||
|
|
|
@ -1410,6 +1410,18 @@ static void ohci_set_hub_status(OHCIState *ohci, uint32_t val)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* This is the one state transition the controller can do by itself */
|
||||||
|
static bool ohci_resume(OHCIState *s)
|
||||||
|
{
|
||||||
|
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
|
||||||
|
trace_usb_ohci_remote_wakeup(s->name);
|
||||||
|
s->ctl &= ~OHCI_CTL_HCFS;
|
||||||
|
s->ctl |= OHCI_USB_RESUME;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Sets a flag in a port status reg but only set it if the port is connected.
|
* Sets a flag in a port status reg but only set it if the port is connected.
|
||||||
* If not set ConnectStatusChange flag. If flag is enabled return 1.
|
* If not set ConnectStatusChange flag. If flag is enabled return 1.
|
||||||
|
@ -1426,7 +1438,10 @@ static int ohci_port_set_if_connected(OHCIState *ohci, int i, uint32_t val)
|
||||||
if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
|
if (!(ohci->rhport[i].ctrl & OHCI_PORT_CCS)) {
|
||||||
ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
|
ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
|
||||||
if (ohci->rhstatus & OHCI_RHS_DRWE) {
|
if (ohci->rhstatus & OHCI_RHS_DRWE) {
|
||||||
/* TODO: CSC is a wakeup event */
|
/* CSC is a wakeup event */
|
||||||
|
if (ohci_resume(ohci)) {
|
||||||
|
ohci_set_interrupt(ohci, OHCI_INTR_RD);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1828,11 +1843,7 @@ static void ohci_wakeup(USBPort *port1)
|
||||||
intr = OHCI_INTR_RHSC;
|
intr = OHCI_INTR_RHSC;
|
||||||
}
|
}
|
||||||
/* Note that the controller can be suspended even if this port is not */
|
/* Note that the controller can be suspended even if this port is not */
|
||||||
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
|
if (ohci_resume(s)) {
|
||||||
trace_usb_ohci_remote_wakeup(s->name);
|
|
||||||
/* This is the one state transition the controller can do by itself */
|
|
||||||
s->ctl &= ~OHCI_CTL_HCFS;
|
|
||||||
s->ctl |= OHCI_USB_RESUME;
|
|
||||||
/*
|
/*
|
||||||
* In suspend mode only ResumeDetected is possible, not RHSC:
|
* In suspend mode only ResumeDetected is possible, not RHSC:
|
||||||
* see the OHCI spec 5.1.2.3.
|
* see the OHCI spec 5.1.2.3.
|
||||||
|
|
|
@ -1,17 +1,7 @@
|
||||||
#include "qemu/osdep.h"
|
#include "qemu/osdep.h"
|
||||||
#include "hw/irq.h"
|
|
||||||
#include "hw/isa/vt82c686.h"
|
#include "hw/isa/vt82c686.h"
|
||||||
#include "hcd-uhci.h"
|
#include "hcd-uhci.h"
|
||||||
|
|
||||||
static void uhci_isa_set_irq(void *opaque, int irq_num, int level)
|
|
||||||
{
|
|
||||||
UHCIState *s = opaque;
|
|
||||||
uint8_t irq = pci_get_byte(s->dev.config + PCI_INTERRUPT_LINE);
|
|
||||||
if (irq > 0 && irq < 15) {
|
|
||||||
via_isa_set_irq(pci_get_function_0(&s->dev), irq, level);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
|
static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
|
||||||
{
|
{
|
||||||
UHCIState *s = UHCI(dev);
|
UHCIState *s = UHCI(dev);
|
||||||
|
@ -25,8 +15,6 @@ static void usb_uhci_vt82c686b_realize(PCIDevice *dev, Error **errp)
|
||||||
pci_set_long(pci_conf + 0xc0, 0x00002000);
|
pci_set_long(pci_conf + 0xc0, 0x00002000);
|
||||||
|
|
||||||
usb_uhci_common_realize(dev, errp);
|
usb_uhci_common_realize(dev, errp);
|
||||||
object_unref(s->irq);
|
|
||||||
s->irq = qemu_allocate_irq(uhci_isa_set_irq, s, 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static UHCIInfo uhci_info[] = {
|
static UHCIInfo uhci_info[] = {
|
||||||
|
|
|
@ -211,8 +211,8 @@ struct MIPSGICState {
|
||||||
/* GIC VP Timer */
|
/* GIC VP Timer */
|
||||||
MIPSGICTimerState *gic_timer;
|
MIPSGICTimerState *gic_timer;
|
||||||
|
|
||||||
int32_t num_vps;
|
uint32_t num_vps;
|
||||||
int32_t num_irq;
|
uint32_t num_irq;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif /* MIPS_GIC_H */
|
#endif /* MIPS_GIC_H */
|
||||||
|
|
|
@ -61,6 +61,7 @@ struct PICCommonState {
|
||||||
uint8_t single_mode; /* true if slave pic is not initialized */
|
uint8_t single_mode; /* true if slave pic is not initialized */
|
||||||
uint8_t elcr; /* PIIX edge/trigger selection*/
|
uint8_t elcr; /* PIIX edge/trigger selection*/
|
||||||
uint8_t elcr_mask;
|
uint8_t elcr_mask;
|
||||||
|
uint8_t ltim; /* Edge/Level Bank Select (pre-PIIX, chip-wide) */
|
||||||
qemu_irq int_out[1];
|
qemu_irq int_out[1];
|
||||||
uint32_t master; /* reflects /SP input pin */
|
uint32_t master; /* reflects /SP input pin */
|
||||||
uint32_t iobase;
|
uint32_t iobase;
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
#ifndef HW_VT82C686_H
|
#ifndef HW_VT82C686_H
|
||||||
#define HW_VT82C686_H
|
#define HW_VT82C686_H
|
||||||
|
|
||||||
|
#include "hw/pci/pci_device.h"
|
||||||
|
#include "audio/audio.h"
|
||||||
|
|
||||||
#define TYPE_VT82C686B_ISA "vt82c686b-isa"
|
#define TYPE_VT82C686B_ISA "vt82c686b-isa"
|
||||||
#define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci"
|
#define TYPE_VT82C686B_USB_UHCI "vt82c686b-usb-uhci"
|
||||||
|
@ -9,6 +11,29 @@
|
||||||
#define TYPE_VIA_IDE "via-ide"
|
#define TYPE_VIA_IDE "via-ide"
|
||||||
#define TYPE_VIA_MC97 "via-mc97"
|
#define TYPE_VIA_MC97 "via-mc97"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint8_t stat;
|
||||||
|
uint8_t type;
|
||||||
|
uint32_t base;
|
||||||
|
uint32_t curr;
|
||||||
|
uint32_t addr;
|
||||||
|
uint32_t clen;
|
||||||
|
} ViaAC97SGDChannel;
|
||||||
|
|
||||||
|
OBJECT_DECLARE_SIMPLE_TYPE(ViaAC97State, VIA_AC97);
|
||||||
|
|
||||||
|
struct ViaAC97State {
|
||||||
|
PCIDevice dev;
|
||||||
|
QEMUSoundCard card;
|
||||||
|
MemoryRegion sgd;
|
||||||
|
MemoryRegion fm;
|
||||||
|
MemoryRegion midi;
|
||||||
|
SWVoiceOut *vo;
|
||||||
|
ViaAC97SGDChannel aur;
|
||||||
|
uint16_t codec_regs[128];
|
||||||
|
uint32_t ac97_cmd;
|
||||||
|
};
|
||||||
|
|
||||||
void via_isa_set_irq(PCIDevice *d, int n, int level);
|
void via_isa_set_irq(PCIDevice *d, int n, int level);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -75,7 +75,7 @@ struct MIPSGCRState {
|
||||||
SysBusDevice parent_obj;
|
SysBusDevice parent_obj;
|
||||||
|
|
||||||
int32_t gcr_rev;
|
int32_t gcr_rev;
|
||||||
int32_t num_vps;
|
uint32_t num_vps;
|
||||||
hwaddr gcr_base;
|
hwaddr gcr_base;
|
||||||
MemoryRegion iomem;
|
MemoryRegion iomem;
|
||||||
MemoryRegion *cpc_mr;
|
MemoryRegion *cpc_mr;
|
||||||
|
|
|
@ -57,8 +57,8 @@ struct MIPSITUState {
|
||||||
SysBusDevice parent_obj;
|
SysBusDevice parent_obj;
|
||||||
/*< public >*/
|
/*< public >*/
|
||||||
|
|
||||||
int32_t num_fifo;
|
uint32_t num_fifo;
|
||||||
int32_t num_semaphores;
|
uint32_t num_semaphores;
|
||||||
|
|
||||||
/* ITC Storage */
|
/* ITC Storage */
|
||||||
ITCStorageCell *cell;
|
ITCStorageCell *cell;
|
||||||
|
@ -72,9 +72,8 @@ struct MIPSITUState {
|
||||||
uint64_t icr0;
|
uint64_t icr0;
|
||||||
|
|
||||||
/* SAAR */
|
/* SAAR */
|
||||||
bool saar_present;
|
uint64_t *saar;
|
||||||
void *saar;
|
MIPSCPU *cpu0;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* Get ITC Configuration Tag memory region. */
|
/* Get ITC Configuration Tag memory region. */
|
||||||
|
|
|
@ -1126,15 +1126,21 @@ GString *ram_block_format(void)
|
||||||
GString *buf = g_string_new("");
|
GString *buf = g_string_new("");
|
||||||
|
|
||||||
RCU_READ_LOCK_GUARD();
|
RCU_READ_LOCK_GUARD();
|
||||||
g_string_append_printf(buf, "%24s %8s %18s %18s %18s\n",
|
g_string_append_printf(buf, "%24s %8s %18s %18s %18s %18s %3s\n",
|
||||||
"Block Name", "PSize", "Offset", "Used", "Total");
|
"Block Name", "PSize", "Offset", "Used", "Total",
|
||||||
|
"HVA", "RO");
|
||||||
|
|
||||||
RAMBLOCK_FOREACH(block) {
|
RAMBLOCK_FOREACH(block) {
|
||||||
psize = size_to_str(block->page_size);
|
psize = size_to_str(block->page_size);
|
||||||
g_string_append_printf(buf, "%24s %8s 0x%016" PRIx64 " 0x%016" PRIx64
|
g_string_append_printf(buf, "%24s %8s 0x%016" PRIx64 " 0x%016" PRIx64
|
||||||
" 0x%016" PRIx64 "\n", block->idstr, psize,
|
" 0x%016" PRIx64 " 0x%016" PRIx64 " %3s\n",
|
||||||
|
block->idstr, psize,
|
||||||
(uint64_t)block->offset,
|
(uint64_t)block->offset,
|
||||||
(uint64_t)block->used_length,
|
(uint64_t)block->used_length,
|
||||||
(uint64_t)block->max_length);
|
(uint64_t)block->max_length,
|
||||||
|
(uint64_t)(uintptr_t)block->host,
|
||||||
|
block->mr->readonly ? "ro" : "rw");
|
||||||
|
|
||||||
g_free(psize);
|
g_free(psize);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -332,7 +332,11 @@ const mips_def_t mips_defs[] =
|
||||||
(0x1 << CP0C0_AR) | (MMU_TYPE_FMT << CP0C0_MT),
|
(0x1 << CP0C0_AR) | (MMU_TYPE_FMT << CP0C0_MT),
|
||||||
.CP0_Config1 = MIPS_CONFIG1,
|
.CP0_Config1 = MIPS_CONFIG1,
|
||||||
.CP0_Config2 = MIPS_CONFIG2,
|
.CP0_Config2 = MIPS_CONFIG2,
|
||||||
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (1 << CP0C3_VInt),
|
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (1 << CP0C3_VInt) |
|
||||||
|
(1 << CP0C3_M),
|
||||||
|
.CP0_Config4 = MIPS_CONFIG4 | (1 << CP0C4_M),
|
||||||
|
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_NFExists),
|
||||||
|
.CP0_Config7 = 1 << CP0C7_WII,
|
||||||
.CP0_LLAddr_rw_bitmask = 0,
|
.CP0_LLAddr_rw_bitmask = 0,
|
||||||
.CP0_LLAddr_shift = 4,
|
.CP0_LLAddr_shift = 4,
|
||||||
.SYNCI_Step = 32,
|
.SYNCI_Step = 32,
|
||||||
|
@ -353,7 +357,11 @@ const mips_def_t mips_defs[] =
|
||||||
(0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
|
(0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
|
||||||
(0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
|
(0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
|
||||||
.CP0_Config2 = MIPS_CONFIG2,
|
.CP0_Config2 = MIPS_CONFIG2,
|
||||||
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (0 << CP0C3_VInt),
|
.CP0_Config3 = MIPS_CONFIG3 | (0x2 << CP0C3_ISA) | (0 << CP0C3_VInt) |
|
||||||
|
(1 << CP0C3_M),
|
||||||
|
.CP0_Config4 = MIPS_CONFIG4 | (1 << CP0C4_M),
|
||||||
|
.CP0_Config5 = MIPS_CONFIG5 | (1 << CP0C5_NFExists),
|
||||||
|
.CP0_Config7 = 1 << CP0C7_WII,
|
||||||
.CP0_LLAddr_rw_bitmask = 0,
|
.CP0_LLAddr_rw_bitmask = 0,
|
||||||
.CP0_LLAddr_shift = 4,
|
.CP0_LLAddr_shift = 4,
|
||||||
.SYNCI_Step = 32,
|
.SYNCI_Step = 32,
|
||||||
|
@ -392,6 +400,7 @@ const mips_def_t mips_defs[] =
|
||||||
.CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) |
|
.CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) |
|
||||||
(1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) |
|
(1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) |
|
||||||
(1 << CP0C5_FRE) | (1 << CP0C5_UFR),
|
(1 << CP0C5_FRE) | (1 << CP0C5_UFR),
|
||||||
|
.CP0_Config7 = 1 << CP0C7_WII,
|
||||||
.CP0_LLAddr_rw_bitmask = 0,
|
.CP0_LLAddr_rw_bitmask = 0,
|
||||||
.CP0_LLAddr_shift = 0,
|
.CP0_LLAddr_shift = 0,
|
||||||
.SYNCI_Step = 32,
|
.SYNCI_Step = 32,
|
||||||
|
|
|
@ -143,11 +143,13 @@ static bool mips_cpu_has_work(CPUState *cs)
|
||||||
/*
|
/*
|
||||||
* Prior to MIPS Release 6 it is implementation dependent if non-enabled
|
* Prior to MIPS Release 6 it is implementation dependent if non-enabled
|
||||||
* interrupts wake-up the CPU, however most of the implementations only
|
* interrupts wake-up the CPU, however most of the implementations only
|
||||||
* check for interrupts that can be taken.
|
* check for interrupts that can be taken. For pre-release 6 CPUs,
|
||||||
|
* check for CP0 Config7 'Wait IE ignore' bit.
|
||||||
*/
|
*/
|
||||||
if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
if ((cs->interrupt_request & CPU_INTERRUPT_HARD) &&
|
||||||
cpu_mips_hw_interrupts_pending(env)) {
|
cpu_mips_hw_interrupts_pending(env)) {
|
||||||
if (cpu_mips_hw_interrupts_enabled(env) ||
|
if (cpu_mips_hw_interrupts_enabled(env) ||
|
||||||
|
(env->CP0_Config7 & (1 << CP0C7_WII)) ||
|
||||||
(env->insn_flags & ISA_MIPS_R6)) {
|
(env->insn_flags & ISA_MIPS_R6)) {
|
||||||
has_work = true;
|
has_work = true;
|
||||||
}
|
}
|
||||||
|
|
|
@ -980,6 +980,7 @@ typedef struct CPUArchState {
|
||||||
#define CP0C6_DATAPREF 0
|
#define CP0C6_DATAPREF 0
|
||||||
int32_t CP0_Config7;
|
int32_t CP0_Config7;
|
||||||
int64_t CP0_Config7_rw_bitmask;
|
int64_t CP0_Config7_rw_bitmask;
|
||||||
|
#define CP0C7_WII 31
|
||||||
#define CP0C7_NAPCGEN 2
|
#define CP0C7_NAPCGEN 2
|
||||||
#define CP0C7_UNIMUEN 1
|
#define CP0C7_UNIMUEN 1
|
||||||
#define CP0C7_VFPUCGEN 0
|
#define CP0C7_VFPUCGEN 0
|
||||||
|
|
|
@ -70,8 +70,7 @@ static int is_seg_am_mapped(unsigned int am, bool eu, int mmu_idx)
|
||||||
/* is this AM mapped in current execution mode */
|
/* is this AM mapped in current execution mode */
|
||||||
return ((adetlb_mask << am) < 0);
|
return ((adetlb_mask << am) < 0);
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
return TLBRET_BADADDR;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -248,14 +248,14 @@ void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
|
||||||
target_ulong i;
|
target_ulong i;
|
||||||
|
|
||||||
for (i = 0; i < base_reglist; i++) {
|
for (i = 0; i < base_reglist; i++) {
|
||||||
cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]],
|
cpu_stl_mmuidx_ra(env, addr, env->active_tc.gpr[multiple_regs[i]],
|
||||||
mem_idx, GETPC());
|
mem_idx, GETPC());
|
||||||
addr += 4;
|
addr += 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_r31) {
|
if (do_r31) {
|
||||||
cpu_stw_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
|
cpu_stl_mmuidx_ra(env, addr, env->active_tc.gpr[31], mem_idx, GETPC());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5333,7 +5333,7 @@ void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
msa_move_v(pwd, pwx);
|
msa_move_v(pwd, pwx);
|
||||||
}
|
}
|
||||||
|
@ -5368,7 +5368,7 @@ void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
assert(0); \
|
g_assert_not_reached(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5413,7 +5413,7 @@ void helper_msa_ldi_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5461,7 +5461,7 @@ void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
assert(0); \
|
g_assert_not_reached(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5511,7 +5511,7 @@ void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
|
||||||
} \
|
} \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
assert(0); \
|
g_assert_not_reached(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5557,7 +5557,7 @@ static inline void msa_sld_df(uint32_t df, wr_t *pwd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5632,7 +5632,7 @@ void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, \
|
||||||
pwd->d[1] = msa_ ## func ## _df(df, pws->d[1], pwt->d[1]); \
|
pwd->d[1] = msa_ ## func ## _df(df, pws->d[1], pwt->d[1]); \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
assert(0); \
|
g_assert_not_reached(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5771,7 +5771,7 @@ void helper_msa_ ## func ## _df(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
||||||
pwd->d[1] = msa_ ## func ## _df(df, pwd->d[1], pws->d[1], pwt->d[1]); \
|
pwd->d[1] = msa_ ## func ## _df(df, pwd->d[1], pws->d[1], pwt->d[1]); \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
assert(0); \
|
g_assert_not_reached(); \
|
||||||
} \
|
} \
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5811,7 +5811,7 @@ static inline void msa_splat_df(uint32_t df, wr_t *pwd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5869,7 +5869,7 @@ void helper_msa_##FUNC(CPUMIPSState *env, uint32_t df, uint32_t wd, \
|
||||||
MSA_LOOP_D; \
|
MSA_LOOP_D; \
|
||||||
break; \
|
break; \
|
||||||
default: \
|
default: \
|
||||||
assert(0); \
|
g_assert_not_reached(); \
|
||||||
} \
|
} \
|
||||||
msa_move_v(pwd, pwx); \
|
msa_move_v(pwd, pwx); \
|
||||||
}
|
}
|
||||||
|
@ -6090,7 +6090,7 @@ void helper_msa_insve_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
pwd->d[n] = (int64_t)pws->d[0];
|
pwd->d[n] = (int64_t)pws->d[0];
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6150,7 +6150,7 @@ void helper_msa_fill_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6565,7 +6565,7 @@ static inline void compare_af(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6596,7 +6596,7 @@ static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6625,7 +6625,7 @@ static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6654,7 +6654,7 @@ static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6683,7 +6683,7 @@ static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6712,7 +6712,7 @@ static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6741,7 +6741,7 @@ static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6770,7 +6770,7 @@ static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6799,7 +6799,7 @@ static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6828,7 +6828,7 @@ static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -6857,7 +6857,7 @@ static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, retaddr);
|
check_msacsr_cause(env, retaddr);
|
||||||
|
@ -7107,7 +7107,7 @@ void helper_msa_fadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7137,7 +7137,7 @@ void helper_msa_fsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7167,7 +7167,7 @@ void helper_msa_fmul_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7198,7 +7198,7 @@ void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7245,7 +7245,7 @@ void helper_msa_fmadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7280,7 +7280,7 @@ void helper_msa_fmsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7317,7 +7317,7 @@ void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7371,7 +7371,7 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7417,7 +7417,7 @@ void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7526,7 +7526,7 @@ void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7555,7 +7555,7 @@ void helper_msa_fmin_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
FMAXMIN_A(min, max, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
|
FMAXMIN_A(min, max, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
|
||||||
FMAXMIN_A(min, max, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
|
FMAXMIN_A(min, max, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7628,7 +7628,7 @@ void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7657,7 +7657,7 @@ void helper_msa_fmax_a_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
FMAXMIN_A(max, min, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
|
FMAXMIN_A(max, min, pwx->d[0], pws->d[0], pwt->d[0], 64, status);
|
||||||
FMAXMIN_A(max, min, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
|
FMAXMIN_A(max, min, pwx->d[1], pws->d[1], pwt->d[1], 64, status);
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7681,7 +7681,7 @@ void helper_msa_fclass_df(CPUMIPSState *env, uint32_t df,
|
||||||
pwd->d[0] = float_class_d(pws->d[0], status);
|
pwd->d[0] = float_class_d(pws->d[0], status);
|
||||||
pwd->d[1] = float_class_d(pws->d[1], status);
|
pwd->d[1] = float_class_d(pws->d[1], status);
|
||||||
} else {
|
} else {
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7723,7 +7723,7 @@ void helper_msa_ftrunc_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7753,7 +7753,7 @@ void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7783,7 +7783,7 @@ void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7832,7 +7832,7 @@ void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7862,7 +7862,7 @@ void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7892,7 +7892,7 @@ void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7946,7 +7946,7 @@ void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -7983,7 +7983,7 @@ void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -8019,7 +8019,7 @@ void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -8046,7 +8046,7 @@ void helper_msa_ffql_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
msa_move_v(pwd, pwx);
|
msa_move_v(pwd, pwx);
|
||||||
|
@ -8072,7 +8072,7 @@ void helper_msa_ffqr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
msa_move_v(pwd, pwx);
|
msa_move_v(pwd, pwx);
|
||||||
|
@ -8100,7 +8100,7 @@ void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -8130,7 +8130,7 @@ void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -8166,7 +8166,7 @@ void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
@ -8196,7 +8196,7 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
assert(0);
|
g_assert_not_reached();
|
||||||
}
|
}
|
||||||
|
|
||||||
check_msacsr_cause(env, GETPC());
|
check_msacsr_cause(env, GETPC());
|
||||||
|
|
|
@ -4887,6 +4887,14 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
|
||||||
break;
|
break;
|
||||||
case OPC_J:
|
case OPC_J:
|
||||||
case OPC_JAL:
|
case OPC_JAL:
|
||||||
|
{
|
||||||
|
/* Jump to immediate */
|
||||||
|
int jal_mask = ctx->hflags & MIPS_HFLAG_M16 ? 0xF8000000
|
||||||
|
: 0xF0000000;
|
||||||
|
btgt = ((ctx->base.pc_next + insn_bytes) & jal_mask)
|
||||||
|
| (uint32_t)offset;
|
||||||
|
break;
|
||||||
|
}
|
||||||
case OPC_JALX:
|
case OPC_JALX:
|
||||||
/* Jump to immediate */
|
/* Jump to immediate */
|
||||||
btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
|
btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |
|
||||||
|
|
11
ui/cocoa.m
11
ui/cocoa.m
|
@ -1330,10 +1330,15 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
|
||||||
return NO;
|
return NO;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Called when QEMU goes into the background */
|
/*
|
||||||
- (void) applicationWillResignActive: (NSNotification *)aNotification
|
* Called when QEMU goes into the background. Note that
|
||||||
|
* [-NSWindowDelegate windowDidResignKey:] is used here instead of
|
||||||
|
* [-NSApplicationDelegate applicationWillResignActive:] because it cannot
|
||||||
|
* detect that the window loses focus when the deck is clicked on macOS 13.2.1.
|
||||||
|
*/
|
||||||
|
- (void) windowDidResignKey: (NSNotification *)aNotification
|
||||||
{
|
{
|
||||||
COCOA_DEBUG("QemuCocoaAppController: applicationWillResignActive\n");
|
COCOA_DEBUG("%s\n", __func__);
|
||||||
[cocoaView ungrabMouse];
|
[cocoaView ungrabMouse];
|
||||||
[cocoaView raiseAllKeys];
|
[cocoaView raiseAllKeys];
|
||||||
}
|
}
|
||||||
|
|
|
@ -489,7 +489,7 @@ const QEMULogItem qemu_log_items[] = {
|
||||||
"do not chain compiled TBs so that \"exec\" and \"cpu\" show\n"
|
"do not chain compiled TBs so that \"exec\" and \"cpu\" show\n"
|
||||||
"complete traces" },
|
"complete traces" },
|
||||||
#ifdef CONFIG_PLUGIN
|
#ifdef CONFIG_PLUGIN
|
||||||
{ CPU_LOG_PLUGIN, "plugin", "output from TCG plugins\n"},
|
{ CPU_LOG_PLUGIN, "plugin", "output from TCG plugins"},
|
||||||
#endif
|
#endif
|
||||||
{ LOG_STRACE, "strace",
|
{ LOG_STRACE, "strace",
|
||||||
"log every user-mode syscall, its input, and its result" },
|
"log every user-mode syscall, its input, and its result" },
|
||||||
|
|
Loading…
Reference in New Issue