hw/arm/pxa2xx_gpio: Fix handling of GPSR/GPCR reads

The PXA2xx GPIO GPSR and GPCR registers are write-only, with reads being
undefined behaviour. Instead of having GPCR return 31337 and GPSR return
the value last written, make both log the guest error and return 0.

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Reviewed-by: Peter Crosthwaite <peter.crosthwaite@xilinx.com>
This commit is contained in:
Peter Maydell 2014-06-29 18:38:40 +01:00
parent ed657d7117
commit ab7a0f0b6d

View File

@ -36,7 +36,6 @@ struct PXA2xxGPIOInfo {
uint32_t rising[PXA2XX_GPIO_BANKS]; uint32_t rising[PXA2XX_GPIO_BANKS];
uint32_t falling[PXA2XX_GPIO_BANKS]; uint32_t falling[PXA2XX_GPIO_BANKS];
uint32_t status[PXA2XX_GPIO_BANKS]; uint32_t status[PXA2XX_GPIO_BANKS];
uint32_t gpsr[PXA2XX_GPIO_BANKS];
uint32_t gafr[PXA2XX_GPIO_BANKS * 2]; uint32_t gafr[PXA2XX_GPIO_BANKS * 2];
uint32_t prev_level[PXA2XX_GPIO_BANKS]; uint32_t prev_level[PXA2XX_GPIO_BANKS];
@ -162,14 +161,14 @@ static uint64_t pxa2xx_gpio_read(void *opaque, hwaddr offset,
return s->dir[bank]; return s->dir[bank];
case GPSR: /* GPIO Pin-Output Set registers */ case GPSR: /* GPIO Pin-Output Set registers */
printf("%s: Read from a write-only register " REG_FMT "\n", qemu_log_mask(LOG_GUEST_ERROR,
__FUNCTION__, offset); "pxa2xx GPIO: read from write only register GPSR\n");
return s->gpsr[bank]; /* Return last written value. */ return 0;
case GPCR: /* GPIO Pin-Output Clear registers */ case GPCR: /* GPIO Pin-Output Clear registers */
printf("%s: Read from a write-only register " REG_FMT "\n", qemu_log_mask(LOG_GUEST_ERROR,
__FUNCTION__, offset); "pxa2xx GPIO: read from write only register GPCR\n");
return 31337; /* Specified as unpredictable in the docs. */ return 0;
case GRER: /* GPIO Rising-Edge Detect Enable registers */ case GRER: /* GPIO Rising-Edge Detect Enable registers */
return s->rising[bank]; return s->rising[bank];
@ -217,7 +216,6 @@ static void pxa2xx_gpio_write(void *opaque, hwaddr offset,
case GPSR: /* GPIO Pin-Output Set registers */ case GPSR: /* GPIO Pin-Output Set registers */
s->olevel[bank] |= value; s->olevel[bank] |= value;
pxa2xx_gpio_handler_update(s); pxa2xx_gpio_handler_update(s);
s->gpsr[bank] = value;
break; break;
case GPCR: /* GPIO Pin-Output Clear registers */ case GPCR: /* GPIO Pin-Output Clear registers */