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:
Peter Maydell 2023-03-09 10:22:49 +00:00
commit 555ce1d855
34 changed files with 768 additions and 169 deletions

View File

@ -8,8 +8,6 @@ endian options, ``qemu-system-mips``, ``qemu-system-mipsel``
``qemu-system-mips64`` and ``qemu-system-mips64el``. Five different
machine types are emulated:
- A generic ISA PC-like machine \"mips\"
- The MIPS Malta prototype board \"malta\"
- 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
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:
- Core board with MIPS 24Kf CPU and Galileo system controller

View File

@ -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_adjust(const char *stream, int pos) "st %s, pos %d"
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

View File

@ -1,39 +1,482 @@
/*
* VIA south bridges sound support
*
* Copyright (c) 2022-2023 BALATON Zoltan
*
* This work is licensed under the GNU GPL license version 2 or later.
*/
/*
* TODO: This is entirely boiler plate just registering empty PCI devices
* with the right ID guests expect, functionality should be added here.
* TODO: This is only a basic implementation of one audio playback channel
* more functionality should be added here.
*/
#include "qemu/osdep.h"
#include "qemu/log.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)
{
pci_set_word(pci_dev->config + PCI_COMMAND,
PCI_COMMAND_INVALIDATE | PCI_COMMAND_PARITY);
ViaAC97State *s = VIA_AC97(pci_dev);
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_STATUS_CAP_LIST | PCI_STATUS_DEVSEL_MEDIUM);
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)
{
DeviceClass *dc = DEVICE_CLASS(klass);
PCIDeviceClass *k = PCI_DEVICE_CLASS(klass);
k->realize = via_ac97_realize;
k->exit = via_ac97_exit;
k->vendor_id = PCI_VENDOR_ID_VIA;
k->device_id = PCI_DEVICE_ID_VIA_AC97;
k->revision = 0x50;
k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO;
device_class_set_props(dc, via_ac97_properties);
set_bit(DEVICE_CATEGORY_SOUND, dc->categories);
dc->desc = "VIA AC97";
dc->reset = via_ac97_reset;
/* Reason: Part of a south bridge chip */
dc->user_creatable = false;
}
@ -41,7 +484,7 @@ static void via_ac97_class_init(ObjectClass *klass, void *data)
static const TypeInfo via_ac97_info = {
.name = TYPE_VIA_AC97,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(PCIDevice),
.instance_size = sizeof(ViaAC97State),
.class_init = via_ac97_class_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },

View File

@ -465,6 +465,7 @@ typedef struct SM501State {
uint32_t last_width;
uint32_t last_height;
bool do_full_update; /* perform a full update next time */
uint8_t use_pixman;
I2CBus *i2c_bus;
/* mmio registers */
@ -827,7 +828,7 @@ static void sm501_2d_operation(SM501State *s)
de = db + (width + (height - 1) * dst_pitch) * bypp;
overlap = (db < se && sb < de);
}
if (overlap) {
if (overlap && (s->use_pixman & BIT(2))) {
/* pixman can't do reverse blit: copy via temporary */
int tmp_stride = DIV_ROUND_UP(width * bypp, sizeof(uint32_t));
uint32_t *tmp = tmp_buf;
@ -852,13 +853,15 @@ static void sm501_2d_operation(SM501State *s)
if (tmp != tmp_buf) {
g_free(tmp);
}
} else {
} else if (!overlap && (s->use_pixman & BIT(1))) {
fallback = !pixman_blt((uint32_t *)&s->local_mem[src_base],
(uint32_t *)&s->local_mem[dst_base],
src_pitch * bypp / sizeof(uint32_t),
dst_pitch * bypp / sizeof(uint32_t),
8 * bypp, 8 * bypp, src_x, src_y,
dst_x, dst_y, width, height);
} else {
fallback = true;
}
if (fallback) {
uint8_t *sp = s->local_mem + src_base;
@ -891,7 +894,7 @@ static void sm501_2d_operation(SM501State *s)
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],
dst_pitch * bypp / sizeof(uint32_t), 8 * bypp,
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[] = {
DEFINE_PROP_UINT32("vram-size", SM501SysBusState, vram_size, 0),
DEFINE_PROP_UINT8("x-pixman", SM501SysBusState, state.use_pixman, 7),
DEFINE_PROP_END_OF_LIST(),
};
@ -2122,6 +2126,7 @@ static void sm501_realize_pci(PCIDevice *dev, Error **errp)
static Property sm501_pci_properties[] = {
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(),
};
@ -2162,11 +2167,18 @@ static void sm501_pci_class_init(ObjectClass *klass, void *data)
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 = {
.name = TYPE_PCI_SM501,
.parent = TYPE_PCI_DEVICE,
.instance_size = sizeof(SM501PCIState),
.class_init = sm501_pci_class_init,
.instance_init = sm501_pci_init,
.interfaces = (InterfaceInfo[]) {
{ INTERFACE_CONVENTIONAL_PCI_DEVICE },
{ },

View File

@ -133,7 +133,7 @@ static void pic_set_irq(void *opaque, int irq, int level)
}
#endif
if (s->elcr & mask) {
if (s->ltim || (s->elcr & mask)) {
/* level triggered */
if (level) {
s->irr |= mask;
@ -167,7 +167,7 @@ static void pic_intack(PICCommonState *s, int irq)
s->isr |= (1 << irq);
}
/* 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);
}
pic_update_irq(s);
@ -224,6 +224,7 @@ static void pic_reset(DeviceState *dev)
PICCommonState *s = PIC_COMMON(dev);
s->elcr = 0;
s->ltim = 0;
pic_init_reset(s);
}
@ -243,10 +244,7 @@ static void pic_ioport_write(void *opaque, hwaddr addr64,
s->init_state = 1;
s->init4 = val & 1;
s->single_mode = val & 2;
if (val & 0x08) {
qemu_log_mask(LOG_UNIMP,
"i8259: level sensitive irq not supported\n");
}
s->ltim = val & 8;
} else if (val & 0x08) {
if (val & 0x04) {
s->poll = 1;

View File

@ -51,7 +51,7 @@ void pic_reset_common(PICCommonState *s)
s->special_fully_nested_mode = 0;
s->init4 = 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)
@ -144,6 +144,24 @@ static void pic_print_info(InterruptStatsProvider *obj, Monitor *mon)
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 = {
.name = "i8259",
.version_id = 1,
@ -168,6 +186,10 @@ static const VMStateDescription vmstate_pic_common = {
VMSTATE_UINT8(single_mode, PICCommonState),
VMSTATE_UINT8(elcr, PICCommonState),
VMSTATE_END_OF_LIST()
},
.subsections = (const VMStateDescription*[]) {
&vmstate_pic_ltim,
NULL
}
};

View File

@ -439,8 +439,8 @@ static void mips_gic_realize(DeviceState *dev, Error **errp)
}
static Property mips_gic_properties[] = {
DEFINE_PROP_INT32("num-vp", MIPSGICState, num_vps, 1),
DEFINE_PROP_INT32("num-irq", MIPSGICState, num_irq, 256),
DEFINE_PROP_UINT32("num-vp", MIPSGICState, num_vps, 1),
DEFINE_PROP_UINT32("num-irq", MIPSGICState, num_irq, 256),
DEFINE_PROP_END_OF_LIST(),
};

View File

@ -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)
{
DeviceState *dev = opaque;
@ -88,7 +94,9 @@ static void i82378_realize(PCIDevice *pci, Error **errp)
*/
/* 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);
/* 1 82C54 (pit) */

View File

@ -16,6 +16,7 @@ apm_io_write(uint8_t addr, uint8_t val) "write addr=0x%x val=0x%02x"
# vt82c686.c
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_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"

View File

@ -554,7 +554,7 @@ struct ViaISAState {
PCIIDEState ide;
UHCIState uhci[2];
ViaPMState pm;
PCIDevice ac97;
ViaAC97State ac97;
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);
}
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)
{
ViaISAState *s = VIA_ISA(d);
DeviceState *dev = DEVICE(d);
PCIBus *pci_bus = pci_get_bus(d);
qemu_irq *isa_irq;
ISABus *isa_bus;
int i;
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),
errp);
@ -614,11 +662,13 @@ static void via_isa_realize(PCIDevice *d, Error **errp)
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);
i8254_pit_init(isa_bus, 0x40, 0, NULL);
i8257_dma_init(isa_bus, 0);
qdev_init_gpio_in_named(dev, via_isa_set_pci_irq, "pirq", PCI_NUM_PINS);
/* RTC */
qdev_prop_set_int32(DEVICE(&s->rtc), "base_year", 2000);
if (!qdev_realize(DEVICE(&s->rtc), BUS(isa_bus), errp)) {

View File

@ -702,7 +702,7 @@ static void boston_mach_init(MachineState *machine)
object_initialize_child(OBJECT(machine), "cps", &s->cps, TYPE_MIPS_CPS);
object_property_set_str(OBJECT(&s->cps), "cpu-type", machine->cpu_type,
&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);
qdev_connect_clock_in(DEVICE(&s->cps), "clk-in",
qdev_get_clock_out(dev, "cpu-refclk"));

View File

@ -66,20 +66,17 @@ static bool cpu_mips_itu_supported(CPUMIPSState *env)
static void mips_cps_realize(DeviceState *dev, Error **errp)
{
MIPSCPSState *s = MIPS_CPS(dev);
CPUMIPSState *env;
MIPSCPU *cpu;
int i;
target_ulong gcr_base;
bool itu_present = false;
bool saar_present = false;
if (!clock_get(s->clock)) {
error_setg(errp, "CPS input clock is not connected to an output clock");
return;
}
for (i = 0; i < s->num_vp; i++) {
cpu = MIPS_CPU(object_new(s->cpu_type));
for (int i = 0; i < s->num_vp; i++) {
MIPSCPU *cpu = MIPS_CPU(object_new(s->cpu_type));
CPUMIPSState *env = &cpu->env;
/* All VPs are halted on reset. Leave powering up to CPC. */
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_clock_init(cpu);
env = &cpu->env;
if (cpu_mips_itu_supported(env)) {
itu_present = true;
/* 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);
}
cpu = MIPS_CPU(first_cpu);
env = &cpu->env;
saar_present = (bool)env->saarp;
/* Inter-Thread Communication Unit */
if (itu_present) {
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);
object_property_set_int(OBJECT(&s->itu), "num-semaphores", 16,
object_property_set_uint(OBJECT(&s->itu), "num-semaphores", 16,
&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)) {
return;
}
@ -133,7 +122,7 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
/* Cluster Power Controller */
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);
object_property_set_int(OBJECT(&s->cpc), "vp-start-running", 1,
&error_abort);
@ -146,9 +135,9 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
/* Global Interrupt Controller */
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);
object_property_set_int(OBJECT(&s->gic), "num-irq", 128,
object_property_set_uint(OBJECT(&s->gic), "num-irq", 128,
&error_abort);
if (!sysbus_realize(SYS_BUS_DEVICE(&s->gic), errp)) {
return;
@ -158,10 +147,10 @@ static void mips_cps_realize(DeviceState *dev, Error **errp)
sysbus_mmio_get_region(SYS_BUS_DEVICE(&s->gic), 0));
/* 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_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);
object_property_set_int(OBJECT(&s->gcr), "gcr-rev", 0x800,
&error_abort);

View File

@ -1066,7 +1066,7 @@ static void create_cps(MachineState *ms, MaltaState *s,
object_initialize_child(OBJECT(s), "cps", &s->cps, TYPE_MIPS_CPS);
object_property_set_str(OBJECT(&s->cps), "cpu-type", ms->cpu_type,
&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);
qdev_connect_clock_in(DEVICE(&s->cps), "clk-in", s->cpuclk);
sysbus_realize(SYS_BUS_DEVICE(&s->cps), &error_fatal);

View File

@ -212,7 +212,7 @@ static const VMStateDescription vmstate_mips_gcr = {
};
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_UINT64("gcr-base", MIPSGCRState, gcr_base, GCR_BASE_ADDR),
DEFINE_PROP_LINK("gic", MIPSGCRState, gic_mr, TYPE_MEMORY_REGION,

View File

@ -93,10 +93,10 @@ void itc_reconfigure(MIPSITUState *tag)
uint64_t size = (1 * KiB) + (am[1] & ITC_AM1_ADDR_MASK_MASK);
bool is_enabled = (am[0] & ITC_AM0_EN_MASK) != 0;
if (tag->saar_present) {
address = ((*(uint64_t *) tag->saar) & 0xFFFFFFFFE000ULL) << 4;
size = 1ULL << ((*(uint64_t *) tag->saar >> 1) & 0x1f);
is_enabled = *(uint64_t *) tag->saar & 1;
if (tag->saar) {
address = (tag->saar[0] & 0xFFFFFFFFE000ULL) << 4;
size = 1ULL << ((tag->saar[0] >> 1) & 0x1f);
is_enabled = tag->saar[0] & 1;
}
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)
{
/* Minimum interval (for EntryGain = 0) is 128 B */
if (s->saar_present) {
if (s->saar) {
return 7 + ((s->icr0 >> ITC_ICR0_BLK_GRAIN) &
ITC_ICR0_BLK_GRAIN_MASK);
} else {
@ -515,6 +515,7 @@ static void mips_itu_init(Object *obj)
static void mips_itu_realize(DeviceState *dev, Error **errp)
{
MIPSITUState *s = MIPS_ITU(dev);
CPUMIPSState *env;
if (s->num_fifo > ITC_FIFO_NUM_MAX) {
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);
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));
}
@ -534,8 +544,8 @@ static void mips_itu_reset(DeviceState *dev)
{
MIPSITUState *s = MIPS_ITU(dev);
if (s->saar_present) {
*(uint64_t *) s->saar = 0x11 << 1;
if (s->saar) {
s->saar[0] = 0x11 << 1;
s->icr0 = get_num_cells(s) << ITC_ICR0_CELL_NUM;
} else {
s->ITCAddressMap[0] = 0;
@ -549,11 +559,11 @@ static void mips_itu_reset(DeviceState *dev)
}
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),
DEFINE_PROP_INT32("num-semaphores", MIPSITUState, num_semaphores,
DEFINE_PROP_UINT32("num-semaphores", MIPSITUState, num_semaphores,
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(),
};

View File

@ -873,10 +873,6 @@ static void mv64361_realize(DeviceState *dev, Error **errp)
}
sysbus_init_irq(SYS_BUS_DEVICE(dev), &s->cpu_irq);
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)

View File

@ -73,6 +73,8 @@ struct Pegasos2MachineState {
MachineState parent_obj;
PowerPCCPU *cpu;
DeviceState *mv;
qemu_irq mv_pirq[PCI_NUM_PINS];
qemu_irq via_pirq[PCI_NUM_PINS];
Vof *vof;
void *fdt_blob;
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)
{
Pegasos2MachineState *pm = PEGASOS2_MACHINE(machine);
@ -106,7 +117,7 @@ static void pegasos2_init(MachineState *machine)
I2CBus *i2c_bus;
const char *fwname = machine->firmware ?: PROM_FILENAME;
char *filename;
int sz;
int i, sz;
uint8_t *spd_data;
/* init CPU */
@ -156,11 +167,18 @@ static void pegasos2_init(MachineState *machine)
/* Marvell Discovery II system controller */
pm->mv = DEVICE(sysbus_create_simple(TYPE_MV64361, -1,
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_irqs(pci_bus, pegasos2_pci_irq, pm, PCI_NUM_PINS);
/* VIA VT8231 South Bridge (multifunction PCI device) */
via = OBJECT(pci_create_simple_multifunction(pci_bus, PCI_DEVFN(12, 0),
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_resolve_path_component(via, "rtc"),
"date");
@ -267,6 +285,12 @@ static void pegasos2_machine_reset(MachineState *machine, ShutdownCause reason)
PCI_INTERRUPT_LINE, 2, 0x9);
pegasos2_pci_config_write(pm, 1, (PCI_DEVFN(12, 0) << 8) |
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) |
PCI_INTERRUPT_LINE, 2, 0x109);

View File

@ -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.
* 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)) {
ohci->rhport[i].ctrl |= OHCI_PORT_CSC;
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;
}
@ -1828,11 +1843,7 @@ static void ohci_wakeup(USBPort *port1)
intr = OHCI_INTR_RHSC;
}
/* Note that the controller can be suspended even if this port is not */
if ((s->ctl & OHCI_CTL_HCFS) == OHCI_USB_SUSPEND) {
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;
if (ohci_resume(s)) {
/*
* In suspend mode only ResumeDetected is possible, not RHSC:
* see the OHCI spec 5.1.2.3.

View File

@ -1,17 +1,7 @@
#include "qemu/osdep.h"
#include "hw/irq.h"
#include "hw/isa/vt82c686.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)
{
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);
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[] = {

View File

@ -211,8 +211,8 @@ struct MIPSGICState {
/* GIC VP Timer */
MIPSGICTimerState *gic_timer;
int32_t num_vps;
int32_t num_irq;
uint32_t num_vps;
uint32_t num_irq;
};
#endif /* MIPS_GIC_H */

View File

@ -61,6 +61,7 @@ struct PICCommonState {
uint8_t single_mode; /* true if slave pic is not initialized */
uint8_t elcr; /* PIIX edge/trigger selection*/
uint8_t elcr_mask;
uint8_t ltim; /* Edge/Level Bank Select (pre-PIIX, chip-wide) */
qemu_irq int_out[1];
uint32_t master; /* reflects /SP input pin */
uint32_t iobase;

View File

@ -1,6 +1,8 @@
#ifndef 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_USB_UHCI "vt82c686b-usb-uhci"
@ -9,6 +11,29 @@
#define TYPE_VIA_IDE "via-ide"
#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);
#endif

View File

@ -75,7 +75,7 @@ struct MIPSGCRState {
SysBusDevice parent_obj;
int32_t gcr_rev;
int32_t num_vps;
uint32_t num_vps;
hwaddr gcr_base;
MemoryRegion iomem;
MemoryRegion *cpc_mr;

View File

@ -57,8 +57,8 @@ struct MIPSITUState {
SysBusDevice parent_obj;
/*< public >*/
int32_t num_fifo;
int32_t num_semaphores;
uint32_t num_fifo;
uint32_t num_semaphores;
/* ITC Storage */
ITCStorageCell *cell;
@ -72,9 +72,8 @@ struct MIPSITUState {
uint64_t icr0;
/* SAAR */
bool saar_present;
void *saar;
uint64_t *saar;
MIPSCPU *cpu0;
};
/* Get ITC Configuration Tag memory region. */

View File

@ -1126,15 +1126,21 @@ GString *ram_block_format(void)
GString *buf = g_string_new("");
RCU_READ_LOCK_GUARD();
g_string_append_printf(buf, "%24s %8s %18s %18s %18s\n",
"Block Name", "PSize", "Offset", "Used", "Total");
g_string_append_printf(buf, "%24s %8s %18s %18s %18s %18s %3s\n",
"Block Name", "PSize", "Offset", "Used", "Total",
"HVA", "RO");
RAMBLOCK_FOREACH(block) {
psize = size_to_str(block->page_size);
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->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);
}

View File

@ -332,7 +332,11 @@ const mips_def_t mips_defs[] =
(0x1 << CP0C0_AR) | (MMU_TYPE_FMT << CP0C0_MT),
.CP0_Config1 = MIPS_CONFIG1,
.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_shift = 4,
.SYNCI_Step = 32,
@ -353,7 +357,11 @@ const mips_def_t mips_defs[] =
(0 << CP0C1_IS) | (3 << CP0C1_IL) | (1 << CP0C1_IA) |
(0 << CP0C1_DS) | (3 << CP0C1_DL) | (1 << CP0C1_DA),
.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_shift = 4,
.SYNCI_Step = 32,
@ -392,6 +400,7 @@ const mips_def_t mips_defs[] =
.CP0_Config5_rw_bitmask = (1 << CP0C5_K) | (1 << CP0C5_CV) |
(1 << CP0C5_MSAEn) | (1 << CP0C5_UFE) |
(1 << CP0C5_FRE) | (1 << CP0C5_UFR),
.CP0_Config7 = 1 << CP0C7_WII,
.CP0_LLAddr_rw_bitmask = 0,
.CP0_LLAddr_shift = 0,
.SYNCI_Step = 32,

View File

@ -143,11 +143,13 @@ static bool mips_cpu_has_work(CPUState *cs)
/*
* Prior to MIPS Release 6 it is implementation dependent if non-enabled
* 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) &&
cpu_mips_hw_interrupts_pending(env)) {
if (cpu_mips_hw_interrupts_enabled(env) ||
(env->CP0_Config7 & (1 << CP0C7_WII)) ||
(env->insn_flags & ISA_MIPS_R6)) {
has_work = true;
}

View File

@ -980,6 +980,7 @@ typedef struct CPUArchState {
#define CP0C6_DATAPREF 0
int32_t CP0_Config7;
int64_t CP0_Config7_rw_bitmask;
#define CP0C7_WII 31
#define CP0C7_NAPCGEN 2
#define CP0C7_UNIMUEN 1
#define CP0C7_VFPUCGEN 0

View File

@ -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 */
return ((adetlb_mask << am) < 0);
default:
assert(0);
return TLBRET_BADADDR;
g_assert_not_reached();
};
}

View File

@ -248,14 +248,14 @@ void helper_swm(CPUMIPSState *env, target_ulong addr, target_ulong reglist,
target_ulong 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());
addr += 4;
}
}
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());
}
}

View File

@ -5333,7 +5333,7 @@ void helper_msa_shf_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
msa_move_v(pwd, pwx);
}
@ -5368,7 +5368,7 @@ void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
} \
break; \
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;
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; \
default: \
assert(0); \
g_assert_not_reached(); \
} \
}
@ -5511,7 +5511,7 @@ void helper_msa_ ## helper ## _df(CPUMIPSState *env, uint32_t df, \
} \
break; \
default: \
assert(0); \
g_assert_not_reached(); \
} \
}
@ -5557,7 +5557,7 @@ static inline void msa_sld_df(uint32_t df, wr_t *pwd,
}
break;
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]); \
break; \
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]); \
break; \
default: \
assert(0); \
g_assert_not_reached(); \
} \
}
@ -5811,7 +5811,7 @@ static inline void msa_splat_df(uint32_t df, wr_t *pwd,
}
break;
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; \
break; \
default: \
assert(0); \
g_assert_not_reached(); \
} \
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];
break;
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;
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;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6596,7 +6596,7 @@ static inline void compare_un(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6625,7 +6625,7 @@ static inline void compare_eq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6654,7 +6654,7 @@ static inline void compare_ueq(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6683,7 +6683,7 @@ static inline void compare_lt(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6712,7 +6712,7 @@ static inline void compare_ult(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6741,7 +6741,7 @@ static inline void compare_le(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6770,7 +6770,7 @@ static inline void compare_ule(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6799,7 +6799,7 @@ static inline void compare_or(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6828,7 +6828,7 @@ static inline void compare_une(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -6857,7 +6857,7 @@ static inline void compare_ne(CPUMIPSState *env, wr_t *pwd, wr_t *pws,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, retaddr);
@ -7107,7 +7107,7 @@ void helper_msa_fadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7137,7 +7137,7 @@ void helper_msa_fsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7167,7 +7167,7 @@ void helper_msa_fmul_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7198,7 +7198,7 @@ void helper_msa_fdiv_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7245,7 +7245,7 @@ void helper_msa_fmadd_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7280,7 +7280,7 @@ void helper_msa_fmsub_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7317,7 +7317,7 @@ void helper_msa_fexp2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7371,7 +7371,7 @@ void helper_msa_fexdo_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7417,7 +7417,7 @@ void helper_msa_ftq_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7526,7 +7526,7 @@ void helper_msa_fmin_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
} 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[1], pws->d[1], pwt->d[1], 64, status);
} else {
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7628,7 +7628,7 @@ void helper_msa_fmax_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
} 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[1], pws->d[1], pwt->d[1], 64, status);
} else {
assert(0);
g_assert_not_reached();
}
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[1] = float_class_d(pws->d[1], status);
} 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;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7753,7 +7753,7 @@ void helper_msa_ftrunc_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7783,7 +7783,7 @@ void helper_msa_fsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7832,7 +7832,7 @@ void helper_msa_frsqrt_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7862,7 +7862,7 @@ void helper_msa_frcp_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7892,7 +7892,7 @@ void helper_msa_frint_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7946,7 +7946,7 @@ void helper_msa_flog2_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -7983,7 +7983,7 @@ void helper_msa_fexupl_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -8019,7 +8019,7 @@ void helper_msa_fexupr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -8046,7 +8046,7 @@ void helper_msa_ffql_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
msa_move_v(pwd, pwx);
@ -8072,7 +8072,7 @@ void helper_msa_ffqr_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
msa_move_v(pwd, pwx);
@ -8100,7 +8100,7 @@ void helper_msa_ftint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -8130,7 +8130,7 @@ void helper_msa_ftint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -8166,7 +8166,7 @@ void helper_msa_ffint_s_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());
@ -8196,7 +8196,7 @@ void helper_msa_ffint_u_df(CPUMIPSState *env, uint32_t df, uint32_t wd,
}
break;
default:
assert(0);
g_assert_not_reached();
}
check_msacsr_cause(env, GETPC());

View File

@ -4887,6 +4887,14 @@ static void gen_compute_branch(DisasContext *ctx, uint32_t opc,
break;
case OPC_J:
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:
/* Jump to immediate */
btgt = ((ctx->base.pc_next + insn_bytes) & (int32_t)0xF0000000) |

View File

@ -1330,10 +1330,15 @@ static CGEventRef handleTapEvent(CGEventTapProxy proxy, CGEventType type, CGEven
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 raiseAllKeys];
}

View File

@ -489,7 +489,7 @@ const QEMULogItem qemu_log_items[] = {
"do not chain compiled TBs so that \"exec\" and \"cpu\" show\n"
"complete traces" },
#ifdef CONFIG_PLUGIN
{ CPU_LOG_PLUGIN, "plugin", "output from TCG plugins\n"},
{ CPU_LOG_PLUGIN, "plugin", "output from TCG plugins"},
#endif
{ LOG_STRACE, "strace",
"log every user-mode syscall, its input, and its result" },