mirror of
https://github.com/saymrwulf/xous-core.git
synced 2026-11-04 04:27:34 +00:00
Give a "Betrusted" namespace to all of the peripherals. This will enable us to upstream various modules without breaking compatibility with our own versions of these peripherals. Signed-off-by: Sean Cross <sean@xobs.io>
187 lines
5.9 KiB
C#
187 lines
5.9 KiB
C#
//
|
|
// Copyright (c) 2010-2019 Antmicro
|
|
//
|
|
// This file is licensed under the MIT License.
|
|
// Full license text is available in 'licenses/MIT.txt'.
|
|
//
|
|
using Antmicro.Renode.Core;
|
|
using Antmicro.Renode.Core.Structure.Registers;
|
|
using Antmicro.Renode.Logging;
|
|
using Antmicro.Renode.Peripherals.Bus;
|
|
|
|
namespace Antmicro.Renode.Peripherals.Timers.Betrusted
|
|
{
|
|
// this is a model of LiteX timer in the Betrusted configuration:
|
|
// * width: 32 bits
|
|
// * csr data width: 32 bit
|
|
[AllowedTranslations(AllowedTranslation.ByteToDoubleWord)]
|
|
public class SusRes : BasicDoubleWordPeripheral, IKnownSize
|
|
{
|
|
public SusRes(Machine machine, ulong periodInMs = 1) : base(machine)
|
|
{
|
|
this.IRQ = new GPIO();
|
|
DefineRegisters();
|
|
}
|
|
|
|
private TickTimer EnsureTickTimer()
|
|
{
|
|
if (MainTimer != null)
|
|
{
|
|
return MainTimer;
|
|
}
|
|
|
|
foreach (var element in machine.ClockSource.GetAllClockEntries())
|
|
{
|
|
if (element.LocalName == "TickTimer")
|
|
{
|
|
MainTimer = (TickTimer)element.Owner;
|
|
this.Log(LogLevel.Info, "Found TickTimer object!");
|
|
return MainTimer;
|
|
}
|
|
}
|
|
|
|
this.Log(LogLevel.Error, "Did not find TickTimer object");
|
|
return null;
|
|
}
|
|
|
|
public override void Reset()
|
|
{
|
|
base.Reset();
|
|
irqPending.Value = false;
|
|
RegistersCollection.Reset();
|
|
}
|
|
|
|
private void UpdateInterrupts()
|
|
{
|
|
IRQ.Set(this.irqPending.Value && this.irqEnabled.Value);
|
|
}
|
|
|
|
public long Size { get { return 4096; } }
|
|
|
|
private void DefineRegisters()
|
|
{
|
|
Registers.Control.Define32(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, writeCallback: (_, val) =>
|
|
{
|
|
if (EnsureTickTimer() == null)
|
|
{
|
|
return;
|
|
}
|
|
MainTimer.paused = val;
|
|
}
|
|
)
|
|
.WithFlag(1, writeCallback: (_, val) =>
|
|
{
|
|
// Don't update the timer if it's not paused.
|
|
if ((!EnsureTickTimer()?.paused) ?? false)
|
|
{
|
|
return;
|
|
}
|
|
if (val) {
|
|
MainTimer.tickValue = ((long)resumeTime0.Value) | (((long)resumeTime1.Value) << 32);
|
|
}
|
|
})
|
|
;
|
|
|
|
Registers.Time1.Define32(this)
|
|
.WithValueField(0, 32, FieldMode.Read, name: "Time1", valueProviderCallback: _ =>
|
|
{
|
|
return EnsureTickTimer()?.Time1() ?? 0;
|
|
})
|
|
;
|
|
|
|
Registers.Time0.Define32(this)
|
|
.WithValueField(0, 32, FieldMode.Read, name: "Time0", valueProviderCallback: _ =>
|
|
{
|
|
return EnsureTickTimer()?.Time0() ?? 0;
|
|
})
|
|
;
|
|
|
|
Registers.ResumeTime0.Define32(this)
|
|
.WithValueField(0, 32, out resumeTime0)
|
|
;
|
|
|
|
Registers.ResumeTime1.Define32(this)
|
|
.WithValueField(0, 32, out resumeTime1)
|
|
;
|
|
|
|
Registers.Status.Define32(this)
|
|
.WithFlag(0, FieldMode.Read, valueProviderCallback: _ => EnsureTickTimer()?.paused ?? false, name: "paused")
|
|
;
|
|
|
|
Registers.State.Define32(this)
|
|
.WithFlag(0, out isResume)
|
|
.WithFlag(1, out wasForced)
|
|
;
|
|
|
|
Registers.Powerdown.Define32(this)
|
|
.WithFlag(0, FieldMode.Read | FieldMode.Write, changeCallback: (_, val) => {
|
|
if (val) {
|
|
this.Log(LogLevel.Info, "Pausing and resetting machine");
|
|
machine.LocalTimeSource.ExecuteInNearestSyncedState(ts => {
|
|
machine.Pause();
|
|
machine.Reset();
|
|
});
|
|
}
|
|
})
|
|
;
|
|
|
|
Registers.Wfi.Define32(this)
|
|
.WithFlag(0, name: "override")
|
|
;
|
|
|
|
Registers.Interrupt.Define32(this)
|
|
.WithFlag(0, FieldMode.Write, writeCallback: (_, val) =>
|
|
{
|
|
if (val)
|
|
{
|
|
irqPending.Value = true;
|
|
}
|
|
UpdateInterrupts();
|
|
})
|
|
;
|
|
|
|
Registers.EventStatus.Define32(this)
|
|
.WithFlag(0, FieldMode.Read, name: "EV_STATUS", valueProviderCallback: _ => false)
|
|
;
|
|
|
|
Registers.EventPending.Define32(this)
|
|
.WithFlag(0, out irqPending, FieldMode.Read | FieldMode.WriteOneToClear, name: "EV_PENDING", changeCallback: (_, __) => UpdateInterrupts())
|
|
;
|
|
|
|
Registers.EventEnable.Define32(this)
|
|
.WithFlag(0, out irqEnabled, name: "EV_ENABLE", changeCallback: (_, __) => UpdateInterrupts())
|
|
;
|
|
|
|
}
|
|
|
|
TickTimer MainTimer;
|
|
|
|
private IFlagRegisterField irqEnabled;
|
|
private IFlagRegisterField irqPending;
|
|
private IValueRegisterField resumeTime0;
|
|
private IValueRegisterField resumeTime1;
|
|
private IFlagRegisterField timerPaused;
|
|
private IFlagRegisterField isResume;
|
|
private IFlagRegisterField wasForced;
|
|
|
|
public GPIO IRQ { get; private set; }
|
|
|
|
private enum Registers
|
|
{
|
|
Control = 0x00,
|
|
ResumeTime1 = 0x04,
|
|
ResumeTime0 = 0x08,
|
|
Time1 = 0x0c,
|
|
Time0 = 0x10,
|
|
Status = 0x14,
|
|
State = 0x18,
|
|
Powerdown = 0x1c,
|
|
Wfi = 0x20,
|
|
Interrupt = 0x24,
|
|
EventStatus = 0x28,
|
|
EventPending = 0x2c,
|
|
EventEnable = 0x30,
|
|
}
|
|
}
|
|
}
|