diff options
Diffstat (limited to 'hw/misc/bcm2835_property.c')
-rw-r--r-- | hw/misc/bcm2835_property.c | 98 |
1 files changed, 53 insertions, 45 deletions
diff --git a/hw/misc/bcm2835_property.c b/hw/misc/bcm2835_property.c index 63de3db..a21c6a5 100644 --- a/hw/misc/bcm2835_property.c +++ b/hw/misc/bcm2835_property.c @@ -13,7 +13,7 @@ #include "hw/irq.h" #include "hw/misc/bcm2835_mbox_defs.h" #include "hw/arm/raspberrypi-fw-defs.h" -#include "sysemu/dma.h" +#include "system/dma.h" #include "qemu/log.h" #include "qemu/module.h" #include "trace.h" @@ -25,14 +25,7 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) { - uint32_t tag; - uint32_t bufsize; uint32_t tot_len; - size_t resplen; - uint32_t tmp; - int n; - uint32_t offset, length, color; - uint32_t start_num, number, otp_row; /* * Copy the current state of the framebuffer config; we will update @@ -51,10 +44,10 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) /* @(addr + 4) : Buffer response code */ value = s->addr + 8; while (value + 8 <= s->addr + tot_len) { - tag = ldl_le_phys(&s->dma_as, value); - bufsize = ldl_le_phys(&s->dma_as, value + 4); + uint32_t tag = ldl_le_phys(&s->dma_as, value); + uint32_t bufsize = ldl_le_phys(&s->dma_as, value + 4); /* @(value + 8) : Request/response indicator */ - resplen = 0; + size_t resplen = 0; switch (tag) { case RPI_FWREQ_PROPERTY_END: break; @@ -98,13 +91,16 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) resplen = 8; break; case RPI_FWREQ_SET_POWER_STATE: - /* Assume that whatever device they asked for exists, - * and we'll just claim we set it to the desired state + { + /* + * Assume that whatever device they asked for exists, + * and we'll just claim we set it to the desired state. */ - tmp = ldl_le_phys(&s->dma_as, value + 16); - stl_le_phys(&s->dma_as, value + 16, (tmp & 1)); + uint32_t state = ldl_le_phys(&s->dma_as, value + 16); + stl_le_phys(&s->dma_as, value + 16, (state & 1)); resplen = 8; break; + } /* Clocks */ @@ -274,19 +270,25 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) resplen = 16; break; case RPI_FWREQ_FRAMEBUFFER_SET_PALETTE: - offset = ldl_le_phys(&s->dma_as, value + 12); - length = ldl_le_phys(&s->dma_as, value + 16); - n = 0; - while (n < length - offset) { - color = ldl_le_phys(&s->dma_as, value + 20 + (n << 2)); - stl_le_phys(&s->dma_as, - s->fbdev->vcram_base + ((offset + n) << 2), color); - n++; + { + uint32_t offset = ldl_le_phys(&s->dma_as, value + 12); + uint32_t length = ldl_le_phys(&s->dma_as, value + 16); + int resp; + + if (offset > 255 || length < 1 || length > 256) { + resp = 1; /* invalid request */ + } else { + for (uint32_t e = 0; e < length; e++) { + uint32_t color = ldl_le_phys(&s->dma_as, value + 20 + (e << 2)); + stl_le_phys(&s->dma_as, + s->fbdev->vcram_base + ((offset + e) << 2), color); + } + resp = 0; } - stl_le_phys(&s->dma_as, value + 12, 0); + stl_le_phys(&s->dma_as, value + 12, resp); resplen = 4; break; - + } case RPI_FWREQ_FRAMEBUFFER_GET_NUM_DISPLAYS: stl_le_phys(&s->dma_as, value + 12, 1); resplen = 4; @@ -327,22 +329,25 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) /* Customer OTP */ case RPI_FWREQ_GET_CUSTOMER_OTP: - start_num = ldl_le_phys(&s->dma_as, value + 12); - number = ldl_le_phys(&s->dma_as, value + 16); + { + uint32_t start_num = ldl_le_phys(&s->dma_as, value + 12); + uint32_t number = ldl_le_phys(&s->dma_as, value + 16); resplen = 8 + 4 * number; - for (n = start_num; n < start_num + number && + for (uint32_t n = start_num; n < start_num + number && n < BCM2835_OTP_CUSTOMER_OTP_LEN; n++) { - otp_row = bcm2835_otp_get_row(s->otp, + uint32_t otp_row = bcm2835_otp_get_row(s->otp, BCM2835_OTP_CUSTOMER_OTP + n); stl_le_phys(&s->dma_as, value + 20 + ((n - start_num) << 2), otp_row); } break; + } case RPI_FWREQ_SET_CUSTOMER_OTP: - start_num = ldl_le_phys(&s->dma_as, value + 12); - number = ldl_le_phys(&s->dma_as, value + 16); + { + uint32_t start_num = ldl_le_phys(&s->dma_as, value + 12); + uint32_t number = ldl_le_phys(&s->dma_as, value + 16); resplen = 4; @@ -361,34 +366,37 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) break; } - for (n = start_num; n < start_num + number && + for (uint32_t n = start_num; n < start_num + number && n < BCM2835_OTP_CUSTOMER_OTP_LEN; n++) { - otp_row = ldl_le_phys(&s->dma_as, + uint32_t otp_row = ldl_le_phys(&s->dma_as, value + 20 + ((n - start_num) << 2)); bcm2835_otp_set_row(s->otp, BCM2835_OTP_CUSTOMER_OTP + n, otp_row); } break; + } /* Device-specific private key */ - case RPI_FWREQ_GET_PRIVATE_KEY: - start_num = ldl_le_phys(&s->dma_as, value + 12); - number = ldl_le_phys(&s->dma_as, value + 16); + { + uint32_t start_num = ldl_le_phys(&s->dma_as, value + 12); + uint32_t number = ldl_le_phys(&s->dma_as, value + 16); resplen = 8 + 4 * number; - for (n = start_num; n < start_num + number && + for (uint32_t n = start_num; n < start_num + number && n < BCM2835_OTP_PRIVATE_KEY_LEN; n++) { - otp_row = bcm2835_otp_get_row(s->otp, + uint32_t otp_row = bcm2835_otp_get_row(s->otp, BCM2835_OTP_PRIVATE_KEY + n); stl_le_phys(&s->dma_as, value + 20 + ((n - start_num) << 2), otp_row); } break; + } case RPI_FWREQ_SET_PRIVATE_KEY: - start_num = ldl_le_phys(&s->dma_as, value + 12); - number = ldl_le_phys(&s->dma_as, value + 16); + { + uint32_t start_num = ldl_le_phys(&s->dma_as, value + 12); + uint32_t number = ldl_le_phys(&s->dma_as, value + 16); resplen = 4; @@ -398,14 +406,15 @@ static void bcm2835_property_mbox_push(BCM2835PropertyState *s, uint32_t value) break; } - for (n = start_num; n < start_num + number && + for (uint32_t n = start_num; n < start_num + number && n < BCM2835_OTP_PRIVATE_KEY_LEN; n++) { - otp_row = ldl_le_phys(&s->dma_as, + uint32_t otp_row = ldl_le_phys(&s->dma_as, value + 20 + ((n - start_num) << 2)); bcm2835_otp_set_row(s->otp, BCM2835_OTP_PRIVATE_KEY + n, otp_row); } break; + } default: qemu_log_mask(LOG_UNIMP, "bcm2835_property: unhandled tag 0x%08x\n", tag); @@ -542,13 +551,12 @@ static void bcm2835_property_realize(DeviceState *dev, Error **errp) bcm2835_property_reset(dev); } -static Property bcm2835_property_props[] = { +static const Property bcm2835_property_props[] = { DEFINE_PROP_UINT32("board-rev", BCM2835PropertyState, board_rev, 0), DEFINE_PROP_STRING("command-line", BCM2835PropertyState, command_line), - DEFINE_PROP_END_OF_LIST() }; -static void bcm2835_property_class_init(ObjectClass *klass, void *data) +static void bcm2835_property_class_init(ObjectClass *klass, const void *data) { DeviceClass *dc = DEVICE_CLASS(klass); |