1 // 2 // Copyright (c) 2010-2024 Antmicro 3 // 4 // This file is licensed under the MIT License. 5 // Full license text is available in 'licenses/MIT.txt'. 6 // 7 using System; 8 using System.Collections.Generic; 9 using System.Linq; 10 using Antmicro.Migrant; 11 using Antmicro.Renode.Core; 12 using Antmicro.Renode.Core.Structure; 13 using Antmicro.Renode.Peripherals.Bus; 14 using Antmicro.Renode.Peripherals.CPU; 15 16 namespace Antmicro.Renode.Peripherals.UART 17 { 18 public static class VirtualConsoleExtensions 19 { CreateVirtualConsole(this IMachine machine, string name)20 public static void CreateVirtualConsole(this IMachine machine, string name) 21 { 22 var virtConsole = new VirtualConsole(machine); 23 machine.RegisterAsAChildOf(machine.SystemBus, virtConsole, NullRegistrationPoint.Instance); 24 machine.SetLocalName(virtConsole, name); 25 } 26 } 27 28 public class VirtualConsole : IUART 29 { VirtualConsole(IMachine machine)30 public VirtualConsole(IMachine machine) 31 { 32 bus = machine.SystemBus; 33 fifo = new Queue<byte>(); 34 locker = new object(); 35 } 36 Reset()37 public void Reset() 38 { 39 Clear(); 40 } 41 Clear()42 public void Clear() 43 { 44 lock(locker) 45 { 46 fifo.Clear(); 47 } 48 } 49 IsEmpty()50 public bool IsEmpty() 51 { 52 lock(locker) 53 { 54 return fifo.Count == 0; 55 } 56 } 57 Contains(byte value)58 public bool Contains(byte value) 59 { 60 lock(locker) 61 { 62 return fifo.Contains(value); 63 } 64 } 65 WriteChar(byte value)66 public void WriteChar(byte value) 67 { 68 lock(locker) 69 { 70 fifo.Enqueue(value); 71 CharWritten?.Invoke(value); 72 } 73 if(Echo) 74 { 75 DisplayChar(value); 76 } 77 } 78 ReadBuffer(int maxCount = 1)79 public byte[] ReadBuffer(int maxCount = 1) 80 { 81 lock(locker) 82 { 83 return GetFifoIterator().Take(maxCount).ToArray(); 84 } 85 } 86 GetBuffer()87 public byte[] GetBuffer() 88 { 89 lock(locker) 90 { 91 return fifo.ToArray(); 92 } 93 } 94 WriteBufferToMemory(ulong address, int maxCount, ICPU context = null)95 public long WriteBufferToMemory(ulong address, int maxCount, ICPU context = null) 96 { 97 var buffer = ReadBuffer(maxCount); 98 bus.WriteBytes(buffer, address, true, context); 99 return buffer.Length; 100 } 101 DisplayChar(byte value)102 public void DisplayChar(byte value) 103 { 104 CharReceived?.Invoke(value); 105 } 106 107 public bool Echo { get; set; } = true; 108 109 public uint BaudRate { get; set; } 110 public Bits StopBits { get; set; } 111 public Parity ParityBit { get; set; } 112 113 [field: Transient] 114 public event Action<byte> CharReceived; 115 116 [field: Transient] 117 public event Action<byte> CharWritten; 118 GetFifoIterator()119 private IEnumerable<byte> GetFifoIterator() 120 { 121 while(fifo.Count > 0) 122 { 123 yield return fifo.Dequeue(); 124 } 125 } 126 127 private readonly IBusController bus; 128 private readonly object locker; 129 private readonly Queue<byte> fifo; 130 } 131 } 132