Пример #1
0
//        private static bool m_debugContextInitalized = false;

        public GameBoy()
        {
            m_parameters = new CParameters();
            LoadParameters();
            m_DebugThread = new System.Threading.Thread(DebuggerThread);
            m_DebugThread.Start();
//          m_debugContextInitalized = false;

            m_timer = new GameBoyTest.MicroTimer.MicroTimer();

            m_BGScreen     = new GBScreenForm(GameBoy.Ram);
            m_memory       = new MappedMemory();
            m_cartridge    = new Cartridge();
            m_sbDebug      = new SB_Debug();
            m_inputsMgr    = new InputsMgr();
            m_video        = new GBVideo(m_BGScreen);
            m_soundManager = new SoundManager();
            m_cpu          = new Z80Cpu(m_timer);

            m_bDebuggerEnabled = false;

            m_cpu.Init();
            m_video.Init();
            m_sbDebug.Init();
            //sDebugReady = false;

            //m_cpu.Start();
            m_video.Start();
            Application.Run();
            System.Windows.Forms.Application.Exit();
        }
Пример #2
0
        public Micron_MT25Q(MappedMemory underlyingMemory)
        {
            // original MT25Q supports capacity 8MB to 256MB,
            // but we extended it down to 64KB
            // to become compatible with N25Q line
            if (underlyingMemory.Size < 64.KB() || underlyingMemory.Size > 256.MB() || !Misc.IsPowerOfTwo((ulong)underlyingMemory.Size))
            {
                throw new ConstructionException("Size of the underlying memory must be a power of 2 value in range 64KB - 256MB");
            }

            volatileConfigurationRegister         = new ByteRegister(this, 0xfb).WithFlag(3, name: "XIP");
            nonVolatileConfigurationRegister      = new WordRegister(this, 0xffff).WithFlag(0, out numberOfAddressBytes, name: "addressWith3Bytes");
            enhancedVolatileConfigurationRegister = new ByteRegister(this, 0xff)
                                                    .WithValueField(0, 3, name: "Output driver strength")
                                                    .WithReservedBits(3, 1)
                                                    .WithTaggedFlag("Reset/hold", 4)
                                                    //these flags are intentionally not implemented, as they described physical details
                                                    .WithFlag(5, name: "Double transfer rate protocol")
                                                    .WithFlag(6, name: "Dual I/O protocol")
                                                    .WithFlag(7, name: "Quad I/O protocol");
            statusRegister     = new ByteRegister(this).WithFlag(1, out enable, name: "volatileControlBit");
            flagStatusRegister = new ByteRegister(this)
                                 .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => numberOfAddressBytes.Value, name: "Addressing")
                                 //other bits indicate either protection errors (not implemented) or pending operations (they already finished)
                                 .WithReservedBits(3, 1)
                                 .WithFlag(7, FieldMode.Read, valueProviderCallback: _ => true, name: "ProgramOrErase");

            this.underlyingMemory      = underlyingMemory;
            underlyingMemory.ResetByte = EmptySegment;

            deviceData = GetDeviceData();
        }
Пример #3
0
 /// <inheritdoc cref="IDisposable.Dispose"/>
 public void Dispose()
 {
     _mapped?.Dispose();
     _mapped = null;
     _memory.Dispose();
     _memory = null;
 }
Пример #4
0
        public GigaDevice_GD25LQ(MappedMemory underlyingMemory)
        {
            var registerMap = new Dictionary <long, ByteRegister>
            {
                { (long)Register.StatusLow, new ByteRegister(this)
                  .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => writeInProgress, name: "Write in progress")
                  .WithFlag(1, FieldMode.Read, valueProviderCallback: _ => writeEnableLatch, name: "Write enable latch")
                  .WithTag("Block protect 0", 2, 1)
                  .WithTag("Block protect 1", 3, 1)
                  .WithTag("Block protect 2", 4, 1)
                  .WithTag("Block protect 3", 5, 1)
                  .WithTag("Block protect 4", 6, 1)
                  .WithTag("Status register protect 0", 7, 1) },
                { (long)Register.StatusHigh, new ByteRegister(this)
                  .WithTag("Status register protect 1", 0, 1)
                  .WithFlag(1, out quadEnable, name: "Quad enable")
                  .WithTag("SUS2", 2, 1)
                  .WithTag("LB1", 3, 1)
                  .WithTag("LB2", 4, 1)
                  .WithTag("LB3", 5, 1)
                  .WithTag("CMP", 6, 1)
                  .WithTag("SUS1", 7, 1) }
            };

            registers             = new ByteRegisterCollection(this, registerMap);
            this.underlyingMemory = underlyingMemory;
        }
 public DeviceInformation(DeviceFamily deviceFamily, ushort deviceNumber, MappedMemory flashDevice, MappedMemory sramDevice, byte productRevision = 0)
 {
     flashSize            = checked ((ushort)(flashDevice.Size / 1024));
     sramSize             = checked ((ushort)(sramDevice.Size / 1024));
     this.productRevision = productRevision;
     this.deviceFamily    = deviceFamily;
     this.deviceNumber    = deviceNumber;
 }
Пример #6
0
 public MPFS_SystemServices(Machine machine, MappedMemory flashMemory)
 {
     this.machine     = machine;
     this.flashMemory = flashMemory;
     mailbox          = new Mailbox(MailboxSize);
     registers        = new DoubleWordRegisterCollection(this);
     IRQ = new GPIO();
     DefineRegisters();
 }
Пример #7
0
        /// <summary>
        /// Allocates a new memory pool.
        /// </summary>
        /// <param name="dev">Device to allocate on</param>
        /// <param name="blockSize">Memory block size</param>
        /// <param name="memoryType">Memory type</param>
        /// <param name="blockCount">Number of blocks to allocate</param>
        /// <param name="mapped">Provide mapped memory</param>
        public DeviceMemoryPool(Device dev, ulong blockSize, uint memoryType, ulong blockCount, bool mapped)
        {
            Device = dev;
            var bitAlignment = (uint)System.Math.Ceiling(System.Math.Log(blockSize) / System.Math.Log(2));

            blockSize = (1UL << (int)bitAlignment);
            _pool     = new MemoryPool(blockSize * blockCount, bitAlignment);
            _memory   = new DeviceMemory(dev, blockSize * blockCount, memoryType);
            _mapped   = mapped ? new MappedMemory(_memory, 0, _memory.Capacity, 0) : null;
        }
 public void ShouldUnregisterPeripheralGroups()
 {
     using (var machine = new Machine())
     {
         var peripheral = new MappedMemory(10);
         machine.SystemBus.Register(peripheral, new BusPointRegistration(0x0));
         var group = machine.PeripheralsGroups.GetOrCreate("test-group", new [] { peripheral });
         Assert.IsTrue(machine.IsRegistered(peripheral));
         group.Unregister();
         Assert.IsFalse(machine.IsRegistered(peripheral));
     }
 }
Пример #9
0
        private void CreateMachineAndExecute(Action <SystemBus> action)
        {
            using (var machine = new Machine())
            {
                var sb     = machine.SystemBus;
                var memory = new MappedMemory(machine, 16);
                sb.Register(memory, 0.By(16));
                sb.Register(memory, 0xC0000000.By(16));

                action(sb);
            }
        }
Пример #10
0
        //ADC A,d8 2  8 Z 0 H C
        public void AddImmediateWithCarry(R8Bit A, R16Bit PC, MappedMemory memory, R8BitFlag flag)
        {
            byte immediate = memory.ReadByte(PC);
            byte carry     = (byte)(flag.CarryFlag ? 1 : 0);

            flag.HalfCarryFlag = ((A.Value & 0x0F) + (B.Value & 0x0F) + carry) > 0x0F;
            var result = A.Value + B.Value + carry;

            flag.CarryFlag = result > 255;
            A.Value        = (byte)result;
            flag.SubFlag   = false;
            flag.ZeroFlag  = A.Value == 0;
        }
Пример #11
0
        public void ShouldReadWriteMemoryBiggerThan2GB()
        {
            const uint MemorySize = 3u * 1024 * 1024 * 1024;
            var        machine    = new Machine();
            var        memory     = new MappedMemory(machine, MemorySize);
            var        start      = (ulong)100.MB();

            machine.SystemBus.Register(memory, start);
            var offset1 = start + 16;
            var offset2 = start + MemorySize - 16;

            machine.SystemBus.WriteByte(offset1, 0x1);
            machine.SystemBus.WriteByte(offset2, 0x2);

            Assert.AreEqual(0x1, machine.SystemBus.ReadByte(offset1));
            Assert.AreEqual(0x2, machine.SystemBus.ReadByte(offset2));
        }
Пример #12
0
        public bool RemoveMap(long Position, out long Size)
        {
            Size = 0;

            if (Maps.Remove(Position, out Range Value))
            {
                MappedMemory Map = (MappedMemory)Value;

                if (Map.VaAllocated)
                {
                    Size = (long)(Map.End - Map.Start);
                }

                return(true);
            }

            return(false);
        }
Пример #13
0
        public bool RemoveMap(long position, out long size)
        {
            size = 0;

            if (_maps.Remove(position, out Range value))
            {
                MappedMemory map = (MappedMemory)value;

                if (map.VaAllocated)
                {
                    size = (long)(map.End - map.Start);
                }

                return(true);
            }

            return(false);
        }
Пример #14
0
        public bool RemoveMap(ulong gpuVa, out ulong size)
        {
            size = 0;

            if (_maps.Remove(gpuVa, out Range value))
            {
                MappedMemory map = (MappedMemory)value;

                if (map.VaAllocated)
                {
                    size = (map.End - map.Start);
                }

                return(true);
            }

            return(false);
        }
Пример #15
0
 public CPU(MappedMemory memory)
 {
     _memory = memory;
     //Create Registers
     A  = new R8Bit("a");
     F  = new R8BitFlag("f");
     AF = new R16Bit(A, F);
     B  = new R8Bit("b");
     C  = new R8Bit("c");
     BC = new R16Bit(B, C);
     D  = new R8Bit("d");
     E  = new R8Bit("e");
     DE = new R16Bit(D, E);
     H  = new R8Bit("h");
     L  = new R8Bit("l");
     HL = new R16Bit(H, L);
     PC = new R16Bit("pc");
     SP = new R16Bit("sp");
 }
Пример #16
0
        public long Map(long PA, long Size)
        {
            lock (PageTable)
            {
                long VA = GetFreePosition(Size);

                if (VA != -1)
                {
                    MappedMemory Map = new MappedMemory(Size);

                    Maps.AddOrUpdate(VA, Map, (Key, Old) => Map);

                    for (long Offset = 0; Offset < Size; Offset += PageSize)
                    {
                        SetPte(VA + Offset, PA + Offset);
                    }
                }

                return(VA);
            }
        }
Пример #17
0
        public void ShouldSerializeMemory()
        {
            // preparing some random data
            const int size     = 128 * 1024 * 1024;
            const int bufCount = 30;
            const int bufSize  = 100 * 1024;
            var       random   = new Random();
            var       buffers  = new List <Tuple <int, byte[]> >(bufCount);

            for (var i = 0; i < bufCount; i++)
            {
                var buffer = new byte[bufSize];
                random.NextBytes(buffer);
                int address;
                do
                {
                    address = random.Next(size - bufSize);
                }while (buffers.Any(x => address >= (x.Item1 - bufSize) && address <= (x.Item1 + bufSize)));
                buffers.Add(new Tuple <int, byte[]>(address, buffer));
            }

            using (var memory = new MappedMemory(size))
            {
                foreach (var buf in buffers)
                {
                    memory.WriteBytes(buf.Item1, buf.Item2);
                }
                serializer.Serialize(memory, stream);
            }

            RewindStream();
            using (var memory = serializer.Deserialize <MappedMemory>(stream))
            {
                foreach (var buf in buffers)
                {
                    var bufCopy = memory.ReadBytes(buf.Item1, bufSize);
                    CollectionAssert.AreEqual(bufCopy, buf.Item2);
                }
            }
        }
        public CC2538FlashController(Machine machine, MappedMemory flash)
        {
            this.flash = flash;
            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.FlashControl, new DoubleWordRegister(this, 0x4)
                  .WithFlag(0, valueProviderCallback: _ => false, changeCallback: (_, value) =>
                    {
                        if (value)
                        {
                            Erase();
                        }
                    }, name: "ERASE")
                  .WithFlag(1, out write, name: "WRITE")
                  .WithTag("CACHE_MODE", 2, 2)
                  .WithReservedBits(4, 1)
                  .WithTag("ABORT", 5, 1)
                  .WithFlag(6, FieldMode.Read, name: "FULL")
                  .WithFlag(7, FieldMode.Read, valueProviderCallback: _ => write.Value, name: "BUSY")
                  .WithTag("SEL_INFO_PAGE", 8, 1)
                  .WithTag("UPPER_PAGE_ACCESS", 9, 1)
                  .WithReservedBits(10, 22) },
                { (long)Registers.FlashAddress, new DoubleWordRegister(this)
                  .WithValueField(0, 16, valueProviderCallback: _ => writeAddress >> 2, writeCallback: (_, value) => { writeAddress = value; }, name: "FADDR")
                  .WithReservedBits(17, 15) },
                { (long)Registers.FlashData, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Write, writeCallback: (_, value) => Write(value), name: "FWDATA") },
                { (long)Registers.DieConfig0, new DoubleWordRegister(this, 0xB9640580)
                  .WithValueField(0, 32, FieldMode.Read) },
                { (long)Registers.DieConfig1, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Read) },
                { (long)Registers.DieConfig2, new DoubleWordRegister(this, 0x2000)
                  .WithValueField(0, 32, FieldMode.Read) },
            };

            registers = new DoubleWordRegisterCollection(this, registersMap);
            Reset();
        }
        public OpenTitan_ROMController(MappedMemory rom, ulong nonce, ulong keyLow, ulong keyHigh)
        {
            this.rom         = rom;
            romLengthInWords = (ulong)rom.Size / 4;
            romIndexWidth    = BitHelper.GetMostSignificantSetBitIndex(romLengthInWords - 1) + 1;
            if (romLengthInWords <= 8)
            {
                throw new ConstructionException("Provided rom's size has to be greater than 8 words (32 bytes)");
            }
            if (rom.Size % 4 != 0)
            {
                throw new ConstructionException("Provided rom's size has to be divisible by word size (4)");
            }

            KeyLow  = keyLow;
            KeyHigh = keyHigh;
            Nonce   = nonce;

            digest         = new byte[NumberOfDigestRegisters * 4];
            expectedDigest = new byte[NumberOfDigestRegisters * 4];
            registers      = new DoubleWordRegisterCollection(this, BuildRegisterMap());
            Reset();
        }
        public void ShouldNotUnregisterSinglePeripheralFromGroup()
        {
            using (var machine = new Machine())
            {
                var peripheral = new MappedMemory(10);
                machine.SystemBus.Register(peripheral, new BusPointRegistration(0x0));
                machine.SystemBus.Unregister(peripheral);

                machine.SystemBus.Register(peripheral, new BusPointRegistration(0x0));
                machine.PeripheralsGroups.GetOrCreate("test-group", new [] { peripheral });

                try
                {
                    machine.SystemBus.Unregister(peripheral);
                }
                catch (RegistrationException)
                {
                    return;
                }

                Assert.Fail();
            }
        }
Пример #21
0
        public void Setup()
        {
            this.machine = new Machine();
            var rom      = new MappedMemory(machine, 0x100);
            var rom_ctrl = new OpenTitan_ROMController(rom, 0, 0, 0);

            this.peripheral = new OpenTitan_KeyManager(machine, rom_ctrl,
                                                       deviceId: "0xfa53b8058e157cb69f1f413e87242971b6b52a656a1cab7febf21e5bf1f45edd",
                                                       lifeCycleDiversificationConstant: "0x6faf88f22bccd612d1c09f5c02b2c8d1",
                                                       creatorKey: "0x9152e32c9380a4bcc3e0ab263581e6b0e8825186e1e445631646e8bef8c45d47",
                                                       ownerKey: "0xfa365df52da48cd752fb3a026a8e608f0098cfe5fa9810494829d0cd9479eb78",
                                                       rootKey: "0xefb7ea7ee90093cf4affd9aaa2d6c0ec446cfdf5f2d5a0bfd7e2d93edc63a10256d24a00181de99e0f690b447a8dde2a1ffb8bc306707107aa6e2410f15cfc37",
                                                       softOutputSeed: "0xdf273097a573a411332efd86009bd0a175f08814ecc17ab02cc1e3404e1cd8bf",
                                                       hardOutputSeed: "0x69582e71443c8be0fc00de9d9734c3fe7f4266d10a752de74814f2a3079f69a3",
                                                       destinationNoneSeed: "0x73e5bc251b143b74476e576754125d61930d203f199a87c123c074e020fd5028",
                                                       destinationAesSeed: "0xce44cbff5e09e6dd3ae54e9e45da6e662fb69c3aab936b415a0d6e7185eaa2e0",
                                                       destinationOtbnSeed: "0xfcc581b66ae11d33f678e7d227881bcfe58a331208f189de6265edc8fde06db0",
                                                       destinationKmacSeed: "0xb76a8aff9e4da0e3ff9f3036fd9c13ac08496db56fbc4894d38bd8674f4b542d",
                                                       revisionSeed: "0x17a9838dd4cd7f1bdce673b937a6d75202fedbf893bf7d52c8a744ad83d2630b",
                                                       creatorIdentitySeed: "0xc20c05a20251023541544776930be76bfbb22e1d8aaa4783f2b5e094e3e8d3f8",
                                                       ownerIntermediateIdentitySeed: "0x93cdb1d9a6a60050ef0d8a166d91200dc6757907237df4401908799dfa1fe8f2",
                                                       ownerIdentitySeed: "0xa88601ca1695a7c8c5d32486aac4e086628d6c8ca138f65d25dfa5f9c912f354"
                                                       );
        }
Пример #22
0
 public NPClientSpoof(bool doLog)
 {
     this.doLog  = doLog;
     freepieData = new MappedMemory <DisconnectedFreepieData>(DisconnectedFreepieData.SharedMemoryName);
 }
        public MusteinGenericGPU(Machine machine, MappedMemory buffer, bool registers64bitAligned = false, int controlBit = 23, uint frameBufferSize = 0x800000) : base(machine)
        {
            this.machine          = machine;
            this.frameBufferSize  = frameBufferSize;
            this.controlBit       = controlBit;
            this.controlOffset    = 1U << controlBit;
            this.is64bitAligned   = registers64bitAligned;
            this.accessAligment   = (registers64bitAligned) ? 8 : 4;
            this.sync             = new object();
            this.underlyingBuffer = buffer;

            // Allows to switch ordering for the 8bit mode lookup table depending what is closer to the native host colorspace
            var lookupTableRgbx = false;

#if !PLATFORM_WINDOWS
            lookupTableRgbx = true;
#endif

            // Populating lookup table for the 8bit color mode to 24bit conversion, because the 332 format is unbalanced so
            // much and the Red/Green have 50% more bits than Blue the value 0xFF has a yellow tint. Balanced white (gray)
            // color is actually value 0xF6. The white color is fairly gray because the discarted least significant bits
            // still acumulate to a 1/4 of the total brightness/value (we are cutting away too many bits).
            colorTable = new uint[256];
            for (var index = 0u; index < colorTable.Length; index++)
            {
                var red   = index & 0x7;
                var green = (index & 0x38) >> 3;
                var blue  = (index & 0xc0) >> 6;
                var value = 0u;
                if (lookupTableRgbx)
                {
                    value = red << 21 | green << 13 | blue << 6;  // Converting RGB332 to RGB888 which will be used for RGBX8888
                }
                else
                {
                    value = red << 5 | green << 13 | blue << 22;  // Converting RGB332 to BGR888 which will be used for BGRX8888
                }
                colorTable[index] = value;
            }

            colorModeToPixelFormatTable = new Dictionary <ColorMode, PixelFormat>()
            {
                { ColorMode.LowColor, (lookupTableRgbx) ? PixelFormat.RGBX8888 : PixelFormat.BGRX8888 },
                { ColorMode.HighColor, PixelFormat.RGB565 },
                { ColorMode.TrueColor, PixelFormat.RGBX8888 }
            };

            Reconfigure(DefaultWidth, DefaultHeight, DefaultColor);

            copyPatterns = new Dictionary <Tuple <ColorMode, bool, PixelPacking>, Action>()
            {
                { Tuple.Create(ColorMode.LowColor, false, PixelPacking.SinglePixelPerWrite), () => ConvertAndSkip(1, 3) },
                { Tuple.Create(ColorMode.HighColor, false, PixelPacking.SinglePixelPerWrite), () => CopyAndSkip(2, 2) },
                { Tuple.Create(ColorMode.TrueColor, false, PixelPacking.SinglePixelPerWrite), CopyFully },

                { Tuple.Create(ColorMode.LowColor, false, PixelPacking.FullyPacked32bit), ConvertFully },
                { Tuple.Create(ColorMode.HighColor, false, PixelPacking.FullyPacked32bit), CopyFully },
                { Tuple.Create(ColorMode.TrueColor, false, PixelPacking.FullyPacked32bit), CopyFully },

                // In a 32bit peripheral aligment mode using fully packed 64bit is ilegal and will act as fully packed 32bit
                { Tuple.Create(ColorMode.LowColor, false, PixelPacking.FullyPacked64bit), ConvertFully },
                { Tuple.Create(ColorMode.HighColor, false, PixelPacking.FullyPacked64bit), CopyFully },
                { Tuple.Create(ColorMode.TrueColor, false, PixelPacking.FullyPacked64bit), CopyFully },

                { Tuple.Create(ColorMode.LowColor, true, PixelPacking.SinglePixelPerWrite), () => ConvertAndSkip(1, 7) },
                { Tuple.Create(ColorMode.HighColor, true, PixelPacking.SinglePixelPerWrite), () => CopyAndSkip(2, 6) },
                { Tuple.Create(ColorMode.TrueColor, true, PixelPacking.SinglePixelPerWrite), () => CopyAndSkip(4, 4) },

                { Tuple.Create(ColorMode.LowColor, true, PixelPacking.FullyPacked32bit), () => ConvertAndSkip(4, 4) },
                { Tuple.Create(ColorMode.HighColor, true, PixelPacking.FullyPacked32bit), () => CopyAndSkip(2, 4) },
                { Tuple.Create(ColorMode.TrueColor, true, PixelPacking.FullyPacked32bit), () => CopyAndSkip(4, 4) },

                { Tuple.Create(ColorMode.LowColor, true, PixelPacking.FullyPacked64bit), ConvertFully },
                { Tuple.Create(ColorMode.HighColor, true, PixelPacking.FullyPacked64bit), CopyFully },
                { Tuple.Create(ColorMode.TrueColor, true, PixelPacking.FullyPacked64bit), CopyFully },
            };

            // Populate the control registers addresses
            GenerateRegisterCollection();
        }
Пример #24
0
 internal void FreeFor(BufferPool pool)
 {
     MappedMemory?.Dispose();
     pool._pool.Free(_handle);
 }
Пример #25
0
        public PSE_eNVM(Machine machine, MappedMemory memory)
        {
            this.memory = memory;
            IRQ         = new GPIO();
            hvTimer     = new LimitTimer(machine.ClockSource, Frequency, this, nameof(hvTimer), direction: Direction.Descending,
                                         workMode: WorkMode.OneShot, eventEnabled: true);
            hvTimer.LimitReached += TimerTick;

            preProgramOrWriteActions = new Dictionary <bool, Action <uint> >()
            {
                { true, x => WriteFlashWithValue(x, 0xFF, RowLength) },
                { false, x => WriteFlashWithPageLatch(x) }
            };

            var registerMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.PageAddress, new DoubleWordRegister(this)
                  .WithTag("Byte Select", 0, 2)
                  .WithValueField(8, 6, out pageLatchAddress, name: "PA") },
                { (long)Registers.WriteDataAtPageAddress, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Read, writeCallback: (_, value) => pageLatch[pageLatchAddress.Value] = value, name: "PAGE_WRITE_ADDR") },
                { (long)Registers.WriteDataAtPageAddressThenIncrement, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Read, writeCallback: (_, value) =>
                    {
                        pageLatch[pageLatchAddress.Value] = value;
                        pageLatchAddress.Value            = (pageLatchAddress.Value + 1) % PageLatchEntries;
                    }, name: "PAGE_WRITE_INC_ADDR") },
                { (long)Registers.FlashMacroAddress, new DoubleWordRegister(this)
                  .WithTag("Bya", 0, 2)
                  .WithFlag(8, out wordAddress, name: "Wa")
                  .WithValueField(9, 5, out columnAddress, name: "Ca")
                  .WithValueField(16, 8, out pageAddress, name: "Ra")
                  .WithEnumField(24, 2, out selectedSector, name: "Ba") },
                { (long)Registers.ReadFlashData, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Read, valueProviderCallback: _ => ReadFlashDoubleWord(FlashAddressToOffset()), name: "FM_READ") },
                { (long)Registers.ReadFlashDataThenIncrement, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Read, valueProviderCallback: _ =>
                    {
                        var value = ReadFlashDoubleWord(FlashAddressToOffset());
                        // The incrementation process treats the address elements as a number in the following scheme:
                        // Ba[1:0] | Ra[7:0] | Ca[4:0] | Wa
                        // Below we implement the manual addition process
                        if (!wordAddress.Value)
                        {
                            wordAddress.Value = true;
                            goto additionFinished;
                        }
                        //carry
                        wordAddress.Value   = false;
                        columnAddress.Value = (columnAddress.Value + 1) % (1u << columnAddress.Width);
                        if (columnAddress.Value != 0)
                        {
                            goto additionFinished;
                        }
                        //carry
                        pageAddress.Value = (pageAddress.Value + 1) % (1u << pageAddress.Width);
                        if (pageAddress.Value != 0)
                        {
                            goto additionFinished;
                        }
                        selectedSector.Value = (Sector)(((uint)selectedSector.Value + 1) % (1u << selectedSector.Width));

                        additionFinished:
                        return(value);
                    }, name: "FM_READ_INC") },
                { (long)Registers.FlashMacroConfiguration, new DoubleWordRegister(this)
                  .WithEnumField(0, 4, out flashMacroMode, name: "FM_Mode")
                  .WithEnumField(8, 2, out hvSequenceState, name: "FM_Seq")
                  .WithTag("DAA MUX Select", 16, 6) },
                { (long)Registers.TimerConfiguration, new DoubleWordRegister(this)
                  .WithValueField(0, 16, writeCallback: (_, value) => hvTimer.Value = value, valueProviderCallback: _ => (uint)hvTimer.Value, name: "Period")
                  .WithFlag(16, writeCallback: (_, value) => hvTimer.Enabled        = value, valueProviderCallback: _ => false

                            /*hvTimer.Enabled - this causes the demo to run extremely slow, as the timers are bumped only
                             * after quantum. This is not that important, as these timers are for delay purposes only*/,
                            name: "Timer_En")
                  .WithFlag(17, writeCallback: (_, value) => hvTimer.Divider = value ? 100 : 1, valueProviderCallback: _ => hvTimer.Divider == 100, name: "Scale")
                  .WithTag("Pe_en", 18, 1)
                  .WithFlag(19, writeCallback: (_, value) => { if (value)
                                                               {
                                                                   DoAclk();
                                                               }
                            }, name: "Aclk_en")
                  .WithTag("cfg", 24, 6) },
                { (long)Registers.AnalogConfiguration, new DoubleWordRegister(this, 0x16140068)
                  .WithTag("BDAC", 0, 4)
                  .WithTag("itim", 4, 4)
                  .WithTag("MDAC", 8, 8)
                  .WithTag("PDAC", 16, 5)
                  .WithTag("NDAC", 24, 5) },
                { (long)Registers.TestModeConfiguration, new DoubleWordRegister(this, 0x00804000)
                  .WithTag("tm", 0, 4)
                  .WithTag("tm_disneg", 6, 1)
                  .WithTag("tm_dispos", 7, 1)
                  .WithTag("tm_itim", 8, 1)
                  .WithTag("tm_rdhvpl", 9, 1)
                  .WithTag("tm_rdstrb", 10, 1)
                  .WithTag("tm_vdac_force", 12, 1)
                  .WithTag("tm_xydec", 13, 1)
                  .WithTag("turbo_b", 14, 1)
                  .WithFlag(15, out compareTestMode, name: "tm_cmpr")
                  .WithTag("extrm_tim", 20, 1)
                  .WithTag("pg_en", 23, 1)
                  .WithTag("pe_tm", 24, 1)
                  .WithTag("pnb", 25, 1)
                  .WithTag("tm_daa", 26, 1)
                  .WithTag("tm_disrow", 27, 1)
                  .WithTag("tm_isa", 31, 1) },
                { (long)Registers.Status, new DoubleWordRegister(this)
                  .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => !hvTimer.Enabled, name: "hv_timer")
                  .WithReadCallback((_, __) => IRQ.Unset())   //this is a guess based on a comment from the sources. The documentation
                                                              //does not describe the interrupt handling at all
                },
                { (long)Registers.Wait, new DoubleWordRegister(this, 0x16)
                  .WithTag("wait_wr_hvpl", 0, 2)
                  .WithTag("wait_rd_fm", 2, 3)
                  .WithTag("vref_vlevel", 8, 3)
                  .WithTag("vref_ilevel_p", 16, 4)
                  .WithTag("vref_ilevel_n", 20, 4)
                  .WithTag("ctat", 24, 3)
                  .WithTag("vbg_ilevel", 27, 2)
                  .WithTag("vbg_curve", 29, 3) },
                { (long)Registers.Monitor, new DoubleWordRegister(this)
                  .WithTag("xy_out", 0, 1)
                  .WithFlag(1, FieldMode.Read, valueProviderCallback: (_) => switchState == SwitchState.OnCode, name: "sw2fm_r")   //the docs is not clear, but this behavior is probably right
                  .WithFlag(2, out compareResult, FieldMode.Read, name: "cmprx") },
                { (long)Registers.SW2FMEnable, new DoubleWordRegister(this)
                  .WithEnumField <DoubleWordRegister, SwitchState>(0, 8, FieldMode.Write, writeCallback: (_, value) =>
                    {
                        if ((switchState == SwitchState.Off && value == SwitchState.S2OnCode) ||
                            (switchState == SwitchState.S2OnCode && value == SwitchState.S1OnCode) ||
                            (switchState == SwitchState.S1OnCode && value == SwitchState.OnCode))
                        {
                            switchState = value;
                        }
                        else
                        {
                            // improper sequence code
                            switchState = SwitchState.Off;
                        }
                    }, name: "switch_code") },
                { (long)Registers.ScratchPad, new DoubleWordRegister(this)
                  .WithValueField(0, 32, name: "scratch_pad") },
                { (long)Registers.HVConfiguration, new DoubleWordRegister(this, 0x19)
                  .WithTag("FM Clock Frequency", 0, 8)   //this field is ignored, as our timer has an absolute frequency, not depending on external clock
                },
                { (long)Registers.InterruptMask, new DoubleWordRegister(this)
                  .WithFlag(0, out timerInterruptEnabled, name: "Mask_reg0") },
                { (long)Registers.GenerateAClk, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Write, writeCallback: (_, __) => DoAclk(), name: "ACLK_GEN_ADDR")   //value of this field is ignored. The fact of being written to is important
                },
                { (long)Registers.FlashMacroDummyRead, new DoubleWordRegister(this)
                  .WithValueField(0, 32, FieldMode.Read, readCallback: (_, __) => hvSequenceState.Value = HVSequence.Seq0, name: "Mask_regX") },
            };

            registers = new DoubleWordRegisterCollection(this, registerMap);
        }
Пример #26
0
 public NPClientSpoof(bool doLog)
 {
     this.doLog = doLog;
     freepieData = new MappedMemory<DisconnectedFreepieData>(DisconnectedFreepieData.SharedMemoryName);
 }
Пример #27
0
        public EFR32xg13FlashController(Machine machine, MappedMemory flash)
        {
            this.flash = flash;
            if (flash.Size < PageNumber * PageSize)
            {
                throw new ConstructionException($"Provided flash size is too small, expected 0x{PageNumber * PageSize:X} bytes, got 0x{flash.Size:X} bytes");
            }
            interruptsManager = new InterruptManager <Interrupt>(this);

            var registersMap = new Dictionary <long, DoubleWordRegister>
            {
                { (long)Registers.Control, new DoubleWordRegister(this, 0x1)
                  .WithTaggedFlag("ADDRFAULTEN", 0)
                  .WithTaggedFlag("CLKDISFAULTEN", 1)
                  .WithTaggedFlag("PWRUPONDEMAND", 2)
                  .WithTaggedFlag("IFCREADCLEAR", 3)
                  .WithTaggedFlag("TIMEOUTFAULTEN", 4)
                  .WithReservedBits(5, 3)
                  .WithIgnoredBits(8, 1)   // this is written by emlib as an errata
                  .WithReservedBits(9, 23) },
                { (long)Registers.ReadControl, new DoubleWordRegister(this, 0x1000100)
                  .WithReservedBits(0, 3)
                  .WithTaggedFlag("IFCDIS", 3)
                  .WithTaggedFlag("AIDIS", 4)
                  .WithTaggedFlag("ICCDIS", 5)
                  .WithReservedBits(6, 2)
                  .WithTaggedFlag("PREFETCH", 8)
                  .WithTaggedFlag("USEHPROT", 9)
                  .WithReservedBits(10, 14)
                  .WithTag("MODE", 24, 2)
                  .WithReservedBits(26, 2)
                  .WithTaggedFlag("SCBTP", 28)
                  .WithReservedBits(29, 3) },
                { (long)Registers.WriteControl, new DoubleWordRegister(this)
                  .WithFlag(0, out isWriteEnabled, name: "WREN")
                  .WithTaggedFlag("IRQERASEABORT", 1)
                  .WithReservedBits(2, 30) },
                { (long)Registers.WriteCommand, new DoubleWordRegister(this)
                  .WithFlag(0, FieldMode.Toggle, changeCallback: (_, __) => UpdateWriteAddress(), name: "LADDRIM")
                  .WithFlag(1, FieldMode.Toggle, changeCallback: (_, __) => ErasePage(), name: "ERASEPAGE")
                  .WithTaggedFlag("WRITEEND", 2)
                  .WithFlag(3, FieldMode.Toggle, changeCallback: (_, __) => WriteWordToFlash(), name: "WRITEONCE")
                  .WithTaggedFlag("WRITETRIG", 4)
                  .WithTaggedFlag("ERASEABORT", 5)
                  .WithReservedBits(6, 2)
                  .WithTaggedFlag("ERASEMAIN0", 8)
                  .WithReservedBits(9, 3)
                  .WithTaggedFlag("CLEARWDATA", 12)
                  .WithReservedBits(13, 19) },
                { (long)Registers.AddressBuffer, new DoubleWordRegister(this)
                  .WithValueField(0, 32, out writeAddress, name: "ADDRB") },
                { (long)Registers.WriteData, new DoubleWordRegister(this)
                  .WithValueField(0, 32, out writeData, writeCallback: (_, __) => writeDataReady.Value = false, name: "WDATA") },
                { (long)Registers.Status, new DoubleWordRegister(this, 0x8)
                  .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => false, name: "BUSY")
                  .WithTaggedFlag("LOCKED", 1)
                  .WithFlag(2, out invalidAddress, FieldMode.Read, name: "INVADDR")
                  // we assume a single-word buffer
                  .WithFlag(3, out writeDataReady, FieldMode.Read, name: "WDATAREADY")
                  .WithTaggedFlag("WORDTIMEOUT", 4)
                  .WithTaggedFlag("ERASEABORT", 5)
                  .WithTaggedFlag("PCRUNNING", 6)
                  .WithReservedBits(7, 17)
                  .WithTag("WDATAVALID", 24, 4)
                  .WithTag("CLEARWDATA", 28, 4) },
                { (long)Registers.InterruptFlag, interruptsManager.GetMaskedInterruptFlagRegister <DoubleWordRegister>() },
                { (long)Registers.InterruptFlagSet, interruptsManager.GetInterruptSetRegister <DoubleWordRegister>() },
                { (long)Registers.InterruptFlagClear, interruptsManager.GetInterruptClearRegister <DoubleWordRegister>() },
                { (long)Registers.InterruptEnable, interruptsManager.GetInterruptEnableRegister <DoubleWordRegister>() },
                { (long)Registers.ConfigurationLock, new DoubleWordRegister(this)
                  .WithValueField(0, 16,
                                  writeCallback: (_, value) => { isLocked = value != UnlockPattern; },
                                  valueProviderCallback: _ => isLocked ? 1u : 0u,
                                  name: "LOCKKEY")
                  .WithReservedBits(16, 16) },
                { (long)Registers.Command, new DoubleWordRegister(this)
                  .WithTaggedFlag("PWRUP", 0)
                  .WithReservedBits(1, 31) },
            };

            registers = new DoubleWordRegisterCollection(this, registersMap);

            //calling Reset to fill the memory with 0xFFs
            Reset();
        }
Пример #28
0
 protected SharedMemoryWorker()
 {
     freePIEData = new MappedMemory<DisconnectedFreepieData>(DisconnectedFreepieData.SharedMemoryName);
 }
 public EFR32DeviceInformation(int deviceFamily, ushort deviceNumber, MappedMemory flashDevice, MappedMemory sramDevice, byte productRevision = 0)
     : this((DeviceFamily)deviceFamily, deviceNumber, flashDevice, sramDevice, productRevision)
 {
 }
        public OpenTitan_FlashController(Machine machine, MappedMemory flash) : base(machine)
        {
            ProgramEmptyIRQ     = new GPIO();
            ProgramLevelIRQ     = new GPIO();
            ReadFullIRQ         = new GPIO();
            ReadLevelIRQ        = new GPIO();
            OperationDoneIRQ    = new GPIO();
            CorrectableErrorIRQ = new GPIO();

            mpRegionEnabled      = new IFlagRegisterField[NumberOfMpRegions];
            mpRegionBase         = new IValueRegisterField[NumberOfMpRegions];
            mpRegionSize         = new IValueRegisterField[NumberOfMpRegions];
            mpRegionReadEnabled  = new IFlagRegisterField[NumberOfMpRegions];
            mpRegionProgEnabled  = new IFlagRegisterField[NumberOfMpRegions];
            mpRegionEraseEnabled = new IFlagRegisterField[NumberOfMpRegions];

            bankInfoPageEnabled        = new IFlagRegisterField[FlashNumberOfBanks, FlashNumberOfInfoTypes][];
            bankInfoPageReadEnabled    = new IFlagRegisterField[FlashNumberOfBanks, FlashNumberOfInfoTypes][];
            bankInfoPageProgramEnabled = new IFlagRegisterField[FlashNumberOfBanks, FlashNumberOfInfoTypes][];
            bankInfoPageEraseEnabled   = new IFlagRegisterField[FlashNumberOfBanks, FlashNumberOfInfoTypes][];

            for (var bankNumber = 0; bankNumber < FlashNumberOfBanks; ++bankNumber)
            {
                for (var infoType = 0; infoType < FlashNumberOfInfoTypes; ++infoType)
                {
                    bankInfoPageEnabled[bankNumber, infoType]        = new IFlagRegisterField[FlashNumberOfPagesInInfo[infoType]];
                    bankInfoPageReadEnabled[bankNumber, infoType]    = new IFlagRegisterField[FlashNumberOfPagesInInfo[infoType]];
                    bankInfoPageProgramEnabled[bankNumber, infoType] = new IFlagRegisterField[FlashNumberOfPagesInInfo[infoType]];
                    bankInfoPageEraseEnabled[bankNumber, infoType]   = new IFlagRegisterField[FlashNumberOfPagesInInfo[infoType]];
                }
            }

            Registers.InterruptState.Define(this)
            .WithFlag(0, out interruptStatusProgramEmpty, FieldMode.Read | FieldMode.WriteOneToClear, name: "prog_empty")
            .WithFlag(1, out interruptStatusProgramLevel, FieldMode.Read | FieldMode.WriteOneToClear, name: "prog_lvl")
            .WithFlag(2, out interruptStatusReadFull, FieldMode.Read | FieldMode.WriteOneToClear, name: "rd_full")
            .WithFlag(3, out interruptStatusReadLevel, FieldMode.Read | FieldMode.WriteOneToClear, name: "rd_lvl")
            .WithFlag(4, out interruptStatusOperationDone, FieldMode.Read | FieldMode.WriteOneToClear, name: "op_done")
            .WithFlag(5, out interruptStatusCorrectableError, FieldMode.Read | FieldMode.WriteOneToClear, name: "corr_err")
            .WithReservedBits(6, 1 + 31 - 6)
            .WithWriteCallback((_, __) => UpdateInterrupts());

            Registers.InterruptEnable.Define(this)
            .WithFlag(0, out interruptEnableProgramEmpty, name: "prog_empty")
            .WithFlag(1, out interruptEnableProgramLevel, name: "prog_lvl")
            .WithFlag(2, out interruptEnableReadFull, name: "rd_full")
            .WithFlag(3, out interruptEnableReadLevel, name: "rd_lvl")
            .WithFlag(4, out interruptEnableOperationDone, name: "op_done")
            .WithFlag(5, out interruptEnableCorrectableError, name: "corr_err")
            .WithReservedBits(6, 1 + 31 - 6)
            .WithWriteCallback((_, __) => UpdateInterrupts());

            Registers.InterruptTest.Define(this)
            .WithFlag(0, FieldMode.Write, writeCallback: (_, val) => { interruptStatusProgramEmpty.Value |= val; }, name: "prog_empty")
            .WithFlag(1, FieldMode.Write, writeCallback: (_, val) => { interruptStatusProgramLevel.Value |= val; }, name: "prog_lvl")
            .WithFlag(2, FieldMode.Write, writeCallback: (_, val) => { interruptStatusReadFull.Value |= val; }, name: "rd_full")
            .WithFlag(3, FieldMode.Write, writeCallback: (_, val) => { interruptStatusReadLevel.Value |= val; }, name: "rd_lvl")
            .WithFlag(4, FieldMode.Write, writeCallback: (_, val) => { interruptStatusOperationDone.Value |= val; }, name: "op_done")
            .WithFlag(5, FieldMode.Write, writeCallback: (_, val) => { interruptStatusCorrectableError.Value |= val; }, name: "corr_err")
            .WithReservedBits(6, 1 + 31 - 6)
            .WithWriteCallback((_, __) => UpdateInterrupts());

            Registers.AlertTest.Define(this)
            .WithTaggedFlag("recov_err", 0)
            .WithTaggedFlag("fatal_err", 1)
            .WithReservedBits(2, 30);

            Registers.DisableFlashFunctionality.Define(this)
            .WithTag("VAL", 0, 4)
            .WithReservedBits(4, 28);

            Registers.ExecutionFetchesEnabled.Define(this)
            .WithTag("EN", 0, 4)
            .WithReservedBits(4, 28);

            Registers.ControllerInit.Define(this)
            .WithTaggedFlag("VAL", 0)
            .WithReservedBits(1, 31);

            // TODO(julianmb): support register write enable. this isnt tested in the unittests currently
            Registers.ControlEnable.Define(this, 0x1)
            .WithFlag(0, FieldMode.Read, valueProviderCallback: _ => true, name: "EN")
            .WithReservedBits(1, 31);

            Registers.Control.Define(this)
            .WithFlag(0, name: "START", writeCallback: (o, n) => {
                if (n)
                {
                    StartOperation();
                }
            })
            .WithReservedBits(1, 3)
            .WithEnumField <DoubleWordRegister, ControlOp>(4, 2, out operation, name: "OP")
            .WithTaggedFlag("PROG_SEL", 6)
            .WithFlag(7, out flashSelectEraseMode, name: "ERASE_SEL")
            .WithFlag(8, out flashSelectPartition, name: "PARTITION_SEL")
            .WithValueField(9, 2, out flashSelectInfo, name: "INFO_SEL")
            .WithReservedBits(11, 1 + 15 - 11)
            .WithValueField(16, 1 + 27 - 16, out controlNum, name: "NUM")
            .WithReservedBits(28, 1 + 31 - 28);

            Registers.AddressForFlashOperation.Define(this)
            .WithValueField(0, 32, out address, changeCallback: (_, address) => {
                flashAddress  = null;
                var addresses = machine.SystemBus.GetRegistrationPoints(dataFlash)
                                .Select(pint => pint.Range)
                                .Where(range => range.Contains(address))
                                .Select(range => range.StartAddress);

                if (!addresses.Any())
                {
                    this.Log(LogLevel.Warning, "Underlying data flash is not registered on the system bus, so it cannot be accessed");
                    return;
                }

                flashAddress = (long)addresses.First();
            }, name: "START");

            Registers.EnableDifferentProgramTypes.Define(this)
            .WithTaggedFlag("NORMAL", 0)
            .WithTaggedFlag("REPAIR", 1)
            .WithReservedBits(2, 30);

            // Erase is performed immediately so write to SuspendErase will never happen during erasing process.
            // Cleared immediately.
            Registers.SuspendErase.Define(this)
            .WithFlag(0, valueProviderCallback: _ => false, name: "REQ")
            .WithReservedBits(1, 31);

            for (var i = 0; i < NumberOfMpRegions; i++)
            {
                // TODO(julianmb): support register write enable. this isnt tested in the unittests currently
                RegistersCollection.AddRegister((long)Registers.RegionConfigurationEnable0 + 0x4 * i, new DoubleWordRegister(this, 0x1)
                                                .WithTaggedFlag($"REGION_{i}", 0)
                                                .WithReservedBits(1, 31));

                RegistersCollection.AddRegister((long)(Registers.RegionConfiguration0 + 0x4 * i), new DoubleWordRegister(this)
                                                .WithFlag(0, out mpRegionEnabled[i], name: $"EN_{i}")
                                                .WithFlag(1, out mpRegionReadEnabled[i], name: $"RD_EN_{i}")
                                                .WithFlag(2, out mpRegionProgEnabled[i], name: $"PROG_EN_{i}")
                                                .WithFlag(3, out mpRegionEraseEnabled[i], name: $"ERASE_EN_{i}")
                                                .WithTaggedFlag($"SCRAMBLE_EN_{i}", 4)
                                                .WithTaggedFlag($"ECC_EN_{i}", 5)
                                                .WithTaggedFlag($"HE_EN_{i}", 6)
                                                .WithReservedBits(7, 1)
                                                .WithValueField(8, 1 + 16 - 8, out mpRegionBase[i], name: $"BASE_{i}")
                                                .WithValueField(17, 1 + 26 - 17, out mpRegionSize[i], name: $"SIZE_{i}")
                                                .WithReservedBits(27, 1 + 31 - 27));
            }

            Registers.DefaultRegionConfiguration.Define(this)
            .WithFlag(0, out defaultMpRegionReadEnabled, name: "RD_EN")
            .WithFlag(1, out defaultMpRegionProgEnabled, name: "PROG_EN")
            .WithFlag(2, out defaultMpRegionEraseEnabled, name: "ERASE_EN")
            .WithTaggedFlag("SCRAMBLE_EN", 3)
            .WithTaggedFlag("ECC_EN", 4)
            .WithTaggedFlag("HE_EN", 5)
            .WithReservedBits(6, 1 + 31 - 6);

            var registerOffset = Registers.Bank0Info0Enable0;

            for (var bankNumber = 0; bankNumber < FlashNumberOfBanks; ++bankNumber)
            {
                for (var infoType = 0; infoType < FlashNumberOfInfoTypes; ++infoType)
                {
                    // For each info type, first are defined configuration enabling registers and then
                    // configuration registers.
                    for (var pageNumber = 0; pageNumber < FlashNumberOfPagesInInfo[infoType]; ++pageNumber)
                    {
                        // TODO(julianmb): support register write enable. this isnt tested in the unittests currently
                        registerOffset.Define(this, 0x1)
                        .WithTaggedFlag($"REGION_{pageNumber}", 0)
                        .WithReservedBits(1, 31);
                        registerOffset += 0x4;
                    }

                    for (var pageNumber = 0; pageNumber < FlashNumberOfPagesInInfo[infoType]; ++pageNumber)
                    {
                        registerOffset.Define(this)
                        .WithFlag(0, out bankInfoPageEnabled[bankNumber, infoType][pageNumber], name: $"EN_{pageNumber}")
                        .WithFlag(1, out bankInfoPageReadEnabled[bankNumber, infoType][pageNumber], name: $"RD_EN_{pageNumber}")
                        .WithFlag(2, out bankInfoPageProgramEnabled[bankNumber, infoType][pageNumber], name: $"PROG_EN_{pageNumber}")
                        .WithFlag(3, out bankInfoPageEraseEnabled[bankNumber, infoType][pageNumber], name: $"ERASE_EN_{pageNumber}")
                        .WithTaggedFlag($"SCRAMBLE_EN_{pageNumber}", 4)
                        .WithTaggedFlag($"ECC_EN_{pageNumber}", 5)
                        .WithTaggedFlag($"HE_EN_{pageNumber}", 6)
                        .WithReservedBits(7, 1 + 31 - 7);
                        registerOffset += 0x4;
                    }
                }
            }

            // TODO(julianmb): support register write enable. this isnt tested in the unittests currently
            Registers.BankConfigurationEnable.Define(this, 0x1)
            .WithTaggedFlag("BANK", 0)
            .WithReservedBits(1, 31);
            Registers.BankConfiguration.Define(this)
            .WithFlag(0, out eraseBank0, name: "ERASE_EN_0")
            .WithFlag(1, out eraseBank1, name: "ERASE_EN_1")
            .WithReservedBits(2, 1 + 31 - 2);

            Registers.FlashOperationStatus.Define(this)
            .WithFlag(0, out opStatusRegisterDoneFlag, name: "done")
            .WithFlag(1, out opStatusRegisterErrorFlag, name: "err")
            .WithReservedBits(2, 1 + 31 - 2);

            Registers.Status.Define(this, 0xa)
            .WithFlag(0, out statusReadFullFlag, FieldMode.Read, name: "rd_full")
            .WithFlag(1, out statusReadEmptyFlag, FieldMode.Read, name: "rd_empty")
            .WithFlag(2, FieldMode.Read, valueProviderCallback: _ => false, name: "prog_full")
            .WithFlag(3, FieldMode.Read, valueProviderCallback: _ => true, name: "prog_empty")
            .WithFlag(4, FieldMode.Read, valueProviderCallback: _ => false, name: "init_wip")
            .WithReservedBits(5, 1 + 31 - 5);

            Registers.ErrorCode.Define(this)
            .WithFlag(0, out outOfBoundsError, FieldMode.Read | FieldMode.WriteOneToClear, name: "oob_err")
            .WithFlag(1, out memoryProtectionError, FieldMode.Read | FieldMode.WriteOneToClear, name: "mp_err")
            .WithTaggedFlag("rd_err", 2)
            .WithTaggedFlag("prog_win_err", 3)
            .WithTaggedFlag("prog_type_err", 4)
            .WithTaggedFlag("flash_phy_err", 5)
            .WithTaggedFlag("update_err", 6)
            .WithReservedBits(7, 1 + 31 - 7);

            Registers.FaultStatus.Define(this)
            .WithTaggedFlag("oob_err", 0)
            .WithTaggedFlag("mp_err", 1)
            .WithTaggedFlag("rd_err", 2)
            .WithTaggedFlag("prog_win_err", 3)
            .WithTaggedFlag("prog_type_err", 4)
            .WithTaggedFlag("flash_phy_err", 5)
            .WithTaggedFlag("reg_intg_err", 6)
            .WithTaggedFlag("phy_intg_err", 7)
            .WithTaggedFlag("lcmgr_err", 8)
            .WithTaggedFlag("storage_err", 9)
            .WithReservedBits(10, 1 + 31 - 10);

            Registers.ErrorAddress.Define(this)
            .WithValueField(0, 32, out errorAddress, FieldMode.Read, name: "ERR_ADDR");

            Registers.ECCSingleErrorCount.Define(this)
            .WithTag("ECC_SINGLE_ERR_CNT_0", 0, 8)
            .WithTag("ECC_SINGLE_ERR_CNT_1", 8, 8)
            .WithReservedBits(16, 16);

            Registers.ECCSingleErrorAddress0.Define(this)
            .WithTag("ECC_SINGLE_ERR_ADDR_0", 0, 20)
            .WithReservedBits(20, 12);

            Registers.ECCSingleErrorAddress1.Define(this)
            .WithTag("ECC_SINGLE_ERR_ADDR_1", 0, 20)
            .WithReservedBits(20, 12);

            Registers.PhyErrorConfigurationEnable.Define(this)
            .WithTaggedFlag("EN", 0)
            .WithReservedBits(1, 31);

            Registers.PhyErrorConfiguration.Define(this)
            .WithTaggedFlag("ECC_MULTI_ERR_DATA_EN", 0)
            .WithReservedBits(1, 31);

            Registers.PhyAlertConfiguration.Define(this)
            .WithTaggedFlag("alert_ack", 0)
            .WithTaggedFlag("alert_trig", 1)
            .WithReservedBits(2, 30);

            Registers.PhyStatus.Define(this, 0x6)
            .WithTaggedFlag("init_wip", 0)
            .WithTaggedFlag("prog_normal_avail", 1)
            .WithTaggedFlag("prog_repair_avail", 2)
            .WithReservedBits(3, 1 + 31 - 3);

            Registers.Scratch.Define(this)
            .WithTag("data", 0, 32);

            Registers.FifoLevel.Define(this, 0xf0f)
            .WithValueField(0, 5, out programFifoLevel, name: "PROG")
            .WithReservedBits(5, 1 + 7 - 5)
            .WithValueField(8, 1 + 12 - 8, out readFifoLevel, name: "RD")
            .WithReservedBits(13, 1 + 31 - 13);

            // TODO(julianmb): implement fifo reset. There isnt any unittest for this currently.
            Registers.FifoReset.Define(this)
            .WithTaggedFlag("EN", 0)
            .WithReservedBits(1, 31);

            Registers.ProgramFifo.Define(this)
            .WithValueField(0, 32, mode: FieldMode.Write, writeCallback: (_, data) =>
            {
                var isInBounds = flashAddress.HasValue && IsOffsetInBounds(programOffset);
                var isAllowed  = isInBounds && IsOperationAllowed(OperationType.ProgramData, programOffset);

                if (isInBounds && isAllowed)
                {
                    var oldData = ReadFlashDoubleWord(programOffset);
                    WriteFlashDoubleWord(programOffset, oldData & data);
                    programOffset += 4;
                }
                else
                {
                    opStatusRegisterErrorFlag.Value    = true;
                    opStatusRegisterDoneFlag.Value     = true;
                    interruptStatusOperationDone.Value = true;

                    if (isInBounds)
                    {
                        memoryProtectionError.Value = true;
                        errorAddress.Value          = (uint)(programOffset + flashAddress.Value);
                    }
                    else
                    {
                        outOfBoundsError.Value = true;
                    }
                    return;
                }

                if (TryGetOffset(out var offset))
                {
                    if (programOffset > (offset + 4 * controlNum.Value))
                    {
                        opStatusRegisterDoneFlag.Value     = true;
                        interruptStatusOperationDone.Value = true;
                    }
                    else
                    {
                        interruptStatusProgramLevel.Value = true;
                        interruptStatusProgramEmpty.Value = true;
                    }
                }
 public EFM32xGDeviceInformation(DeviceFamily deviceFamily, ushort deviceNumber, MappedMemory flashDevice, MappedMemory sramDevice, byte productRevision = 0)
     : base(deviceFamily, deviceNumber, flashDevice, sramDevice, productRevision)
 {
 }
Пример #32
0
 //ADC A,(HL) 1  8 Z 0 H C
 public void AddWithCarryHL(R8Bit A, R16Bit HL, MappedMemory memory, R8BitFlag flag)
 {
     AddImmediateWithCarry(A, HL, memory, flag);
 }