Skip to content

Commit

Permalink
Merge commit 'e72d6fe2b39490737b7057828541b7a14a4a48c5' into 334-maco…
Browse files Browse the repository at this point in the history
…s_keyboard
  • Loading branch information
Chris Pick committed Jul 2, 2024
2 parents ebe435b + e72d6fe commit f8f02c1
Show file tree
Hide file tree
Showing 1,045 changed files with 136,742 additions and 16,543 deletions.
281 changes: 264 additions & 17 deletions src/Emulator/Cores/Arm-M/CortexM.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
//
// Copyright (c) 2010-2022 Antmicro
// Copyright (c) 2010-2024 Antmicro
// Copyright (c) 2011-2015 Realtime Embedded
// Copyright (c) 2020-2021 Microsoft
//
Expand All @@ -21,23 +21,34 @@

namespace Antmicro.Renode.Peripherals.CPU
{
public partial class CortexM : Arm, IControllableCPU
public partial class CortexM : Arm
{
public CortexM(string cpuType, Machine machine, NVIC nvic, uint id = 0, Endianess endianness = Endianess.LittleEndian) : base(cpuType, machine, id, endianness)
public CortexM(string cpuType, IMachine machine, NVIC nvic, uint id = 0, Endianess endianness = Endianess.LittleEndian, uint? fpuInterruptNumber = null, uint? numberOfMPURegions = null) : base(cpuType, machine, id, endianness, numberOfMPURegions)
{
if(nvic == null)
{
throw new RecoverableException(new ArgumentNullException("nvic"));
}

this.nvic = nvic;
nvic.AttachCPU(this);
}
tlibSetFpuInterruptNumber((int?)fpuInterruptNumber ?? -1);

public override void Start()
{
InitPCAndSP();
base.Start();
if(!numberOfMPURegions.HasValue)
{
// FIXME: This is not correct for M7 and v8M cores
// Setting 8 regions backward-compatibility for now
this.NumberOfMPURegions = 8;
}

this.nvic = nvic;
try
{
nvic.AttachCPU(this);
}
catch(RecoverableException e)
{
// Rethrow attachment error as ConstructionException, so the CreationDriver doesn't crash
throw new ConstructionException("Exception occurred when attaching NVIC: ", e);
}
}

public override void Reset()
Expand All @@ -47,10 +58,14 @@ public override void Reset()
base.Reset();
}

public override void Resume()
protected override void OnResume()
{
InitPCAndSP();
base.Resume();
// Suppress initialization when processor is turned off as binary may not even be loaded yet
if(!IsHalted)
{
InitPCAndSP();
}
base.OnResume();
}

public override string Architecture { get { return "arm-m"; } }
Expand Down Expand Up @@ -112,6 +127,154 @@ public bool FpuEnabled
}
}

public UInt32 FaultStatus
{
set
{
tlibSetFaultStatus(value);
}
get
{
return tlibGetFaultStatus();
}
}

public UInt32 MemoryFaultAddress
{
get
{
return tlibGetMemoryFaultAddress();
}
}

public bool IsV8
{
get
{
return tlibIsV8() > 0;
}
}

public UInt32 PmsaV8Ctrl
{
get
{
return tlibGetPmsav8Ctrl();
}
set
{
tlibSetPmsav8Ctrl(value);
}
}

public UInt32 PmsaV8Rnr
{
get
{
return tlibGetPmsav8Rnr();
}
set
{
tlibSetPmsav8Rnr(value);
}
}

public UInt32 PmsaV8Rbar
{
get
{
return tlibGetPmsav8Rbar();
}
set
{
tlibSetPmsav8Rbar(value);
}
}

public UInt32 PmsaV8Rlar
{
get
{
return tlibGetPmsav8Rlar();
}
set
{
tlibSetPmsav8Rlar(value);
}
}

public UInt32 PmsaV8Mair0
{
get
{
return tlibGetPmsav8Mair(0);
}
set
{
tlibSetPmsav8Mair(0, value);
}
}

public UInt32 PmsaV8Mair1
{
get
{
return tlibGetPmsav8Mair(1);
}
set
{
tlibSetPmsav8Mair(1, value);
}
}

public bool MPUEnabled
{
get
{
return tlibIsMpuEnabled() != 0;
}
set
{
tlibEnableMpu(value ? 1 : 0);
}
}

public UInt32 MPURegionBaseAddress
{
set
{
tlibSetMpuRegionBaseAddress(value);
}
get
{
return tlibGetMpuRegionBaseAddress();
}
}

public UInt32 MPURegionAttributeAndSize
{
set
{
tlibSetMpuRegionSizeAndEnable(value);
}
get
{
return tlibGetMpuRegionSizeAndEnable();
}
}

public UInt32 MPURegionNumber
{
set
{
tlibSetMpuRegionNumber(value);
}
get
{
return tlibGetMpuRegionNumber();
}
}

public uint XProgramStatusRegister
{
get
Expand All @@ -120,12 +283,12 @@ public uint XProgramStatusRegister
}
}

void IControllableCPU.InitFromElf(IELF elf)
public override void InitFromElf(IELF elf)
{
// do nothing
}

void IControllableCPU.InitFromUImage(UImage uImage)
public override void InitFromUImage(UImage uImage)
{
// do nothing
}
Expand All @@ -141,9 +304,18 @@ protected override UInt32 BeforePCWrite(UInt32 value)
return base.BeforePCWrite(value);
}

protected override void OnLeavingResetState()
{
if(State == CPUState.Running)
{
InitPCAndSP();
}
base.OnLeavingResetState();
}

private void InitPCAndSP()
{
var firstNotNullSection = machine.SystemBus.Lookup.FirstNotNullSectionAddress;
var firstNotNullSection = machine.SystemBus.GetLookup(this).FirstNotNullSectionAddress;
if(!vtorInitialized && firstNotNullSection.HasValue)
{
if((firstNotNullSection.Value & (2 << 6 - 1)) > 0)
Expand All @@ -154,12 +326,16 @@ private void InitPCAndSP()
{
var value = firstNotNullSection.Value;
this.Log(LogLevel.Info, "Guessing VectorTableOffset value to be 0x{0:X}.", value);
if(value > uint.MaxValue)
{
this.Log(LogLevel.Error, "Guessed VectorTableOffset doesn't fit in 32-bit address space: 0x{0:X}.", value);
return; // Keep VectorTableOffset uninitialized in the case of error condition
}
VectorTableOffset = checked((uint)value);
}
}
if(pcNotInitialized)
{
pcNotInitialized = false;
// stack pointer and program counter are being sent according
// to VTOR (vector table offset register)
var sysbus = machine.SystemBus;
Expand All @@ -169,6 +345,7 @@ private void InitPCAndSP()
{
this.Log(LogLevel.Error, "PC does not lay in memory or PC and SP are equal to zero. CPU was halted.");
IsHalted = true;
return; // Keep PC and SP uninitialized in the case of error condition
}
this.Log(LogLevel.Info, "Setting initial values: PC = 0x{0:X}, SP = 0x{1:X}.", pc, sp);
PC = pc;
Expand Down Expand Up @@ -224,6 +401,42 @@ private int PendingMaskedIRQ()
[Import]
private ActionInt32 tlibToggleFpu;

[Import]
private FuncUInt32 tlibGetFaultStatus;

[Import]
private ActionUInt32 tlibSetFaultStatus;

[Import]
private FuncUInt32 tlibGetMemoryFaultAddress;

[Import]
private ActionInt32 tlibEnableMpu;

[Import]
private FuncInt32 tlibIsMpuEnabled;

[Import]
private ActionUInt32 tlibSetMpuRegionBaseAddress;

[Import]
private FuncUInt32 tlibGetMpuRegionBaseAddress;

[Import]
private ActionUInt32 tlibSetMpuRegionSizeAndEnable;

[Import]
private FuncUInt32 tlibGetMpuRegionSizeAndEnable;

[Import]
private ActionUInt32 tlibSetMpuRegionNumber;

[Import]
private FuncUInt32 tlibGetMpuRegionNumber;

[Import]
private ActionInt32 tlibSetFpuInterruptNumber;

[Import]
private FuncUInt32 tlibGetInterruptVectorBase;

Expand All @@ -233,6 +446,40 @@ private int PendingMaskedIRQ()
[Import]
private FuncUInt32 tlibGetXpsr;

[Import]
private FuncUInt32 tlibIsV8;

/* PMSAv8 MPU */
[Import]
private ActionUInt32 tlibSetPmsav8Ctrl;

[Import]
private ActionUInt32 tlibSetPmsav8Rnr;

[Import]
private ActionUInt32 tlibSetPmsav8Rbar;

[Import]
private ActionUInt32 tlibSetPmsav8Rlar;

[Import]
private ActionUInt32UInt32 tlibSetPmsav8Mair;

[Import]
private FuncUInt32 tlibGetPmsav8Ctrl;

[Import]
private FuncUInt32 tlibGetPmsav8Rnr;

[Import]
private FuncUInt32 tlibGetPmsav8Rbar;

[Import]
private FuncUInt32 tlibGetPmsav8Rlar;

[Import]
private FuncUInt32UInt32 tlibGetPmsav8Mair;

#pragma warning restore 649
}
}
Expand Down
Loading

0 comments on commit f8f02c1

Please sign in to comment.