diff options
-rw-r--r-- | hw/misc/mps2-fpgaio.c | 31 | ||||
-rw-r--r-- | include/hw/misc/mps2-fpgaio.h | 5 |
2 files changed, 27 insertions, 9 deletions
diff --git a/hw/misc/mps2-fpgaio.c b/hw/misc/mps2-fpgaio.c index 6af0e8f837..e74dec670f 100644 --- a/hw/misc/mps2-fpgaio.c +++ b/hw/misc/mps2-fpgaio.c @@ -177,9 +177,14 @@ static void mps2_fpgaio_write(void *opaque, hwaddr offset, uint64_t value, switch (offset) { case A_LED0: - s->led0 = value & 0x3; - led_set_state(s->led[0], value & 0x01); - led_set_state(s->led[1], value & 0x02); + if (s->num_leds != 0) { + uint32_t i; + + s->led0 = value & MAKE_64BIT_MASK(0, s->num_leds); + for (i = 0; i < s->num_leds; i++) { + led_set_state(s->led[i], value & (1 << i)); + } + } break; case A_PRESCALE: resync_counter(s); @@ -238,7 +243,7 @@ static void mps2_fpgaio_reset(DeviceState *dev) s->pscntr = 0; s->pscntr_sync_ticks = now; - for (size_t i = 0; i < ARRAY_SIZE(s->led); i++) { + for (size_t i = 0; i < s->num_leds; i++) { device_cold_reset(DEVICE(s->led[i])); } } @@ -256,11 +261,19 @@ static void mps2_fpgaio_init(Object *obj) static void mps2_fpgaio_realize(DeviceState *dev, Error **errp) { MPS2FPGAIO *s = MPS2_FPGAIO(dev); + uint32_t i; + + if (s->num_leds > MPS2FPGAIO_MAX_LEDS) { + error_setg(errp, "num-leds cannot be greater than %d", + MPS2FPGAIO_MAX_LEDS); + return; + } - s->led[0] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH, - LED_COLOR_GREEN, "USERLED0"); - s->led[1] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH, - LED_COLOR_GREEN, "USERLED1"); + for (i = 0; i < s->num_leds; i++) { + g_autofree char *ledname = g_strdup_printf("USERLED%d", i); + s->led[i] = led_create_simple(OBJECT(dev), GPIO_POLARITY_ACTIVE_HIGH, + LED_COLOR_GREEN, ledname); + } } static bool mps2_fpgaio_counters_needed(void *opaque) @@ -303,6 +316,8 @@ static const VMStateDescription mps2_fpgaio_vmstate = { static Property mps2_fpgaio_properties[] = { /* Frequency of the prescale counter */ DEFINE_PROP_UINT32("prescale-clk", MPS2FPGAIO, prescale_clk, 20000000), + /* Number of LEDs controlled by LED0 register */ + DEFINE_PROP_UINT32("num-leds", MPS2FPGAIO, num_leds, 2), DEFINE_PROP_END_OF_LIST(), }; diff --git a/include/hw/misc/mps2-fpgaio.h b/include/hw/misc/mps2-fpgaio.h index a010fdb2b6..bfe73134e7 100644 --- a/include/hw/misc/mps2-fpgaio.h +++ b/include/hw/misc/mps2-fpgaio.h @@ -28,13 +28,16 @@ #define TYPE_MPS2_FPGAIO "mps2-fpgaio" OBJECT_DECLARE_SIMPLE_TYPE(MPS2FPGAIO, MPS2_FPGAIO) +#define MPS2FPGAIO_MAX_LEDS 32 + struct MPS2FPGAIO { /*< private >*/ SysBusDevice parent_obj; /*< public >*/ MemoryRegion iomem; - LEDState *led[2]; + LEDState *led[MPS2FPGAIO_MAX_LEDS]; + uint32_t num_leds; uint32_t led0; uint32_t prescale; |