sim/config: Merge ITCM and DTCM into TCM.

Remove references to individual TCMs, replace with single TCM.

Change-Id: Ie0281b33d7085f50d8ec24da2c179b6971d4722e
diff --git a/platforms/springbok.repl b/platforms/springbok.repl
index 7e550ca..348b678 100644
--- a/platforms/springbok.repl
+++ b/platforms/springbok.repl
@@ -19,12 +19,6 @@
 cpu2: CPU.SpringbokRiscV32 @ sysbus
     hartId: 2
 
-// TODO(b/214092253): IMEM size blow-up needs to be addressed.
-//RAM_VEC_IMEM      [‘h3200_0000 - ‘h320F_FFFF) 1MB RAM for Vector core Instruction
-// Remember to update hart_is_vc in rom_crt.S if this changes.
-ram_vec_imem: Memory.MappedMemory @ sysbus 0x32000000
-    size: 0x00100000
-
 // TODO(b/196910893): Revert the temporary change on DMEM memory later
 //RAM_VEC_DMEM      [‘h3400_0000 - ‘h34FF_FFFF)   16MB RAM for Vector core Data
 ram_vec_dmem: Memory.MappedMemory @ sysbus 0x34000000
@@ -36,12 +30,7 @@
 
 vec_controlblock : CPU.SpringbokRiscV32_ControlBlock @ sysbus 0x47000000
     core: cpu2
-    iMmuNumWindows: 2
-    // TODO(b/214092253): IMEM size blow-up needs to be addressed.
-    iMmuVirtualWindowSize: 0x100000
-    iMmuMemorySize: 0x100000
-    iMmuRangeStart: 0x32000000
-    dMmuNumWindows: 4
-    dMmuVirtualWindowSize: 0x400000
-    dMmuMemorySize: 0x1000000
-    dMmuRangeStart: 0x34000000
+    mmuNumWindows: 6 // See: go/shodan-vc-memory
+    mmuVirtualWindowSize: 0x1000000
+    mmuMemorySize: 0x1000000
+    mmuRangeStart: 0x34000000
diff --git a/shodan_infrastructure/SpringbokRiscV32.cs b/shodan_infrastructure/SpringbokRiscV32.cs
index db08c92..b5faf0a 100644
--- a/shodan_infrastructure/SpringbokRiscV32.cs
+++ b/shodan_infrastructure/SpringbokRiscV32.cs
@@ -198,31 +198,22 @@
 
         public SpringbokRiscV32_ControlBlock(Machine machine,
                                              SpringbokRiscV32 core,
-                                             uint iMmuNumWindows,
-                                             ulong iMmuMemorySize,
-                                             ulong iMmuVirtualWindowSize,
-                                             ulong iMmuRangeStart,
-                                             uint dMmuNumWindows,
-                                             ulong dMmuRangeStart,
-                                             ulong dMmuMemorySize,
-                                             ulong dMmuVirtualWindowSize)
+                                             uint mmuNumWindows,
+                                             ulong mmuMemorySize,
+                                             ulong mmuVirtualWindowSize,
+                                             ulong mmuRangeStart)
         {
             Machine = machine;
             Core = core;
 
-            this.iMmuNumWindows = iMmuNumWindows;
-            this.iMmuRangeStart = iMmuRangeStart;
-            this.iMmuMemorySize = iMmuMemorySize;
-            this.dMmuNumWindows = dMmuNumWindows;
-            this.dMmuRangeStart = dMmuRangeStart;
-            this.dMmuMemorySize = dMmuMemorySize;
-            this.iMmuVirtualWindowSize = iMmuVirtualWindowSize;
-            this.dMmuVirtualWindowSize = dMmuVirtualWindowSize;
+            this.mmuNumWindows = mmuNumWindows;
+            this.mmuRangeStart = mmuRangeStart;
+            this.mmuMemorySize = mmuMemorySize;
+            this.mmuVirtualWindowSize = mmuVirtualWindowSize;
 
             Core.EnableExternalWindowMmu(true);
 
-            IMmu = InitMmu(iMmuRangeStart, iMmuMemorySize, iMmuNumWindows, iMmuVirtualWindowSize);
-            DMmu = InitMmu(dMmuRangeStart, dMmuMemorySize, dMmuNumWindows, dMmuVirtualWindowSize);
+            Mmu = InitMmu(mmuRangeStart, mmuMemorySize, mmuNumWindows, mmuVirtualWindowSize);
 
             HostReqIRQ = new GPIO();
             FinishIRQ = new GPIO();
@@ -311,7 +302,7 @@
                         {
                             this.Log(LogLevel.Noisy, "Resetting core.");
                             Core.Reset();
-                            ulong startAddress = (val & ~(ulong)Mode.Mask) + iMmuRangeStart;
+                            ulong startAddress = (val & ~(ulong)Mode.Mask) + mmuRangeStart;
                             this.Log(LogLevel.Noisy, "Setting PC to 0x{0:X}.", startAddress);
                             Core.PC = startAddress;
                         }
@@ -331,22 +322,18 @@
 
             // To-do: Not sure how to implement disablable memory banks.
             Registers.MemoryBankControl.Define32(this)
-                    .WithValueField(0, 4, out InstructionMemoryEnable, name: "I_MEM_ENABLE")
-                    .WithValueField(4, 8, out DataMemoryEnable, name: "D_MEM_ENABLE")
-                    .WithIgnoredBits(12, 32 - 12);
+                    .WithValueField(0, 4, out MemoryEnable, name: "MEM_ENABLE")
+                    .WithIgnoredBits(16, 32 - 16);
 
             // To-do: Not sure how to implement memory access range checks.
             Registers.ErrorStatus.Define32(this)
-                    .WithFlag(0, name: "I_MEM_OUT_OF_RANGE")
-                    .WithFlag(1, name: "D_MEM_OUT_OF_RANGE")
-                    .WithValueField(2, 4, out InstructionMemoryDisableAccess, name: "I_MEM_DISABLE_ACCESS")
-                    .WithValueField(6, 8, out DataMemoryDisableAccess, name: "D_MEM_DISABLE_ACCESS")
-                    .WithIgnoredBits(14, 32 - 14);
+                    .WithFlag(0, name: "MEM_OUT_OF_RANGE")
+                    .WithValueField(2, 4, out MemoryDisableAccess, name: "MEM_DISABLE_ACCESS")
+                    .WithIgnoredBits(16, 32 - 16);
 
             Registers.InitStart.Define32(this)
                     .WithValueField(0, 22, out InitStartAddress, name: "ADDRESS")
-                    .WithFlag(22, out InitMemSelect, name: "IMEM_DMEM_SEL")
-                    .WithIgnoredBits(23, 32 - 23);
+                    .WithIgnoredBits(24, 32 - 24);
 
             Registers.InitEnd.Define32(this)
                     .WithValueField(0, 22, out InitEndAddress, name: "ADDRESS")
@@ -358,23 +345,11 @@
                             InitStatusPending.Value = true;
                             InitStatusDone.Value = false;
                             Machine.LocalTimeSource.ExecuteInNearestSyncedState( __ => {
-                                if (InitMemSelect.Value)
+                                for(long writeAddress = InitStartAddress.Value & ~(DataPageSize - 1);
+                                    writeAddress < ((InitEndAddress.Value + DataPageSize - 1) & ~(DataPageSize - 1));
+                                    writeAddress += DataPageSize)
                                 {
-                                    for(long writeAddress = InitStartAddress.Value & ~(InstructionPageSize - 1);
-                                writeAddress < ((InitEndAddress.Value + InstructionPageSize - 1) & ~(InstructionPageSize - 1));
-                                writeAddress += InstructionPageSize)
-                                    {
-                                        Machine.SystemBus.WriteBytes(InstructionErasePattern, iMmuRangeStart + (ulong)writeAddress, (uint)InstructionPageSize, true);
-                                    }
-                                }
-                                else
-                                {
-                                    for(long writeAddress = InitStartAddress.Value & ~(DataPageSize - 1);
-                                writeAddress < ((InitEndAddress.Value + DataPageSize - 1) & ~(DataPageSize - 1));
-                                writeAddress += DataPageSize)
-                                    {
-                                        Machine.SystemBus.WriteBytes(DataErasePattern, dMmuRangeStart + (ulong)writeAddress, (uint)DataPageSize, true);
-                                    }
+                                    Machine.SystemBus.WriteBytes(DataErasePattern, mmuRangeStart + (ulong)writeAddress, (uint)DataPageSize, true);
                                 }
                                 InitStatusPending.Value = false;
                                 InitStatusDone.Value = true;
@@ -395,11 +370,11 @@
             case 0: /* 0..1023 */
                 return RegistersCollection.Read(offset);
             case 1: /* 1024..2047 */
-                if (IMmu != null)
+                if (Mmu != null)
                 {
                     offset -= 1024;
                     uint window = (uint)(offset >> 4);
-                    if(window >= iMmuNumWindows)
+                    if(window >= mmuNumWindows)
                     {
                         this.Log(LogLevel.Warning, "Invalid window number {}", window);
                         return 0;
@@ -407,44 +382,19 @@
                     switch (offset & 15)
                     {
                     case 0:
-                        return checked((uint)IMmu.GetWindowStart(window));
+                        return checked((uint)Mmu.GetWindowStart(window));
                     case 4:
-                        return checked((uint)(IMmu.GetWindowEnd(window) - IMmu.GetWindowStart(window))); // windowLength
+                        return checked((uint)(Mmu.GetWindowEnd(window) - Mmu.GetWindowStart(window))); // windowLength
                     case 8:
-                        return checked((uint)IMmu.GetWindowPrivileges(window));
+                        return checked((uint)Mmu.GetWindowPrivileges(window));
                     default:
-                        this.Log(LogLevel.Warning, "No Springbok IMmu register at address 0x{0:X}.", offset);
+                        this.Log(LogLevel.Warning, "No Springbok Mmu register at address 0x{0:X}.", offset);
                         return 0;
                     }
                 }
-                this.Log(LogLevel.Warning, "Attempting to access Springbok IMmu when it was not included in system.", offset);
+                this.Log(LogLevel.Warning, "Attempting to access Springbok Mmu when it was not included in system.", offset);
                 return 0;
-            case 2: /* 2048..3071 */
-                if (DMmu != null)
-                {
-                    offset -= 2048;
-                    uint window = (uint)(offset >> 4);
-                    if(window >= dMmuNumWindows)
-                    {
-                        this.Log(LogLevel.Warning, "Invalid window number {}", window);
-                        return 0;
-                    }
-                    switch (offset & 15)
-                    {
-                    case 0:
-                        return checked((uint)DMmu.GetWindowStart(window));
-                    case 4:
-                        return checked((uint)(DMmu.GetWindowEnd(window) - DMmu.GetWindowStart(window))); // windowLength
-                    case 8:
-                        return checked((uint)DMmu.GetWindowPrivileges(window));
-                    default:
-                        this.Log(LogLevel.Warning, "No Springbok DMmu register at address 0x{0:X}.", offset);
-                        return 0;
-                    }
-                }
-                this.Log(LogLevel.Warning, "Attempting to access Springbok DMmu when it was not included in system.", offset);
-                return 0;
-            default: /* 3072..4095 */
+            default: /* 2048..4095 */
                 return 0;
             }
         }
@@ -457,11 +407,11 @@
                 RegistersCollection.Write(offset, value);
                 return;
             case 1: /* 1024..2047 */
-                if (IMmu != null)
+                if (Mmu != null)
                 {
                     offset -= 1024;
                     uint window = (uint)(offset >> 4);
-                    if(window >= iMmuNumWindows)
+                    if(window >= mmuNumWindows)
                     {
                         this.Log(LogLevel.Warning, "Invalid window number {}", window);
                         return;
@@ -469,60 +419,25 @@
                     switch (offset & 15)
                     {
                     case 0:
-                        var virtualWindowOffset = this.iMmuRangeStart + window * this.iMmuVirtualWindowSize;
-                        IMmu.SetWindowAddend(window, value - virtualWindowOffset);
+                        var virtualWindowOffset = this.mmuRangeStart + window * this.mmuVirtualWindowSize;
+                        Mmu.SetWindowAddend(window, value - virtualWindowOffset);
                         return;
                     case 4:
                         // This assumes that the window start has already been set
-                        var windowEnd = IMmu.GetWindowStart(window) + value + 1;
-                        IMmu.SetWindowEnd(window, windowEnd); // windowLength
+                        var windowEnd = Mmu.GetWindowStart(window) + value + 1;
+                        Mmu.SetWindowEnd(window, windowEnd); // windowLength
                         return;
                     case 8:
                         if (value > 3)
                         {
                             this.Log(LogLevel.Noisy, "Window permission value {0} out of range", value);
                         }
-                        IMmu.SetWindowPrivileges(window, value << 2); // For the insn, the DataRead is InsnFetch
+                        Mmu.SetWindowPrivileges(window, value);
                         return;
                     }
                 }
                 return;
-            case 2: /* 2048..3071 */
-                if (DMmu != null)
-                {
-                    offset -= 2048;
-                    uint window = (uint)(offset >> 4);
-                    if(window >= dMmuNumWindows)
-                    {
-                        this.Log(LogLevel.Warning, "Invalid window number {}", window);
-                        return;
-                    }
-                    switch (offset & 15)
-                    {
-                    case 0:
-                        uint virtualWindowOffset = (uint)(this.dMmuRangeStart + window * this.dMmuVirtualWindowSize);
-                        DMmu.SetWindowAddend(window, value - (uint)virtualWindowOffset);
-                        return;
-                    case 4:
-                        if ((value + 1) > this.dMmuMemorySize)
-                        {
-                            this.Log(LogLevel.Error, "Window length 0x{1:X} exceeds the memory size 0x{1:X}", value, dMmuMemorySize);
-                        }
-                        // This assumes that the window start has already been set
-                        var windowEnd = DMmu.GetWindowStart(window) + value + 1;
-                        DMmu.SetWindowEnd(window, windowEnd); //windowLength
-                        return;
-                    case 8:
-                        if (value > 3)
-                        {
-                            this.Log(LogLevel.Noisy, "Window permission value {0} out of range", value);
-                        }
-                        DMmu.SetWindowPrivileges(window, value);
-                        return;
-                    }
-                }
-                return;
-            default: /* 3072..4095 */
+            default: /* 2048..4095 */
                 return;
             }
         }
@@ -561,7 +476,7 @@
             IrqUpdate();
         }
 
-        private void ExecFault(FaultType faultType)
+        private void ExecFault()
         {
             // Pause, reset the core (actual reset occurs when SwReset is cleared) and trigger a host interrupt indicating a fault
             if (mode == Mode.Run)
@@ -574,38 +489,17 @@
             }
             Core.IsHalted = true;
             mode = Mode.Freeze | Mode.SwReset;
-            switch (faultType)
-            {
-            case FaultType.InstructionFetch:
-                irqsPending |= InterruptBits.InstructionFault;
-                IrqUpdate();
-                return;
-            case FaultType.DataAccess:
-                irqsPending |= InterruptBits.DataFault;
-                IrqUpdate();
-                return;
-            default:
-                this.Log(LogLevel.Error, "Unknown fault type!");
-                return;
-            }
+            irqsPending |= InterruptBits.DataFault;
+            IrqUpdate();
+            return;
         }
 
         public DoubleWordRegisterCollection RegistersCollection { get; private set; }
 
         private void HandleFault(ulong faultAddress, AccessType accessType, int windowIndex)
         {
-            var faultType = (accessType == AccessType.Execute)? FaultType.InstructionFetch : FaultType.DataAccess;
-
-            if(faultType == FaultType.InstructionFetch)
-            {
-                LogFaultType(IMmu, faultAddress, accessType, iMmuRangeStart, iMmuVirtualWindowSize, iMmuNumWindows);
-            }
-            else
-            {
-                LogFaultType(DMmu, faultAddress, accessType, dMmuRangeStart, dMmuVirtualWindowSize, dMmuNumWindows);
-            }
-
-            ExecFault(faultType);
+            LogFaultType(Mmu, faultAddress, accessType, mmuRangeStart, mmuVirtualWindowSize, mmuNumWindows);
+            ExecFault();
         }
 
         private void LogFaultType(ExternalMmuBase mmu, ulong faultAddress, AccessType accessType, ulong rangeStart, ulong virtualWindowSize, uint numberOfWindows)
@@ -659,20 +553,15 @@
 
         // To-do: Set the erase pattern to what the hardware actually does. 0x5A is
         // only for debugging purposes.
-        private const int InstructionPageSize = 4;
-        private readonly byte[] InstructionErasePattern = (byte[])Enumerable.Repeat((byte)0x5A, InstructionPageSize).ToArray();
         private const int DataPageSize = 64;
         private readonly byte[] DataErasePattern = (byte[])Enumerable.Repeat((byte)0x5A, DataPageSize).ToArray();
 
         // Disable unused variable warnings. These warnings will go away on their
         // their own when each register's behavior is implemented.
 #pragma warning disable 414
-        private IValueRegisterField InstructionMemoryEnable;
-        private IValueRegisterField DataMemoryEnable;
-        private IValueRegisterField InstructionMemoryDisableAccess;
-        private IValueRegisterField DataMemoryDisableAccess;
+        private IValueRegisterField MemoryEnable;
+        private IValueRegisterField MemoryDisableAccess;
         private IValueRegisterField InitStartAddress;
-        private IFlagRegisterField InitMemSelect;
         private IValueRegisterField InitEndAddress;
         private IFlagRegisterField InitStatusPending;
         private IFlagRegisterField InitStatusDone;
@@ -681,16 +570,11 @@
         private Mode mode;
         private readonly Machine Machine;
         private readonly SpringbokRiscV32 Core;
-        private readonly ExternalMmuBase IMmu;
-        private readonly ExternalMmuBase DMmu;
-        private readonly uint dMmuNumWindows;
-        private readonly ulong dMmuRangeStart;
-        private readonly ulong dMmuMemorySize;
-        private readonly ulong dMmuVirtualWindowSize;
-        private readonly uint iMmuNumWindows;
-        private readonly ulong iMmuRangeStart;
-        private readonly ulong iMmuMemorySize;
-        private readonly ulong iMmuVirtualWindowSize;
+        private readonly ExternalMmuBase Mmu;
+        private readonly uint mmuNumWindows;
+        private readonly ulong mmuRangeStart;
+        private readonly ulong mmuMemorySize;
+        private readonly ulong mmuVirtualWindowSize;
 
         // Length of register space.
         public long Size => 0x1000;
diff --git a/springbok.resc b/springbok.resc
index 85b9881..8954892 100644
--- a/springbok.resc
+++ b/springbok.resc
@@ -32,8 +32,8 @@
 macro reset
 """
     sysbus LoadELF $bin
-    # Start the vector core at address 0 of its instruction TCM.
+    # Start the vector core at address 0 of its TCM.
     sysbus.cpu2 IsHalted true
-    sysbus.cpu2 PC 0x32000000
+    sysbus.cpu2 PC 0x34000000
 """
 runMacro $reset