diff --git a/UART16550.cs b/UART16550.cs
new file mode 100644
index 0000000..5e147e3
--- /dev/null
+++ b/UART16550.cs
@@ -0,0 +1,677 @@
+//
+// 16550 UART 外设实现
+// 基于 16550 UART 规格,包含完整的 FIFO、中断和调制解调器控制功能
+// author:liuwenbo
+//
+
+using System;
+using System.Collections.Generic;
+using Antmicro.Renode.Core;
+using Antmicro.Renode.Logging;
+using Antmicro.Renode.Peripherals.Bus;
+using Antmicro.Renode.Peripherals.UART;
+using Antmicro.Renode.Utilities;
+
+namespace Antmicro.Renode.Peripherals.CustomPeripherals
+{
+ ///
+ /// 16550 UART 控制器
+ /// 兼容 16550 UART 规格,支持 FIFO、中断和调制解调器控制
+ ///
+ public class UART16550 : UARTBase, IDoubleWordPeripheral, IBytePeripheral, IKnownSize
+ {
+ public UART16550(IMachine machine, uint clockFrequency = 1843200)
+ : base(machine)
+ {
+ this.clockFrequency = clockFrequency;
+
+ // 创建 FIFO
+ rxFifo = new Queue();
+ txFifo = new Queue();
+
+ // 创建中断线
+ IRQ = new GPIO();
+
+ // 初始化寄存器
+ DefineRegisters();
+ Reset();
+
+ this.Log(LogLevel.Info, "16550 UART initialized, clock: {0} Hz", clockFrequency);
+ }
+
+ public override void Reset()
+ {
+ rxFifo.Clear();
+ txFifo.Clear();
+
+ // 寄存器复位值
+ ier = 0x00;
+ lcr = 0x00;
+ mcr = 0x00;
+ lsr = (byte)(LSR_TEMT | LSR_THRE); // 发送器初始为空
+ msr = 0x00;
+ scr = 0x00;
+ dll = 0x00;
+ dlh = 0x00;
+ fcr = 0x00;
+
+ fifoEnabled = false;
+ fifoTriggerLevel = 1;
+
+ IRQ.Set(false);
+ UpdateInterrupts();
+
+ this.Log(LogLevel.Debug, "16550 UART reset");
+ }
+
+ private void DefineRegisters()
+ {
+ // 寄存器访问通过 ReadDoubleWord/WriteDoubleWord 实现
+ // 因为 16550 是字节外设,但 Renode 通常使用 32 位访问
+ }
+
+ // ========================================
+ // IBusPeripheral 接口实现
+ // ========================================
+
+ public uint ReadDoubleWord(long offset)
+ {
+ return ReadByte(offset);
+ }
+
+ public void WriteDoubleWord(long offset, uint value)
+ {
+ WriteByte(offset, (byte)value);
+ }
+
+ public byte ReadByte(long offset)
+ {
+ byte value = 0;
+
+ switch (offset)
+ {
+ case (long)Registers.RBR_THR_DLL:
+ if ((lcr & LCR_DLAB) != 0)
+ {
+ // DLAB=1: 读取 DLL
+ value = dll;
+ this.Log(LogLevel.Noisy, "Read DLL: 0x{0:X2}", value);
+ }
+ else
+ {
+ // DLAB=0: 读取 RBR
+ value = ReadRBR();
+ }
+ break;
+
+ case (long)Registers.IER_DLH:
+ if ((lcr & LCR_DLAB) != 0)
+ {
+ // DLAB=1: 读取 DLH
+ value = dlh;
+ this.Log(LogLevel.Noisy, "Read DLH: 0x{0:X2}", value);
+ }
+ else
+ {
+ // DLAB=0: 读取 IER
+ value = (byte)(ier & 0x0F);
+ this.Log(LogLevel.Noisy, "Read IER: 0x{0:X2}", value);
+ }
+ break;
+
+ case (long)Registers.IIR_FCR:
+ // IIR - 中断识别寄存器
+ value = ReadIIR();
+ break;
+
+ case (long)Registers.LCR:
+ value = lcr;
+ this.Log(LogLevel.Noisy, "Read LCR: 0x{0:X2}", value);
+ break;
+
+ case (long)Registers.MCR:
+ value = mcr;
+ this.Log(LogLevel.Noisy, "Read MCR: 0x{0:X2}", value);
+ break;
+
+ case (long)Registers.LSR:
+ value = lsr;
+ this.Log(LogLevel.Noisy, "Read LSR: 0x{0:X2}", value);
+ // 读取 LSR 清除错误位
+ lsr = (byte)(lsr & ~(LSR_BI | LSR_FE | LSR_PE));
+ UpdateInterrupts();
+ break;
+
+ case (long)Registers.MSR:
+ value = msr;
+ this.Log(LogLevel.Noisy, "Read MSR: 0x{0:X2}", value);
+ // 读取 MSR 清除变化位
+ msr = (byte)(msr & 0xF0);
+ UpdateInterrupts();
+ break;
+
+ case (long)Registers.SCR:
+ value = scr;
+ this.Log(LogLevel.Noisy, "Read SCR: 0x{0:X2}", value);
+ break;
+
+ default:
+ this.Log(LogLevel.Warning, "Read from unknown offset: 0x{0:X}", offset);
+ break;
+ }
+
+ return value;
+ }
+
+ public void WriteByte(long offset, byte value)
+ {
+ switch (offset)
+ {
+ case (long)Registers.RBR_THR_DLL:
+ if ((lcr & LCR_DLAB) != 0)
+ {
+ // DLAB=1: 写入 DLL
+ dll = value;
+ UpdateBaudRate();
+ this.Log(LogLevel.Debug, "Write DLL: 0x{0:X2}", value);
+ }
+ else
+ {
+ // DLAB=0: 写入 THR
+ WriteTHR(value);
+ }
+ break;
+
+ case (long)Registers.IER_DLH:
+ if ((lcr & LCR_DLAB) != 0)
+ {
+ // DLAB=1: 写入 DLH
+ dlh = value;
+ UpdateBaudRate();
+ this.Log(LogLevel.Debug, "Write DLH: 0x{0:X2}", value);
+ }
+ else
+ {
+ // DLAB=0: 写入 IER
+ ier = (byte)(value & 0x0F);
+ this.Log(LogLevel.Debug, "Write IER: 0x{0:X2}", ier);
+ UpdateInterrupts();
+ }
+ break;
+
+ case (long)Registers.IIR_FCR:
+ // FCR - FIFO 控制寄存器
+ WriteFCR(value);
+ break;
+
+ case (long)Registers.LCR:
+ lcr = value;
+ this.Log(LogLevel.Debug, "Write LCR: 0x{0:X2}", value);
+ UpdateLineParameters();
+ break;
+
+ case (long)Registers.MCR:
+ mcr = (byte)(value & 0x1F);
+ this.Log(LogLevel.Debug, "Write MCR: 0x{0:X2}", mcr);
+ UpdateModemControl();
+ break;
+
+ case (long)Registers.LSR:
+ // LSR 是只读寄存器
+ this.Log(LogLevel.Warning, "Attempted write to read-only LSR");
+ break;
+
+ case (long)Registers.MSR:
+ // MSR 是只读寄存器
+ this.Log(LogLevel.Warning, "Attempted write to read-only MSR");
+ break;
+
+ case (long)Registers.SCR:
+ scr = value;
+ this.Log(LogLevel.Noisy, "Write SCR: 0x{0:X2}", value);
+ break;
+
+ default:
+ this.Log(LogLevel.Warning, "Write to unknown offset: 0x{0:X} = 0x{1:X2}", offset, value);
+ break;
+ }
+ }
+
+ // ========================================
+ // FIFO 和数据传输
+ // ========================================
+
+ private byte ReadRBR()
+ {
+ byte value = 0;
+
+ if (rxFifo.Count > 0)
+ {
+ value = rxFifo.Dequeue();
+ this.Log(LogLevel.Debug, "Read RBR: 0x{0:X2} ('{1}')", value,
+ (value >= 32 && value < 127) ? (char)value : '.');
+
+ // 更新状态
+ if (rxFifo.Count == 0)
+ {
+ lsr = (byte)(lsr & ~LSR_DR); // 清除数据就绪
+ }
+
+ // 检查溢出
+ if (rxFifo.Count == 0)
+ {
+ lsr = (byte)(lsr & ~LSR_OE); // 清除溢出错误
+ }
+ }
+ else
+ {
+ this.Log(LogLevel.Warning, "Read from empty RBR");
+ }
+
+ UpdateInterrupts();
+ return value;
+ }
+
+ private void WriteTHR(byte value)
+ {
+ this.Log(LogLevel.Debug, "Write THR: 0x{0:X2} ('{1}')", value,
+ (value >= 32 && value < 127) ? (char)value : '.');
+
+ if (fifoEnabled)
+ {
+ if (txFifo.Count < FIFO_SIZE)
+ {
+ txFifo.Enqueue(value);
+ lsr = (byte)(lsr & ~LSR_THRE); // THR 非空
+ lsr = (byte)(lsr & ~LSR_TEMT); // 发送器非空
+ }
+ else
+ {
+ this.Log(LogLevel.Warning, "TX FIFO overflow");
+ }
+ }
+ else
+ {
+ // 非 FIFO 模式,直接发送
+ txFifo.Clear();
+ txFifo.Enqueue(value);
+ lsr = (byte)(lsr & ~LSR_THRE);
+ lsr = (byte)(lsr & ~LSR_TEMT);
+ }
+
+ // 实际发送数据
+ TransmitData();
+ }
+
+ private void WriteFCR(byte value)
+ {
+ fcr = value;
+ this.Log(LogLevel.Debug, "Write FCR: 0x{0:X2}", value);
+
+ // FIFO 使能
+ bool newFifoEnabled = (value & FCR_FIFO_EN) != 0;
+ if (newFifoEnabled != fifoEnabled)
+ {
+ fifoEnabled = newFifoEnabled;
+ this.Log(LogLevel.Info, "FIFO {0}", fifoEnabled ? "enabled" : "disabled");
+
+ if (!fifoEnabled)
+ {
+ // 禁用 FIFO 时清空
+ rxFifo.Clear();
+ txFifo.Clear();
+ }
+ }
+
+ // 清除 RX FIFO
+ if ((value & FCR_RCVR_RESET) != 0)
+ {
+ rxFifo.Clear();
+ lsr = (byte)(lsr & ~LSR_DR);
+ this.Log(LogLevel.Debug, "RX FIFO cleared");
+ }
+
+ // 清除 TX FIFO
+ if ((value & FCR_XMIT_RESET) != 0)
+ {
+ txFifo.Clear();
+ lsr = (byte)(lsr | (LSR_THRE | LSR_TEMT));
+ this.Log(LogLevel.Debug, "TX FIFO cleared");
+ }
+
+ // 设置触发级别
+ byte trigger = (byte)((value >> 6) & 0x03);
+ switch (trigger)
+ {
+ case 0: fifoTriggerLevel = 1; break;
+ case 1: fifoTriggerLevel = 4; break;
+ case 2: fifoTriggerLevel = 8; break;
+ case 3: fifoTriggerLevel = 14; break;
+ }
+ this.Log(LogLevel.Debug, "FIFO trigger level: {0} bytes", fifoTriggerLevel);
+
+ UpdateInterrupts();
+ }
+
+ private byte ReadIIR()
+ {
+ byte iir = IIR_NO_INT; // 默认无中断
+
+ // 检查中断使能
+ if ((mcr & MCR_OUT2) == 0)
+ {
+ // OUT2 未置位,禁用中断
+ this.Log(LogLevel.Noisy, "Read IIR: 0x{0:X2} (interrupts disabled)", iir);
+ return iir;
+ }
+
+ // 按优先级检查中断
+ // 1. 接收线路状态中断 (最高优先级)
+ if ((ier & IER_ELSI) != 0 && (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) != 0)
+ {
+ iir = IIR_RLS; // 0x06
+ }
+ // 2. 接收数据可用中断
+ else if ((ier & IER_ERBFI) != 0 && (lsr & LSR_DR) != 0 && rxFifo.Count >= fifoTriggerLevel)
+ {
+ iir = IIR_RDA; // 0x04
+ }
+ // 3. 字符超时中断
+ else if ((ier & IER_ERBFI) != 0 && (lsr & LSR_DR) != 0 && rxFifo.Count > 0)
+ {
+ iir = IIR_CTI; // 0x0C
+ }
+ // 4. THR 空中断
+ else if ((ier & IER_ETBEI) != 0 && (lsr & LSR_THRE) != 0)
+ {
+ iir = IIR_THRE; // 0x02
+ }
+ // 5. 调制解调器状态中断 (最低优先级)
+ else if ((ier & IER_EDSSI) != 0 && (msr & 0x0F) != 0)
+ {
+ iir = IIR_MS; // 0x00
+ }
+
+ // FIFO 使能状态
+ if (fifoEnabled)
+ {
+ iir |= IIR_FIFO_EN;
+ }
+
+ this.Log(LogLevel.Noisy, "Read IIR: 0x{0:X2}", iir);
+
+ // 读取 IIR 清除 THRE 中断
+ if ((iir & 0x0F) == IIR_THRE)
+ {
+ UpdateInterrupts();
+ }
+
+ return iir;
+ }
+
+ private void TransmitData()
+ {
+ // 从 TX FIFO 发送数据
+ while (txFifo.Count > 0)
+ {
+ byte data = txFifo.Dequeue();
+
+ // 调用基类的 TransmitCharacter 发送数据
+ TransmitCharacter(data);
+
+ this.Log(LogLevel.Debug, "Transmitted: 0x{0:X2} ('{1}')", data,
+ (data >= 32 && data < 127) ? (char)data : '.');
+ }
+
+ // 更新状态
+ lsr = (byte)(lsr | LSR_THRE); // THR 空
+ lsr = (byte)(lsr | LSR_TEMT); // 发送器空
+
+ UpdateInterrupts();
+ }
+
+ // ========================================
+ // UARTBase 接口实现
+ // ========================================
+
+ public override void WriteChar(byte value)
+ {
+ // 从外部接收数据 (例如从终端或网络)
+ if (fifoEnabled)
+ {
+ if (rxFifo.Count < FIFO_SIZE)
+ {
+ rxFifo.Enqueue(value);
+ lsr = (byte)(lsr | LSR_DR); // 数据就绪
+
+ this.Log(LogLevel.Debug, "Received: 0x{0:X2} ('{1}'), FIFO count: {2}",
+ value, (value >= 32 && value < 127) ? (char)value : '.', rxFifo.Count);
+ }
+ else
+ {
+ lsr = (byte)(lsr | LSR_OE); // 溢出错误
+ this.Log(LogLevel.Warning, "RX FIFO overflow");
+ }
+ }
+ else
+ {
+ // 非 FIFO 模式
+ if (rxFifo.Count > 0)
+ {
+ lsr = (byte)(lsr | LSR_OE); // 溢出错误
+ }
+ rxFifo.Clear();
+ rxFifo.Enqueue(value);
+ lsr = (byte)(lsr | LSR_DR);
+ }
+
+ UpdateInterrupts();
+ }
+
+ protected override void CharWritten()
+ {
+ // UARTBase 要求实现此方法
+ // 在字符写入后调用,这里不需要额外操作
+ }
+
+ protected override void QueueEmptied()
+ {
+ // UARTBase 要求实现此方法
+ // 当队列为空时调用,这里不需要额外操作
+ }
+
+ public override Bits StopBits
+ {
+ get
+ {
+ return ((lcr & LCR_STB) != 0) ? Bits.Two : Bits.One;
+ }
+ }
+
+ public override Parity ParityBit
+ {
+ get
+ {
+ if ((lcr & LCR_PEN) == 0)
+ return Parity.None;
+
+ if ((lcr & LCR_EPS) != 0)
+ return Parity.Even;
+ else
+ return Parity.Odd;
+ }
+ }
+
+ public override uint BaudRate
+ {
+ get { return currentBaudRate; }
+ }
+
+ // ========================================
+ // 辅助方法
+ // ========================================
+
+ private void UpdateBaudRate()
+ {
+ ushort divisor = (ushort)((dlh << 8) | dll);
+
+ if (divisor == 0)
+ {
+ currentBaudRate = 0;
+ }
+ else
+ {
+ currentBaudRate = clockFrequency / (16u * divisor);
+ this.Log(LogLevel.Info, "Baud rate set to {0} (divisor: {1})", currentBaudRate, divisor);
+ }
+ }
+
+ private void UpdateLineParameters()
+ {
+ // 字长
+ byte wordLength = (byte)((lcr & LCR_WLS) + 5);
+
+ // 停止位
+ string stopBits = ((lcr & LCR_STB) != 0) ? "2" : "1";
+
+ // 奇偶校验
+ string parity;
+ if ((lcr & LCR_PEN) == 0)
+ parity = "N";
+ else if ((lcr & LCR_EPS) != 0)
+ parity = "E";
+ else
+ parity = "O";
+
+ this.Log(LogLevel.Info, "Line format: {0}{1}{2}", wordLength, parity, stopBits);
+ }
+
+ private void UpdateModemControl()
+ {
+ this.Log(LogLevel.Debug, "Modem control: DTR={0}, RTS={1}, OUT1={2}, OUT2={3}, LOOP={4}",
+ (mcr & MCR_DTR) != 0, (mcr & MCR_RTS) != 0, (mcr & MCR_OUT1) != 0,
+ (mcr & MCR_OUT2) != 0, (mcr & MCR_LOOP) != 0);
+
+ UpdateInterrupts();
+ }
+
+ private void UpdateInterrupts()
+ {
+ bool interrupt = false;
+
+ // OUT2 必须置位才能产生中断
+ if ((mcr & MCR_OUT2) != 0)
+ {
+ // 检查各种中断条件
+ if ((ier & IER_ELSI) != 0 && (lsr & (LSR_OE | LSR_PE | LSR_FE | LSR_BI)) != 0)
+ interrupt = true;
+ else if ((ier & IER_ERBFI) != 0 && (lsr & LSR_DR) != 0 && rxFifo.Count >= fifoTriggerLevel)
+ interrupt = true;
+ else if ((ier & IER_ETBEI) != 0 && (lsr & LSR_THRE) != 0)
+ interrupt = true;
+ else if ((ier & IER_EDSSI) != 0 && (msr & 0x0F) != 0)
+ interrupt = true;
+ }
+
+ IRQ.Set(interrupt);
+
+ if (interrupt)
+ {
+ this.Log(LogLevel.Debug, "Interrupt asserted");
+ }
+ }
+
+ public long Size => 0x08;
+
+ public GPIO IRQ { get; }
+
+ // ========================================
+ // 寄存器定义
+ // ========================================
+
+ private enum Registers : long
+ {
+ RBR_THR_DLL = 0x00, // RBR/THR (DLAB=0), DLL (DLAB=1)
+ IER_DLH = 0x01, // IER (DLAB=0), DLH (DLAB=1)
+ IIR_FCR = 0x02, // IIR (R), FCR (W)
+ LCR = 0x03, // Line Control Register
+ MCR = 0x04, // Modem Control Register
+ LSR = 0x05, // Line Status Register
+ MSR = 0x06, // Modem Status Register
+ SCR = 0x07, // Scratch Register
+ }
+
+ // LCR 位定义
+ private const byte LCR_WLS = 0x03; // 字长选择
+ private const byte LCR_STB = 0x04; // 停止位
+ private const byte LCR_PEN = 0x08; // 奇偶校验使能
+ private const byte LCR_EPS = 0x10; // 偶校验选择
+ private const byte LCR_SPAR = 0x20; // 强制奇偶校验
+ private const byte LCR_SBC = 0x40; // 设置中断
+ private const byte LCR_DLAB = 0x80; // 除数锁存访问
+
+ // LSR 位定义
+ private const byte LSR_DR = 0x01; // 数据就绪
+ private const byte LSR_OE = 0x02; // 溢出错误
+ private const byte LSR_PE = 0x04; // 奇偶校验错误
+ private const byte LSR_FE = 0x08; // 帧错误
+ private const byte LSR_BI = 0x10; // 中断指示
+ private const byte LSR_THRE = 0x20; // THR 空
+ private const byte LSR_TEMT = 0x40; // 发送器空
+ private const byte LSR_FIFO_ERR = 0x80; // FIFO 错误
+
+ // IER 位定义
+ private const byte IER_ERBFI = 0x01; // 使能接收数据可用中断
+ private const byte IER_ETBEI = 0x02; // 使能 THR 空中断
+ private const byte IER_ELSI = 0x04; // 使能接收线路状态中断
+ private const byte IER_EDSSI = 0x08; // 使能调制解调器状态中断
+
+ // IIR 值定义
+ private const byte IIR_NO_INT = 0x01; // 无中断挂起
+ private const byte IIR_MS = 0x00; // 调制解调器状态
+ private const byte IIR_THRE = 0x02; // THR 空
+ private const byte IIR_RDA = 0x04; // 接收数据可用
+ private const byte IIR_RLS = 0x06; // 接收线路状态
+ private const byte IIR_CTI = 0x0C; // 字符超时
+ private const byte IIR_FIFO_EN = 0xC0; // FIFO 使能标志
+
+ // FCR 位定义
+ private const byte FCR_FIFO_EN = 0x01; // FIFO 使能
+ private const byte FCR_RCVR_RESET = 0x02; // 清除 RX FIFO
+ private const byte FCR_XMIT_RESET = 0x04; // 清除 TX FIFO
+
+ // MCR 位定义
+ private const byte MCR_DTR = 0x01; // DTR
+ private const byte MCR_RTS = 0x02; // RTS
+ private const byte MCR_OUT1 = 0x04; // OUT1
+ private const byte MCR_OUT2 = 0x08; // OUT2
+ private const byte MCR_LOOP = 0x10; // 环回模式
+
+ // 常量
+ private const int FIFO_SIZE = 16;
+
+ // ========================================
+ // 私有字段
+ // ========================================
+
+ private readonly uint clockFrequency;
+ private uint currentBaudRate;
+
+ // 寄存器
+ private byte ier; // 中断使能寄存器
+ private byte lcr; // 线路控制寄存器
+ private byte mcr; // 调制解调器控制寄存器
+ private byte lsr; // 线路状态寄存器
+ private byte msr; // 调制解调器状态寄存器
+ private byte scr; // 暂存寄存器
+ private byte dll; // 除数锁存低字节
+ private byte dlh; // 除数锁存高字节
+ private byte fcr; // FIFO 控制寄存器
+
+ // FIFO
+ private readonly Queue rxFifo;
+ private readonly Queue txFifo;
+ private bool fifoEnabled;
+ private int fifoTriggerLevel;
+ }
+}