예제 #1
0
파일: GIC.cs 프로젝트: rte-se/emul8
        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();
        }
예제 #2
0
        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();
        }
예제 #3
0
 public void Reset()
 {
     localTimer.Reset();
     registers.Reset();
     interrupts = new IRQState[availableVectors];
     activeIrqs.Clear();
 }
예제 #4
0
        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));
        }
예제 #5
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);
        }
예제 #6
0
        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;
            }
        }
예제 #7
0
 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();
 }
예제 #8
0
파일: NVIC.cs 프로젝트: rasomc/emul8
 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();
 }
예제 #9
0
파일: NVIC.cs 프로젝트: rte-se/emul8
 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();
 }
예제 #10
0
 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();
 }
예제 #11
0
파일: GIC.cs 프로젝트: rte-se/emul8
 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;
     }
 }
예제 #12
0
파일: GIC.cs 프로젝트: rte-se/emul8
        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;
        }
예제 #13
0
파일: GIC.cs 프로젝트: rte-se/emul8
 private bool IsEnabled(IRQState state, int cpuNo)
 {
     return ((int)state & (1 << cpuNo)) != 0 && (state & IRQState.Enabled) != 0;
 }
예제 #14
0
 private bool IsEnabled(IRQState state, int cpuNo)
 {
     return(((int)state & (1 << cpuNo)) != 0 && (state & IRQState.Enabled) != 0);
 }
예제 #15
0
파일: NVIC.cs 프로젝트: rte-se/emul8
        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;
        }