using System; using System.Collections.ObjectModel; using Antmicro.Renode.Peripherals.Bus; using Antmicro.Renode.Core; using Antmicro.Renode.Core.Structure.Registers; using Antmicro.Renode.Logging; using System.Collections.Generic; namespace Antmicro.Renode.Peripherals.IRQControllers { public class ESP32S3 : IIRQController, INumberedGPIOOutput, IDoubleWordPeripheral, IProvidesRegisterCollection, IKnownSize { public GPIO IRQ { get; private set; } public DoubleWordRegisterCollection RegistersCollection { get; } public long Size => 0x1000; // 0x1a4 private readonly Machine machine; public IReadOnlyDictionary Connections { get; } public long NumberOfLines => Connections.Count; private Destination[] destinations; private readonly bool[] routingTable; public ESP32S3(Machine machine) { this.machine = machine; IRQ = new GPIO(); RegistersCollection = new DoubleWordRegisterCollection(this); Connections = new IGPIORedirector(100, HandleIRQConnect, HandleIRQDisconnect); DefineRegisters(); Reset(); } private void DefineRegisters() { // mac interrupt configuration register Registers.PRO_MAC_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "MAC_INTR_MAP") // this register used to map mac interrupt to one of core0's external interrupt ; // mac_nmi interrupt configuration register Registers.MAC_NMI_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "MAC_NMI_MAP") // this register used to map_nmi interrupt to one of core0's external interrupt ; // pwr interrupt configuration register Registers.PWR_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "PWR_INTR_MAP") // this register used to map pwr interrupt to one of core0's external interrupt ; // bb interrupt configuration register Registers.BB_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "BB_INT_MAP") // this register used to map bb interrupt to one of core0's external interrupt ; // bb_mac interrupt configuration register Registers.BT_MAC_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "BT_MAC_INT_MAP") // this register used to map bb_mac interrupt to one of core0's external interrupt ; // bt_bb interrupt configuration register Registers.BT_BB_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "BT_BB_INT_MAP") // this register used to map bt_bb interrupt to one of core0's external interrupt ; // bt_bb_nmi interrupt configuration register Registers.BT_BB_NMI_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "BT_BB_NMI_MAP") // this register used to map bb_bt_nmi interrupt to one of core0's external interrupt ; // rwbt_irq interrupt configuration register Registers.RWBT_IRQ_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "RWBT_IRQ_MAP") // this register used to map rwbt_irq interrupt to one of core0's external interrupt ; // rwble_irq interrupt configuration register Registers.RWBLE_IRQ_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "RWBLE_IRQ_MAP") // this register used to map rwble_irq interrupt to one of core0's external interrupt ; // rwbt_nmi interrupt configuration register Registers.RWBT_NMI_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "RWBT_NMI_MAP") // this register used to map mac rwbt_nmi to one of core0's external interrupt ; // rwble_nmi interrupt configuration register Registers.RWBLE_NMI_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "RWBLE_NMI_MAP") // this register used to map rwble_nmi interrupt to one of core0's external interrupt ; // i2c_mst interrupt configuration register Registers.I2C_MST_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "I2C_MST_INT_MAP") // this register used to map i2c_mst interrupt to one of core0's external interrupt ; // slc0 interrupt configuration register Registers.SLC0_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SLC0_INTR_MAP") // this register used to map slc0 interrupt to one of core0's external interrupt ; // slc1 interrupt configuration register Registers.SLC1_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SLC1_INTR_MAP") // this register used to map slc1 interrupt to one of core0's external interrupt ; // uhci0 interrupt configuration register Registers.UHCI0_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "UHCI0_INTR_MAP") // this register used to map uhci0 interrupt to one of core0's external interrupt ; // uhci1 interrupt configuration register Registers.UHCI1_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "UHCI1_INTR_MAP") // this register used to map uhci1 interrupt to one of core0's external interrupt ; // gpio_interrupt_pro interrupt configuration register Registers.GPIO_INTERRUPT_PRO_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "GPIO_INTERRUPT_PRO_MAP") // this register used to map gpio_interrupt_pro interrupt to one of core0's external interrupt ; // gpio_interrupt_pro_nmi interrupt configuration register Registers.GPIO_INTERRUPT_PRO_NMI_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "GPIO_INTERRUPT_PRO_NMI_MAP") // this register used to map gpio_interrupt_pro_nmi interrupt to one of core0's external interrupt ; // gpio_interrupt_app interrupt configuration register Registers.GPIO_INTERRUPT_APP_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "GPIO_INTERRUPT_APP_MAP") // this register used to map gpio_interrupt_app interrupt to one of core0's external interrupt ; // gpio_interrupt_app_nmi interrupt configuration register Registers.GPIO_INTERRUPT_APP_NMI_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "GPIO_INTERRUPT_APP_NMI_MAP") // this register used to map gpio_interrupt_app_nmi interrupt to one of core0's external interrupt ; // spi_intr_1 interrupt configuration register Registers.SPI_INTR_1_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SPI_INTR_1_MAP") // this register used to map spi_intr_1 interrupt to one of core0's external interrupt ; // spi_intr_2 interrupt configuration register Registers.SPI_INTR_2_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SPI_INTR_2_MAP") // this register used to map spi_intr_2 interrupt to one of core0's external interrupt ; // spi_intr_3 interrupt configuration register Registers.SPI_INTR_3_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SPI_INTR_3_MAP") // this register used to map spi_intr_3 interrupt to one of core0's external interrupt ; // spi_intr_4 interrupt configuration register Registers.SPI_INTR_4_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SPI_INTR_4_MAP") // this register used to map spi_intr_4 interrupt to one of core0's external interrupt ; // lcd_cam interrupt configuration register Registers.LCD_CAM_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "LCD_CAM_INT_MAP") // this register used to map lcd_cam interrupt to one of core0's external interrupt ; // i2s0 interrupt configuration register Registers.I2S0_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "I2S0_INT_MAP") // this register used to map i2s0 interrupt to one of core0's external interrupt ; // i2s1 interrupt configuration register Registers.I2S1_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "I2S1_INT_MAP") // this register used to map i2s1 interrupt to one of core0's external interrupt ; // uart interrupt configuration register Registers.UART_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "UART_INTR_MAP") // this register used to map uart interrupt to one of core0's external interrupt ; // uart1 interrupt configuration register Registers.UART1_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "UART1_INTR_MAP") // this register used to map uart1 interrupt to one of core0's external interrupt ; // uart2 interrupt configuration register Registers.UART2_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "UART2_INTR_MAP") // this register used to map uart2 interrupt to one of core0's external interrupt ; // sdio_host interrupt configuration register Registers.SDIO_HOST_INTERRUPT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SDIO_HOST_INTERRUPT_MAP") // this register used to map sdio_host interrupt to one of core0's external interrupt ; // pwm0 interrupt configuration register Registers.PWM0_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "PWM0_INTR_MAP") // this register used to map pwm0 interrupt to one of core0's external interrupt ; // pwm1 interrupt configuration register Registers.PWM1_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "PWM1_INTR_MAP") // this register used to map pwm1 interrupt to one of core0's external interrupt ; // pwm2 interrupt configuration register Registers.PWM2_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "PWM2_INTR_MAP") // this register used to map pwm2 interrupt to one of core0's external interrupt ; // pwm3 interrupt configuration register Registers.PWM3_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "PWM3_INTR_MAP") // this register used to map pwm3 interrupt to one of core0's external interrupt ; // ledc interrupt configuration register Registers.LEDC_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "LEDC_INT_MAP") // this register used to map ledc interrupt to one of core0's external interrupt ; // efuse interrupt configuration register Registers.EFUSE_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "EFUSE_INT_MAP") // this register used to map efuse interrupt to one of core0's external interrupt ; // can interrupt configuration register Registers.CAN_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CAN_INT_MAP") // this register used to map can interrupt to one of core0's external interrupt ; // usb interrupt configuration register Registers.USB_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "USB_INTR_MAP") // this register used to map usb interrupt to one of core0's external interrupt ; // rtc_core interrupt configuration register Registers.RTC_CORE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "RTC_CORE_INTR_MAP") // this register used to map rtc_core interrupt to one of core0's external interrupt ; // rmt interrupt configuration register Registers.RMT_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "RMT_INTR_MAP") // this register used to map rmt interrupt to one of core0's external interrupt ; // pcnt interrupt configuration register Registers.PCNT_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "PCNT_INTR_MAP") // this register used to map pcnt interrupt to one of core0's external interrupt ; // i2c_ext0 interrupt configuration register Registers.I2C_EXT0_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "I2C_EXT0_INTR_MAP") // this register used to map i2c_ext0 interrupt to one of core0's external interrupt ; // i2c_ext1 interrupt configuration register Registers.I2C_EXT1_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "I2C_EXT1_INTR_MAP") // this register used to map i2c_ext1 interrupt to one of core0's external interrupt ; // spi2_dma interrupt configuration register Registers.SPI2_DMA_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SPI2_DMA_INT_MAP") // this register used to map spi2_dma interrupt to one of core0's external interrupt ; // spi3_dma interrupt configuration register Registers.SPI3_DMA_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SPI3_DMA_INT_MAP") // this register used to map spi3_dma interrupt to one of core0's external interrupt ; // spi4_dma interrupt configuration register Registers.SPI4_DMA_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SPI4_DMA_INT_MAP") // this register used to map spi4_dma interrupt to one of core0's external interrupt ; // wdg interrupt configuration register Registers.WDG_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "WDG_INT_MAP") // this register used to map wdg interrupt to one of core0's external interrupt ; // timer_int1 interrupt configuration register Registers.TIMER_INT1_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "TIMER_INT1_MAP") // this register used to map timer_int1 interrupt to one of core0's external interrupt ; // timer_int2 interrupt configuration register Registers.TIMER_INT2_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "TIMER_INT2_MAP") // this register used to map timer_int2 interrupt to one of core0's external interrupt ; // tg_t0 interrupt configuration register Registers.TG_T0_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "TG_T0_INT_MAP") // this register used to map tg_t0 interrupt to one of core0's external interrupt ; // tg_t1 interrupt configuration register Registers.TG_T1_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "TG_T1_INT_MAP") // this register used to map tg_t1 interrupt to one of core0's external interrupt ; // tg_wdt interrupt configuration register Registers.TG_WDT_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "TG_WDT_INT_MAP") // this register used to map rg_wdt interrupt to one of core0's external interrupt ; // tg1_t0 interrupt configuration register Registers.TG1_T0_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "TG1_T0_INT_MAP") // this register used to map tg1_t0 interrupt to one of core0's external interrupt ; // tg1_t1 interrupt configuration register Registers.TG1_T1_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "TG1_T1_INT_MAP") // this register used to map tg1_t1 interrupt to one of core0's external interrupt ; // tg1_wdt interrupt configuration register Registers.TG1_WDT_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "TG1_WDT_INT_MAP") // this register used to map tg1_wdt interrupt to one of core0's external interrupt ; // cache_ia interrupt configuration register Registers.CACHE_IA_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CACHE_IA_INT_MAP") // this register used to map cache_ia interrupt to one of core0's external interrupt ; // systimer_target0 interrupt configuration register Registers.SYSTIMER_TARGET0_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SYSTIMER_TARGET0_INT_MAP") // this register used to map systimer_target0 interrupt to one of core0's external interrupt ; // systimer_target1 interrupt configuration register Registers.SYSTIMER_TARGET1_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SYSTIMER_TARGET1_INT_MAP") // this register used to map systimer_target1 interrupt to one of core0's external interrupt ; // systimer_target2 interrupt configuration register Registers.SYSTIMER_TARGET2_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SYSTIMER_TARGET2_INT_MAP") // this register used to map systimer_target2 interrupt to one of core0's external interrupt ; // spi_mem_reject interrupt configuration register Registers.SPI_MEM_REJECT_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SPI_MEM_REJECT_INTR_MAP") // this register used to map spi_mem_reject interrupt to one of core0's external interrupt ; // dcache_prelaod interrupt configuration register Registers.DCACHE_PRELOAD_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DCACHE_PRELOAD_INT_MAP") // this register used to map dcache_prelaod interrupt to one of core0's external interrupt ; // icache_preload interrupt configuration register Registers.ICACHE_PRELOAD_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "ICACHE_PRELOAD_INT_MAP") // this register used to map icache_preload interrupt to one of core0's external interrupt ; // dcache_sync interrupt configuration register Registers.DCACHE_SYNC_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DCACHE_SYNC_INT_MAP") // this register used to map dcache_sync interrupt to one of core0's external interrupt ; // icache_sync interrupt configuration register Registers.ICACHE_SYNC_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "ICACHE_SYNC_INT_MAP") // this register used to map icache_sync interrupt to one of core0's external interrupt ; // apb_adc interrupt configuration register Registers.APB_ADC_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "APB_ADC_INT_MAP") // this register used to map apb_adc interrupt to one of core0's external interrupt ; // dma_in_ch0 interrupt configuration register Registers.DMA_IN_CH0_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_IN_CH0_INT_MAP") // this register used to map dma_in_ch0 interrupt to one of core0's external interrupt ; // dma_in_ch1 interrupt configuration register Registers.DMA_IN_CH1_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_IN_CH1_INT_MAP") // this register used to map dma_in_ch1 interrupt to one of core0's external interrupt ; // dma_in_ch2 interrupt configuration register Registers.DMA_IN_CH2_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_IN_CH2_INT_MAP") // this register used to map dma_in_ch2 interrupt to one of core0's external interrupt ; // dma_in_ch3 interrupt configuration register Registers.DMA_IN_CH3_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_IN_CH3_INT_MAP") // this register used to map dma_in_ch3 interrupt to one of core0's external interrupt ; // dma_in_ch4 interrupt configuration register Registers.DMA_IN_CH4_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_IN_CH4_INT_MAP") // this register used to map dma_in_ch4 interrupt to one of core0's external interrupt ; // dma_out_ch0 interrupt configuration register Registers.DMA_OUT_CH0_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_OUT_CH0_INT_MAP") // this register used to map dma_out_ch0 interrupt to one of core0's external interrupt ; // dma_out_ch1 interrupt configuration register Registers.DMA_OUT_CH1_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_OUT_CH1_INT_MAP") // this register used to map dma_out_ch1 interrupt to one of core0's external interrupt ; // dma_out_ch2 interrupt configuration register Registers.DMA_OUT_CH2_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_OUT_CH2_INT_MAP") // this register used to map dma_out_ch2 interrupt to one of core0's external interrupt ; // dma_out_ch3 interrupt configuration register Registers.DMA_OUT_CH3_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_OUT_CH3_INT_MAP") // this register used to map dma_out_ch3 interrupt to one of core0's external interrupt ; // dma_out_ch4 interrupt configuration register Registers.DMA_OUT_CH4_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_OUT_CH4_INT_MAP") // this register used to map dma_out_ch4 interrupt to one of core0's external interrupt ; // rsa interrupt configuration register Registers.RSA_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "RSA_INT_MAP") // this register used to map rsa interrupt to one of core0's external interrupt ; // aes interrupt configuration register Registers.AES_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "AES_INT_MAP") // this register used to map aes interrupt to one of core0's external interrupt ; // sha interrupt configuration register Registers.SHA_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "SHA_INT_MAP") // this register used to map sha interrupt to one of core0's external interrupt ; // cpu_intr_from_cpu_0 interrupt configuration register Registers.CPU_INTR_FROM_CPU_0_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CPU_INTR_FROM_CPU_0_MAP") // this register used to map cpu_intr_from_cpu_0 interrupt to one of core0's external interrupt ; // cpu_intr_from_cpu_1 interrupt configuration register Registers.CPU_INTR_FROM_CPU_1_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CPU_INTR_FROM_CPU_1_MAP") // this register used to map cpu_intr_from_cpu_1 interrupt to one of core0's external interrupt ; // cpu_intr_from_cpu_2 interrupt configuration register Registers.CPU_INTR_FROM_CPU_2_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CPU_INTR_FROM_CPU_2_MAP") // this register used to map cpu_intr_from_cpu_2 interrupt to one of core0's external interrupt ; // cpu_intr_from_cpu_3 interrupt configuration register Registers.CPU_INTR_FROM_CPU_3_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CPU_INTR_FROM_CPU_3_MAP") // this register used to map cpu_intr_from_cpu_3 interrupt to one of core0's external interrupt ; // assist_debug interrupt configuration register Registers.ASSIST_DEBUG_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "ASSIST_DEBUG_INTR_MAP") // this register used to map assist_debug interrupt to one of core0's external interrupt ; // dma_pms_monitor_violatile interrupt configuration register Registers.DMA_APBPERI_PMS_MONITOR_VIOLATE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_APBPERI_PMS_MONITOR_VIOLATE_INTR_MAP") // this register used to map dma_pms_monitor_violatile interrupt to one of core0's external interrupt ; // core0_IRam0_pms_monitor_violatile interrupt configuration register Registers.CORE_0_IRAM0_PMS_MONITOR_VIOLATE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CORE_0_IRAM0_PMS_MONITOR_VIOLATE_INTR_MAP") // this register used to map core0_IRam0_pms_monitor_violatile interrupt to one of core0's external interrupt ; // core0_DRam0_pms_monitor_violatile interrupt configuration register Registers.CORE_0_DRAM0_PMS_MONITOR_VIOLATE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CORE_0_DRAM0_PMS_MONITOR_VIOLATE_INTR_MAP") // this register used to map core0_DRam0_pms_monitor_violatile interrupt to one of core0's external interrupt ; // core0_PIF_pms_monitor_violatile interrupt configuration register Registers.CORE_0_PIF_PMS_MONITOR_VIOLATE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CORE_0_PIF_PMS_MONITOR_VIOLATE_INTR_MAP") // this register used to map core0_PIF_pms_monitor_violatile interrupt to one of core0's external interrupt ; // core0_PIF_pms_monitor_violatile_size interrupt configuration register Registers.CORE_0_PIF_PMS_MONITOR_VIOLATE_SIZE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CORE_0_PIF_PMS_MONITOR_VIOLATE_SIZE_INTR_MAP") // this register used to map core0_PIF_pms_monitor_violatile_size interrupt to one of core0's external interrupt ; // core1_IRam0_pms_monitor_violatile interrupt configuration register Registers.CORE_1_IRAM0_PMS_MONITOR_VIOLATE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CORE_1_IRAM0_PMS_MONITOR_VIOLATE_INTR_MAP") // this register used to map core1_IRam0_pms_monitor_violatile interrupt to one of core0's external interrupt ; // core1_DRam0_pms_monitor_violatile interrupt configuration register Registers.CORE_1_DRAM0_PMS_MONITOR_VIOLATE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CORE_1_DRAM0_PMS_MONITOR_VIOLATE_INTR_MAP") // this register used to map core1_DRam0_pms_monitor_violatile interrupt to one of core0's external interrupt ; // core1_PIF_pms_monitor_violatile interrupt configuration register Registers.CORE_1_PIF_PMS_MONITOR_VIOLATE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CORE_1_PIF_PMS_MONITOR_VIOLATE_INTR_MAP") // this register used to map core1_PIF_pms_monitor_violatile interrupt to one of core0's external interrupt ; // core1_PIF_pms_monitor_violatile_size interrupt configuration register Registers.CORE_1_PIF_PMS_MONITOR_VIOLATE_SIZE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CORE_1_PIF_PMS_MONITOR_VIOLATE_SIZE_INTR_MAP") // this register used to map core1_PIF_pms_monitor_violatile_size interrupt to one of core0's external interrupt ; // backup_pms_monitor_violatile interrupt configuration register Registers.BACKUP_PMS_VIOLATE_INTR_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "BACKUP_PMS_VIOLATE_INTR_MAP") // this register used to map backup_pms_monitor_violatile interrupt to one of core0's external interrupt ; // cache_core0_acs interrupt configuration register Registers.CACHE_CORE0_ACS_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CACHE_CORE0_ACS_INT_MAP") // this register used to map cache_core0_acs interrupt to one of core0's external interrupt ; // cache_core1_acs interrupt configuration register Registers.CACHE_CORE1_ACS_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "CACHE_CORE1_ACS_INT_MAP") // this register used to map cache_core1_acs interrupt to one of core0's external interrupt ; // usb_device interrupt configuration register Registers.USB_DEVICE_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "USB_DEVICE_INT_MAP") // this register used to map usb_device interrupt to one of core0's external interrupt ; // peri_backup interrupt configuration register Registers.PERI_BACKUP_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "PERI_BACKUP_INT_MAP") // this register used to map peri_backup interrupt to one of core0's external interrupt ; // dma_extmem_reject interrupt configuration register Registers.DMA_EXTMEM_REJECT_INT_MAP.Define(this, 0x10) .WithValueField(0, 5, FieldMode.Read | FieldMode.Write, name: "DMA_EXTMEM_REJECT_INT_MAP") // this register used to map dma_extmem_reject interrupt to one of core0's external interrupt ; // interrupt status register Registers.PRO_INTR_STATUS_0.Define(this, 0x0) .WithValueField(0, 32, FieldMode.Read, name: "INTR_STATUS_0") // this register store the status of the first 32 interrupt source ; // interrupt status register Registers.PRO_INTR_STATUS_1.Define(this, 0x0) .WithValueField(0, 32, FieldMode.Read, name: "INTR_STATUS_1") // this register store the status of the first 32 interrupt source ; // interrupt status register Registers.PRO_INTR_STATUS_2.Define(this, 0x0) .WithValueField(0, 32, FieldMode.Read, name: "INTR_STATUS_2") // this register store the status of the first 32 interrupt source ; // interrupt status register Registers.PRO_INTR_STATUS_3.Define(this, 0x0) .WithValueField(0, 32, FieldMode.Read, name: "INTR_STATUS_3") // this register store the status of the first 32 interrupt source ; // clock gate register Registers.CLOCK_GATE.Define(this, 0x1) .WithFlag(0, FieldMode.Read | FieldMode.Write, name: "REG_CLK_EN") // this register uesd to control clock-gating interupt martrix ; // version register Registers.DATE.Define(this, 0x2012300) .WithValueField(0, 28, FieldMode.Read | FieldMode.Write, name: "INTERRUPT_REG_DATE") // version register ; } public void Reset() { RegistersCollection.Reset(); Array.Clear(routingTable, 0, routingTable.Length); UpdateInterrupts(); } private void HandleIRQConnect(int sourceNumber, IGPIOReceiver destination, int destinationNumber) { lock (routingTable) { destinations[sourceNumber] = new Destination(destination, destinationNumber); } } private void HandleIRQDisconnect(int sourceNumber) { lock (routingTable) { destinations[sourceNumber] = new Destination(); } } public void OnGPIO(int number, bool value) { lock (routingTable) { if (routingTable[number]) { destinations[number].OnGPIO(value); } } } public uint ReadDoubleWord(long offset) { return RegistersCollection.Read(offset); } public void WriteDoubleWord(long offset, uint value) { RegistersCollection.Write(offset, value); } private void UpdateInterrupts() { var status = false; this.Log(LogLevel.Noisy, "Setting IRQ to {0}", status); IRQ.Set(status); } private enum Registers { PRO_MAC_INTR_MAP = 0x0, MAC_NMI_MAP = 0x4, PWR_INTR_MAP = 0x8, BB_INT_MAP = 0xc, BT_MAC_INT_MAP = 0x10, BT_BB_INT_MAP = 0x14, BT_BB_NMI_MAP = 0x18, RWBT_IRQ_MAP = 0x1c, RWBLE_IRQ_MAP = 0x20, RWBT_NMI_MAP = 0x24, RWBLE_NMI_MAP = 0x28, I2C_MST_INT_MAP = 0x2c, SLC0_INTR_MAP = 0x30, SLC1_INTR_MAP = 0x34, UHCI0_INTR_MAP = 0x38, UHCI1_INTR_MAP = 0x3c, GPIO_INTERRUPT_PRO_MAP = 0x40, GPIO_INTERRUPT_PRO_NMI_MAP = 0x44, GPIO_INTERRUPT_APP_MAP = 0x48, GPIO_INTERRUPT_APP_NMI_MAP = 0x4c, SPI_INTR_1_MAP = 0x50, SPI_INTR_2_MAP = 0x54, SPI_INTR_3_MAP = 0x58, SPI_INTR_4_MAP = 0x5c, LCD_CAM_INT_MAP = 0x60, I2S0_INT_MAP = 0x64, I2S1_INT_MAP = 0x68, UART_INTR_MAP = 0x6c, UART1_INTR_MAP = 0x70, UART2_INTR_MAP = 0x74, SDIO_HOST_INTERRUPT_MAP = 0x78, PWM0_INTR_MAP = 0x7c, PWM1_INTR_MAP = 0x80, PWM2_INTR_MAP = 0x84, PWM3_INTR_MAP = 0x88, LEDC_INT_MAP = 0x8c, EFUSE_INT_MAP = 0x90, CAN_INT_MAP = 0x94, USB_INTR_MAP = 0x98, RTC_CORE_INTR_MAP = 0x9c, RMT_INTR_MAP = 0xa0, PCNT_INTR_MAP = 0xa4, I2C_EXT0_INTR_MAP = 0xa8, I2C_EXT1_INTR_MAP = 0xac, SPI2_DMA_INT_MAP = 0xb0, SPI3_DMA_INT_MAP = 0xb4, SPI4_DMA_INT_MAP = 0xb8, WDG_INT_MAP = 0xbc, TIMER_INT1_MAP = 0xc0, TIMER_INT2_MAP = 0xc4, TG_T0_INT_MAP = 0xc8, TG_T1_INT_MAP = 0xcc, TG_WDT_INT_MAP = 0xd0, TG1_T0_INT_MAP = 0xd4, TG1_T1_INT_MAP = 0xd8, TG1_WDT_INT_MAP = 0xdc, CACHE_IA_INT_MAP = 0xe0, SYSTIMER_TARGET0_INT_MAP = 0xe4, SYSTIMER_TARGET1_INT_MAP = 0xe8, SYSTIMER_TARGET2_INT_MAP = 0xec, SPI_MEM_REJECT_INTR_MAP = 0xf0, DCACHE_PRELOAD_INT_MAP = 0xf4, ICACHE_PRELOAD_INT_MAP = 0xf8, DCACHE_SYNC_INT_MAP = 0xfc, ICACHE_SYNC_INT_MAP = 0x100, APB_ADC_INT_MAP = 0x104, DMA_IN_CH0_INT_MAP = 0x108, DMA_IN_CH1_INT_MAP = 0x10c, DMA_IN_CH2_INT_MAP = 0x110, DMA_IN_CH3_INT_MAP = 0x114, DMA_IN_CH4_INT_MAP = 0x118, DMA_OUT_CH0_INT_MAP = 0x11c, DMA_OUT_CH1_INT_MAP = 0x120, DMA_OUT_CH2_INT_MAP = 0x124, DMA_OUT_CH3_INT_MAP = 0x128, DMA_OUT_CH4_INT_MAP = 0x12c, RSA_INT_MAP = 0x130, AES_INT_MAP = 0x134, SHA_INT_MAP = 0x138, CPU_INTR_FROM_CPU_0_MAP = 0x13c, CPU_INTR_FROM_CPU_1_MAP = 0x140, CPU_INTR_FROM_CPU_2_MAP = 0x144, CPU_INTR_FROM_CPU_3_MAP = 0x148, ASSIST_DEBUG_INTR_MAP = 0x14c, DMA_APBPERI_PMS_MONITOR_VIOLATE_INTR_MAP = 0x150, CORE_0_IRAM0_PMS_MONITOR_VIOLATE_INTR_MAP = 0x154, CORE_0_DRAM0_PMS_MONITOR_VIOLATE_INTR_MAP = 0x158, CORE_0_PIF_PMS_MONITOR_VIOLATE_INTR_MAP = 0x15c, CORE_0_PIF_PMS_MONITOR_VIOLATE_SIZE_INTR_MAP = 0x160, CORE_1_IRAM0_PMS_MONITOR_VIOLATE_INTR_MAP = 0x164, CORE_1_DRAM0_PMS_MONITOR_VIOLATE_INTR_MAP = 0x168, CORE_1_PIF_PMS_MONITOR_VIOLATE_INTR_MAP = 0x16c, CORE_1_PIF_PMS_MONITOR_VIOLATE_SIZE_INTR_MAP = 0x170, BACKUP_PMS_VIOLATE_INTR_MAP = 0x174, CACHE_CORE0_ACS_INT_MAP = 0x178, CACHE_CORE1_ACS_INT_MAP = 0x17c, USB_DEVICE_INT_MAP = 0x180, PERI_BACKUP_INT_MAP = 0x184, DMA_EXTMEM_REJECT_INT_MAP = 0x188, PRO_INTR_STATUS_0 = 0x18c, PRO_INTR_STATUS_1 = 0x190, PRO_INTR_STATUS_2 = 0x194, PRO_INTR_STATUS_3 = 0x198, CLOCK_GATE = 0x19c, DATE = 0x7fc, } private struct Destination { public Destination(IGPIOReceiver receiver, int destinationNo) { this.receiver = receiver; this.destinationNo = destinationNo; } public void OnGPIO(bool state) { receiver.OnGPIO(destinationNo, state); } public readonly IGPIOReceiver receiver; public readonly int destinationNo; } } }