670 likes | 940 Views
ARM Software Development. ARM Software Development Platform. ARMulator An instruction set simulator for various ARM processors. Support a full ANSI C library to allow complete C programs to run on the simulated system. The main modules are A model of the ARM Processor core
E N D
ARM Software Development Platform • ARMulator • An instruction set simulator for various ARM processors. • Support a full ANSI C library to allow complete C programs to run on the simulated system. • The main modules are • A model of the ARM Processor core • A model of the memory used by the processor (armmap) • Some other predefined modules • Model additional hardware, such as a coprocessor or peripherals. • Model pre-installed software, such as a C library, semihosting SWI handler, or an operating system. • Provide debugging or benchmarking information • You can write your own modules for the above tasks. • ARM Development Boards
Configuring ARMulator • Related configuration files • default.ami • peripherals.ami • example.ami • What you can do? • Configuring tracer • Configuring profiler • Configuring memory model • Configuring ARMulator to use the peripheral models • Chapter 2 of Debug Target Guide
Writing ARMulator Models • Supplied models • Basic models • tracer.c, profiler.c, pagetab.c, stackuse.c, nothing.c, semihost.c, dcc.c, mapfile.c • Peripheral models • intc.c, timer.c, millisec.c, watchdog.c, tube.c • Writing your own models • Using the API provided in Chapter 4 of Debug Target Guide to develop the new model. • Configuring ARMulator to use new models • Chapter 3.4 of Debug Target Guide
Semihosting • Provides code running on an ARM target use of facilities on a host computer that is running an ARM debugger. • These include the keyboard input, screen output, and disk I/O. • To allow functions in the C library, such as printf() and scanf(), to use the screen and keyboard of the host. • Is implemented by a set of defined software interrupt (SWI) operations. • In many case, the semihosting SWI will be invoked by code within library functions.
SWI Interface • SWI instructions contain a field that encode the SWI number used by application code. • The SWI number used for semihosting • 0x123456 in ARM state • 0xAB in Thumb state • To distinguish between operations, operation type is passed in r0. • 0x00 to 0x31 used by ARM • 0x32 to 0xFF reserved for future use by ARM • 0x100 to 0x1FF reserved for user applications • Example • 0x01 SYS_OPEN • 0x02 SYS_CLOSE
ARM-Thumb Procedure Call Standard(ATPCS) • It defines register usage and stack conventions that must be followed in order to enable separately compiled or assembled subroutines to work together. • It describes a contract between a calling and a called routine: • Obligations on the caller to create a memory state in which the called routine may start to execute. • Obligations on the called routine to preserve the memory-state of the caller across the call. • The rights of the called routine to alter the memory-state of its caller.
ATPCS (2) • Specifies a family of Procedure Call Standard (PCS) Variants, generated by a cross product of user choices that reflect alternative priorities among: • Code size • Performance • Functionality (Ex. Ease of debugging, run-time checking, …) • Contains • A machine-level base standard. • A set of machine-level variants. • Constraints on the layout of activation records and function entry sequences to support stack unwinding. • The representation of externally visible C-language and C++ extern “C”{…} entities.
Base Standard (1) • Defines • a machine-level, integer-only calling standard common to ARM and Thumb, and • a machine-level floating-point standard for ARM. • The base standard does not provide for • Interworking between ARM state and Thumb state. • Position independence of either data or code. • Re-entry to routines with independent data for each invocation. • Stack checking. • They are specified by the PCS variants.
Base Standard (2) • Machine registers
Base Standard (3) • Floating point registers • FPA architecture • Eight floating-point registers, f0-f7 • Each may hold a value of single, double or extended precision. • VFP architecture • Sixteen double-precision registers, d0-d15 • each may also be used to hold two single precision numbers. • No extended precision
Base Standard (4) • Routine call can be implemented by any instruction sequence that has the effect: LR <--- Return address PC <--- Destination address • A subroutine call preserves the values of r4-r11 and SP • Parameter Passing • Types • 32-bit integers • Single-precision floating-point numbers • Double-precision floating-point numbers
Base Standard (4) • Parameter Passing (cont.) • A source language parameter value is converted to a machine parameter value as follows: • An integer value narrower than 32 bits: widen to 32 bits • A 64-bit integer: treated as two 32-bit integer values • A floating-point value • One or more floating-point values of the corresponding machine types if floating point hardware exists. • A sequence of integer machine words if floating-point operation is simulated. • Others • Converted to a sequence of 32-bit integers
Base Standard (5) • Parameter passing (cont.) • Variadic routines (passing variable number of parameters) • Loading the first 4 words into integers a1-a4 (lowest addressed into a1). • Pushing remaining words onto the stack in reverse order. • A floating point value can be passed in integer registers, or can be split between an integer register and memory. • Non-variadic routines • The first N floating-point values are assigned to floating-point argument registers. • The rest is the same as Variadic routine.
Base Standard (6) • Result Return • A procedure returns no result. • A function returns a single value; a value occupies 1 or more words • Integer function • Must return a 1-word value in a1 • May return a value of length 2-4 words in a1-a2, a1-a3, a1-a4. • Must return a longer value indirectly in memory. • Floating-point function • FPA procedure call standard • VFP procedure call standard • No floating-point hardware procedure call standard
Standard Variants (1) • ARM and Thumb interworking • Read-only position-independence (ROPI) • A read-only segment of a program can be loaded and used at any address • Read-write position-independence (RWPI) • A read-write segment of a program can be loaded and executed at any address. • Re-entrant code • A program which is RWPI is also re-entrant. • Shared libraries • A shared library is a re-entrant program to which other programs may link at execution time.
Standard Variants (2) • Stack limit checking • SL (Stack limit) must point at least 256 bytes above the lowest usable address in the stack. • SL must not be altered by code compiled or assembled with stack limit checking selected. • The value held SP (stack pointer) must always greater than or equal to the value in SL.
Interworking ARM and Thumb (1) • Interworking • Mixing ARM and Thumb code as you wish. • The ARM linker alters call and return instructions, or insert small code sections called veneers, to change processor states as necessary when it detects a state change exist. • Why interworking? • Thumb state provides good code density, but we need the application running in ARM state because of • Speed • Functionality (enable or disable interrupts can only be done in ARM state) • Exception handling • A Thumb-capable ARM processor always starts in ARM state
Interworking ARM and Thumb (2) • Use –apcs/interwork options for assembler and compilers • The compiler or assembler records an interworking attribute in the object file. • The linker provides interworking veneers for subroutine entry. • In assembly language, you must write function exit code that returns to the instruction set state of the caller. • In C or C++, the compiler creates function exit code. • When to use? If your object file contains: • Thumb subroutines that might need to return to ARM state. • ARM subroutines that might need to return to Thumb state. • Thumb subroutines that might make indirect or virtual calls to ARM state. • ARM subroutines that might make indirect or virtual calls to Thumb state.
Assembly Language interworking • Instructions perform processor state change • BX Rn • The value of bit 0 of the branch address determines the processor state • If bit 0 is set, the instructions at the branch address are executed in Thumb state. • If not, the instructions at the branch address are executed in ARM state • BLX, LDR, LDM, and POP (ARM architecture v5 only) • Assembly directives • CODE16 • CODE32
Mixing C, C++ and Assembly Language • In-line assembler • Accessing C global variables • Using C header files from C++ • Calling between C, C++, and ARM assembly language
Accessing C global variables • To access a global variable, use the IMPORT directive to import the global and then load the address into a register.
Handling Processor Exceptions • Why normal processor execution interrupted? • To handle some events such as • Externally generated interrupts • An attempt by the processor to execute an undefined instruction • Accessing privileged operating system functions • Others • Basic rules of handling exceptions • After handling the exception, the processor execution can be resumed with a previous processor status.
Entering an Exception • When an exception is generated, the processor takes the following actions: • Copies the CPSR into SPSR for the mode in which the exception is to be handled. • Change the appropriate CPSR mode bits in order to • Change to the appropriate mode, and map in the appropriate banked registers for that mode. • Disable interrupts. • IRQs are disabled when any exception occurs. • FIQs are disabled when a FIQ occurs, and on reset. • Set lr_mode to the return address • Set PC to the vector address for the exception.
Returning from an Exception • The actions taken by the processor • Restore the CPSR from SPSR_mode • Restore the PC using return address stored in lr_mode • The way to return depends on whether a stack is used during entering the subroutine • Without a stack • Performing a data processing instruction with S flag set and the PC as the destination register. • With a stack • Restoring the saved registers by performing • LDMFD sp!, {r0-r12,pc}^ • ^ indicates that the CPSR is restored from the SPSR
Returning from SWI and Undefined Instruction Handlers • SWI and UI exceptions are generated by the instruction itself, so the PC is not updated when the exception is taken. Thus, storing (PC-4) in lr_mode makes lr_mode points to the next instruction be executed. SWI xxx being executed PC-8 INST-1 being decoded PC-4 INST-2 being fetched PC • Restoring the PC from lr • Without a stack MOVS pc, lr • With a stack STMFD sp!, {reglist,lr} … LDMFD sp!, {reglist, pc}^
Returning from FIQ and IRQ • Check IRQ and FIQ at the end of executing each instruction. INST-1 being executed PC-12 , IRQ or FIQ checked INST-2 being decoded PC-8 INST-3 being fetched PC-4 INST-4 PC • Restoring PC from lr • Without a stack SUBS pc, lr, #4 • With a stack SUB lr, lr, #4 STMFD sp!, {reglist, lr} … LDMFD sp!, {reglist, pc}^
Returning from Prefetch Abort • Prefetch abort is generated when it reaches the execution stage. INST-1 being executed PC-8 , Aborted INST-2 being decoded PC-4 INST-3 being fetched PC • Restoring PC from lr • Without a stack SUBS pc, lr, #4 • With a stack SUB lr, lr, #4 STMFD sp!, {reglist, lr} … LDMFD sp!, {reglist, pc}^
Returning from Data Abort • When a data abort occurs, the program counter has been updated. INST-1 being executed PC-12 , Aborted INST-2 being decoded PC-8 INST-3 being fetched PC-4 INST-4 PC • Restoring PC from lr • Without a stack SUBS pc, lr, #8 • With a stack SUB lr, lr, #8 STMFD sp!, {reglist, lr} … LDMFD sp!, {reglist, pc}^
Install an Exception Handler • Exception handlers can be reached by the instruction contained in each entry in the vector table: • A branch instruction • PC relative • A load PC instruction • The absolute address of a handler must be stored in a suitable memory location.
Installing the Handlers at Reset (1) • If the ROM is at location 0x0 in memory (load PC can be replaced by branch)
Installing the Handlers at Reset (2) • If the RAM is at location 0x0 in memory
Installing the Handler from C (1) • Branch Method • Take the address of the exception handler. • Subtract the address of the corresponding vector. • Subtract 0x8 to allow for prefetching. • Shift the result to the right by two to give a word offset, rather than a byte offset. • Test the top eight bits of this are clear. • Logically OR this with 0xEA000000 (the Opcode for the branch instruction) to produce the value to be placed in the vector.
Installing the Handler from C (2) • Example for branch method
Installing the Handler from C (3) • Load PC method Steps 1, 2, and 3 are the same as branch method. 4. Logically OR this with 0xE59FF000 (the Opcode for LDR pc, [pc, #offset]) to produce the value to be placed in the vector. 5. Push the address of the handler into the storage location • Example
SWI Handlers • ARM SWI instruction • Work to be done by the handler • First load the SWI instruction into a register by LDR r0, [lr, # -4] • Why? SWI being executed PC-8 INST-1 decoded PC-4 INST-2 fetched PC • Obtain the SWI number by BIC r0, r0, #0xFF000000
SWI Handlers in Assembly Language • According to the value in r0, jump to the corresponding handler.
SWI Handlers in C and Assembly Lang. • Add the following line to the SWI_handler routine in page 46. BL C_SWI_handler
Using SWIs in Supervisor Mode • Must store lr_svc and spsr_svc
Calling SWIs from an Application (1) • Use __swi directive. This allows a SWI to be compiled inline, without overhead, if • Any arguments are passed in r0-r3 only, and • Any results are returned in r0-r3 only. • If more than four results are returned, we have to use a struct to store the results and use the _ _value_in_regs directive.