178 lines
14 KiB
C#
178 lines
14 KiB
C#
//
|
|
// Copyright (c) 2010-2023 Antmicro
|
|
// Copyright (c) 2011-2015 Realtime Embedded
|
|
//
|
|
// This file is licensed under the MIT License.
|
|
// Full license text is available in 'licenses/MIT.txt'.
|
|
//
|
|
using System;
|
|
using Antmicro.Renode.Peripherals.Bus;
|
|
using Antmicro.Renode.Core;
|
|
using Antmicro.Renode.Peripherals;
|
|
using Antmicro.Renode.Utilities;
|
|
using Antmicro.Renode.Logging;
|
|
using System.Collections.Generic;
|
|
using Antmicro.Renode.Core.Structure.Registers;
|
|
|
|
namespace Antmicro.Renode.Peripherals.Miscellaneous
|
|
{
|
|
public class ESP32S3_EXTMEM : IBytePeripheral, IDoubleWordPeripheral, IKnownSize
|
|
{
|
|
public ESP32S3_EXTMEM(Machine machine)
|
|
{
|
|
var registersMap = new Dictionary<long, DoubleWordRegister>
|
|
{
|
|
{(long)Registers.DCACHE_CTRL, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, name: "DCACHE_ENABLE") // The bit is used to activate the data cache. 0: disable, 1: enable
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, name: "DCACHE_SIZE_MODE") // The bit is used to configure cache memory size.0: 32KB, 1: 64KB
|
|
.WithValueField(2, 2, FieldMode.Read | FieldMode.Write, name: "DCACHE_BLOCKSIZE_MODE") // The bit is used to configure cache block size.0: 16 bytes, 1: 32 bytes,2: 64 bytes
|
|
},
|
|
{(long)Registers.DCACHE_CTRL1, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, name: "DCACHE_SHUT_CORE0_BUS") // The bit is used to disable core0 dbus, 0: enable, 1: disable
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, name: "DCACHE_SHUT_CORE1_BUS") // The bit is used to disable core1 dbus, 0: enable, 1: disable
|
|
},
|
|
{(long)Registers.DCACHE_SYNC_CTRL, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => false, name: "DCACHE_INVALIDATE_ENA") // The bit is used to enable invalidate operation. It will be cleared by hardware after invalidate operation done.
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => false, name: "DCACHE_WRITEBACK_ENA") // The bit is used to enable writeback operation. It will be cleared by hardware after writeback operation done.
|
|
.WithFlag(2, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => false, name: "DCACHE_CLEAN_ENA") // The bit is used to enable clean operation. It will be cleared by hardware after clean operation done.
|
|
.WithFlag(3, FieldMode.Read, valueProviderCallback: (_) => true, name: "DCACHE_SYNC_DONE") // The bit is used to indicate clean/writeback/invalidate operation is finished.
|
|
},
|
|
{(long)Registers.DCACHE_SYNC_ADDR, new DoubleWordRegister(this)
|
|
.WithValueField(0, 32, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => 0, name: "DCACHE_SYNC_ADDR") // The bits are used to configure the start virtual address for clean operations. It should be combined with DCACHE_SYNC_SIZE_REG.
|
|
},
|
|
{(long)Registers.DCACHE_SYNC_SIZE, new DoubleWordRegister(this)
|
|
.WithValueField(0, 32, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => 0, name: "DCACHE_SYNC_SIZE") // The bits are used to configure the length for sync operations. The bits are the counts of cache block. It should be combined with DCACHE_SYNC_ADDR_REG.
|
|
},
|
|
{(long)Registers.DCACHE_PRELOAD_CTRL, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => false, name: "DCACHE_PRELOAD_ENA") // The bit is used to enable preload operation. It will be cleared by hardware after preload operation done.
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => true, name: "DCACHE_PRELOAD_DONE") // The bit is used to indicate preload operation is finished.
|
|
.WithFlag(2, FieldMode.Read | FieldMode.Write, name: "DCACHE_PRELOAD_ORDER") // The bit is used to configure the direction of preload operation. 1: descending, 0: ascending.
|
|
},
|
|
{(long)Registers.DCACHE_AUTOLOAD_CTRL, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, name: "DCACHE_AUTOLOAD_SCT0_ENA") // The bits are used to enable the first section for autoload operation.
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, name: "DCACHE_AUTOLOAD_SCT1_ENA") // The bits are used to enable the second section for autoload operation.
|
|
.WithFlag(2, FieldMode.Read | FieldMode.Write, name: "DCACHE_AUTOLOAD_ENA") // The bit is used to enable and disable autoload operation. It is combined with dcache_autoload_done. 1: enable, 0: disable.
|
|
.WithFlag(3, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => true, name: "DCACHE_AUTOLOAD_DONE") // The bit is used to indicate autoload operation is finished.
|
|
.WithFlag(4, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => false, name: "DCACHE_AUTOLOAD_ORDER") // The bits are used to configure the direction of autoload. 1: descending, 0: ascending.
|
|
.WithValueField(5, 2, FieldMode.Read | FieldMode.Write, name: "DCACHE_AUTOLOAD_RQST") // The bits are used to configure trigger conditions for autoload. 0/3: cache miss, 1: cache hit, 2: both cache miss and hit.
|
|
.WithValueField(7, 2, FieldMode.Read | FieldMode.Write, name: "DCACHE_AUTOLOAD_SIZE") // The bits are used to configure the numbers of the cache block for the issuing autoload operation.
|
|
.WithFlag(9, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => false, name: "DCACHE_AUTOLOAD_BUFFER_CLEAR") // The bit is used to clear autoload buffer in dcache.
|
|
},
|
|
{(long)Registers.CACHE_ILG_INT_CLR, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, name: "ICACHE_SYNC_OP_FAULT_INT_CLR") // The bit is used to clear interrupt by sync configurations fault.
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, name: "ICACHE_PRELOAD_OP_FAULT_INT_CLR") // The bit is used to clear interrupt by preload configurations fault.
|
|
.WithFlag(2, FieldMode.Read | FieldMode.Write, name: "DCACHE_SYNC_OP_FAULT_INT_CLR") // The bit is used to clear interrupt by sync configurations fault.
|
|
.WithFlag(3, FieldMode.Read | FieldMode.Write, name: "DCACHE_PRELOAD_OP_FAULT_INT_CLR") // The bit is used to clear interrupt by preload configurations fault.
|
|
.WithFlag(4, FieldMode.Read | FieldMode.Write, name: "DCACHE_WRITE_FLASH_INT_CLR") // The bit is used to clear interrupt by dcache trying to write flash.
|
|
.WithFlag(5, FieldMode.Read | FieldMode.Write, name: "MMU_ENTRY_FAULT_INT_CLR") // The bit is used to clear interrupt by mmu entry fault.
|
|
.WithFlag(6, FieldMode.Read | FieldMode.Write, name: "DCACHE_OCCUPY_EXC_INT_CLR") // The bit is used to clear interrupt by dcache trying to replace a line whose blocks all have been occupied by occupy-mode.
|
|
.WithFlag(7, FieldMode.Read | FieldMode.Write, name: "IBUS_CNT_OVF_INT_CLR") // The bit is used to clear interrupt by ibus counter overflow.
|
|
.WithFlag(8, FieldMode.Read | FieldMode.Write, name: "DBUS_CNT_OVF_INT_CLR") // The bit is used to clear interrupt by dbus counter overflow.
|
|
},
|
|
{(long)Registers.CACHE_WRAP_AROUND_CTRL, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, name: "CACHE_FLASH_WRAP_AROUND") // The bit is used to enable wrap around mode when read data from flash.
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, name: "CACHE_SRAM_RD_WRAP_AROUND") // The bit is used to enable wrap around mode when read data from spiram.
|
|
|
|
// .WithValueField(0, 2, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => 0, name: "SW_STALL_APPCPU_C0") // {reg_sw_stall_appcpu_c1[5:0], reg_sw_stall_appcpu_c0[1:0]} == 0x86 will stall APP CPU
|
|
// .WithValueField(2, 2, FieldMode.Read | FieldMode.Write, valueProviderCallback: (_) => 0, name: "SW_STALL_PROCPU_C0") // {reg_sw_stall_procpu_c1[5:0], reg_sw_stall_procpu_c0[1:0]} == 0x86 will stall PRO CPU
|
|
// .WithFlag(4, FieldMode.Read | FieldMode.Write, name: "SW_APPCPU_RST") // APP CPU SW reset
|
|
// .WithFlag(5, FieldMode.Read | FieldMode.Write, name: "SW_PROCPU_RST") // PRO CPU SW reset
|
|
// .WithFlag(6, FieldMode.Read | FieldMode.Write, name: "BB_I2C_FORCE_PD") // BB_I2C force power down
|
|
// .WithFlag(7, FieldMode.Read | FieldMode.Write, name: "BB_I2C_FORCE_PU") // BB_I2C force power up
|
|
// .WithFlag(8, FieldMode.Read | FieldMode.Write, name: "BBPLL_I2C_FORCE_PD") // BB_PLL _I2C force power down
|
|
// .WithFlag(9, FieldMode.Read | FieldMode.Write, name: "BBPLL_I2C_FORCE_PU") // BB_PLL_I2C force power up
|
|
// .WithFlag(10, FieldMode.Read | FieldMode.Write, name: "BBPLL_FORCE_PD") // BB_PLL force power down
|
|
// .WithFlag(11, FieldMode.Read | FieldMode.Write, name: "BBPLL_FORCE_PU") // BB_PLL force power up
|
|
// .WithFlag(12, FieldMode.Read | FieldMode.Write, name: "XTL_FORCE_PD") // crystall force power down
|
|
// .WithFlag(13, FieldMode.Read | FieldMode.Write, name: "XTL_FORCE_PU") // crystall force power up
|
|
// .WithValueField(14, 4, FieldMode.Read | FieldMode.Write, name: "XTL_EN_WAIT") // wait bias_sleep and current source wakeup
|
|
// .WithFlag(23, FieldMode.Read | FieldMode.Write, name: "XTL_FORCE_ISO") // No public
|
|
// .WithFlag(24, FieldMode.Read | FieldMode.Write, name: "PLL_FORCE_ISO") // No public
|
|
// .WithFlag(25, FieldMode.Read | FieldMode.Write, name: "ANALOG_FORCE_ISO") // No public
|
|
// .WithFlag(26, FieldMode.Read | FieldMode.Write, name: "XTL_FORCE_NOISO") // No public
|
|
// .WithFlag(27, FieldMode.Read | FieldMode.Write, name: "PLL_FORCE_NOISO") // No public
|
|
// .WithFlag(28, FieldMode.Read | FieldMode.Write, name: "ANALOG_FORCE_NOISO") // No public
|
|
// .WithFlag(29, FieldMode.Read | FieldMode.Write, name: "DG_WRAP_FORCE_RST") // digital wrap force reset in deep sleep
|
|
// .WithFlag(30, FieldMode.Read | FieldMode.Write, name: "DG_WRAP_FORCE_NORST") // digital core force no reset in deep sleep
|
|
// .WithFlag(31, FieldMode.Write, name: "SW_SYS_RST") // SW system reset
|
|
},
|
|
{(long)Registers.CACHE_MMU_OWNER, new DoubleWordRegister(this)
|
|
.WithValueField(7, 2, FieldMode.Read | FieldMode.Write, name: "CACHE_MMU_OWNER") // The bits are used to specify the owner of MMU.bit0: icache, bit1: dcache, bit2: dma, bit3: reserved.
|
|
},
|
|
{(long)Registers.DCACHE_FREEZE, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, name: "ENA") // The bit is used to enable dcache freeze mode
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, name: "MODE") // The bit is used to configure freeze mode, 0: assert busy if CPU miss 1: assert hit if CPU miss
|
|
.WithFlag(2, FieldMode.Read, valueProviderCallback: (_) => true, name: "DONE") // The bit is used to indicate dcache freeze success
|
|
},
|
|
{(long)Registers.ICACHE_FREEZE, new DoubleWordRegister(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, name: "ENA") // The bit is used to enable icache freeze mode
|
|
.WithFlag(1, FieldMode.Read | FieldMode.Write, name: "MODE") // The bit is used to configure freeze mode, 0: assert busy if CPU miss 1: assert hit if CPU miss
|
|
.WithFlag(2, FieldMode.Read, valueProviderCallback: (_) => true, name: "DONE") // The bit is used to indicate icache freeze success
|
|
},
|
|
};
|
|
|
|
registers = new DoubleWordRegisterCollection(this, registersMap);
|
|
}
|
|
|
|
public uint ReadDoubleWord(long offset)
|
|
{
|
|
return registers.Read(offset);
|
|
}
|
|
|
|
public byte ReadByte(long offset)
|
|
{
|
|
if (offset % 4 != 0)
|
|
{
|
|
// in the current configuration, only the lowest byte
|
|
// contains a meaningful data
|
|
return 0;
|
|
}
|
|
return (byte)ReadDoubleWord(offset);
|
|
}
|
|
|
|
public void Reset()
|
|
{
|
|
// base.Reset();
|
|
registers.Reset();
|
|
|
|
// UpdateInterrupts();
|
|
}
|
|
|
|
public void WriteDoubleWord(long offset, uint value)
|
|
{
|
|
registers.Write(offset, value);
|
|
}
|
|
|
|
public void WriteByte(long offset, byte value)
|
|
{
|
|
if (offset % 4 != 0)
|
|
{
|
|
// in the current configuration, only the lowest byte
|
|
// contains a meaningful data
|
|
return;
|
|
}
|
|
|
|
WriteDoubleWord(offset, value);
|
|
}
|
|
|
|
public long Size => 0x17C;
|
|
private readonly DoubleWordRegisterCollection registers;
|
|
|
|
private enum Registers : long
|
|
{
|
|
DCACHE_CTRL = 0x00,
|
|
DCACHE_CTRL1 = 0x04,
|
|
DCACHE_SYNC_CTRL = 0x28,
|
|
DCACHE_SYNC_ADDR = 0x2C,
|
|
DCACHE_SYNC_SIZE = 0x30,
|
|
DCACHE_PRELOAD_CTRL = 0x40,
|
|
DCACHE_AUTOLOAD_CTRL = 0x4C,
|
|
CACHE_ILG_INT_CLR = 0xE0,
|
|
CACHE_WRAP_AROUND_CTRL = 0x128,
|
|
CACHE_MMU_OWNER = 0x148,
|
|
DCACHE_FREEZE = 0x150,
|
|
ICACHE_FREEZE = 0x154,
|
|
}
|
|
}
|
|
}
|