static void stm32_exti_writew(void *opaque, hwaddr offset, uint64_t value) { Stm32Exti *s = (Stm32Exti *)opaque; int pos, bit_value; if(offset <= EXTI_EMR_OFFSET) { switch (offset) { case EXTI_IMR_OFFSET: s->EXTI_IMR = value; break; case EXTI_EMR_OFFSET: /* Do nothing, events are not implemented yet. * But we don't want to throw an error. */ break; default: STM32_BAD_REG(offset, WORD_ACCESS_SIZE); break; } } else { /* These registers all contain one bit per EXTI line. We will loop * through each line and then update each bit in the appropriate * register. */ for(pos = 0; pos < EXTI_LINE_COUNT; pos++) { bit_value = GET_BIT_VALUE(value, pos); switch (offset) { case EXTI_RTSR_OFFSET: update_TSR_bit(s, &(s->EXTI_RTSR), pos, bit_value); break; case EXTI_FTSR_OFFSET: update_TSR_bit(s, &(s->EXTI_FTSR), pos, bit_value); break; case EXTI_SWIER_OFFSET: /* If the Software Interrupt Event Register is changed * from 0 to 1, trigger an interrupt. Changing the * bit to 0 does nothing. */ if(bit_value == 1) { if(GET_BIT_VALUE(s->EXTI_SWIER, pos) == 0) { SET_BIT(s->EXTI_SWIER, pos); stm32_exti_trigger(s, pos); } } break; case EXTI_PR_OFFSET: /* When a 1 is written to a PR bit, it actually clears the * PR bit. */ if(bit_value == 1) { stm32_exti_change_EXTI_PR_bit(s, pos, 0); } break; default: STM32_BAD_REG(offset, WORD_ACCESS_SIZE); break; } } } }
static uint64_t stm32_rcc_readw(void *opaque, hwaddr offset) { Stm32Rcc *s = (Stm32Rcc *)opaque; switch (offset) { case RCC_CR_OFFSET: return stm32_rcc_RCC_CR_read(s); case RCC_CFGR_OFFSET: return stm32_rcc_RCC_CFGR_read(s); case RCC_CIR_OFFSET: return 0; case RCC_APB2RSTR_OFFSET: case RCC_APB1RSTR_OFFSET: case RCC_AHBENR_OFFSET: STM32_NOT_IMPL_REG(offset, 4); return 0; case RCC_APB2ENR_OFFSET: return s->RCC_APB2ENR; case RCC_APB1ENR_OFFSET: return s->RCC_APB1ENR; case RCC_BDCR_OFFSET: return stm32_rcc_RCC_BDCR_read(s); case RCC_CSR_OFFSET: return stm32_rcc_RCC_CSR_read(s); case RCC_AHBRSTR: STM32_NOT_IMPL_REG(offset, 4); return 0; case RCC_CFGR2_OFFSET: STM32_NOT_IMPL_REG(offset, 4); return 0; default: STM32_BAD_REG(offset, 4); break; } }
static uint64_t stm32_exti_read(void *opaque, hwaddr offset, unsigned size) { switch(size) { case WORD_ACCESS_SIZE: return stm32_exti_readw(opaque, offset); default: STM32_BAD_REG(offset, size); return 0; } }
static void stm32_exti_write(void *opaque, hwaddr offset, uint64_t value, unsigned size) { switch(size) { case WORD_ACCESS_SIZE: stm32_exti_writew(opaque, offset, value); break; default: STM32_BAD_REG(offset, size); break; } }
static void stm32_rcc_writew(void *opaque, hwaddr offset, uint64_t value) { Stm32Rcc *s = (Stm32Rcc *)opaque; switch(offset) { case RCC_CR_OFFSET: stm32_rcc_RCC_CR_write(s, value, false); break; case RCC_CFGR_OFFSET: stm32_rcc_RCC_CFGR_write(s, value, false); break; case RCC_CIR_OFFSET: /* Allow a write but don't take any action */ break; case RCC_APB2RSTR_OFFSET: case RCC_APB1RSTR_OFFSET: case RCC_AHBENR_OFFSET: STM32_NOT_IMPL_REG(offset, 4); break; case RCC_APB2ENR_OFFSET: stm32_rcc_RCC_APB2ENR_write(s, value, false); break; case RCC_APB1ENR_OFFSET: stm32_rcc_RCC_APB1ENR_write(s, value, false); break; case RCC_BDCR_OFFSET: stm32_rcc_RCC_BDCR_write(s, value, false); break; case RCC_CSR_OFFSET: stm32_rcc_RCC_CSR_write(s, value, false); break; case RCC_AHBRSTR: STM32_NOT_IMPL_REG(offset, 4); break; case RCC_CFGR2_OFFSET: STM32_NOT_IMPL_REG(offset, 4); break; default: STM32_BAD_REG(offset, 4); break; } }
static uint64_t stm32_exti_readw(void *opaque, hwaddr offset) { Stm32Exti *s = (Stm32Exti *)opaque; switch (offset) { case EXTI_IMR_OFFSET: return s->EXTI_IMR; case EXTI_EMR_OFFSET: /* Do nothing, events are not implemented yet. */ return 0; case EXTI_RTSR_OFFSET: return s->EXTI_RTSR; case EXTI_FTSR_OFFSET: return s->EXTI_FTSR; case EXTI_SWIER_OFFSET: return s->EXTI_SWIER; case EXTI_PR_OFFSET: return s->EXTI_PR; default: STM32_BAD_REG(offset, WORD_ACCESS_SIZE); return 0; } }