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