public STM32LTDC(Machine machine) : base(machine)
        {
            Reconfigure(format: PixelFormat.RGBX8888);

            IRQ = new GPIO();

            this.machine = machine;
            internalLock = new object();

            var activeWidthConfigurationRegister = new DoubleWordRegister(this);

            accumulatedActiveHeightField = activeWidthConfigurationRegister.DefineValueField(0, 11, name: "AAH");
            accumulatedActiveWidthField  = activeWidthConfigurationRegister.DefineValueField(16, 12, name: "AAW", writeCallback: (_, __) => HandleActiveDisplayChange());

            var backPorchConfigurationRegister = new DoubleWordRegister(this);

            accumulatedVerticalBackPorchField   = backPorchConfigurationRegister.DefineValueField(0, 11, name: "AVBP");
            accumulatedHorizontalBackPorchField = backPorchConfigurationRegister.DefineValueField(16, 12, name: "AHBP", writeCallback: (_, __) => HandleActiveDisplayChange());

            var backgroundColorConfigurationRegister = new DoubleWordRegister(this);

            backgroundColorBlueChannelField  = backgroundColorConfigurationRegister.DefineValueField(0, 8, name: "BCBLUE");
            backgroundColorGreenChannelField = backgroundColorConfigurationRegister.DefineValueField(8, 8, name: "BCGREEN");
            backgroundColorRedChannelField   = backgroundColorConfigurationRegister.DefineValueField(16, 8, name: "BCRED", writeCallback: (_, __) => HandleBackgroundColorChange());

            var interruptEnableRegister = new DoubleWordRegister(this);

            lineInterruptEnableFlag = interruptEnableRegister.DefineFlagField(0, name: "LIE");

            var interruptClearRegister = new DoubleWordRegister(this);

            interruptClearRegister.DefineFlagField(0, FieldMode.Write, name: "CLIF", writeCallback: (old, @new) => { if (@new)
                                                                                                                     {
                                                                                                                         IRQ.Unset();
                                                                                                                     }
                                                   });
            interruptClearRegister.DefineFlagField(3, FieldMode.Write, name: "CRRIF", writeCallback: (old, @new) => { if (@new)
                                                                                                                      {
                                                                                                                          IRQ.Unset();
                                                                                                                      }
                                                   });

            lineInterruptPositionConfigurationRegister = new DoubleWordRegister(this).WithValueField(0, 11, name: "LIPOS");

            var registerMappings = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Register.BackPorchConfigurationRegister, backPorchConfigurationRegister },
                { (long)Register.ActiveWidthConfigurationRegister, activeWidthConfigurationRegister },
                { (long)Register.BackgroundColorConfigurationRegister, backgroundColorConfigurationRegister },
                { (long)Register.InterruptEnableRegister, interruptEnableRegister },
                { (long)Register.InterruptClearRegister, interruptClearRegister },
                { (long)Register.LineInterruptPositionConfigurationRegister, lineInterruptPositionConfigurationRegister }
            };

            localLayerBuffer = new byte[2][];
            layer            = new Layer[2];
            for (var i = 0; i < layer.Length; i++)
            {
                layer[i] = new Layer(this, i);

                var offset = 0x80 * i;
                registerMappings.Add(0x84 + offset, layer[i].ControlRegister);
                registerMappings.Add(0x88 + offset, layer[i].WindowHorizontalPositionConfigurationRegister);
                registerMappings.Add(0x8C + offset, layer[i].WindowVerticalPositionConfigurationRegister);
                registerMappings.Add(0x94 + offset, layer[i].PixelFormatConfigurationRegister);
                registerMappings.Add(0x98 + offset, layer[i].ConstantAlphaConfigurationRegister);
                registerMappings.Add(0x9C + offset, layer[i].DefaultColorConfigurationRegister);
                registerMappings.Add(0xA0 + offset, layer[i].BlendingFactorConfigurationRegister);
                registerMappings.Add(0xAC + offset, layer[i].ColorFrameBufferAddressRegister);
            }

            registers = new DoubleWordRegisterCollection(this, registerMappings);
            registers.Reset();
            HandlePixelFormatChange();
        }
Beispiel #2
0
 public STM32L_Timer(Machine machine) : base(machine, 0xF42400, direction: Direction.Ascending) //freq guesed from driver
 {
     IRQ = new GPIO();
     SetupRegisters();
 }
Beispiel #3
0
        public TM16XX(GPIO data, GPIO clock, GPIO strobe, int displays, bool activateDisplay, int intensity)
        {
            // Set the pins
            _data = data;
            _clock = clock;
            _strobe = strobe;
            _displays = displays;

            _strobe.Write(true);
            _clock.Write(true);

            sendCommand(0x40);
            sendCommand((byte)(0x80 | (activateDisplay ? 0x08 : 0x00) | Math.Min(7, intensity)));

            _strobe.Write(false);
            send(0xC0);
            for (int i = 0; i < 16; i++)
            {
                send(0x00);
            }
            _strobe.Write(true);
        }
Beispiel #4
0
        public STM32F0Timer3(Machine machine, long frequency, uint initialLimit) : base(machine.ClockSource, frequency, limit: initialLimit, direction: Direction.Ascending, enabled: false, autoUpdate: false)
        {
            IRQ = new GPIO();
            this.initialLimit = initialLimit;

            LimitReached += delegate
            {
                if (updateDisable.Value)
                {
                    return;
                }
                if (updateInterruptEnable.Value)
                {
                    IRQ.Set();
                    updateInterruptFlag = true;
                }
                Limit = autoReloadValue;
            };

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.Control1, new DoubleWordRegister(this)
                  .WithFlag(0, writeCallback: (_, val) => Enabled = val, valueProviderCallback: _ => Enabled, name: "Counter enable (CEN)")
                  .WithFlag(1, out updateDisable, name: "Update disable (UDIS)")
                  .WithFlag(2, out updateRequestSource, name: "Update request source (URS)")
                  .WithFlag(3, writeCallback: (_, val) => Mode      = val ? WorkMode.OneShot : WorkMode.Periodic, valueProviderCallback: _ => Mode == WorkMode.OneShot, name: "One-pulse mode (OPM)")
                  .WithFlag(4, writeCallback: (_, val) => Direction = val ? Direction.Descending : Direction.Ascending, valueProviderCallback: _ => Direction == Direction.Descending, name: "Direction (DIR)")
                  .WithTag("Center-aligned mode selection (CMS)", 5, 2)
                  .WithFlag(7, out autoReloadPreloadEnable, name: "Auto-reload preload enable (APRE)")
                  .WithTag("Clock Division (CKD)", 8, 2)
                  .WithReservedBits(10, 22) },

                { (long)Registers.Control2, new DoubleWordRegister(this)
                  .WithReservedBits(0, 2)
                  .WithTag("Capture/compare DMA selection (CCDS)", 3, 1)
                  .WithTag("Master mode selection (MMS)", 4, 3)
                  .WithTag("TI1 selection (TI1S)", 7, 1)
                  .WithReservedBits(8, 24) },

                { (long)Registers.SlaveModeControl, new DoubleWordRegister(this)
                  .WithTag("Slave mode selection (SMS)", 0, 3)
                  .WithTag("OCREF clear selection (OCCS)", 3, 1)
                  .WithTag("Trigger selection (TS)", 4, 3)
                  .WithTag("Master/Slave mode (MSM)", 7, 1)
                  .WithTag("External trigger filter (ETF)", 8, 3)
                  .WithTag("External trigger prescaler (ETPS)", 12, 2)
                  .WithTag("External clock enable (ECE)", 14, 1)
                  .WithTag("External trigger polarity (ETP)", 15, 1)
                  .WithReservedBits(16, 16) },

                { (long)Registers.DmaOrInterruptEnable, new DoubleWordRegister(this)
                  .WithFlag(0, out updateInterruptEnable, name: "Update interrupt enable (UIE)")
                  .WithTag("Capture/Compare 1 interrupt enable (CC1IE)", 1, 1)
                  .WithTag("Capture/Compare 2 interrupt enable (CC2IE)", 2, 1)
                  .WithTag("Capture/Compare 3 interrupt enable (CC3IE)", 3, 1)
                  .WithTag("Capture/Compare 4 interrupt enable (CC4IE)", 4, 1)
                  .WithReservedBits(5, 1)
                  .WithTag("Trigger interrupt enable (TIE)", 6, 1)
                  .WithReservedBits(7, 1)
                  .WithTag("Update DMA request enable (UDE)", 8, 1)
                  .WithTag("Capture/Compare 1 DMA request enable (CC1DE)", 9, 1)
                  .WithTag("Capture/Compare 2 DMA request enable (CC2DE)", 10, 1)
                  .WithTag("Capture/Compare 3 DMA request enable (CC3DE)", 11, 1)
                  .WithTag("Capture/Compare 4 DMA request enable (CC4DE)", 12, 1)
                  .WithReservedBits(13, 1)
                  .WithTag("Trigger DMA request enable (TDE)", 14, 1)
                  .WithReservedBits(15, 17) },

                { (long)Registers.Status, new DoubleWordRegister(this)
                  .WithFlag(0, FieldMode.Read | FieldMode.WriteZeroToClear,
                            writeCallback: (_, val) =>
                    {
                        if (!val)
                        {
                            updateInterruptFlag = false;
                            IRQ.Unset();
                        }
                    },
                            valueProviderCallback: (_) =>
                    {
                        return(updateInterruptFlag);
                    },
                            name: "Update interrupt flag (UIF)")
                  // These write callbacks are here only to prevent from very frequent logging.
                  .WithValueField(1, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 1 interrupt flag (CC1IF)")
                  .WithValueField(2, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 2 interrupt flag (CC2IF)")
                  .WithValueField(3, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 3 interrupt flag (CC3IF)")
                  .WithValueField(4, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 4 interrupt flag (CC4IF)")
                  .WithReservedBits(5, 1)
                  .WithValueField(6, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Trigger interrupt flag (TIE)")
                  .WithReservedBits(7, 2)
                  .WithValueField(9, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 1 overcapture flag (CC1OF)")
                  .WithValueField(10, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 2 overcapture flag (CC2OF)")
                  .WithValueField(11, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 3 overcapture flag (CC3OF)")
                  .WithValueField(12, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 4 overcapture flag (CC4OF)")
                  .WithReservedBits(13, 18) },

                { (long)Registers.EventGeneration, new DoubleWordRegister(this)
                  .WithFlag(0, FieldMode.WriteOneToClear, writeCallback: (_, val) =>
                    {
                        if (updateDisable.Value)
                        {
                            return;
                        }
                        if (Direction == Direction.Ascending)
                        {
                            Value = 0;
                        }
                        else if (Direction == Direction.Descending)
                        {
                            Value = autoReloadValue;
                        }
                        if (!updateRequestSource.Value && updateInterruptEnable.Value)
                        {
                            IRQ.Set();
                            updateInterruptFlag = true;
                        }
                    }, name: "Update generation (UG)")
                  .WithTag("Capture/compare 1 generation (CC1G)", 1, 1)
                  .WithTag("Capture/compare 2 generation (CC2G)", 2, 1)
                  .WithTag("Capture/compare 3 generation (CC3G)", 3, 1)
                  .WithTag("Capture/compare 4 generation (CC4G)", 4, 1)
                  .WithReservedBits(5, 1)
                  .WithTag("Trigger generation (TG)", 6, 1)
                  .WithReservedBits(7, 25) },

                { (long)Registers.CaptureOrCompareMode1, new DoubleWordRegister(this)
                  .WithTag("Capture/Compare 1 selection (CC1S)", 0, 2)
                  .WithTag("Output compare 1 fast enable (OC1FE)", 2, 1)
                  .WithTag("Output compare 1 preload enable (OC1PE)", 3, 1)
                  .WithTag("Output compare 1 mode (OC1M)", 4, 3)
                  .WithTag("Output compare 1 clear enable (OC1CE)", 7, 1)
                  .WithTag("Capture/Compare 2 selection (CC1S)", 8, 2)
                  .WithTag("Output compare 2 fast enable (OC1FE)", 10, 1)
                  .WithTag("Output compare 2 preload enable (OC1PE)", 11, 1)
                  .WithTag("Output compare 2 mode (OC1M)", 12, 3)
                  .WithTag("Output compare 2 clear enable (OC1CE)", 15, 1)
                  .WithReservedBits(16, 6) },

                { (long)Registers.CaptureOrCompareMode2, new DoubleWordRegister(this)
                  .WithTag("Capture/Compare 3 selection (CC1S)", 0, 2)
                  .WithTag("Output compare 3 fast enable (OC1FE)", 2, 1)
                  .WithTag("Output compare 3 preload enable (OC1PE)", 3, 1)
                  .WithTag("Output compare 3 mode (OC1M)", 4, 3)
                  .WithTag("Output compare 3 clear enable (OC1CE)", 7, 1)
                  .WithTag("Capture/Compare 4 selection (CC1S)", 8, 2)
                  .WithTag("Output compare 4 fast enable (OC1FE)", 10, 1)
                  .WithTag("Output compare 4 preload enable (OC1PE)", 11, 1)
                  .WithTag("Output compare 4 mode (OC1M)", 12, 3)
                  .WithTag("Output compare 4 clear enable (OC1CE)", 15, 1)
                  .WithReservedBits(16, 16) },

                { (long)Registers.CaptureOrCompareEnable, new DoubleWordRegister(this)
                  .WithTag("Capture/Compare 1 output enable (CC1E)", 0, 1)
                  .WithTag("Capture/Compare 1 output polarity (CC1P)", 1, 1)
                  .WithReservedBits(2, 1)
                  .WithTag("Capture/Compare 1 output polarity (CC1NP)", 3, 1)
                  .WithTag("Capture/Compare 2 output enable (CC2E)", 4, 1)
                  .WithTag("Capture/Compare 2 output polarity (CC2P)", 5, 1)
                  .WithReservedBits(6, 1)
                  .WithTag("Capture/Compare 2 output polarity (CC2NP)", 7, 1)
                  .WithTag("Capture/Compare 3 output enable (CC3E)", 8, 1)
                  .WithTag("Capture/Compare 3 output polarity (CC3P)", 9, 1)
                  .WithReservedBits(10, 1)
                  .WithTag("Capture/Compare 3 output polarity (CC3NP)", 11, 1)
                  .WithTag("Capture/Compare 4 output enable (CC4E)", 12, 1)
                  .WithTag("Capture/Compare 4 output polarity (CC4P)", 13, 1)
                  .WithReservedBits(14, 1)
                  .WithTag("Capture/Compare 4 output polarity (CC4NP)", 15, 1) },

                { (long)Registers.Counter, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => Value = val, valueProviderCallback: _ => (uint)Value, name: "Counter value (CNT)") },

                { (long)Registers.Prescaler, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => Divider = (int)val + 1, valueProviderCallback: _ => (uint)Divider - 1, name: "Prescaler value (PSC)") },

                { (long)Registers.AutoReload, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) =>
                    {
                        autoReloadValue = val;
                        if (!autoReloadPreloadEnable.Value)
                        {
                            Limit = autoReloadValue;
                        }
                    }, valueProviderCallback: _ => autoReloadValue, name: "Counter value (CNT)") },

                { (long)Registers.CaptureOrCompare1, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => channel1 = val, valueProviderCallback: _ => channel1, name: "Capture/compare register 1 (CCR1)") },

                { (long)Registers.CaptureOrCompare2, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => channel2 = val, valueProviderCallback: _ => channel2, name: "Capture/compare register 2 (CCR2)") },

                { (long)Registers.CaptureOrCompare3, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => channel3 = val, valueProviderCallback: _ => channel3, name: "Capture/compare register 3 (CCR3)") },

                { (long)Registers.CaptureOrCompare4, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => channel4 = val, valueProviderCallback: _ => channel4, name: "Capture/compare register 4 (CCR4)") }
            };

            registers = new DoubleWordRegisterCollection(this, registersMap);
            Reset();

            EventEnabled = true;
        }
 public STM32W_UART(Machine machine)
 {
     this.machine = machine;
     IRQ          = new GPIO();
     charFifo     = new Queue <byte>();
 }
        public PlatformLevelInterruptController(Machine machine, int numberOfSources, int numberOfTargets = 1, bool prioritiesEnabled = true)
        {
            if (numberOfTargets != 1)
            {
                throw new ConstructionException($"Current {this.GetType().Name} implementation does not support more than one target");
            }
            // numberOfSources has to fit between these two registers, one bit per source
            if (Math.Ceiling((numberOfSources + 1) / 32.0) * 4 > Registers.Target1Enables - Registers.Target0Enables)
            {
                throw new ConstructionException($"Current {this.GetType().Name} implementation more than {Registers.Target1Enables - Registers.Target0Enables} sources");
            }

            this.prioritiesEnabled = prioritiesEnabled;

            this.machine = machine;
            IRQ          = new GPIO();
            // irqSources are initialized from 1, as the source "0" is not used.
            irqSources = new IrqSource[numberOfSources + 1];
            for (var i = 1; i <= numberOfSources; i++)
            {
                irqSources[i] = new IrqSource();
            }
            activeInterrupts = new Stack <uint>();

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.Target0ClaimComplete, new DoubleWordRegister(this).WithValueField(0, 32, valueProviderCallback: _ =>
                    {
                        return(AcknowledgePendingInterrupt());
                    }, writeCallback: (_, value) =>
                    {
                        CompleteHandlingInterrupt(value);
                    }
                                                                                                    ) }
            };

            registersMap.Add((long)Registers.Source0Priority, new DoubleWordRegister(this)
                             .WithValueField(0, 3, FieldMode.Read,
                                             writeCallback: (_, value) => { if (value != 0)
                                                                            {
                                                                                this.Log(LogLevel.Warning, $"Trying to set priority {value} to Source 0, which is illegal");
                                                                            }
                                             }));
            for (var i = 1; i <= numberOfSources; i++)
            {
                var j = i;
                registersMap[(long)Registers.Source1Priority * i] = new DoubleWordRegister(this)
                                                                    .WithValueField(0, 3,
                                                                                    valueProviderCallback: (_) => irqSources[j].Priority,
                                                                                    writeCallback: (_, value) => { if (prioritiesEnabled)
                                                                                                                   {
                                                                                                                       irqSources[j].Priority = value;
                                                                                                                   }
                                                                                    });
            }

            var vectorWidth = (uint)Registers.Target1Enables - (uint)Registers.Target0Enables;
            var maximumSourceDoubleWords = (int)Math.Ceiling((numberOfSources + 1) / 32.0) * 4;

            // When writing to TargetXEnables registers, the user will get an error in log when he tries to write to an
            // unused bit of a register that is at least partially used. A warning will be issued on a usual undefined register access otherwise.
            for (var target = 0u; target < numberOfTargets; target++)
            {
                for (var offset = 0u; offset < maximumSourceDoubleWords; offset += 4)
                {
                    var lTarget = target;
                    var lOffset = offset;
                    registersMap.Add((long)Registers.Target0Enables + (vectorWidth * target) + offset, new DoubleWordRegister(this).WithValueField(0, 32, writeCallback: (_, value) =>
                    {
                        lock (irqSources)
                        {
                            // Each source is represented by one bit. offset and lOffset indicate the offset in double words from TargetXEnables,
                            // `bit` is the bit number in the given double word,
                            // and `sourceIdBase + bit` indicate the source number.
                            var sourceIdBase = lOffset * 8;
                            var bits         = BitHelper.GetBits(value);
                            for (var bit = 0u; bit < bits.Length; bit++)
                            {
                                if (sourceIdBase + bit == 0)
                                {
                                    //Source number 0 is not used.
                                    continue;
                                }
                                if (irqSources.Length <= (sourceIdBase + bit))
                                {
                                    if (bits[bit])
                                    {
                                        this.Log(LogLevel.Error, "Trying to enable non-existing source: {0}", sourceIdBase + bit);
                                    }
                                    continue;
                                }
                                var targets = irqSources[sourceIdBase + bit].EnabledTargets;
                                if (bits[bit])
                                {
                                    targets.Add(lTarget);
                                }
                                else
                                {
                                    targets.Remove(lTarget);
                                }
                            }
                            RefreshInterrupts();
                        }
                    }));
                }
            }

            registers = new DoubleWordRegisterCollection(this, registersMap);
        }
 public STM32F7_USART(Machine machine) : base(machine)
 {
     IRQ          = new GPIO();
     receiveQueue = new Queue <byte>();
     DefineRegisters();
 }
Beispiel #8
0
        public BetrustedI2C(Machine machine) : base(machine)
        {
            dataToSlave   = new Queue <byte>();
            dataFromSlave = new Queue <byte>();
            IRQ           = new GPIO();

            irqTimeoutCallback = new ClockEntry((ulong)5, ClockEntry.FrequencyToRatio(machine, 1000), this.FinishTransaction, machine, "Irq Scheduler");

            var registersMap = new Dictionary <long, DoubleWordRegister>()
            {
                { (long)Registers.ClockPrescale, new DoubleWordRegister(this)
                  .WithValueField(0, 16, FieldMode.Read | FieldMode.Write) },

                { (long)Registers.Control, new DoubleWordRegister(this)
                  .WithFlag(7, out enabled)
                  .WithTag("Interrupt enable", 6, 1)
                  .WithReservedBits(0, 6) },

                { (long)Registers.Transmit, new DoubleWordRegister(this)
                  .WithValueField(0, 8, out transmitBuffer, FieldMode.Write) },

                { (long)Registers.Receive, new DoubleWordRegister(this)
                  .WithValueField(0, 8, out receiveBuffer, FieldMode.Read) },

                { (long)Registers.Status, new DoubleWordRegister(this)
                  .WithFlag(7, out receivedAckFromSlaveNegated, FieldMode.Read)
                  .WithFlag(6, FieldMode.Read, valueProviderCallback: _ => false, name: "Busy")
                  .WithFlag(5, FieldMode.Read, valueProviderCallback: _ => false, name: "Arbitration lost")
                  .WithReservedBits(2, 3)
                  .WithFlag(1, FieldMode.Read, valueProviderCallback: _ => false, name: "Transfer in progress")
                  .WithFlag(0, out i2cIntIrqStatus, FieldMode.Read) },

                { (long)Registers.EventStatus, new DoubleWordRegister(this)
                  .WithFlag(1, FieldMode.Read, name: "TX_RX_DONE_STATUS", valueProviderCallback: _ => txRxDoneIrqStatus)
                  .WithFlag(0, FieldMode.Read, name: "I2C_INT_STATUS", valueProviderCallback: _ => i2cIntIrqStatus.Value) },

                { (long)Registers.EventPending, new DoubleWordRegister(this)
                  .WithFlag(1, out txRxDoneIrqPending, FieldMode.Read | FieldMode.WriteOneToClear, name: "TX_RX_DONE_PENDING", changeCallback: (_, __) => UpdateInterrupts())
                  .WithFlag(0, out i2cIntIrqPending, FieldMode.Read | FieldMode.WriteOneToClear, name: "I2C_INT_PENDING", changeCallback: (_, __) => UpdateInterrupts()) },

                { (long)Registers.EventEnable, new DoubleWordRegister(this)
                  .WithFlag(1, out txRxDoneIrqEnabled, name: "TX_RX_DONE_ENABLE", changeCallback: (_, __) => UpdateInterrupts())
                  .WithFlag(0, out i2cIntIrqEnabled, name: "I2C_INT_ENABLE", changeCallback: (_, __) => UpdateInterrupts()) },

                { (long)Registers.Command, new DoubleWordRegister(this)
                  .WithFlag(7, out generateStartCondition, FieldMode.Write)
                  .WithFlag(6, out generateStopCondition, FieldMode.Write)
                  .WithFlag(5, out readFromSlave, FieldMode.Write)
                  .WithFlag(4, out writeToSlave, FieldMode.Write)
                  .WithFlag(3, FieldMode.Read, name: "ACK", valueProviderCallback: _ => true)
                  // .WithTag("ACK", 3, 1)
                  .WithReservedBits(1, 2)
                  .WithFlag(0, FieldMode.Write, writeCallback: (_, __) => i2cIntIrqStatus.Value = false)
                  .WithWriteCallback((_, __) =>
                    {
                        if (!enabled.Value)
                        {
                            return;
                        }

                        if (generateStartCondition.Value)
                        {
                            generateStartCondition.Value = false;
                            if (transactionInProgress)
                            {
                                // repeated start - finish previous transaction first
                                SendDataToSlave();
                            }
                            else
                            {
                                transactionInProgress = true;
                            }

                            dataFromSlave.Clear();
                            if (selectedSlave != null)
                            {
                                selectedSlave.FinishTransmission();
                            }

                            if (!TryResolveSelectedSlave(out selectedSlave))
                            {
                                return;
                            }
                        }

                        if (writeToSlave.Value)
                        {
                            writeToSlave.Value = false;
                            HandleWriteToSlaveCommand();
                        }

                        if (readFromSlave.Value)
                        {
                            readFromSlave.Value = false;
                            HandleReadFromSlaveCommand();
                        }

                        if (transactionInProgress)
                        {
                            machine.ClockSource.AddClockEntry(irqTimeoutCallback);
                        }

                        if (generateStopCondition.Value)
                        {
                            selectedSlave.FinishTransmission();

                            generateStopCondition.Value = false;
                            if (!transactionInProgress)
                            {
                                return;
                            }

                            SendDataToSlave();
                            transactionInProgress = false;
                        }

                        shouldSendTxRxIrq = true;
                    }) }
            };

            registers = new DoubleWordRegisterCollection(this, registersMap);
            UpdateInterrupts();
        }
        public BeagleV_PlatformLevelInterruptController(int numberOfSources, int numberOfContexts = 1, bool prioritiesEnabled = true)
        {
            if (numberOfSources + 1 > MaxSources)
            {
                throw new ConstructionException($"Current {this.GetType().Name} implementation does not support more than {MaxSources} sources");
            }

            var connections = new Dictionary <int, IGPIO>();

            for (var i = 0; i < numberOfContexts; i++)
            {
                connections[i] = new GPIO();
            }
            Connections = connections;

            irqSources = new IrqSource[numberOfSources];
            for (var i = 0u; i < numberOfSources; i++)
            {
                irqSources[i] = new IrqSource(i, this);
            }

            irqContexts = new IrqContext[numberOfContexts];
            for (var i = 0u; i < irqContexts.Length; i++)
            {
                irqContexts[i] = new IrqContext(i, this);
            }

            var registersMap = new Dictionary <long, DoubleWordRegister>();

            registersMap.Add((long)Registers.Source0Priority, new DoubleWordRegister(this)
                             .WithValueField(0, 3, FieldMode.Read, writeCallback: (_, value) =>
            {
                if (value != 0)
                {
                    this.Log(LogLevel.Warning, $"Trying to set priority {value} for Source 0, which is illegal");
                }
            }));
            for (var i = 1; i < numberOfSources; i++)
            {
                var j = i;
                registersMap[(long)Registers.Source1Priority * i] = new DoubleWordRegister(this)
                                                                    .WithValueField(0, 3,
                                                                                    valueProviderCallback: (_) => irqSources[j].Priority,
                                                                                    writeCallback: (_, value) =>
                {
                    if (prioritiesEnabled)
                    {
                        irqSources[j].Priority = value;
                        RefreshInterrupts();
                    }
                });
            }

            for (var i = 0u; i < numberOfContexts; i++)
            {
                AddContextEnablesRegister(registersMap, (long)Registers.Context0Enables + i * ContextEnablesWidth, i, numberOfSources);
                AddContextClaimCompleteRegister(registersMap, (long)Registers.Context0ClaimComplete + i * ContextClaimWidth, i);
            }

            registers = new DoubleWordRegisterCollection(this, registersMap);
        }
Beispiel #10
0
 public STM32DMA2D(Machine machine) : this()
 {
     this.machine = machine;
     IRQ          = new GPIO();
     Reset();
 }
 public Atmel91DebugUnit()
 {
     buffer = new Queue <byte>();
     Reset();
     IRQ = new GPIO();
 }
Beispiel #12
0
 public Efm32Timer(Machine machine) : base(machine, 48000000, direction: Direction.Ascending, limit: 0x100000, enabled: false)
 {
     AutoUpdate = true;
     IRQ        = new GPIO();
 }
Beispiel #13
0
        public CoreLevelInterruptor(Machine machine, long frequency, int numberOfTargets = 1)
        {
            this.machine        = machine;
            this.timerFrequency = frequency;
            if (numberOfTargets < 1)
            {
                throw new ConstructionException("Invalid numberOfTargets: provided {numberOfTargets} but should be greater or equal to 1.");
            }
            for (var i = 0; i < numberOfTargets; i++)
            {
                var hartId = i;
                irqs[2 * hartId]     = new GPIO();
                irqs[2 * hartId + 1] = new GPIO();

                var timer = new ComparingTimer(machine.ClockSource, timerFrequency, this, hartId.ToString(), enabled: true, eventEnabled: true);
                timer.CompareReached += () => irqs[2 * hartId + 1].Set(true);

                mTimers.Add(timer);
            }

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                {
                    (long)Registers.MTimeLo, new DoubleWordRegister(this).WithValueField(0, 32, FieldMode.Read,
                                                                                         valueProviderCallback: _ => (uint)mTimers[0].Value,
                                                                                         writeCallback: (_, value) =>
                    {
                        var timerValue = mTimers[0].Value;
                        timerValue    &= ~0xffffffffUL;
                        timerValue    |= value;
                        foreach (var timer in mTimers)
                        {
                            timer.Value = timerValue;
                        }
                    })
                },
                {
                    (long)Registers.MTimeHi, new DoubleWordRegister(this).WithValueField(0, 32, FieldMode.Read,
                                                                                         valueProviderCallback: _ => (uint)(mTimers[0].Value >> 32),
                                                                                         writeCallback: (_, value) =>
                    {
                        var timerValue = mTimers[0].Value;
                        timerValue    &= 0xffffffffUL;
                        timerValue    |= (ulong)value << 32;
                        foreach (var timer in mTimers)
                        {
                            timer.Value = timerValue;
                        }
                    })
                }
            };

            for (var hart = 0; hart < numberOfTargets; ++hart)
            {
                var hartId = hart;
                registersMap.Add((long)Registers.MSipHart0 + 4 * hartId, new DoubleWordRegister(this).WithFlag(0, writeCallback: (_, value) => { irqs[2 * hartId].Set(value); }));
                registersMap.Add((long)Registers.MTimeCmpHart0Lo + 8 * hartId, new DoubleWordRegister(this).WithValueField(0, 32, writeCallback: (_, value) =>
                {
                    var limit = mTimers[hartId].Compare;
                    limit    &= ~0xffffffffUL;
                    limit    |= value;

                    irqs[2 * hartId + 1].Set(false);
                    mTimers[hartId].Compare = limit;
                }));

                registersMap.Add((long)Registers.MTimeCmpHart0Hi + 8 * hartId, new DoubleWordRegister(this).WithValueField(0, 32, writeCallback: (_, value) =>
                {
                    var limit = mTimers[hartId].Compare;
                    limit    &= 0xffffffffUL;
                    limit    |= (ulong)value << 32;

                    irqs[2 * hartId + 1].Set(false);
                    mTimers[hartId].Compare = limit;
                }));
            }

            registers = new DoubleWordRegisterCollection(this, registersMap);

            Connections = new ReadOnlyDictionary <int, IGPIO>(irqs);
        }
 public NS16550(bool wideRegisters = false)
 {
     mode32 = wideRegisters;
     IRQ    = new GPIO();
     Reset();
 }
 public MockReceiver()
 {
     IRQ = new GPIO();
 }
Beispiel #16
0
        public MiV_CoreGPIO(Machine machine) : base(machine, NumberOfInterrupts)
        {
            innerLock = new object();
            IRQ       = new GPIO();

            irqManager = new GPIOInterruptManager(IRQ, State);

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.InterruptClearRegister, new DoubleWordRegister(this).WithValueField(0, 32, FieldMode.Write,
                                                                                                      writeCallback: (_, value) =>
                    {
                        lock (innerLock)
                        {
                            foreach (var i in BitHelper.GetSetBits(value))
                            {
                                irqManager.ClearInterrupt(i);
                            }
                        }
                    }) },

                { (long)Registers.InputRegister, new DoubleWordRegister(this).WithValueField(0, 32, FieldMode.Read,
                                                                                             valueProviderCallback: _ =>
                    {
                        lock (innerLock)
                        {
                            return(GetConnectedInputPinsState());
                        }
                    }) },

                { (long)Registers.OutputRegister, new DoubleWordRegister(this).WithValueField(0, 32,
                                                                                              writeCallback: (_, value) =>
                    {
                        lock (innerLock)
                        {
                            var bits = BitHelper.GetBits(value);
                            for (var i = 0; i < bits.Length; i++)
                            {
                                if ((irqManager.PinDirection[i] & GPIOInterruptManager.Direction.Output) != 0)
                                {
                                    Connections[i].Set(bits[i]);
                                }
                            }
                        }
                    }, valueProviderCallback: _ =>
                    {
                        lock (innerLock)
                        {
                            return(GetConnectedOutputPinsState());
                        }
                    }) }
            };

            var intTypeToVal = new TwoWayDictionary <GPIOInterruptManager.InterruptTrigger, uint>();

            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.ActiveHigh, 0);
            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.ActiveLow, 1);
            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.RisingEdge, 2);
            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.FallingEdge, 3);
            intTypeToVal.Add(GPIOInterruptManager.InterruptTrigger.BothEdges, 4);

            for (var i = 0; i < NumberOfInterrupts; i++)
            {
                var j = i;
                registersMap.Add((long)Registers.ConfigurationRegisterBase + i * 0x4, new DoubleWordRegister(this)
                                 .WithFlag(0,
                                           writeCallback: (_, v) =>
                {
                    if (v)
                    {
                        irqManager.PinDirection[j] |= GPIOInterruptManager.Direction.Output;
                    }
                    else
                    {
                        irqManager.PinDirection[j] &= ~GPIOInterruptManager.Direction.Output;
                    }
                },
                                           valueProviderCallback: _ =>
                {
                    return((irqManager.PinDirection[j] & GPIOInterruptManager.Direction.Output) != 0);
                }, name: "OUTREG")
                                 .WithFlag(1,
                                           writeCallback: (_, value) =>
                {
                    if (value)
                    {
                        irqManager.PinDirection[j] |= GPIOInterruptManager.Direction.Input;
                    }
                    else
                    {
                        irqManager.PinDirection[j] &= ~GPIOInterruptManager.Direction.Input;
                    }
                },
                                           valueProviderCallback: _ =>
                {
                    return((irqManager.PinDirection[j] & GPIOInterruptManager.Direction.Input) != 0);
                }, name: "INREG")
                                 .WithTag("OUTBUFF", 2, 1)
                                 .WithFlag(3, writeCallback: (_, v) => irqManager.InterruptEnable[j] = v, valueProviderCallback: _ => irqManager.InterruptEnable[j], name: "INTENABLE")
                                 .WithReservedBits(4, 1)
                                 .WithValueField(5, 3, writeCallback: (_, value) =>
                {
                    if (!intTypeToVal.TryGetValue(value, out var type))
                    {
                        this.Log(LogLevel.Warning, "Invalid interrupt type for pin #{0}: {1}", j, value);
                        return;
                    }
                    irqManager.InterruptType[j] = type;
                }, valueProviderCallback: _ =>
                {
                    if (!intTypeToVal.TryGetValue(irqManager.InterruptType[j], out var value))
                    {
                        throw new ArgumentOutOfRangeException($"Unknown interrupt trigger type: {irqManager.InterruptType[j]}");
                    }
                    return(value);
                }, name: "INTTYPE"));
            }

            registers = new DoubleWordRegisterCollection(this, registersMap);
        }
Beispiel #17
0
 public AT86RF233(Machine machine)
 {
     IRQ          = new GPIO();
     this.machine = machine;
     Reset();
 }
Beispiel #18
0
        public STM32_Timer(Machine machine, long frequency, uint initialLimit) : base(machine.ClockSource, frequency, limit: initialLimit, direction: Direction.Ascending, enabled: false, autoUpdate: false)
        {
            IRQ = new GPIO();
            this.initialLimit = initialLimit;

            LimitReached += delegate
            {
                if (updateDisable.Value)
                {
                    return;
                }
                if (updateInterruptEnable.Value)
                {
                    IRQ.Set();
                    updateInterruptFlag = true;
                }
                Limit = autoReloadValue;
            };

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.Control1, new DoubleWordRegister(this)
                  .WithFlag(0, writeCallback: (_, val) => Enabled = val, valueProviderCallback: _ => Enabled, name: "Counter enable (CEN)")
                  .WithFlag(1, out updateDisable, name: "Update disable (UDIS)")
                  .WithFlag(2, out updateRequestSource, name: "Update request source (URS)")
                  .WithFlag(3, writeCallback: (_, val) => Mode      = val ? WorkMode.OneShot : WorkMode.Periodic, valueProviderCallback: _ => Mode == WorkMode.OneShot, name: "One-pulse mode (OPM)")
                  .WithFlag(4, writeCallback: (_, val) => Direction = val ? Direction.Descending : Direction.Ascending, valueProviderCallback: _ => Direction == Direction.Descending, name: "Direction (DIR)")
                  .WithTag("Center-aligned mode selection (CMS)", 5, 2)
                  .WithFlag(7, out autoReloadPreloadEnable, name: "Auto-reload preload enable (APRE)")
                  .WithTag("Clock Division (CKD)", 8, 2)
                  .WithReservedBits(10, 22) },

                { (long)Registers.DmaOrInterruptEnable, new DoubleWordRegister(this)
                  .WithFlag(0, out updateInterruptEnable, name: "Update interrupt enable (UIE)")
                  .WithTag("Capture/Compare 1 interrupt enable (CC1IE)", 1, 1)
                  .WithTag("Capture/Compare 2 interrupt enable (CC2IE)", 2, 1)
                  .WithTag("Capture/Compare 3 interrupt enable (CC3IE)", 3, 1)
                  .WithTag("Capture/Compare 4 interrupt enable (CC4IE)", 4, 1)
                  .WithReservedBits(5, 1)
                  .WithTag("Trigger interrupt enable (TIE)", 6, 1)
                  .WithReservedBits(7, 1)
                  .WithTag("Update DMA request enable (UDE)", 8, 1)
                  .WithTag("Capture/Compare 1 DMA request enable (CC1DE)", 9, 1)
                  .WithTag("Capture/Compare 2 DMA request enable (CC2DE)", 10, 1)
                  .WithTag("Capture/Compare 3 DMA request enable (CC3DE)", 11, 1)
                  .WithTag("Capture/Compare 4 DMA request enable (CC4DE)", 12, 1)
                  .WithReservedBits(13, 1)
                  .WithTag("Trigger DMA request enable (TDE)", 14, 1)
                  .WithReservedBits(15, 17) },

                { (long)Registers.Status, new DoubleWordRegister(this)
                  .WithFlag(0, FieldMode.Read | FieldMode.WriteZeroToClear,
                            writeCallback: (_, val) =>
                    {
                        if (!val)
                        {
                            updateInterruptFlag = false;
                            IRQ.Unset();
                        }
                    },
                            valueProviderCallback: (_) =>
                    {
                        return(updateInterruptFlag);
                    },
                            name: "Update interrupt flag (UIF)")
                  // These write callbacks are here only to prevent from very frequent logging.
                  .WithValueField(1, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 1 interrupt flag (CC1IF)")
                  .WithValueField(2, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 2 interrupt flag (CC2IF)")
                  .WithValueField(3, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 3 interrupt flag (CC3IF)")
                  .WithValueField(4, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 4 interrupt flag (CC4IF)")
                  .WithReservedBits(5, 1)
                  .WithValueField(6, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Trigger interrupt flag (TIE)")
                  .WithReservedBits(7, 2)
                  .WithValueField(9, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 1 overcapture flag (CC1OF)")
                  .WithValueField(10, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 2 overcapture flag (CC2OF)")
                  .WithValueField(11, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 3 overcapture flag (CC3OF)")
                  .WithValueField(12, 1, FieldMode.WriteZeroToClear, writeCallback: (_, __) => {}, name: "Capture/Compare 4 overcapture flag (CC4OF)")
                  .WithReservedBits(13, 18) },

                { (long)Registers.EventGeneration, new DoubleWordRegister(this)
                  .WithFlag(0, FieldMode.WriteOneToClear, writeCallback: (_, val) =>
                    {
                        if (updateDisable.Value)
                        {
                            return;
                        }
                        if (Direction == Direction.Ascending)
                        {
                            Value = 0;
                        }
                        else if (Direction == Direction.Descending)
                        {
                            Value = autoReloadValue;
                        }
                        if (!updateRequestSource.Value && updateInterruptEnable.Value)
                        {
                            IRQ.Set();
                            updateInterruptFlag = true;
                        }
                    }, name: "Update generation (UG)")
                  .WithTag("Capture/compare 1 generation (CC1G)", 1, 1)
                  .WithTag("Capture/compare 2 generation (CC2G)", 2, 1)
                  .WithTag("Capture/compare 3 generation (CC3G)", 3, 1)
                  .WithTag("Capture/compare 4 generation (CC4G)", 4, 1)
                  .WithReservedBits(5, 1)
                  .WithTag("Trigger generation (TG)", 6, 1)
                  .WithReservedBits(7, 25) },

                { (long)Registers.Counter, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => Value = val, valueProviderCallback: _ => (uint)Value, name: "Counter value (CNT)") },

                { (long)Registers.Prescaler, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) => Divider = (int)val + 1, valueProviderCallback: _ => (uint)Divider - 1, name: "Prescaler value (PSC)") },

                { (long)Registers.AutoReload, new DoubleWordRegister(this)
                  .WithValueField(0, 32, writeCallback: (_, val) =>
                    {
                        autoReloadValue = val;
                        if (!autoReloadPreloadEnable.Value)
                        {
                            Limit = autoReloadValue;
                        }
                    }, valueProviderCallback: _ => autoReloadValue, name: "Counter value (CNT)") }
            };

            registers = new DoubleWordRegisterCollection(this, registersMap);
            Reset();

            EventEnabled = true;
        }
Beispiel #19
0
 public EFM32_UART(Machine machine) : base(machine)
 {
     TransmitIRQ = new GPIO();
     ReceiveIRQ  = new GPIO();
 }
        public PULP_uDMA_UART(Machine machine) : base(machine)
        {
            TxIRQ = new GPIO();
            RxIRQ = new GPIO();

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.RxBaseAddress, new DoubleWordRegister(this)
                  .WithValueField(0, 32, out rxBufferAddress, name: "RX_SADDR / Rx buffer base address") },
                { (long)Registers.RxSize, new DoubleWordRegister(this)
                  .WithValueField(0, 17, out rxBufferSize, name: "RX_SIZE / Rx buffer size") },
                { (long)Registers.RxConfig, new DoubleWordRegister(this)
                  .WithFlag(4, out rxStart, name: "EN / RX channel enable and start",
                            // Continuous mode is currently not supported
                            valueProviderCallback: _ => false,
                            writeCallback: (_, value) =>
                    {
                        if (value)
                        {
                            rxData    = new byte[rxBufferSize.Value];
                            rxIdx     = 0;
                            rxStarted = true;
                            if (Count > 0)
                            {
                                // With the new round of reception we might still have some characters in the
                                // buffer.
                                CharWritten();
                            }
                        }
                        rxStarted = value;
                    }) },
                { (long)Registers.TxBaseAddress, new DoubleWordRegister(this)
                  .WithValueField(0, 32, out txBufferAddress, name: "TX_SADDR / Tx buffer base address") },
                { (long)Registers.TxSize, new DoubleWordRegister(this)
                  .WithValueField(0, 17, out txBufferSize, name: "TX_SIZE / Tx buffer size") },
                { (long)Registers.TxConfig, new DoubleWordRegister(this)
                  .WithFlag(4, out txStart, name: "EN / TX channel enable and start",
                            // Continuous mode is currently not supported
                            valueProviderCallback: _ => false,
                            writeCallback: (_, value) =>
                    {
                        if (value && txBufferSize.Value != 0)
                        {
                            var data = new byte[txBufferSize.Value];
                            machine.SystemBus.ReadBytes(txBufferAddress.Value, (int)txBufferSize.Value, data, 0);
                            foreach (var c in data)
                            {
                                TransmitCharacter(c);
                            }
                            bufferSent = true;
                            UpdateInterrupts();
                        }
                    }) },
                { (long)Registers.Status, new DoubleWordRegister(this)
                  .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => false, name: "TX busy")   // tx is never busy
                  .WithFlag(1, FieldMode.Read, valueProviderCallback: _ => false, name: "RX busy")   // rx is never busy
                },
                { (long)Registers.Setup, new DoubleWordRegister(this)
                  .WithFlag(0, out parityEnable, name: "PARITY_ENA / Parity Enable")
                  .WithValueField(1, 2, out bitLength, name: "BIT_LENGTH / Character length")
                  .WithFlag(3, out stopBits, name: "STOP_BITS / Stop bits length")
                  .WithFlag(4, out pollingEnabled, name: "POLLING_EN / Polling Enabled")
                  .WithFlag(5, out cleanFIFO, name: "CLEAN_FIFO / Clean RX FIFO")
                  .WithFlag(8, out txEnabled, name: "TX_ENA / TX enabled")
                  .WithFlag(9, out rxEnabled, name: "RX_ENA / RX enabled")
                  .WithValueField(16, 16, out clockDivider, name: "CLKDIV / Clock divider") },
            };

            registers = new DoubleWordRegisterCollection(this, registersMap);
        }
 public NRF52840_I2S(Machine machine) : base(machine)
 {
     CreateRegisters();
     IRQ = new GPIO();
     Reset();
 }
 public GaislerEth(Machine machine) : base(machine)
 {
     IRQ = new GPIO();
     Reset();
 }
Beispiel #23
0
        public PlatformLevelInterruptController(int numberOfSources, int numberOfTargets = 1, bool prioritiesEnabled = true)
        {
            // numberOfSources has to fit between these two registers, one bit per source
            if (Math.Ceiling((numberOfSources + 1) / 32.0) * 4 > Targets01EnablesWidth)
            {
                throw new ConstructionException($"Current {this.GetType().Name} implementation does not support more than {Targets01EnablesWidth} sources");
            }

            var connections = new Dictionary <int, IGPIO>();

            for (var i = 0; i < 4 * numberOfTargets; i++)
            {
                connections[i] = new GPIO();
            }
            Connections = connections;

            // irqSources are initialized from 1, as the source "0" is not used.
            irqSources = new IrqSource[numberOfSources + 1];
            for (var i = 1u; i <= numberOfSources; i++)
            {
                irqSources[i] = new IrqSource(i, this);
            }

            irqTargets = new IrqTarget[numberOfTargets];
            for (var i = 0u; i < numberOfTargets; i++)
            {
                irqTargets[i] = new IrqTarget(i, this);
            }

            var registersMap = new Dictionary <long, DoubleWordRegister>();

            registersMap.Add((long)Registers.Source0Priority, new DoubleWordRegister(this)
                             .WithValueField(0, 3, FieldMode.Read, writeCallback: (_, value) =>
            {
                if (value != 0)
                {
                    this.Log(LogLevel.Warning, $"Trying to set priority {value} for Source 0, which is illegal");
                }
            }));
            for (var i = 1; i <= numberOfSources; i++)
            {
                var j = i;
                registersMap[(long)Registers.Source1Priority * i] = new DoubleWordRegister(this)
                                                                    .WithValueField(0, 3,
                                                                                    valueProviderCallback: (_) => irqSources[j].Priority,
                                                                                    writeCallback: (_, value) =>
                {
                    if (prioritiesEnabled)
                    {
                        irqSources[j].Priority = value;
                        RefreshInterrupts();
                    }
                });
            }

            AddTargetEnablesRegister(registersMap, (long)Registers.Target0MachineEnables, 0, PrivilegeLevel.Machine, numberOfSources);
            AddTargetClaimCompleteRegister(registersMap, (long)Registers.Target0ClaimComplete, 0, PrivilegeLevel.Machine);
            // Target 0 does not support supervisor mode

            for (var i = 0u; i < numberOfTargets; i++)
            {
                AddTargetEnablesRegister(registersMap, (long)Registers.Target1MachineEnables + i * Targets12EnablesWidth, i + 1, PrivilegeLevel.Machine, numberOfSources);
                AddTargetEnablesRegister(registersMap, (long)Registers.Target1SupervisorEnables + i * Targets12EnablesWidth, i + 1, PrivilegeLevel.Supervisor, numberOfSources);

                AddTargetClaimCompleteRegister(registersMap, (long)Registers.Target1MachineClaimComplete + i * Targets12ClaimCompleteWidth, i + 1, PrivilegeLevel.Machine);
                AddTargetClaimCompleteRegister(registersMap, (long)Registers.Target1SupervisorClaimComplete + i * Targets12ClaimCompleteWidth, i + 1, PrivilegeLevel.Supervisor);
            }

            registers = new DoubleWordRegisterCollection(this, registersMap);
        }
Beispiel #24
0
 public TM1638(GPIO data, GPIO clock, GPIO strobe, bool activateDisplay, byte intensity)
     : base(data, clock, strobe, 8, activateDisplay, intensity)
 {
 }
Beispiel #25
0
        public OpenTitan_KeyManager(Machine machine, OpenTitan_ROMController romController,
                                    string deviceId, string lifeCycleDiversificationConstant, string creatorKey, string ownerKey, string rootKey,
                                    string softOutputSeed, string hardOutputSeed, string destinationNoneSeed, string destinationAesSeed, string destinationOtbnSeed, string destinationKmacSeed,
                                    string revisionSeed, string creatorIdentitySeed, string ownerIntermediateIdentitySeed, string ownerIdentitySeed,
                                    bool kmacEnableMasking = true, int randomSeed = 0, ISideloadableKey kmac = null, ISideloadableKey aes = null, ISideloadableKey otbn = null) : base(machine)
        {
            this.romController = romController;
            destinations       = new Dictionary <Destination, ISideloadableKey>();
            if (kmac != null)
            {
                destinations.Add(Destination.KMAC, kmac);
            }
            if (aes != null)
            {
                destinations.Add(Destination.AES, aes);
            }
            if (otbn != null)
            {
                destinations.Add(Destination.OTBN, otbn);
            }
            OperationDoneIRQ           = new GPIO();
            random                     = new Random(randomSeed);
            sealingSoftwareBinding     = new byte[MultiRegistersCount * 4];
            attestationSoftwareBinding = new byte[MultiRegistersCount * 4];
            salt = new byte[MultiRegistersCount * 4];
            softwareShareOutput = new byte[MultiRegistersCount * 4 * NumberOfSoftwareShareOutputs];

            this.deviceId = ConstructorParseHexstringArgument("deviceId", deviceId, DeviceIdExpectedLength);                                                                                         // OTP_HW_CFG_DATA_DEFAULT.device_id
            this.lifeCycleDiversificationConstant = ConstructorParseHexstringArgument("lifeCycleDiversificationConstant", lifeCycleDiversificationConstant, LifeCycleDiversificationConstantLength); // RndCnstLcKeymgrDiv
            this.creatorKey = ConstructorParseHexstringArgument("creatorKey", creatorKey, CreatorKeyExpectedLength);                                                                                 // KEYMGR_FLASH_DEFAULT.seeds[CreatorSeedIdx]
            this.ownerKey   = ConstructorParseHexstringArgument("ownerKey", ownerKey, OwnerKeyExpectedLength);                                                                                       // KEYMGR_FLASH_DEFAULT.seeds[OwnerSeedIdx]
            var rootKeyTemp = ConstructorParseHexstringArgument("rootKey", rootKey, RootKeyExpectedLength);                                                                                          // OTP_KEYMGR_KEY_DEFAULT

            // If `KmacEnMasking` is set then key is composed of both shares,
            // otherwise the first key share is a xor of shares and the second key share is zero
            if (kmacEnableMasking)
            {
                this.rootKey = rootKeyTemp;
            }
            else
            {
                this.rootKey = rootKeyTemp
                               .Take(rootKeyTemp.Length / 2)
                               .Zip(rootKeyTemp.Skip(rootKeyTemp.Length / 2), (b0, b1) => (byte)(b0 ^ b1))
                               .Concat(Enumerable.Repeat((byte)0, rootKeyTemp.Length / 2))
                               .ToArray();
            }
            this.softOutputSeed                = ConstructorParseHexstringArgument("softOutputSeed", softOutputSeed, SeedExpectedLength);                               // RndCnstSoftOutputSeed
            this.hardOutputSeed                = ConstructorParseHexstringArgument("hardOutputSeed", hardOutputSeed, SeedExpectedLength);                               // RndCnstHardOutputSeed
            this.destinationNoneSeed           = ConstructorParseHexstringArgument("destinationNoneSeed", destinationNoneSeed, SeedExpectedLength);                     // RndCnstAesSeed
            this.destinationAesSeed            = ConstructorParseHexstringArgument("destinationAesSeed", destinationAesSeed, SeedExpectedLength);                       // RndCnstKmacSeed
            this.destinationOtbnSeed           = ConstructorParseHexstringArgument("destinationOtbnSeed", destinationOtbnSeed, SeedExpectedLength);                     // RndCnstOtbnSeed
            this.destinationKmacSeed           = ConstructorParseHexstringArgument("destinationKmacSeed", destinationKmacSeed, SeedExpectedLength);                     // RndCnstNoneSeed
            this.revisionSeed                  = ConstructorParseHexstringArgument("revisionSeed", revisionSeed, SeedExpectedLength);                                   // RndCnstRevisionSeed
            this.creatorIdentitySeed           = ConstructorParseHexstringArgument("creatorIdentitySeed", creatorIdentitySeed, SeedExpectedLength);                     // RndCnstCreatorIdentitySeed
            this.ownerIntermediateIdentitySeed = ConstructorParseHexstringArgument("ownerIntermediateIdentitySeed", ownerIntermediateIdentitySeed, SeedExpectedLength); // RndCnstOwnerIntIdentitySeed
            this.ownerIdentitySeed             = ConstructorParseHexstringArgument("ownerIdentitySeed", ownerIdentitySeed, SeedExpectedLength);                         // RndCnstOwnerIdentitySeed

            DefineRegisters();
            Reset();
        }