Documentation ¶
Overview ¶
Package arm imlplements the ARM7TDMI instruction set as defined in the ARM7TDMI Instruction Set Reference:
http://www.ecs.csun.edu/~smirzaei/docs/ece425/arm7tdmi_instruction_set_reference.pdf
For this project we only need to emulte the Thumb architecture. The strategy for this was to implement the nineteen opcode formats. As of writing only format 17, software interrupts, remain unimplemented. To this end, the following reference was preferred:
http://bear.ces.cwru.edu/eecs_382/ARM7-TDMI-manual-pt1.pdf
More detailed explanations of Thumb instruction were found in chapter A7.1 of the ARM Architecture Reference Manual. In particular the side-effects of particular instructions were found in the supplied pseudo-code. Where appropriate, the pseudo-code has been included as a comment in the Go source.
https://www.cs.miami.edu/home/burt/learning/Csc521.141/Documents/arm_arm.pdf
Reference for the ARM7TDMI-S, as used in the Harmony cartridge formats. This contains the cycle information for all ARM instructions.
https://developer.arm.com/documentation/ddi0234/b
Specific information about the NXP ARM7TDMI-S used by the Harmony cartridge. This contains good information about the MAM.
https://www.nxp.com/docs/en/user-guide/UM10161.pdf
And the errata, explaining a bug in the MAM that is experienced in the some versions of the Harmony cartridge.
Index ¶
- Constants
- func AddWithCarry(a uint32, b uint32, c uint32) (uint32, bool, bool)
- func AlignTo16bits(v uint32) uint32
- func AlignTo32bits(v uint32) uint32
- func AlignTo64bits(v uint32) uint32
- func IsAlignedTo16bits(v uint32) bool
- func IsAlignedTo32bits(v uint32) bool
- func IsAlignedTo64bits(v uint32) bool
- func ROR_C(imm32 uint32, shift uint32) (uint32, bool)
- func RRX_C(imm32 uint32, carryIn bool) (uint32, bool)
- func StaticDisassemble(config StaticDisassembleConfig) error
- func ThumbExpandImm_C(imm12 uint32, carry bool) (uint32, bool)
- type ARM
- func (arm *ARM) BreakpointsEnable(enable bool)
- func (arm *ARM) CoreRegisters() [NumCoreRegisters]uint32
- func (arm *ARM) ImmediateMode() bool
- func (arm *ARM) Interrupt()
- func (arm *ARM) MemoryFault(event string, fault faults.Category)
- func (arm *ARM) Peek(addr uint32) (uint32, bool)
- func (arm *ARM) Plumb(env *environment.Environment, state *ARMState, mem SharedMemory, ...)
- func (arm *ARM) ProcessProfiling()
- func (arm *ARM) ProcessorID() string
- func (arm *ARM) Register(register int) (uint32, bool)
- func (arm *ARM) RegisterFormatted(register int) (uint32, string, bool)
- func (arm *ARM) RegisterSet(register int, value uint32) bool
- func (arm *ARM) RegisterSpec() coprocessor.ExtendedRegisterSpec
- func (arm *ARM) Run() (coprocessor.CoProcYield, float32)
- func (arm *ARM) SetByteOrder(o binary.ByteOrder)
- func (arm *ARM) SetDeveloper(dev coprocessor.CartCoProcDeveloper)
- func (arm *ARM) SetDisassembler(disasm coprocessor.CartCoProcDisassembler)
- func (arm *ARM) SetInitialRegisters(args ...uint32) error
- func (arm *ARM) Snapshot() *ARMState
- func (arm *ARM) StackFrame() uint32
- func (arm *ARM) StartProfiling()
- func (arm *ARM) Step(vcsClock float32)
- func (arm *ARM) String() string
- type ARMState
- type ARMinterruptReturn
- type BranchTrail
- type CartridgeHook
- type DisasmEntry
- type DisasmSummary
- type SharedMemory
- type StaticDisassembleConfig
Constants ¶
const ( N cycleType = 'N' I cycleType = 'I' S cycleType = 'S' )
const DisasmEntryErrorOperator = "error:"
The string that will be in the Operator field in the case of a decoding error
const (
NumCoreRegisters
)
core register names
Variables ¶
This section is empty.
Functions ¶
func AddWithCarry ¶
returns result, carry, overflow
func AlignTo32bits ¶ added in v0.25.0
align address to 32bits. some instructions will align the PC to the 32bit boundary
func AlignTo64bits ¶ added in v0.25.0
align address to 32bits. some instructions will align the PC to the 64bit boundary
func IsAlignedTo16bits ¶ added in v0.25.0
checks whether address is aligned to 16bits
func IsAlignedTo32bits ¶ added in v0.25.0
checks whether address is aligned to 32bits
func IsAlignedTo64bits ¶ added in v0.25.0
checks whether address is aligned to 64bits
func StaticDisassemble ¶ added in v0.22.0
func StaticDisassemble(config StaticDisassembleConfig) error
StaticDisassemble is used to statically disassemble a block of memory. It is assumed that there is a valid instruction at the start of the block
For disassemblies of executed code see the coprocessor.CartCoProcDisassembler interface
Types ¶
type ARM ¶
type ARM struct { // the speed at which the arm is running at and the required stretching for // access to flash memory. speed is in MHz. Access latency of Flash memory is // 50ns which is 20MHz. Rounding up, this means that the clklen (clk stretching // amount) is 4. // // "The pipelined nature of the ARM7TDMI-S processor bus interface means that // there is a distinction between clock cycles and bus cycles. CLKEN can be // used to stretch a bus cycle, so that it lasts for many clock cycles. The // CLKEN input extends the timing of bus cycles in increments of of complete // CLK cycles" // // Access speed of SRAM is 10ns which is fast enough not to require stretching. // MAM also requires no stretching. // // updated from prefs on every Run() invocation Clk float32 // rather than call the cycle counting functions directly, we assign the // functions to these fields. in this way, we can use stubs when executing // in immediate mode (when cycle counting isn't necessary) // // other aspects of cycle counting are not expensive and can remain Icycle func() Scycle func(bus busAccess, addr uint32) Ncycle func(bus busAccess, addr uint32) // contains filtered or unexported fields }
ARM implements the ARM7TDMI-S LPC2103 processor.
func NewARM ¶
func NewARM(env *environment.Environment, mmap architecture.Map, mem SharedMemory, hook CartridgeHook) *ARM
NewARM is the preferred method of initialisation for the ARM type.
func (*ARM) BreakpointsEnable ¶ added in v0.20.0
BreakpointsEnable implements the coprocessor.CartCoProc interface. Enables breakpoint checking for the duration that disable is true.
func (*ARM) CoreRegisters ¶ added in v0.25.0
func (arm *ARM) CoreRegisters() [NumCoreRegisters]uint32
CoreRegisters returns all 16 core registers as an array
func (*ARM) ImmediateMode ¶ added in v0.22.0
ImmediateMode returns whether the most recent execution was in immediate mode or not.
func (*ARM) Interrupt ¶ added in v0.20.0
func (arm *ARM) Interrupt()
Interrupt indicates that the ARM execution should cease after the current instruction has been executed. The ARM will then yield with the reson YieldSyncWithVCS.
func (*ARM) MemoryFault ¶ added in v0.29.0
MemoryFault causes a memory fault to be triggered
func (*ARM) Plumb ¶
func (arm *ARM) Plumb(env *environment.Environment, state *ARMState, mem SharedMemory, hook CartridgeHook)
Plumb should be used to update the shared memory reference. Useful when used in conjunction with the rewind system.
The ARMState argument can be nil as a special case. If it is nil then the existing state does not change. For some cartridge mappers this is acceptable and more convenient
Plumb implements the mapper.CartMapper interface.
func (*ARM) ProcessProfiling ¶ added in v0.25.0
func (arm *ARM) ProcessProfiling()
ProcessProfiling ends a profiling session
func (*ARM) ProcessorID ¶ added in v0.25.0
ProcessorID implements the coprocessor.CartCoProc interface. Names the type of ARM being emulated
func (*ARM) Register ¶ added in v0.25.0
Register implements the coprocess.CartCoProc interface. Returns the value in the register. Returns false if the requested register is not recognised
func (*ARM) RegisterFormatted ¶ added in v0.25.0
RegisterFormatted implements the coprocess.CartCoProc interface. Returns the value in the register. Returns false if the requested register is not recognised
func (*ARM) RegisterSet ¶ added in v0.25.0
RegisterSet implements the coprocess.CartCoProc interface. Sets the register to the specified value. Returns false if the requested register is not recognised
func (*ARM) RegisterSpec ¶ added in v0.25.0
func (arm *ARM) RegisterSpec() coprocessor.ExtendedRegisterSpec
RegisterSpec implements the coprocessor.CartCoProc interface
func (*ARM) Run ¶
func (arm *ARM) Run() (coprocessor.CoProcYield, float32)
Run will execute an ARM program from the current PC address, unless the previous execution ran to completion (ie. was uninterrupted).
Returns the yield reason, the number of ARM cycles consumed.
func (*ARM) SetByteOrder ¶ added in v0.22.0
SetByteOrder changes the binary interface used to read memory returned by the SharedMemory interface
func (*ARM) SetDeveloper ¶
func (arm *ARM) SetDeveloper(dev coprocessor.CartCoProcDeveloper)
SetDeveloper implements the coprocessor.CartCoProc interface.
func (*ARM) SetDisassembler ¶
func (arm *ARM) SetDisassembler(disasm coprocessor.CartCoProcDisassembler)
SetDisassembler implements the coprocessor.CartCoProc interface.
func (*ARM) SetInitialRegisters ¶
SetInitialRegisters is intended to be called after creation but before the first call to Run().
The optional arguments are used to initialise the registers in order starting with R0. The remaining options will be set to their default values (SP, LR and PC set according to the ResetVectors() via the SharedMemory interface).
Note that you don't need to use this to set the initial values for SP, LR or PC. Those registers are initialised via the ResetVectors() function of the SharedMemory interface. The function will return with an error if those registers are attempted to be initialised.
The emulated ARM will be left with a yield state of YieldSyncWithVCS
func (*ARM) StackFrame ¶ added in v0.20.0
StackFrame implements the coprocess.CartCoProc interface
func (*ARM) StartProfiling ¶ added in v0.25.0
func (arm *ARM) StartProfiling()
StartProfiling starts a profiling session
type ARMState ¶
type ARMState struct {
// contains filtered or unexported fields
}
func (*ARMState) Plumb ¶ added in v0.31.0
func (s *ARMState) Plumb(env *environment.Environment)
Plumb implements the mapper.CartMapper interface.
type ARMinterruptReturn ¶
type ARMinterruptReturn struct { InterruptEvent string SaveResult bool SaveRegister uint32 SaveValue uint32 InterruptServiced bool NumMemAccess int NumAdditionalCycles int }
ARMInterruptReturn is the return value of the ARMinterrupt type.
type BranchTrail ¶
type BranchTrail int
BranchTrail indicates how the BrainTrail buffer was used for a cycle.
const ( BranchTrailNotUsed BranchTrail = iota BranchTrailUsed BranchTrailFlushed )
List of valid BranchTrail values.
type CartridgeHook ¶
type CartridgeHook interface { // Returns false if parent cartridge mapping does not understand the // address. ARMinterrupt(addr uint32, val1 uint32, val2 uint32) (ARMinterruptReturn, error) }
CartridgeHook allows the parent cartridge mapping to emulate ARM code in a more direct way. This is primarily because we do not yet emulate full ARM bytecode only Thumb bytecode, and the value of doing so is unclear.
type DisasmEntry ¶
type DisasmEntry struct { // the address value. the formatted value is in the Address field Addr uint32 // the opcode for the instruction. in the case of a 32bit instruction, this // will be the second word of the opcode Opcode uint16 // instruction is 32bit and the high opcode Is32bit bool OpcodeHi uint16 // formated address for use by disassemblies. more convenient that the Addr // field in some contexts Address string // the operator is the instruction specified by the Opcode field (and // OpcodeHi if the instruction is 32bit) // // the operand is the specific details of the instruction. what registers // and what values are used, etc. // // in the case of an error Operator will contain the DisasmEntryErrorOperator // string and the Operand will be the detaled message of the error Operator string Operand string // snapshot of CPU registers at the result of the instruction Registers [NumCoreRegisters]uint32 // basic cycle information Cycles int CyclesSequence string // cycle details MAMCR int BranchTrail BranchTrail MergedIS bool // whether this entry was executed in immediate mode. if this field is true // then the Cycles and "cycle details" fields will be zero ImmediateMode bool }
DisasmEntry implements the CartCoProcDisasmEntry interface.
func (DisasmEntry) CSV ¶
func (e DisasmEntry) CSV() string
CSV implements the CartCoProcDisasmEntry interface. Outputs CSV friendly entries, albeit seprated by semicolons rather than commas.
func (DisasmEntry) Key ¶
func (e DisasmEntry) Key() string
Key implements the CartCoProcDisasmEntry interface.
func (DisasmEntry) Size ¶ added in v0.22.0
func (e DisasmEntry) Size() int
Size implements the CartCoProcDisasmEntry interface.
func (DisasmEntry) String ¶
func (e DisasmEntry) String() string
String implements the CartCoProcDisasmEntry interface. Returns a very simple representation of the disassembly entry.
type DisasmSummary ¶
type DisasmSummary struct { // whether this particular execution was run in immediate mode (ie. no cycle counting) ImmediateMode bool // count of N, I and S cycles. will be zero if ImmediateMode is true. N int I int S int }
DisasmSummary implements the CartCoProcDisasmSummary interface.
func (DisasmSummary) String ¶
func (s DisasmSummary) String() string
type SharedMemory ¶
type SharedMemory interface { // blocks mays be different for read and write operations. // // Note that there is no indication of how the memory will be accessed. For // instance whether it's for a 32bit or an 8bit access. For this reason the // implemention can assume that the access is 8bit and that the user of the // result will make further boundary checks as appropriate. // // The write and executing flags provide context for the MapAddress() // implementation. for example, if the executing flag is true then // MapAddress() is being called because the ARM will be running instructions // stored at that address MapAddress(addr uint32, write bool, executing bool) (*[]byte, uint32) // and Program Counter ResetVectors() (uint32, uint32, uint32) IsExecutable(addr uint32) bool }
SharedMemory represents the memory passed between the parent cartridge-mapper implementation and the ARM.
type StaticDisassembleConfig ¶ added in v0.22.0
type StaticDisassembleConfig struct { Data []byte Origin uint32 ByteOrder binary.ByteOrder Callback func(DisasmEntry) }
StaticDisassembleConfig is used to set the parameters for a static disassembly
Source Files ¶
- arm.go
- cycles.go
- cycles_arm7tdmi.go
- cycles_armv7_m.go
- disassembly.go
- disassembly_entry.go
- disassembly_summary.go
- doc.go
- extended_registers.go
- interface.go
- mam.go
- memory_access.go
- memory_alignment.go
- stack_protection.go
- status.go
- thumb.go
- thumb2.go
- thumb2_32bit.go
- thumb2_coproc.go
- thumb2_fpu.go
- thumb2_helpers.go
Directories ¶
Path | Synopsis |
---|---|
Package architecture defines the Map type that is used to specify the differences in cartridge and ARM archtectures.
|
Package architecture defines the Map type that is used to specify the differences in cartridge and ARM archtectures. |
Package Callfn facilitates the ARM CALLFN process common to both DPC+ and CDF* cartridge mappers.
|
Package Callfn facilitates the ARM CALLFN process common to both DPC+ and CDF* cartridge mappers. |
Package peripherals implements the optional modules that can make up the ARM processor.
|
Package peripherals implements the optional modules that can make up the ARM processor. |