//
// Copyright (c) 2010-2024 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'licenses/MIT.txt'.
//
using System;
using Antmicro.Migrant;
using Antmicro.Renode.Debugging;
using Antmicro.Renode.Logging;
namespace Antmicro.Renode.Peripherals.CPU
{
public abstract class CPUCore : IdentifiableObject, IEmulationElement
{
protected CPUCore(uint cpuId)
{
MultiprocessingId = cpuId;
}
public virtual void Start()
{
Resume();
}
public void Resume()
{
lock(pauseLock)
{
if(isAborted || !isPaused)
{
return;
}
started = true;
isPaused = false;
OnResume();
this.NoisyLog("Resumed.");
}
}
public void Pause()
{
if(isAborted || isPaused)
{
// cpu is already paused or aborted
return;
}
lock(pauseLock)
{
OnPause();
}
}
///
/// An ID that can identify a CPU in a multicore environment. Its specific interpretation will depend on CPU architecture.
///
///
/// This ID doesn't have to be either globally unique or sequential.
/// On certain heterogeneous systems, there might be processors with duplicate IDs, which can be valid, depending on the platform configuration.
///
public uint MultiprocessingId { get; }
public bool IsStarted => started;
public virtual bool IsHalted { get; set; }
protected void Abort()
{
isAborted = true;
this.Log(LogLevel.Error, "CPU aborted");
}
protected virtual void OnResume()
{
// by default do nothing
}
protected virtual void OnPause()
{
// by default do nothing
}
[Transient]
protected volatile bool started;
protected volatile bool isAborted;
protected volatile bool isPaused;
protected readonly object pauseLock = new object();
protected readonly object haltedLock = new object();
}
}