Bennett/Requirements
< Bennett
Jump to navigation
Jump to search
Base Requirements
- Multiplatform (Linux/Windows. Mac if possible, but has serious challenges) - use C++/Qt
- Needs to support different different architectures: ARM, RISC-V, [others]
- Needs to be configurable to 8, 12, 16, 24, 32, or 64 bit architecture
- Needs to support different memory models, different register configurations, etc
- Needs be able to work with simulators, or to communicate with a lab board
- Display of CPU registers (which registers are available will depend on architecture)
- Display of Status Flags (which flags are available will depend on architecture)
- Memory view, with optional disassembly.
- View should be configurable to show memory in different ways: single word, multiple words, ascii characters, disassembly (word size and disassembly will depend on architecture) and if an address matches the value in a register, the register name should be highlighted next to that address.
- Multiple memory views need to be available, and individually configurable.
- Breakpoints (stop on PC reaching memory address)
- Watchpoint (stop on value at address being changed/set to value)
- CPU controls: step [single, multiple], run, halt, reset - is continue just another form of 'run', is 'run' just unconstrained 'step'?
- Needs to be extensible to support different simulated memory-mapped peripherals. Peripherals separate from architecture?
- avoid using linux-specific mechanisms for IPC: sockets instead of pipes, for example. Dynamic loading of extensions will need thought (QLibrary system in Qt provides portable option here).
Extras
- Compilers/assemblers for target architectures
- GNU as (GAS) (part of the gcc suite) will target almost any architecture, but may not produce useful file types (MU0 support is curiously absent, for example)
- Writing assemblers for all possible targets is possible but nontrivial. Are there real reasons not to use GAS (mingw under Windows) when a suitable target exists? Would they function as stopgaps in the short-term?
Design thoughts
These are general thoughts about the design, expect these to change/be refined as things progress.
- First, and most important concept: the design of the system is split so that there is a 'monitor core' and a number of 'system modules', with a controlled interface between the two.
- The core handles module discovery, module selection and loading, and the behaviour of the common monitor UI.
- System modules contain AND FULLY ENCAPSULATE individual simulators or hardware interfaces.
- System modules should expose a set of 'capabilities' that describe the configuration of UI elements in the core.
- The core should have absolutely no system-specific logic inside it: it should be as completely architecture and implementation agnostic as possible. It should be just a user interface that is capable of enabling/disabling/configuring the interface elements presented to the user based on the selected system module capabilities [NOTE: Means we need to decide on an appropriate superset of possible elements that may be needed for each interface element]
- The core needs to provide a mechanism whereby system modules can register UI extensions. These allow specific UI elements or windows implemented in the system module to be shown to the user. For example, a simulator system module may provide a separate console output window, or a simulated 'screen' and keyboard. Note again: everything about such extensions - from UI definition to callbacks - should happen inside the module, all the core should care about is providing a way to register/add the UI elements!
- endianness is a problem. All current and future planned architectures are little-endian, but if the system can be made endian-agnostic, if might have wider application.
Interface Elements
The two key features a monitor needs to provide are CPU view and control, and memory view and control. Below are summaries of the interface elements and features needed to provide CPU and memory view and control, followed by additional elements the rest of the monitor should support.
Memory
The memory view and control should provide:
- Multiple independently configurable memory views (with pop in/ pop out to separate windows?)
- Means to select which memory to show if there are multiple memories (system module capabilities should give names and address ranges).
- Memory address display.
- A means to set the current address shown in the memory view.
- Word size is determined by the capabilities information from the system module.
- A way to configure the number of words shown per line in the memory display (note that having more than one word per line will mean hiding disassembly/source views).
- Optional indication of whether a CPU register contains a current address.
- Allow the user to 'lock' the memory display to a register address. Default to PC following, but allow other register following.
- Memory contents display: hex, ascii equivalent, disassembly/source view.
- Set the value stored in memory if allowed.
- Show breakpoint locations, allow set/clear.
- Show watchpoint locations, allow set/clear.
Notes:
- the memory view window logic should not include code to attempt disassembly! Things that can be handled by the memory view in the core:
- current address and window size.
- hex version of memory contents (simple conversion from bytes).
- ascii equivalent of memory contents (simple conversion from bytes).
- metadata display, if appropriate. This is a display of data provided by the system module for that address.
- display of breakpoints/watchpoints
- Data from the system module should contain the word data as bytes.
- Data from the system module should contain metadata to show for an address. This is typically either the disassembly or source for that address.
- Data from the system module should include whether an address has a watchpoint or breakpoint set on it.
- Setting the value at an address in the memory view should tell the system module that the value has been updated. The system module should update its memory, and send back revised data to show in the memory view. The monitor core should not assume it has been set successfully until the system module says so.
- setting/clearing breakpoints and watchpoints is like setting memory: tell the system module that the action has happened, system module sends back revised memory data with the setting updated. Monitor should not assume breakpoint/watchpoint has been set or cleared until the system module says.
CPU
The CPU view should provide:
- Potentially multiple banks of registers (needs to be specified by system module capabilities).
- Multiple registers per bank (potentially different numbers per bank, again set by capabilities).
- Register display should give register name, hex value, and optional ascii equivalent.
- Do we need to treat the Status Register/CCR/CPSR/SPSR specially and provide a decoded flags field? Komodo and Perentie both do this.
- control buttons for the processor:
- step (possibly with multi-step counter). Multi-step could be done inside the core, as that's just repeatedly calling single step in the system module.
- run/continue
- halt
- reset
Notes:
- The list of register banks and registers in each bank should be given to the core by the system module. The core should make no assumption other than that there is one or more banks of registers, with one or more registers in it (MU0 just has one bank with PC, Accumulator, and a status register, but more complex processors will have more registers in more banks)
- Core needs to have a way to ask the system module to tell it what values are stored in each register, and which bank should be considered active at a given time.
- If a decoded status register display is needed, the system module needs to tell the core
- how many status registers there are
- what possible flags there are in the status
- which flags are set or cleared in each register - the core should not attempt to decode the flags itself, the system module should do the decode and give the core a list of flags and their states!
- Do all system modules provide all controls? Possibly a control module might not support single stepping, so that may need to be part of the capabilities.
- Komodo provides a "walk" feature - essentially a step function that does X steps, pauses for a configurable time, does another X steps and so on until halted. Do we want that?