#define NPCM7XX_CH_INV BIT(2)
#define NPCM7XX_CH_MOD BIT(3)
+#define NPCM7XX_MAX_CMR 65535
+#define NPCM7XX_MAX_CNR 65535
+
/* Offset of each PWM channel's prescaler in the PPR register. */
static const int npcm7xx_ppr_base[] = { 0, 0, 8, 8 };
/* Offset of each PWM channel's clock selector in the CSR register. */
static uint32_t npcm7xx_pwm_calculate_duty(NPCM7xxPWM *p)
{
- uint64_t duty;
+ uint32_t duty;
if (p->running) {
if (p->cnr == 0) {
} else if (p->cmr >= p->cnr) {
duty = NPCM7XX_PWM_MAX_DUTY;
} else {
- duty = NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
+ duty = (uint64_t)NPCM7XX_PWM_MAX_DUTY * (p->cmr + 1) / (p->cnr + 1);
}
} else {
duty = 0;
case A_NPCM7XX_PWM_CNR2:
case A_NPCM7XX_PWM_CNR3:
p = &s->pwm[npcm7xx_cnr_index(offset)];
- p->cnr = value;
+ if (value > NPCM7XX_MAX_CNR) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid cnr value: %u", __func__, value);
+ p->cnr = NPCM7XX_MAX_CNR;
+ } else {
+ p->cnr = value;
+ }
npcm7xx_pwm_update_output(p);
break;
case A_NPCM7XX_PWM_CMR2:
case A_NPCM7XX_PWM_CMR3:
p = &s->pwm[npcm7xx_cmr_index(offset)];
- p->cmr = value;
+ if (value > NPCM7XX_MAX_CMR) {
+ qemu_log_mask(LOG_GUEST_ERROR,
+ "%s: invalid cmr value: %u", __func__, value);
+ p->cmr = NPCM7XX_MAX_CMR;
+ } else {
+ p->cmr = value;
+ }
npcm7xx_pwm_update_output(p);
break;