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:50 +00:00
34 changed files with 768 additions and 169 deletions
-14
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
+6
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
+449 -6
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 },
+15 -3
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 },
{ },
+4 -6
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;
+23 -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
}
};
+2 -2
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(),
};
+9 -1
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) */
+1
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"
+52 -2
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)) {
+1 -1
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"));
+12 -23
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);
+1 -1
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);
+1 -1
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,
+20 -10
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(),
};
-4
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)
+25 -1
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);
+17 -6
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.
-12
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[] = {
+2 -2
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 */

Some files were not shown because too many files have changed in this diff Show More