1 // 2 // Copyright (c) 2010-2018 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.Collections.Generic; 8 using Antmicro.Renode.Core; 9 using Antmicro.Renode.Utilities; 10 11 namespace Antmicro.Renode.Peripherals 12 { 13 public class InterruptHandler<TRegister, TFlag> 14 { InterruptHandler(IGPIO gpio)15 public InterruptHandler(IGPIO gpio) 16 { 17 irqs = new Dictionary<TRegister, IrqState>(); 18 flagToRegister = new Dictionary<TFlag, FlagState>(); 19 this.gpio = gpio; 20 } 21 Reset()22 public void Reset() 23 { 24 foreach(var irq in irqs) 25 { 26 irq.Value.Value = 0; 27 irq.Value.Mask = 0; 28 } 29 gpio.Unset(); 30 } 31 RegisterInterrupt(TRegister register, TFlag flag, byte position, bool masked = false)32 public void RegisterInterrupt(TRegister register, TFlag flag, byte position, bool masked = false) 33 { 34 if(!irqs.ContainsKey(register)) 35 { 36 irqs[register] = new IrqState(); 37 } 38 39 flagToRegister.Add(flag, new FlagState { Position = position, Register = register }); 40 if(masked) 41 { 42 BitHelper.SetBit(ref irqs[register].Mask, position, true); 43 } 44 } 45 RequestInterrupt(TFlag flag)46 public void RequestInterrupt(TFlag flag) 47 { 48 var reg = flagToRegister[flag]; 49 BitHelper.SetBit(ref irqs[reg.Register].Value, reg.Position, true); 50 Refresh(); 51 } 52 GetRegisterValue(TRegister register)53 public uint GetRegisterValue(TRegister register) 54 { 55 return irqs[register].Value; 56 } 57 SetRegisterValue(TRegister register, uint value)58 public void SetRegisterValue(TRegister register, uint value) 59 { 60 irqs[register].Value = value; 61 Refresh(); 62 } 63 GetRegisterMask(TRegister register)64 public uint GetRegisterMask(TRegister register) 65 { 66 return irqs[register].Mask; 67 } 68 SetRegisterMask(TRegister register, uint value)69 public void SetRegisterMask(TRegister register, uint value) 70 { 71 irqs[register].Mask = value; 72 Refresh(); 73 } 74 Refresh()75 public void Refresh() 76 { 77 foreach(var flag in flagToRegister) 78 { 79 if(BitHelper.IsBitSet(irqs[flag.Value.Register].EffectiveValue, flag.Value.Position)) 80 { 81 gpio.Set(true); 82 return; 83 } 84 } 85 gpio.Set(false); 86 } 87 88 private readonly Dictionary<TRegister, IrqState> irqs; 89 private readonly Dictionary<TFlag, FlagState> flagToRegister; 90 private readonly IGPIO gpio; 91 92 private class IrqState 93 { 94 public uint Value; 95 public uint Mask; 96 97 public uint EffectiveValue { get { return Value & Mask; } } 98 } 99 100 private class FlagState 101 { 102 public TRegister Register; 103 public byte Position; 104 } 105 } 106 } 107