public GIC(int numberOfCPUs = 1, int itLinesNumber = 10) { this.numberOfCPUs = numberOfCPUs; this.itLinesNumber = itLinesNumber; var innerConnections = new Dictionary<int, IGPIO>(); for(var i = 0; i < numberOfCPUs; i++) { innerConnections[i] = new GPIO(); } Connections = new ReadOnlyDictionary<int, IGPIO>(innerConnections); privateInterrupts = new IRQState[numberOfCPUs][]; for(var i = 0; i < privateInterrupts.Length; i++) { privateInterrupts[i] = new IRQState[32]; } publicInterrupts = new IRQState[991]; privatePriorities = new byte[numberOfCPUs][]; for(var i = 0; i < privatePriorities.Length; i++) { privatePriorities[i] = new byte[32]; } publicPriorities = new byte[991]; runningPriorities = new byte[numberOfCPUs]; priorityMasks = new byte[numberOfCPUs]; enabled = new bool[numberOfCPUs]; localReceivers = new LocalGPIOReceiver[numberOfCPUs]; for(var i = 0; i < localReceivers.Length; i++) { localReceivers[i] = new LocalGPIOReceiver(i, this); } Reset(); }
public GIC(int numberOfCPUs = 1, int itLinesNumber = 10) { this.numberOfCPUs = numberOfCPUs; this.itLinesNumber = itLinesNumber; var innerConnections = new Dictionary <int, IGPIO>(); for (var i = 0; i < numberOfCPUs; i++) { innerConnections[i] = new GPIO(); } Connections = new ReadOnlyDictionary <int, IGPIO>(innerConnections); privateInterrupts = new IRQState[numberOfCPUs][]; for (var i = 0; i < privateInterrupts.Length; i++) { privateInterrupts[i] = new IRQState[32]; } publicInterrupts = new IRQState[991]; privatePriorities = new byte[numberOfCPUs][]; for (var i = 0; i < privatePriorities.Length; i++) { privatePriorities[i] = new byte[32]; } publicPriorities = new byte[991]; runningPriorities = new byte[numberOfCPUs]; priorityMasks = new byte[numberOfCPUs]; enabled = new bool[numberOfCPUs]; localReceivers = new LocalGPIOReceiver[numberOfCPUs]; for (var i = 0; i < localReceivers.Length; i++) { localReceivers[i] = new LocalGPIOReceiver(i, this); } Reset(); }
public void Reset() { localTimer.Reset(); registers.Reset(); interrupts = new IRQState[availableVectors]; activeIrqs.Clear(); }
private bool IsCandidate(IRQState state, int index) { const IRQState mask = IRQState.Pending | IRQState.Enabled | IRQState.Active; const IRQState candidate = IRQState.Pending | IRQState.Enabled; return(((state & mask) == candidate) && (basepri == 0 || priorities[index] < basepri)); }
private bool IsCandidate(IRQState state, int index) { var result = (state & IRQState.Pending) != 0 && (state & IRQState.Enabled) != 0 && (state & IRQState.Active) == 0; if (BASEPRI != 0) { result &= (priorities[index] < BASEPRI); } return(result); }
private void SetRunningInterrupt(ref IRQState state, bool isRunning) { if (isRunning) { state |= IRQState.Pending; } var levelTriggered = (state & IRQState.EdgeTriggered) == 0; if (levelTriggered && !isRunning) { state &= ~IRQState.Pending; } }
public NVIC(Machine machine, int systickFrequency = 50 * 0x800000) { priorities = new byte[IRQCount]; activeIRQs = new Stack <int>(); systick = new LimitTimer(machine.ClockSource, systickFrequency, this, nameof(systick), uint.MaxValue, Direction.Descending, false, autoUpdate: true); irqs = new IRQState[IRQCount]; IRQ = new GPIO(); systick.LimitReached += () => { SetPendingIRQ(15); }; InitInterrupts(); Init(); }
public NVIC(Machine machine, int systickFrequency = 50 * 0x800000) { priorities = new byte[IRQCount]; activeIRQs = new Stack <int>(); systick = new LimitTimer(machine, systickFrequency, limit: uint.MaxValue, direction: Direction.Descending, enabled: false); systick.EventEnabled = false; systick.AutoUpdate = true; irqs = new IRQState[IRQCount]; IRQ = new GPIO(); systick.LimitReached += () => { SetPendingIRQ(15); }; InitInterrupts(); Init(); }
public NVIC(Machine machine, int systickFrequency = 50 * 0x800000) { priorities = new byte[IRQCount]; activeIRQs = new Stack<int>(); systick = new LimitTimer(machine, systickFrequency, limit: uint.MaxValue, direction: Direction.Descending, enabled: false); systick.EventEnabled = false; systick.AutoUpdate = true; irqs = new IRQState[IRQCount]; IRQ = new GPIO(); systick.LimitReached += () => { SetPendingIRQ(15); }; InitInterrupts(); Init(); }
public NVIC(Machine machine, long systickFrequency = 50 * 0x800000, byte priorityMask = 0xFF) { priorities = new byte[IRQCount]; activeIRQs = new Stack <int>(); pendingIRQs = new SortedSet <int>(); systick = new LimitTimer(machine.ClockSource, systickFrequency, this, nameof(systick), uint.MaxValue, Direction.Descending, false, autoUpdate: true); this.priorityMask = priorityMask; irqs = new IRQState[IRQCount]; IRQ = new GPIO(); resetMachine = machine.RequestReset; systick.LimitReached += () => { countFlag = true; SetPendingIRQ(15); }; InitInterrupts(); }
private void SetRunningInterrupt(ref IRQState state, bool isRunning) { if(isRunning) { state |= IRQState.Pending; } var levelTriggered = (state & IRQState.EdgeTriggered) == 0; if(levelTriggered && !isRunning) { state &= ~IRQState.Pending; } }
private int ScanInterrupts(IRQState[] interrupts, byte[] priorities, ref byte bestPriority, int cpu) { var bestInterrupt = SpuriousInterrupt; if(!globallyEnabled || !enabled[cpu]) { return bestInterrupt; } var runningPriority = runningPriorities[cpu]; var forwardedToThisCpu = 1 << cpu; for(var i = 0; i < interrupts.Length; i++) { var state = interrupts[i]; if((state & IRQState.Pending) != 0 && priorities[i] < bestPriority && priorities[i] < runningPriority && (state & (IRQState)forwardedToThisCpu) != 0 && priorities[i] < priorityMasks[cpu] && (state & IRQState.Enabled) != 0) { bestPriority = priorities[i]; bestInterrupt = i; } } return bestInterrupt; }
private bool IsEnabled(IRQState state, int cpuNo) { return ((int)state & (1 << cpuNo)) != 0 && (state & IRQState.Enabled) != 0; }
private bool IsEnabled(IRQState state, int cpuNo) { return(((int)state & (1 << cpuNo)) != 0 && (state & IRQState.Enabled) != 0); }
private bool IsCandidate(IRQState state, int index) { var result = (state & IRQState.Pending) != 0 && (state & IRQState.Enabled) != 0 && (state & IRQState.Active) == 0; if (BASEPRI != 0) { result &= (priorities[index] < BASEPRI); } return result; }