Skip to content

Commit

Permalink
Merge remote-tracking branch 'remotes/dgibson/tags/ppc-for-2.12-20180…
Browse files Browse the repository at this point in the history
…111' into staging

ppc patch queue 2018-01-11

This pull request supersedes ppc-for-2.12-20180108 and several before
it.  The earlier pull request included a patch which exposed a bug in
the ARM TCG backend.  I've pulled that out and will repost once the
ARM bug is fixed (a patch has been posted by Richard Henderson).

Higlights from this series:
  * SLOF update
  * Several new devices for embedded platforms
  * Fix to correctly set compatiblity mode for hotplugged CPUs
  * dtc compile fix for older MacOS versions

# gpg: Signature made Thu 11 Jan 2018 04:58:11 GMT
# gpg:                using RSA key 0x6C38CACA20D9B392
# gpg: Good signature from "David Gibson <[email protected]>"
# gpg:                 aka "David Gibson (Red Hat) <[email protected]>"
# gpg:                 aka "David Gibson (ozlabs.org) <[email protected]>"
# gpg:                 aka "David Gibson (kernel.org) <[email protected]>"
# Primary key fingerprint: 75F4 6586 AE61 A66C C44E  87DC 6C38 CACA 20D9 B392

* remotes/dgibson/tags/ppc-for-2.12-20180111:
  spapr: Correct compatibility mode setting for hotplugged CPUs
  hw/ppc: Remove the deprecated spapr-pci-vfio-host-bridge device
  Update dtc to fix compilation problem on Mac OS 10.6
  target/ppc: more use of the PPC_*() macros
  ppc/pnv: change powernv_ prefix to pnv_ for overall naming consistency
  hw/ide: Emulate SiI3112 SATA controller
  spapr_pci: use warn_report()
  ppc4xx_i2c: Implement basic I2C functions
  sm501: Add some more unimplemented registers
  sm501: Add panel hardware cursor registers also to read function
  pseries: Update SLOF firmware image to qemu-slof-20171214

Signed-off-by: Peter Maydell <[email protected]>
  • Loading branch information
pm215 committed Jan 11, 2018
2 parents 612061b + 51f8446 commit e890966
Show file tree
Hide file tree
Showing 28 changed files with 705 additions and 189 deletions.
6 changes: 6 additions & 0 deletions MAINTAINERS
Original file line number Diff line number Diff line change
Expand Up @@ -766,6 +766,12 @@ L: [email protected]
S: Odd Fixes
F: hw/ppc/virtex_ml507.c

sam460ex
M: BALATON Zoltan <[email protected]>
L: [email protected]
S: Maintained
F: hw/ide/sii3112.c

SH4 Machines
------------
R2D
Expand Down
1 change: 1 addition & 0 deletions default-configs/ppcemb-softmmu.mak
Original file line number Diff line number Diff line change
Expand Up @@ -16,3 +16,4 @@ CONFIG_I8259=y
CONFIG_XILINX=y
CONFIG_XILINX_ETHLITE=y
CONFIG_SM501=y
CONFIG_IDE_SII3112=y
2 changes: 1 addition & 1 deletion dtc
Submodule dtc updated from 558cd8 to e54388
30 changes: 30 additions & 0 deletions hw/display/sm501.c
Original file line number Diff line number Diff line change
Expand Up @@ -795,6 +795,8 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
case SM501_ARBTRTN_CONTROL:
ret = s->arbitration_control;
break;
case SM501_COMMAND_LIST_STATUS:
ret = 0x00180002; /* FIFOs are empty, everything idle */
case SM501_IRQ_MASK:
ret = s->irq_mask;
break;
Expand All @@ -812,6 +814,9 @@ static uint64_t sm501_system_config_read(void *opaque, hwaddr addr,
case SM501_POWER_MODE_CONTROL:
ret = s->power_mode_control;
break;
case SM501_ENDIAN_CONTROL:
ret = 0; /* Only default little endian mode is supported */
break;

default:
printf("sm501 system config : not implemented register read."
Expand Down Expand Up @@ -865,6 +870,12 @@ static void sm501_system_config_write(void *opaque, hwaddr addr,
case SM501_POWER_MODE_CONTROL:
s->power_mode_control = value & 0x00000003;
break;
case SM501_ENDIAN_CONTROL:
if (value & 0x00000001) {
printf("sm501 system config : big endian mode not implemented.\n");
abort();
}
break;

default:
printf("sm501 system config : not implemented register write."
Expand Down Expand Up @@ -924,6 +935,9 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr,
case SM501_DC_PANEL_PANNING_CONTROL:
ret = s->dc_panel_panning_control;
break;
case SM501_DC_PANEL_COLOR_KEY:
/* Not implemented yet */
break;
case SM501_DC_PANEL_FB_ADDR:
ret = s->dc_panel_fb_addr;
break;
Expand Down Expand Up @@ -956,6 +970,19 @@ static uint64_t sm501_disp_ctrl_read(void *opaque, hwaddr addr,
ret = s->dc_panel_v_sync;
break;

case SM501_DC_PANEL_HWC_ADDR:
ret = s->dc_panel_hwc_addr;
break;
case SM501_DC_PANEL_HWC_LOC:
ret = s->dc_panel_hwc_location;
break;
case SM501_DC_PANEL_HWC_COLOR_1_2:
ret = s->dc_panel_hwc_color_1_2;
break;
case SM501_DC_PANEL_HWC_COLOR_3:
ret = s->dc_panel_hwc_color_3;
break;

case SM501_DC_VIDEO_CONTROL:
ret = s->dc_video_control;
break;
Expand Down Expand Up @@ -1022,6 +1049,9 @@ static void sm501_disp_ctrl_write(void *opaque, hwaddr addr,
case SM501_DC_PANEL_PANNING_CONTROL:
s->dc_panel_panning_control = value & 0xFF3FFF3F;
break;
case SM501_DC_PANEL_COLOR_KEY:
/* Not implemented yet */
break;
case SM501_DC_PANEL_FB_ADDR:
s->dc_panel_fb_addr = value & 0x8FFFFFF0;
break;
Expand Down
198 changes: 168 additions & 30 deletions hw/i2c/ppc4xx_i2c.c
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
* PPC4xx I2C controller emulation
*
* Copyright (c) 2007 Jocelyn Mayer
* Copyright (c) 2012 François Revol
* Copyright (c) 2016 BALATON Zoltan
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
Expand All @@ -25,26 +27,118 @@
#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qemu-common.h"
#include "qemu/log.h"
#include "cpu.h"
#include "hw/hw.h"
#include "hw/i2c/ppc4xx_i2c.h"

/*#define DEBUG_I2C*/
#define PPC4xx_I2C_MEM_SIZE 0x12

#define PPC4xx_I2C_MEM_SIZE 0x11
#define IIC_CNTL_PT (1 << 0)
#define IIC_CNTL_READ (1 << 1)
#define IIC_CNTL_CHT (1 << 2)
#define IIC_CNTL_RPST (1 << 3)

#define IIC_STS_PT (1 << 0)
#define IIC_STS_ERR (1 << 2)
#define IIC_STS_MDBS (1 << 5)

#define IIC_EXTSTS_XFRA (1 << 0)

#define IIC_XTCNTLSS_SRST (1 << 0)

static void ppc4xx_i2c_reset(DeviceState *s)
{
PPC4xxI2CState *i2c = PPC4xx_I2C(s);

/* FIXME: Should also reset bus?
*if (s->address != ADDR_RESET) {
* i2c_end_transfer(s->bus);
*}
*/

i2c->mdata = 0;
i2c->lmadr = 0;
i2c->hmadr = 0;
i2c->cntl = 0;
i2c->mdcntl = 0;
i2c->sts = 0;
i2c->extsts = 0x8f;
i2c->sdata = 0;
i2c->lsadr = 0;
i2c->hsadr = 0;
i2c->clkdiv = 0;
i2c->intrmsk = 0;
i2c->xfrcnt = 0;
i2c->xtcntlss = 0;
i2c->directcntl = 0x0f;
i2c->intr = 0;
}

static inline bool ppc4xx_i2c_is_master(PPC4xxI2CState *i2c)
{
return true;
}

static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size)
{
PPC4xxI2CState *i2c = PPC4xx_I2C(opaque);
uint64_t ret;

#ifdef DEBUG_I2C
printf("%s: addr " TARGET_FMT_plx "\n", __func__, addr);
#endif
switch (addr) {
case 0x00:
/*i2c_readbyte(&i2c->mdata);*/
ret = i2c->mdata;
if (ppc4xx_i2c_is_master(i2c)) {
ret = 0xff;

if (!(i2c->sts & IIC_STS_MDBS)) {
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Trying to read "
"without starting transfer\n",
TYPE_PPC4xx_I2C, __func__);
} else {
int pending = (i2c->cntl >> 4) & 3;

/* get the next byte */
int byte = i2c_recv(i2c->bus);

if (byte < 0) {
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: read failed "
"for device 0x%02x\n", TYPE_PPC4xx_I2C,
__func__, i2c->lmadr);
ret = 0xff;
} else {
ret = byte;
/* Raise interrupt if enabled */
/*ppc4xx_i2c_raise_interrupt(i2c)*/;
}

if (!pending) {
i2c->sts &= ~IIC_STS_MDBS;
/*i2c_end_transfer(i2c->bus);*/
/*} else if (i2c->cntl & (IIC_CNTL_RPST | IIC_CNTL_CHT)) {*/
} else if (pending) {
/* current smbus implementation doesn't like
multibyte xfer repeated start */
i2c_end_transfer(i2c->bus);
if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 1)) {
/* if non zero is returned, the adress is not valid */
i2c->sts &= ~IIC_STS_PT;
i2c->sts |= IIC_STS_ERR;
i2c->extsts |= IIC_EXTSTS_XFRA;
} else {
/*i2c->sts |= IIC_STS_PT;*/
i2c->sts |= IIC_STS_MDBS;
i2c->sts &= ~IIC_STS_ERR;
i2c->extsts = 0;
}
}
pending--;
i2c->cntl = (i2c->cntl & 0xcf) | (pending << 4);
}
} else {
qemu_log_mask(LOG_UNIMP, "[%s]%s: slave mode not implemented\n",
TYPE_PPC4xx_I2C, __func__);
}
break;
case 0x02:
ret = i2c->sdata;
Expand Down Expand Up @@ -88,13 +182,15 @@ static uint64_t ppc4xx_i2c_readb(void *opaque, hwaddr addr, unsigned int size)
case 0x10:
ret = i2c->directcntl;
break;
case 0x11:
ret = i2c->intr;
break;
default:
ret = 0x00;
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
HWADDR_PRIx "\n", TYPE_PPC4xx_I2C, __func__, addr);
ret = 0;
break;
}
#ifdef DEBUG_I2C
printf("%s: addr " TARGET_FMT_plx " %02" PRIx64 "\n", __func__, addr, ret);
#endif

return ret;
}
Expand All @@ -103,26 +199,70 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
unsigned int size)
{
PPC4xxI2CState *i2c = opaque;
#ifdef DEBUG_I2C
printf("%s: addr " TARGET_FMT_plx " val %08" PRIx64 "\n",
__func__, addr, value);
#endif

switch (addr) {
case 0x00:
i2c->mdata = value;
/*i2c_sendbyte(&i2c->mdata);*/
if (!i2c_bus_busy(i2c->bus)) {
/* assume we start a write transfer */
if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 0)) {
/* if non zero is returned, the adress is not valid */
i2c->sts &= ~IIC_STS_PT;
i2c->sts |= IIC_STS_ERR;
i2c->extsts |= IIC_EXTSTS_XFRA;
} else {
i2c->sts |= IIC_STS_PT;
i2c->sts &= ~IIC_STS_ERR;
i2c->extsts = 0;
}
}
if (i2c_bus_busy(i2c->bus)) {
if (i2c_send(i2c->bus, i2c->mdata)) {
/* if the target return non zero then end the transfer */
i2c->sts &= ~IIC_STS_PT;
i2c->sts |= IIC_STS_ERR;
i2c->extsts |= IIC_EXTSTS_XFRA;
i2c_end_transfer(i2c->bus);
}
}
break;
case 0x02:
i2c->sdata = value;
break;
case 0x04:
i2c->lmadr = value;
if (i2c_bus_busy(i2c->bus)) {
i2c_end_transfer(i2c->bus);
}
break;
case 0x05:
i2c->hmadr = value;
break;
case 0x06:
i2c->cntl = value;
if (i2c->cntl & IIC_CNTL_PT) {
if (i2c->cntl & IIC_CNTL_READ) {
if (i2c_bus_busy(i2c->bus)) {
/* end previous transfer */
i2c->sts &= ~IIC_STS_PT;
i2c_end_transfer(i2c->bus);
}
if (i2c_start_transfer(i2c->bus, i2c->lmadr >> 1, 1)) {
/* if non zero is returned, the adress is not valid */
i2c->sts &= ~IIC_STS_PT;
i2c->sts |= IIC_STS_ERR;
i2c->extsts |= IIC_EXTSTS_XFRA;
} else {
/*i2c->sts |= IIC_STS_PT;*/
i2c->sts |= IIC_STS_MDBS;
i2c->sts &= ~IIC_STS_ERR;
i2c->extsts = 0;
}
} else {
/* we actually already did the write transfer... */
i2c->sts &= ~IIC_STS_PT;
}
}
break;
case 0x07:
i2c->mdcntl = value & 0xDF;
Expand All @@ -135,6 +275,7 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
break;
case 0x0A:
i2c->lsadr = value;
/*i2c_set_slave_address(i2c->bus, i2c->lsadr);*/
break;
case 0x0B:
i2c->hsadr = value;
Expand All @@ -149,11 +290,23 @@ static void ppc4xx_i2c_writeb(void *opaque, hwaddr addr, uint64_t value,
i2c->xfrcnt = value & 0x77;
break;
case 0x0F:
if (value & IIC_XTCNTLSS_SRST) {
/* Is it actually a full reset? U-Boot sets some regs before */
ppc4xx_i2c_reset(DEVICE(i2c));
break;
}
i2c->xtcntlss = value;
break;
case 0x10:
i2c->directcntl = value & 0x7;
break;
case 0x11:
i2c->intr = value;
break;
default:
qemu_log_mask(LOG_GUEST_ERROR, "[%s]%s: Bad address at offset 0x%"
HWADDR_PRIx "\n", TYPE_PPC4xx_I2C, __func__, addr);
break;
}
}

Expand All @@ -167,21 +320,6 @@ static const MemoryRegionOps ppc4xx_i2c_ops = {
.endianness = DEVICE_NATIVE_ENDIAN,
};

static void ppc4xx_i2c_reset(DeviceState *s)
{
PPC4xxI2CState *i2c = PPC4xx_I2C(s);

i2c->mdata = 0x00;
i2c->sdata = 0x00;
i2c->cntl = 0x00;
i2c->mdcntl = 0x00;
i2c->sts = 0x00;
i2c->extsts = 0x00;
i2c->clkdiv = 0x00;
i2c->xfrcnt = 0x00;
i2c->directcntl = 0x0F;
}

static void ppc4xx_i2c_init(Object *o)
{
PPC4xxI2CState *s = PPC4xx_I2C(o);
Expand Down
1 change: 1 addition & 0 deletions hw/ide/Makefile.objs
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ common-obj-$(CONFIG_MICRODRIVE) += microdrive.o
common-obj-$(CONFIG_AHCI) += ahci.o
common-obj-$(CONFIG_AHCI) += ich.o
common-obj-$(CONFIG_ALLWINNER_A10) += ahci-allwinner.o
common-obj-$(CONFIG_IDE_SII3112) += sii3112.o
Loading

0 comments on commit e890966

Please sign in to comment.