diff --git a/badge.repl b/badge.repl index 786566c..937b37e 100644 --- a/badge.repl +++ b/badge.repl @@ -38,6 +38,8 @@ uart1: UART.ESP32_UART @ sysbus 0x60010000 extmem: Miscellaneous.ESP32S3_EXTMEM @ sysbus 0x600C4000 gpio: GPIOPort.ESP32S3_GPIO @ sysbus 0x60004000 +//spi1: SPI.ESP32_SPIController @ sysbus 0x60002000 + // EFUSES efuse: Memory.MappedMemory @ sysbus 0x60007000 size: 0x1000 @@ -45,13 +47,6 @@ efuse: Memory.MappedMemory @ sysbus 0x60007000 // RTC Control rtc_cntl: Miscellaneous.ESP32S3_RTC_CNTL @ sysbus 0x60008000 -flash: - size: 0x200000 - -spiflash: SPI.Micron_MT25Q @ usart2 - irq: 20 - underlyingMemory: flash - sysbus: init: ApplySVD @esp32s3.svd diff --git a/badge.resc b/badge.resc index fa8e129..1e3dc2a 100644 --- a/badge.resc +++ b/badge.resc @@ -5,6 +5,7 @@ # we can include files relative to ourselves. path add $ORIGIN +i @peripherals/ESP32_SPIController.cs i @peripherals/ESP32_UART.cs i @peripherals/ESP32S3_EXTMEM.cs i @peripherals/ESP32S3_GPIO.cs diff --git a/blackmagic.elf b/blackmagic.elf new file mode 100644 index 0000000..756de35 Binary files /dev/null and b/blackmagic.elf differ diff --git a/bootloader.elf b/bootloader.elf new file mode 100644 index 0000000..71969e1 Binary files /dev/null and b/bootloader.elf differ diff --git a/peripherals/ESP32S3_Interrupt_Core0.cs b/peripherals/ESP32S3_Interrupt_Core0.cs new file mode 100644 index 0000000..b9828d7 --- /dev/null +++ b/peripherals/ESP32S3_Interrupt_Core0.cs @@ -0,0 +1,740 @@ +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; + } + } +} diff --git a/svd-to-renode.py b/svd-to-renode.py index 1de2926..01c3cc3 100644 --- a/svd-to-renode.py +++ b/svd-to-renode.py @@ -82,7 +82,9 @@ class SVDExtractor: if "\n" in register_description: raise Exception("Register description contains a newline") print(f" // {register_description}") - print(f" Registers.{register_name}.Define(this, {hex(register_default)})") + print( + f" Registers.{register_name}.Define(this, {hex(register_default)})" + ) for field in register.find("fields").iter("field"): field_offset = int(field.find("bitOffset").text, 0) field_width = int(field.find("bitWidth").text, 0) @@ -137,7 +139,7 @@ class SVDExtractor: print(" private void UpdateInterrupts()") print(" {") print(" var status = false;") - print(" this.Log(LogLevel.Noisy, \"Setting IRQ to {0}\", status);") + print(' this.Log(LogLevel.Noisy, "Setting IRQ to {0}", status);') print(" IRQ.Set(status);") print(" }") print() @@ -152,20 +154,36 @@ class SVDExtractor: if __name__ == "__main__": extractor = SVDExtractor("esp32s3.svd") + # extractor.extract( + # "SPI1", + # "Antmicro.Renode.Peripherals.SPI", + # "ESP32_SPIController", + # imports=[ + # "System.Linq", + # "System.Collections.Generic", + # "Antmicro.Renode.Core", + # "Antmicro.Renode.Core.Structure", + # "Antmicro.Renode.Core.Structure.Registers", + # "Antmicro.Renode.Logging", + # "Antmicro.Renode.Peripherals.Bus", + # "Antmicro.Renode.Peripherals.Memory", + # "Antmicro.Renode.Peripherals.MTD", + # ], + # extra_subclasses=["NullRegistrationPointPeripheralContainer"], + # ) extractor.extract( - "SPI1", - "Antmicro.Renode.Peripherals.SPI", - "ESP32_SPIController", + "INTERRUPT_CORE0", + "Antmicro.Renode.Peripherals.IRQControllers", + "ESP32S3", imports=[ - "System.Linq", - "System.Collections.Generic", + "System", + "System.Collections.ObjectModel", + "Antmicro.Renode.Peripherals.Bus", "Antmicro.Renode.Core", - "Antmicro.Renode.Core.Structure", "Antmicro.Renode.Core.Structure.Registers", "Antmicro.Renode.Logging", - "Antmicro.Renode.Peripherals.Bus", - "Antmicro.Renode.Peripherals.Memory", - "Antmicro.Renode.Peripherals.MTD", + "System.Collections.Generic", + "Antmicro.Renode.Utilities", ], - extra_subclasses=["NullRegistrationPointPeripheralContainer"], + extra_subclasses=["IIRQController", "INumberedGPIOOutput"], )