コード例 #1
0
ファイル: OtpPeripheral.cs プロジェクト: Riscure/FiSim
        public override void OnRead(IPlatformEngine engine, ulong address, uint size)
        {
            var ctx = engine.GetState <Ctx>(this);

            switch (address & 0xFFF)
            {
            case 0:     // status
                engine.Write(address, BitConverter.GetBytes(ctx.Status));

                if ((ctx.Status & 0x4) == 0x4)       // is ready?
                {
                    ctx.Data    = ctx.WaitingData;
                    ctx.Status ^= 0x4;
                }

                break;

            case 4:     // cmd
                engine.Write(address, new byte[4]);
                break;

            case 8:     // address
                engine.Write(address, BitConverter.GetBytes(ctx.Address));
                break;

            case 12:     // data
                engine.Write(address, BitConverter.GetBytes(ctx.Data));
                break;

            default:
                throw new InvalidHwOperationException(engine, "Unknown register");
            }
        }
コード例 #2
0
ファイル: OtpPeripheral.cs プロジェクト: Riscure/FiSim
        public override void OnWrite(IPlatformEngine engine, ulong address, uint size, ulong value)
        {
            var ctx = engine.GetState <Ctx>(this);

            switch (address & 0xFFF)
            {
            case 0:     // status
                break;

            case 4:     // cmd
                switch (value)
                {
                case 1:         // OTP_CMD_INIT
                    if (_otpOriginalData.Length == 0 && File.Exists(_otpBinPath))
                    {
                        _otpOriginalData = File.ReadAllBytes(_otpBinPath);
                    }
                    else if (_otpOriginalData.Length == 0)
                    {
                        _otpOriginalData = new byte[4096];
                    }

                    ctx.OTPData = _otpOriginalData;

                    ctx.Status = 0x2;         // ready
                    break;

                case 2:                                                         // OTP_CMD_READ
                    if ((ctx.Status & 0x2) == 0x2 && (ctx.Status & 0x4) == 0x0) // is ready and not working?
                    {
                        if (ctx.Address + 4 < (ulong)ctx.OTPData.Length)
                        {
                            ctx.WaitingData = (uint)(ctx.OTPData[ctx.Address] + (ctx.OTPData[ctx.Address + 1] << 8) + (ctx.OTPData[ctx.Address + 2] << 16) + (ctx.OTPData[ctx.Address + 3] << 24));

                            ctx.Status |= 0x4;         // working
                        }
                        else
                        {
                            ctx.Status |= 0x1;         // error
                        }
                    }
                    break;

                case 3:                                                         // OTP_CMD_WRITE
                    if ((ctx.Status & 0x2) == 0x2 && (ctx.Status & 0x4) == 0x0) // is ready and not working?
                    {
                        if (ctx.Address + 4 < (ulong)ctx.OTPData.Length)
                        {
                            ctx.OTPData[ctx.Address]     = (byte)(ctx.OTPData[ctx.Address] | (byte)(ctx.Data & 0xFF));
                            ctx.OTPData[ctx.Address + 1] = (byte)(ctx.OTPData[ctx.Address + 1] | (byte)(ctx.Data >> 8 & 0xFF));
                            ctx.OTPData[ctx.Address + 2] = (byte)(ctx.OTPData[ctx.Address + 2] | (byte)(ctx.Data >> 16 & 0xFF));
                            ctx.OTPData[ctx.Address + 3] = (byte)(ctx.OTPData[ctx.Address + 3] | (byte)(ctx.Data >> 24 & 0xFF));

                            if (PersistentChanges)
                            {
                                _otpOriginalData = ctx.OTPData;

                                File.WriteAllBytes(_otpBinPath, ctx.OTPData);
                            }

                            ctx.WaitingData = (uint)value;

                            ctx.Status |= 0x4;         // working
                        }
                        else
                        {
                            ctx.Status |= 0x1;         // error
                        }
                    }
                    break;

                default:
                    throw new InvalidHwOperationException(engine, $"Unknown OTP command {value}");
                }
                break;

            case 8:     // address
                ctx.Address = (uint)value;
                break;

            case 12:     // data
                ctx.Data = (uint)value;
                break;

            default:
                throw new InvalidHwOperationException(engine, "Unknown register");
            }
        }