public unsafe byte ReadByte(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); byte result; RawRead(reader, address, &result, sizeof(byte)); return result; }
public void DebugCore(Core core, string format, params object[] args) { if (core == null) throw new ArgumentNullException("core"); if (format == null) throw new ArgumentNullException("format"); if (args == null) throw new ArgumentNullException("args"); Debug("{0} {1}".Interpolate(core.Id, format), args); }
public unsafe byte[] ReadBytes(Core reader, uint address, int count) { if (reader == null) throw new ArgumentNullException("reader"); if (count < 0) throw new ArgumentOutOfRangeException( "count", "Byte count is negative."); var data = new byte[count]; fixed (byte* p = &data[0]) RawRead(reader, address, p, count); return data; }
public void Write(Core writer, uint address, double value) { if (writer == null) throw new ArgumentNullException("writer"); Write(writer, address, value.CoerceToUInt64()); }
public unsafe void Write(Core writer, uint address, ulong value) { if (writer == null) throw new ArgumentNullException("writer"); RawWrite(writer, address, &value, sizeof(ulong)); }
public void Write(Core writer, uint address, long value) { if (writer == null) throw new ArgumentNullException("writer"); Write(writer, address, (ulong)value); }
internal DirectAccessEngine(Core core) { Core = core; }
internal RegisterFile(Core core) { Core = core; }
uint Translate(Core core, uint address, bool? write, out byte[] memory, out Core target) { // Is it in external memory? if (address >= ExternalBaseAddress && address < ExternalBaseAddress + Size) { memory = _external; target = null; return address - ExternalBaseAddress; } uint raw; var id = CoreId.FromAddress(address, out raw); // These ranges are reserved for future expansion of // local core memory by Adapteva. if ((raw >= Reserved0Address && raw < RegisterFileAddress || raw >= Reserved1Address && raw < 0x10000) && write != null) throw new MemoryException( "Reserved memory access at 0x{0:X8}.".Interpolate(address), address, (bool)write); if (id != CoreId.Current) core = Machine.GetCore(id); // Is it local core memory? if (raw < LocalMemorySize && core != null) { memory = core.Memory; target = core; return raw; } // No? Then it's trying to access arbitrary memory, at // which point we have to bail since we can't give it // access to anything meaningful. Even on a real board, // accessing arbitrary physical memory is questionable // at best, since it can screw the host kernel up. if (write != null) throw new MemoryException( "Invalid memory access at 0x{0:X8}.".Interpolate(address), address, (bool)write); memory = null; target = null; return address; }
public long ReadInt64(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); return (long)ReadUInt64(reader, address); }
public int ReadInt32(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); return (int)ReadUInt32(reader, address); }
public short ReadInt16(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); return (short)ReadUInt16(reader, address); }
public double ReadDouble(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); return ReadUInt64(reader, address).CoerceToDouble(); }
internal InterruptController(Core core) { Core = core; }
public unsafe void Write(Core writer, uint address, byte[] data) { if (writer == null) throw new ArgumentNullException("writer"); if (data == null) throw new ArgumentNullException("data"); fixed (byte* p = &data[0]) RawWrite(writer, address, p, data.Length); }
unsafe void RawWrite(Core writer, uint address, void* data, int size) { byte[] mem; Core tgt; var idx = Translate(writer, address, true, out mem, out tgt); if (idx + size >= mem.Length) throw new MemoryException( "Out-of-bounds memory access at 0x{0:X8}.".Interpolate(address), address, true); var lockObj = tgt != null ? tgt.MemoryLock : _lock; lock (lockObj) Marshal.Copy(new IntPtr(data), mem, (int)idx, size); }
public sbyte ReadSByte(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); return (sbyte)ReadByte(reader, address); }
public float ReadSingle(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); return ReadUInt32(reader, address).CoerceToSingle(); }
public unsafe ushort ReadUInt16(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); ushort result; RawRead(reader, address, &result, sizeof(ushort)); return result; }
public static void LoadCode(Core core, Stream stream) { if (core == null) throw new ArgumentNullException("core"); if (stream == null) throw new ArgumentNullException("stream"); core.Machine.Logger.VerboseCore(core, "Loading ELF executable"); using (var reader = new BinaryReader(stream, Encoding.ASCII, true)) { if (reader.ReadByte() != 0x7F || reader.ReadByte() != 'E' || reader.ReadByte() != 'L' || reader.ReadByte() != 'F') throw new LoaderException("ELF magic number doesn't match EI_MAG{0..3}."); if (reader.ReadByte() != 1) throw new LoaderException("ELF class is not ELFCLASS32."); if (reader.ReadByte() != 1) throw new LoaderException("ELF data encoding is not ELFDATA2LSB."); if (reader.ReadByte() != 1) throw new LoaderException("ELF version number is not EV_CURRENT."); if (reader.ReadByte() != 0) throw new LoaderException("ELF ABI is not ELFOSABI_SYSV."); if (reader.ReadByte() != 0) throw new LoaderException("ELF ABI version number is not zero."); reader.ReadBytes(7); // Padding bytes. if (reader.ReadUInt16() != 2) throw new LoaderException("ELF object type is not ET_EXEC."); if (reader.ReadUInt16() != 0x1223) throw new LoaderException("ELF machine type is not EM_ADAPTEVA_EPIPHANY."); if (reader.ReadUInt32() != 1) throw new LoaderException("ELF file version number is not EV_CURRENT."); reader.ReadUInt32(); // The `e_entry` field. var phOff = reader.ReadUInt32(); // The `e_phoff` field. var shOff = reader.ReadUInt32(); // The `e_shoff` field. if (reader.ReadUInt32() != 0x00000000) throw new LoaderException("ELF machine flags are not 0x00000000."); reader.ReadUInt16(); // The `e_ehsize` field. reader.ReadUInt16(); // The `e_phentsize` field. var num = reader.ReadUInt16(); // The `e_phnum` field. // ELF has this wonderful feature where, if `e_phnum` is // `ushort.MaxValue`, we have to seek to the first section // header and read its `sh_info` field to get the real, // 32-bit `e_phnum` value. if (num == ushort.MaxValue) { stream.Position = shOff; // Skip all the crap we don't care about... reader.ReadUInt32(); // The `sh_name` field. reader.ReadUInt32(); // The `sh_type` field. reader.ReadUInt32(); // The `sh_flags` field. reader.ReadUInt32(); // The `sh_addr` field. reader.ReadUInt32(); // The `sh_offset` field. reader.ReadUInt32(); // The `sh_size` field. reader.ReadUInt32(); // The `sh_info` field. // And finally, the `sh_info` field that we want. At // this point, we just stop reading the section header // and skip right ahead to the program headers (below). phOff = reader.ReadUInt32(); } stream.Position = phOff; for (var i = 0; i < num; i++) { reader.ReadUInt32(); // The `p_type` field. var offset = reader.ReadUInt32(); // The `p_offset` field. var vaddr = reader.ReadUInt32(); // The `p_vaddr` field. reader.ReadUInt32(); // The `p_paddr` field. var size = reader.ReadUInt32(); // The `p_filesz` field. reader.ReadUInt32(); // The `p_memsz` field. reader.ReadUInt32(); // The `p_flags` field. reader.ReadUInt32(); // The `p_align` field. bool local; bool chip; if ((vaddr & 0xFFF00000) != 0) { // Global address. local = false; chip = IsOnChip(core.Machine, vaddr); } else { // Local address. local = true; chip = true; } Core destCore; uint dest; if (local) { // It's on the current core. destCore = core; dest = vaddr; } else if (chip) { // It's on some other core. uint raw; var id = CoreId.FromAddress(vaddr, out raw); destCore = core.Machine.Grid[id.Row][id.Column]; dest = raw; } else { // It's on external memory. destCore = core; dest = vaddr; // If it's a physical address, translate it to a // device-side virtual address that lies within the // external memory region. `0x1E000000` is the start // of the external memory region as seen by the host // on the Parallella boards. if (!(vaddr >= Memory.ExternalBaseAddress && vaddr < Memory.ExternalBaseAddress + core.Machine.Memory.Size)) dest += Memory.ExternalBaseAddress - 0x1E000000; } var pos = stream.Position; stream.Position = offset; // Now read in the machine code. for (var j = 0; j < size; j++) core.Machine.Memory.Write(destCore, (uint)(dest + j), reader.ReadByte()); // Jump back and continue reading program headers. stream.Position = pos; } } }
public unsafe ulong ReadUInt64(Core reader, uint address) { if (reader == null) throw new ArgumentNullException("reader"); ulong result; RawRead(reader, address, &result, sizeof(ulong)); return result; }
public abstract Operation Execute(Core core);
public virtual void SystemCall(Core core, ref int r3, ref int r0, int r1, int r2) { throw new NotSupportedException("This kernel does not implement system calls."); }