current wip of betrusted
Signed-off-by: Sean Cross <sean@xobs.io>
This commit is contained in:
parent
67423523a9
commit
9053b459e8
53
fb.cs
53
fb.cs
@ -25,10 +25,10 @@ namespace Antmicro.Renode.Peripherals.Video
|
|||||||
|
|
||||||
RegistersCollection = new DoubleWordRegisterCollection(this);
|
RegistersCollection = new DoubleWordRegisterCollection(this);
|
||||||
Reconfigure(336, 536, PixelFormat.RGB565, false);
|
Reconfigure(336, 536, PixelFormat.RGB565, false);
|
||||||
for (int i = 0; i < buffer.Length; i++) buffer[i] = 0;
|
for (int i = 0; i < buffer.Length; i++) buffer[i] = 0;
|
||||||
DoRepaint();
|
DoRepaint();
|
||||||
DefineRegisters();
|
DefineRegisters();
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void WriteDoubleWord(long address, uint value)
|
public void WriteDoubleWord(long address, uint value)
|
||||||
@ -46,40 +46,43 @@ namespace Antmicro.Renode.Peripherals.Video
|
|||||||
RegistersCollection.Reset();
|
RegistersCollection.Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long Size => 0x800;
|
public long Size { get{ return 0x800; }}
|
||||||
public DoubleWordRegisterCollection RegistersCollection { get; private set; }
|
public DoubleWordRegisterCollection RegistersCollection { get; private set; }
|
||||||
|
|
||||||
protected override void Repaint()
|
protected override void Repaint()
|
||||||
{
|
{
|
||||||
var newbuf = new Byte[44*Height];
|
var newbuf = new Byte[44*Height];
|
||||||
machine.SystemBus.ReadBytes(bufferAddress, newbuf.Length, newbuf, 0);
|
machine.SystemBus.ReadBytes(bufferAddress, newbuf.Length, newbuf, 0);
|
||||||
for (int y = 0; y < Height; y++) {
|
for (int y = 0; y < Height; y++) {
|
||||||
if (!updateDirty || updateAll || ((newbuf[y*44+0x2a] & 0x1) == 0x1)) for (int x = 0; x < Width; x++) {
|
if (!updateDirty || updateAll || ((newbuf[y*44+0x2a] & 0x1) == 0x1)) for (int x = 0; x < Width; x++) {
|
||||||
if (((newbuf[((x+y*44*8))/8] >> (x%8))&1) > 0) {
|
if (((newbuf[((x+y*44*8))/8] >> (x%8))&1) > 0) {
|
||||||
buffer[2*(x+y*Width)] = 0xFF;
|
buffer[2*(x+y*Width)] = 0xFF;
|
||||||
buffer[2*(x+y*Width)+1] = 0xFF;
|
buffer[2*(x+y*Width)+1] = 0xFF;
|
||||||
} else {
|
} else {
|
||||||
buffer[2*(x+y*Width)] = 0x0;
|
buffer[2*(x+y*Width)] = 0x0;
|
||||||
buffer[2*(x+y*Width)+1] = 0x0;
|
buffer[2*(x+y*Width)+1] = 0x0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void DefineRegisters()
|
private void DefineRegisters()
|
||||||
{
|
{
|
||||||
Registers.COMMAND.Define(this)
|
Registers.COMMAND.Define(this)
|
||||||
.WithValueField(0, 32, writeCallback: (_, val) =>
|
.WithValueField(0, 32, writeCallback: (_, val) =>
|
||||||
{
|
{
|
||||||
updateDirty = (val & 0x1) == 0x1;
|
updateDirty = (val & 0x1) == 0x1;
|
||||||
updateAll = (val & 0x10) == 0x10;
|
updateAll = (val & 0x2) == 0x2;
|
||||||
DoRepaint();
|
DoRepaint();
|
||||||
})
|
})
|
||||||
|
;
|
||||||
|
Registers.BUSY.Define(this)
|
||||||
|
.WithValueField(0, 32, valueProviderCallback: _ => { return 0; })
|
||||||
;
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
private bool updateDirty = false;
|
private bool updateDirty = false;
|
||||||
private bool updateAll = false;
|
private bool updateAll = false;
|
||||||
|
|
||||||
private uint bufferAddress = 0xB0000000;
|
private uint bufferAddress = 0xB0000000;
|
||||||
|
|
||||||
@ -88,7 +91,7 @@ namespace Antmicro.Renode.Peripherals.Video
|
|||||||
private enum Registers
|
private enum Registers
|
||||||
{
|
{
|
||||||
COMMAND = 0x0,
|
COMMAND = 0x0,
|
||||||
BUSY = 0x04
|
BUSY = 0x04
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
108
kbd_soc.cs
Normal file
108
kbd_soc.cs
Normal file
@ -0,0 +1,108 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2010 - 2019 Antmicro
|
||||||
|
//
|
||||||
|
// This file is licensed under the MIT License.
|
||||||
|
// Full license text is available in 'licenses/MIT.txt'.
|
||||||
|
//
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Linq;
|
||||||
|
using Antmicro.Renode.Backends.Display;
|
||||||
|
using Antmicro.Renode.Core;
|
||||||
|
using Antmicro.Renode.Core.Structure.Registers;
|
||||||
|
using Antmicro.Renode.Logging;
|
||||||
|
using Antmicro.Renode.Peripherals.Bus;
|
||||||
|
using Antmicro.Renode.Peripherals.Memory;
|
||||||
|
using Antmicro.Renode.Utilities;
|
||||||
|
|
||||||
|
namespace Antmicro.Renode.Peripherals.Input
|
||||||
|
{
|
||||||
|
public class betrusted_kbd : IKeyboard, IDoubleWordPeripheral, IProvidesRegisterCollection<DoubleWordRegisterCollection>, IKnownSize
|
||||||
|
{
|
||||||
|
public betrusted_kbd(Machine machine) : base(machine)
|
||||||
|
{
|
||||||
|
this.machine = machine;
|
||||||
|
|
||||||
|
RegistersCollection = new DoubleWordRegisterCollection(this);
|
||||||
|
for (int i = 0; i < buffer.Length; i++) buffer[i] = 0;
|
||||||
|
// DefineRegisters();
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteDoubleWord(long address, uint value)
|
||||||
|
{
|
||||||
|
RegistersCollection.Write(address, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ReadDoubleWord(long offset)
|
||||||
|
{
|
||||||
|
return RegistersCollection.Read(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
RegistersCollection.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Size { get{ return 0x800; }}
|
||||||
|
public DoubleWordRegisterCollection RegistersCollection { get; private set; }
|
||||||
|
|
||||||
|
// protected override void Repaint()
|
||||||
|
// {
|
||||||
|
// var newbuf = new Byte[44*Height];
|
||||||
|
// machine.SystemBus.ReadBytes(bufferAddress, newbuf.Length, newbuf, 0);
|
||||||
|
// for (int y = 0; y < Height; y++) {
|
||||||
|
// if (!updateDirty || updateAll || ((newbuf[y*44+0x2a] & 0x1) == 0x1)) for (int x = 0; x < Width; x++) {
|
||||||
|
// if (((newbuf[((x+y*44*8))/8] >> (x%8))&1) > 0) {
|
||||||
|
// buffer[2*(x+y*Width)] = 0xFF;
|
||||||
|
// buffer[2*(x+y*Width)+1] = 0xFF;
|
||||||
|
// } else {
|
||||||
|
// buffer[2*(x+y*Width)] = 0x0;
|
||||||
|
// buffer[2*(x+y*Width)+1] = 0x0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void DefineRegisters()
|
||||||
|
// {
|
||||||
|
// Registers.COMMAND.Define(this)
|
||||||
|
// .WithValueField(0, 32, writeCallback: (_, val) =>
|
||||||
|
// {
|
||||||
|
// updateDirty = (val & 0x1) == 0x1;
|
||||||
|
// updateAll = (val & 0x10) == 0x10;
|
||||||
|
// DoRepaint();
|
||||||
|
// })
|
||||||
|
// ;
|
||||||
|
// }
|
||||||
|
private readonly Machine machine;
|
||||||
|
|
||||||
|
private enum Registers
|
||||||
|
{
|
||||||
|
ROW0DAT1 = 0x0,
|
||||||
|
ROW0DAT0 = 0x4,
|
||||||
|
ROW1DAT1 = 0x8,
|
||||||
|
ROW1DAT0 = 0xc,
|
||||||
|
ROW2DAT1 = 0x10,
|
||||||
|
ROW2DAT0 = 0x14,
|
||||||
|
ROW3DAT1 = 0x18,
|
||||||
|
ROW3DAT0 = 0x1c,
|
||||||
|
ROW4DAT1 = 0x20,
|
||||||
|
ROW4DAT0 = 0x24,
|
||||||
|
ROW5DAT1 = 0x28,
|
||||||
|
ROW5DAT0 = 0x2c,
|
||||||
|
ROW6DAT1 = 0x30,
|
||||||
|
ROW6DAT0 = 0x34,
|
||||||
|
ROW7DAT1 = 0x38,
|
||||||
|
ROW7DAT0 = 0x3c,
|
||||||
|
ROW8DAT1 = 0x40,
|
||||||
|
ROW8DAT0 = 0x44,
|
||||||
|
EV_STATUS = 0x48,
|
||||||
|
EV_PENDING = 0x4c,
|
||||||
|
EV_ENABLE = 0x50,
|
||||||
|
ROWCHANGE1 = 0x54,
|
||||||
|
ROWCHANGE0 = 0x58,
|
||||||
|
BUSY = 0x04
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
193
spi_ec.cs
Normal file
193
spi_ec.cs
Normal file
@ -0,0 +1,193 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2010-2018 Antmicro
|
||||||
|
// Copyright (c) 2011-2015 Realtime Embedded
|
||||||
|
//
|
||||||
|
// This file is licensed under the MIT License.
|
||||||
|
// Full license text is available in 'licenses/MIT.txt'.
|
||||||
|
//
|
||||||
|
using System;
|
||||||
|
using Antmicro.Renode.Peripherals.Bus;
|
||||||
|
using Antmicro.Renode.Logging;
|
||||||
|
using Antmicro.Renode.Core.Structure;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Antmicro.Renode.Core;
|
||||||
|
using Antmicro.Renode.Core.Structure.Registers;
|
||||||
|
|
||||||
|
namespace Antmicro.Renode.Peripherals.SPI
|
||||||
|
{
|
||||||
|
public sealed class STM32SPI : NullRegistrationPointPeripheralContainer<ISPIPeripheral>, IWordPeripheral, IDoubleWordPeripheral, IBytePeripheral, IKnownSize
|
||||||
|
{
|
||||||
|
public STM32SPI(Machine machine) : base(machine)
|
||||||
|
{
|
||||||
|
receiveBuffer = new Queue<byte>();
|
||||||
|
IRQ = new GPIO();
|
||||||
|
SetupRegisters();
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte ReadByte(long offset)
|
||||||
|
{
|
||||||
|
// byte interface is there for DMA
|
||||||
|
if(offset % 4 == 0)
|
||||||
|
{
|
||||||
|
return (byte)ReadDoubleWord(offset);
|
||||||
|
}
|
||||||
|
this.LogUnhandledRead(offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteByte(long offset, byte value)
|
||||||
|
{
|
||||||
|
if(offset % 4 == 0)
|
||||||
|
{
|
||||||
|
WriteDoubleWord(offset, (uint)value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.LogUnhandledWrite(offset, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ushort ReadWord(long offset)
|
||||||
|
{
|
||||||
|
return (ushort)ReadDoubleWord(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteWord(long offset, ushort value)
|
||||||
|
{
|
||||||
|
WriteDoubleWord(offset, (uint)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ReadDoubleWord(long offset)
|
||||||
|
{
|
||||||
|
switch((Registers)offset)
|
||||||
|
{
|
||||||
|
case Registers.Data:
|
||||||
|
return HandleDataRead();
|
||||||
|
default:
|
||||||
|
return registers.Read(offset);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteDoubleWord(long offset, uint value)
|
||||||
|
{
|
||||||
|
switch((Registers)offset)
|
||||||
|
{
|
||||||
|
case Registers.Data:
|
||||||
|
HandleDataWrite(value);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
registers.Write(offset, value);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
lock(receiveBuffer)
|
||||||
|
{
|
||||||
|
receiveBuffer.Clear();
|
||||||
|
}
|
||||||
|
registers.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Size
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return 0x400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public GPIO IRQ
|
||||||
|
{
|
||||||
|
get;
|
||||||
|
private set;
|
||||||
|
}
|
||||||
|
|
||||||
|
private uint HandleDataRead()
|
||||||
|
{
|
||||||
|
IRQ.Unset();
|
||||||
|
lock(receiveBuffer)
|
||||||
|
{
|
||||||
|
if(receiveBuffer.Count > 0)
|
||||||
|
{
|
||||||
|
var value = receiveBuffer.Dequeue();
|
||||||
|
return value; // TODO: verify if Update should be called
|
||||||
|
}
|
||||||
|
this.Log(LogLevel.Warning, "Trying to read data register while no data has been received.");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void HandleDataWrite(uint value)
|
||||||
|
{
|
||||||
|
IRQ.Unset();
|
||||||
|
lock(receiveBuffer)
|
||||||
|
{
|
||||||
|
var peripheral = RegisteredPeripheral;
|
||||||
|
if(peripheral == null)
|
||||||
|
{
|
||||||
|
this.Log(LogLevel.Warning, "SPI transmission while no SPI peripheral is connected.");
|
||||||
|
receiveBuffer.Enqueue(0x0);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
receiveBuffer.Enqueue(peripheral.Transmit((byte)value)); // currently byte mode is the only one we support
|
||||||
|
this.NoisyLog("Transmitted 0x{0:X}, received 0x{1:X}.", value, receiveBuffer.Peek());
|
||||||
|
}
|
||||||
|
Update();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
// TODO: verify this condition
|
||||||
|
IRQ.Set(txBufferEmptyInterruptEnable.Value || rxBufferNotEmptyInterruptEnable.Value || txDmaEnable.Value || rxDmaEnable.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupRegisters()
|
||||||
|
{
|
||||||
|
var control2 = new DoubleWordRegister(this);
|
||||||
|
txBufferEmptyInterruptEnable = control2.DefineFlagField(7);
|
||||||
|
rxBufferNotEmptyInterruptEnable = control2.DefineFlagField(6);
|
||||||
|
txDmaEnable = control2.DefineFlagField(1);
|
||||||
|
rxDmaEnable = control2.DefineFlagField(0, writeCallback: (_,__) => Update());
|
||||||
|
|
||||||
|
var registerDictionary = new Dictionary<long, DoubleWordRegister>
|
||||||
|
{
|
||||||
|
{ (long)Registers.Control1, new DoubleWordRegister(this).WithValueField(3,3, name:"Baud").WithFlag(2, name:"Master")
|
||||||
|
.WithFlag(8, name:"SSI").WithFlag(9, name:"SSM").WithFlag(6, changeCallback: (oldValue, newValue) => {
|
||||||
|
if(!newValue)
|
||||||
|
{
|
||||||
|
IRQ.Unset();
|
||||||
|
}
|
||||||
|
}, name:"SpiEnable")},
|
||||||
|
{(long)Registers.Status, new DoubleWordRegister(this, 2).WithFlag(1, FieldMode.Read, name:"TXE").WithFlag(0, FieldMode.Read, valueProviderCallback: _ => receiveBuffer.Count != 0 , name:"RXNE")},
|
||||||
|
{(long)Registers.CRCPolynomial, new DoubleWordRegister(this, 7).WithValueField(0, 16, name:"CRCPoly") },
|
||||||
|
{(long)Registers.I2SConfiguration, new DoubleWordRegister(this, 0).WithFlag(10, FieldMode.Read | FieldMode.WriteOneToClear, writeCallback: (oldValue, newValue) => {
|
||||||
|
// write one to clear to keep this bit 0
|
||||||
|
if(newValue)
|
||||||
|
{
|
||||||
|
this.Log(LogLevel.Warning, "Trying to enable not supported I2S mode.");
|
||||||
|
}
|
||||||
|
}, name:"I2SE")},
|
||||||
|
{ (long)Registers.Control2, control2 }
|
||||||
|
};
|
||||||
|
registers = new DoubleWordRegisterCollection(this, registerDictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
private DoubleWordRegisterCollection registers;
|
||||||
|
private IFlagRegisterField txBufferEmptyInterruptEnable, rxBufferNotEmptyInterruptEnable, txDmaEnable, rxDmaEnable;
|
||||||
|
|
||||||
|
private readonly Queue<byte> receiveBuffer;
|
||||||
|
|
||||||
|
private enum Registers
|
||||||
|
{
|
||||||
|
Control1 = 0x0, // SPI_CR1,
|
||||||
|
Control2 = 0x4, // SPI_CR2
|
||||||
|
Status = 0x8, // SPI_SR
|
||||||
|
Data = 0xC, // SPI_DR
|
||||||
|
CRCPolynomial = 0x10, // SPI_CRCPR
|
||||||
|
I2SConfiguration = 0x1C // SPI_I2SCFGR
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
184
spi_soc.cs
Normal file
184
spi_soc.cs
Normal file
@ -0,0 +1,184 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2010-2018 Antmicro
|
||||||
|
// Copyright (c) 2011-2015 Realtime Embedded
|
||||||
|
//
|
||||||
|
// This file is licensed under the MIT License.
|
||||||
|
// Full license text is available in 'licenses/MIT.txt'.
|
||||||
|
//
|
||||||
|
using System;
|
||||||
|
using Antmicro.Renode.Peripherals.Bus;
|
||||||
|
using Antmicro.Renode.Logging;
|
||||||
|
using Antmicro.Renode.Core.Structure;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Antmicro.Renode.Core;
|
||||||
|
using Antmicro.Renode.Core.Structure.Registers;
|
||||||
|
|
||||||
|
namespace Antmicro.Renode.Peripherals.SPI
|
||||||
|
{
|
||||||
|
public sealed class BSOCSPI : NullRegistrationPointPeripheralContainer<ISPIPeripheral>, IWordPeripheral, IDoubleWordPeripheral, IBytePeripheral, IKnownSize
|
||||||
|
{
|
||||||
|
public BSOCSPI(Machine machine) : base(machine)
|
||||||
|
{
|
||||||
|
// receiveBuffer = new Queue<byte>();
|
||||||
|
// IRQ = new GPIO();
|
||||||
|
SetupRegisters();
|
||||||
|
Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte ReadByte(long offset)
|
||||||
|
{
|
||||||
|
// byte interface is there for DMA
|
||||||
|
if(offset % 4 == 0)
|
||||||
|
{
|
||||||
|
return (byte)ReadDoubleWord(offset);
|
||||||
|
}
|
||||||
|
this.LogUnhandledRead(offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteByte(long offset, byte value)
|
||||||
|
{
|
||||||
|
if(offset % 4 == 0)
|
||||||
|
{
|
||||||
|
WriteDoubleWord(offset, (uint)value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
this.LogUnhandledWrite(offset, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public ushort ReadWord(long offset)
|
||||||
|
{
|
||||||
|
return (ushort)ReadDoubleWord(offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteWord(long offset, ushort value)
|
||||||
|
{
|
||||||
|
WriteDoubleWord(offset, (uint)value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public uint ReadDoubleWord(long offset)
|
||||||
|
{
|
||||||
|
// switch((Registers)offset)
|
||||||
|
// {
|
||||||
|
// case Registers.Data:
|
||||||
|
// return HandleDataRead();
|
||||||
|
// default:
|
||||||
|
return registers.Read(offset);
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public void WriteDoubleWord(long offset, uint value)
|
||||||
|
{
|
||||||
|
// switch((Registers)offset)
|
||||||
|
// {
|
||||||
|
// case Registers.Data:
|
||||||
|
// HandleDataWrite(value);
|
||||||
|
// break;
|
||||||
|
// default:
|
||||||
|
registers.Write(offset, value);
|
||||||
|
// break;
|
||||||
|
// }
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void Reset()
|
||||||
|
{
|
||||||
|
// lock(receiveBuffer)
|
||||||
|
// {
|
||||||
|
// receiveBuffer.Clear();
|
||||||
|
// }
|
||||||
|
registers.Reset();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Size
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return 0x400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// public GPIO IRQ
|
||||||
|
// {
|
||||||
|
// get;
|
||||||
|
// private set;
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private uint HandleDataRead()
|
||||||
|
// {
|
||||||
|
// IRQ.Unset();
|
||||||
|
// lock(receiveBuffer)
|
||||||
|
// {
|
||||||
|
// if(receiveBuffer.Count > 0)
|
||||||
|
// {
|
||||||
|
// var value = receiveBuffer.Dequeue();
|
||||||
|
// return value; // TODO: verify if Update should be called
|
||||||
|
// }
|
||||||
|
// this.Log(LogLevel.Warning, "Trying to read data register while no data has been received.");
|
||||||
|
// return 0;
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
|
||||||
|
// private void HandleDataWrite(uint value)
|
||||||
|
// {
|
||||||
|
// IRQ.Unset();
|
||||||
|
// lock(receiveBuffer)
|
||||||
|
// {
|
||||||
|
// var peripheral = RegisteredPeripheral;
|
||||||
|
// if(peripheral == null)
|
||||||
|
// {
|
||||||
|
// this.Log(LogLevel.Warning, "SPI transmission while no SPI peripheral is connected.");
|
||||||
|
// receiveBuffer.Enqueue(0x0);
|
||||||
|
// return;
|
||||||
|
// }
|
||||||
|
// receiveBuffer.Enqueue(peripheral.Transmit((byte)value)); // currently byte mode is the only one we support
|
||||||
|
// this.NoisyLog("Transmitted 0x{0:X}, received 0x{1:X}.", value, receiveBuffer.Peek());
|
||||||
|
// }
|
||||||
|
// Update();
|
||||||
|
// }
|
||||||
|
|
||||||
|
private void Update()
|
||||||
|
{
|
||||||
|
// TODO: verify this condition
|
||||||
|
// IRQ.Set(txBufferEmptyInterruptEnable.Value || rxBufferNotEmptyInterruptEnable.Value || txDmaEnable.Value || rxDmaEnable.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void SetupRegisters()
|
||||||
|
{
|
||||||
|
var registerDictionary = new Dictionary<long, DoubleWordRegister>
|
||||||
|
{
|
||||||
|
{ (long)Registers.TX1, new DoubleWordRegister(this, 0).WithValueField(0, 8, name:"TX1")},
|
||||||
|
{ (long)Registers.TX0, new DoubleWordRegister(this, 0).WithValueField(0, 8, name:"TX0")},
|
||||||
|
{ (long)Registers.RX1, new DoubleWordRegister(this, 0).WithValueField(0, 8, name:"RX1")},
|
||||||
|
{ (long)Registers.RX0, new DoubleWordRegister(this, 0).WithValueField(0, 8, name:"RX0")},
|
||||||
|
{ (long)Registers.CONTROL, new DoubleWordRegister(this)
|
||||||
|
.WithFlag(0, FieldMode.Write, name:"CLR_DONE")
|
||||||
|
.WithFlag(1, FieldMode.Write, name:"GO", changeCallback: (oldValue, newValue) => {
|
||||||
|
// Execute operation here
|
||||||
|
})
|
||||||
|
.WithFlag(2, FieldMode.Write, name:"INTENA")
|
||||||
|
},
|
||||||
|
{(long)Registers.STATUS, new DoubleWordRegister(this, 2)
|
||||||
|
.WithFlag(0, FieldMode.Read, name:"TIP")
|
||||||
|
.WithFlag(1, FieldMode.Read, name: "DONE", valueProviderCallback: (_) => {doneBit = !doneBit; return doneBit; })
|
||||||
|
},
|
||||||
|
};
|
||||||
|
registers = new DoubleWordRegisterCollection(this, registerDictionary);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool doneBit;
|
||||||
|
|
||||||
|
private DoubleWordRegisterCollection registers;
|
||||||
|
|
||||||
|
private enum Registers
|
||||||
|
{
|
||||||
|
TX1 = 0x00,
|
||||||
|
TX0 = 0x04,
|
||||||
|
RX1 = 0x08,
|
||||||
|
RX0 = 0x0c,
|
||||||
|
CONTROL = 0x10,
|
||||||
|
STATUS = 0x14,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@ cpu: CPU.VexRiscv @ sysbus
|
|||||||
cpuType: "rv32gc"
|
cpuType: "rv32gc"
|
||||||
|
|
||||||
mem: Memory.MappedMemory @ sysbus 0x20500000
|
mem: Memory.MappedMemory @ sysbus 0x20500000
|
||||||
size: 0x10000
|
size: 0x80000
|
||||||
|
|
||||||
mem2: Memory.MappedMemory @ sysbus 0x00001000
|
mem2: Memory.MappedMemory @ sysbus 0x00001000
|
||||||
size: 0x40000
|
size: 0x40000
|
||||||
@ -15,3 +15,9 @@ fbmem: Memory.MappedMemory @ sysbus 0xB0000000
|
|||||||
|
|
||||||
fb: Video.fb @ sysbus 0xF0005000
|
fb: Video.fb @ sysbus 0xF0005000
|
||||||
|
|
||||||
|
bsocspi: SPI.BSOCSPI @ sysbus 0xF0005800
|
||||||
|
|
||||||
|
bsocticktimer: Timers.BSOCTickTimer @ sysbus 0xF0007800
|
||||||
|
periodInMs: 1
|
||||||
|
|
||||||
|
//betrusted_kbd: Input.betrusted_kbd @ 0xF0009000
|
10
test.resc
10
test.resc
@ -1,7 +1,11 @@
|
|||||||
mach create
|
mach create
|
||||||
i @fb.cs
|
i @fb.cs
|
||||||
|
i @spi_soc.cs
|
||||||
|
i @ticktimer_soc.cs
|
||||||
|
#i @kbd.cs
|
||||||
using sysbus
|
using sysbus
|
||||||
machine LoadPlatformDescription "test.repl"
|
machine LoadPlatformDescription $ORIGIN/test.repl
|
||||||
sysbus ApplySVD @soc.svd
|
sysbus ApplySVD $ORIGIN/Betrusted\ SoC.svd
|
||||||
sysbus LoadELF @betrusted-soc
|
sysbus LoadELF "D:/Code/Betrusted/betrusted-soc/sw/target/riscv32imac-unknown-none-elf/debug/betrusted-soc"
|
||||||
showAnalyzer sysbus.fb
|
showAnalyzer sysbus.fb
|
||||||
|
machine StartGdbServer 3333 true
|
82
ticktimer_soc.cs
Normal file
82
ticktimer_soc.cs
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
//
|
||||||
|
// Copyright (c) 2010-2018 Antmicro
|
||||||
|
// Copyright (c) 2011-2015 Realtime Embedded
|
||||||
|
//
|
||||||
|
// This file is licensed under the MIT License.
|
||||||
|
// Full license text is available in 'licenses/MIT.txt'.
|
||||||
|
//
|
||||||
|
using System;
|
||||||
|
using Antmicro.Renode.Core;
|
||||||
|
using Antmicro.Renode.Peripherals.Bus;
|
||||||
|
using Antmicro.Renode.Time;
|
||||||
|
using Antmicro.Renode.Logging;
|
||||||
|
using System.Threading;
|
||||||
|
|
||||||
|
namespace Antmicro.Renode.Peripherals.Timers
|
||||||
|
{
|
||||||
|
public class BSOCTickTimer : IDoubleWordPeripheral, IKnownSize
|
||||||
|
{
|
||||||
|
public BSOCTickTimer(ulong periodInMs, Machine machine)
|
||||||
|
{
|
||||||
|
running = true;
|
||||||
|
machine.ClockSource.AddClockEntry(new ClockEntry(periodInMs, ClockEntry.FrequencyToRatio(this, 1000), OnTick, this, String.Empty));
|
||||||
|
}
|
||||||
|
|
||||||
|
public long Size
|
||||||
|
{
|
||||||
|
get
|
||||||
|
{
|
||||||
|
return 0x400;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual uint ReadDoubleWord(long offset)
|
||||||
|
{
|
||||||
|
if (offset == 0)
|
||||||
|
return 0;
|
||||||
|
else if (offset == 4)
|
||||||
|
offset = 40;
|
||||||
|
else if (offset == 8)
|
||||||
|
offset = 32;
|
||||||
|
else if (offset == 12)
|
||||||
|
offset = 24;
|
||||||
|
else if (offset == 16)
|
||||||
|
offset = 16;
|
||||||
|
else if (offset == 20)
|
||||||
|
offset = 8;
|
||||||
|
else if (offset == 24)
|
||||||
|
offset = 0;
|
||||||
|
else {
|
||||||
|
this.LogUnhandledRead(offset);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return (uint)(Interlocked.CompareExchange(ref counter, 0, 0) >> (int)offset);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void WriteDoubleWord(long offset, uint value)
|
||||||
|
{
|
||||||
|
if (offset == 0) {
|
||||||
|
if ((value & 1) == 1)
|
||||||
|
Interlocked.Exchange(ref counter, 0);
|
||||||
|
running = ((value & 2) != 2);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
this.LogUnhandledWrite(offset, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual void Reset()
|
||||||
|
{
|
||||||
|
Interlocked.Exchange(ref counter, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void OnTick()
|
||||||
|
{
|
||||||
|
if (running)
|
||||||
|
Interlocked.Increment(ref counter);
|
||||||
|
}
|
||||||
|
|
||||||
|
private long counter;
|
||||||
|
private bool running;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user