mirror of
https://git.rtems.org/rtems-docs/
synced 2025-06-03 18:19:24 +08:00
373 lines
14 KiB
ReStructuredText
373 lines
14 KiB
ReStructuredText
M68xxx and Coldfire Specific Information
|
||
########################################
|
||
|
||
This chapter discusses the Freescale (formerly Motorola) MC68xxx
|
||
and Coldfire architectural dependencies. The MC68xxx family has a
|
||
wide variety of CPU models within it based upon different CPU core
|
||
implementations. Ignoring the Coldfire parts, the part numbers for
|
||
these models are generally divided into MC680xx and MC683xx. The MC680xx
|
||
models are more general purpose processors with no integrated peripherals.
|
||
The MC683xx models, on the other hand, are more specialized and have a
|
||
variety of peripherals on chip including sophisticated timers and serial
|
||
communications controllers.
|
||
|
||
**Architecture Documents**
|
||
|
||
For information on the MC68xxx and Coldfire architecture, refer to the following documents available from Freescale website (:file:`http//www.freescale.com/`):
|
||
|
||
- *M68000 Family Reference, Motorola, FR68K/D*.
|
||
|
||
- *MC68020 User’s Manual, Motorola, MC68020UM/AD*.
|
||
|
||
- *MC68881/MC68882 Floating-Point Coprocessor User’s Manual,
|
||
Motorola, MC68881UM/AD*.
|
||
|
||
CPU Model Dependent Features
|
||
============================
|
||
|
||
This section presents the set of features which vary
|
||
across m68k/Coldfire implementations that are of importance to RTEMS.
|
||
The set of CPU model feature macros are defined in the file``cpukit/score/cpu/m68k/m68k.h`` based upon the particular CPU
|
||
model selected on the compilation command line.
|
||
|
||
BFFFO Instruction
|
||
-----------------
|
||
|
||
The macro ``M68K_HAS_BFFFO`` is set to 1 to indicate that
|
||
this CPU model has the bfffo instruction.
|
||
|
||
Vector Base Register
|
||
--------------------
|
||
|
||
The macro ``M68K_HAS_VBR`` is set to 1 to indicate that
|
||
this CPU model has a vector base register (vbr).
|
||
|
||
Separate Stacks
|
||
---------------
|
||
|
||
The macro ``M68K_HAS_SEPARATE_STACKS`` is set to 1 to
|
||
indicate that this CPU model has separate interrupt, user, and
|
||
supervisor mode stacks.
|
||
|
||
Pre-Indexing Address Mode
|
||
-------------------------
|
||
|
||
The macro ``M68K_HAS_PREINDEXING`` is set to 1 to indicate that
|
||
this CPU model has the pre-indexing address mode.
|
||
|
||
Extend Byte to Long Instruction
|
||
-------------------------------
|
||
|
||
The macro ``M68K_HAS_EXTB_L`` is set to 1 to indicate that this CPU model
|
||
has the extb.l instruction. This instruction is supposed to be available
|
||
in all models based on the cpu32 core as well as mc68020 and up models.
|
||
|
||
Calling Conventions
|
||
===================
|
||
|
||
The MC68xxx architecture supports a simple yet effective call and
|
||
return mechanism. A subroutine is invoked via the branch to subroutine
|
||
(``bsr``) or the jump to subroutine (``jsr``) instructions.
|
||
These instructions push the return address on the current stack.
|
||
The return from subroutine (``rts``) instruction pops the return
|
||
address off the current stack and transfers control to that instruction.
|
||
It is is important to note that the MC68xxx call and return mechanism does
|
||
not automatically save or restore any registers. It is the responsibility
|
||
of the high-level language compiler to define the register preservation
|
||
and usage convention.
|
||
|
||
Calling Mechanism
|
||
-----------------
|
||
|
||
All RTEMS directives are invoked using either a ``bsr`` or ``jsr``
|
||
instruction and return to the user application via the rts instruction.
|
||
|
||
Register Usage
|
||
--------------
|
||
|
||
As discussed above, the ``bsr`` and ``jsr`` instructions do not
|
||
automatically save any registers. RTEMS uses the registers D0, D1,
|
||
A0, and A1 as scratch registers. These registers are not preserved by
|
||
RTEMS directives therefore, the contents of these registers should not
|
||
be assumed upon return from any RTEMS directive.
|
||
|
||
Parameter Passing
|
||
-----------------
|
||
|
||
RTEMS assumes that arguments are placed on the current stack before
|
||
the directive is invoked via the bsr or jsr instruction. The first
|
||
argument is assumed to be closest to the return address on the stack.
|
||
This means that the first argument of the C calling sequence is pushed
|
||
last. The following pseudo-code illustrates the typical sequence used
|
||
to call a RTEMS directive with three (3) arguments:
|
||
.. code:: c
|
||
|
||
push third argument
|
||
push second argument
|
||
push first argument
|
||
invoke directive
|
||
remove arguments from the stack
|
||
|
||
The arguments to RTEMS are typically pushed onto the stack using a move
|
||
instruction with a pre-decremented stack pointer as the destination.
|
||
These arguments must be removed from the stack after control is returned
|
||
to the caller. This removal is typically accomplished by adding the
|
||
size of the argument list in bytes to the current stack pointer.
|
||
|
||
Memory Model
|
||
============
|
||
|
||
The MC68xxx family supports a flat 32-bit address
|
||
space with addresses ranging from 0x00000000 to 0xFFFFFFFF (4
|
||
gigabytes). Each address is represented by a 32-bit value and
|
||
is byte addressable. The address may be used to reference a
|
||
single byte, word (2-bytes), or long word (4 bytes). Memory
|
||
accesses within this address space are performed in big endian
|
||
fashion by the processors in this family.
|
||
|
||
Some of the MC68xxx family members such as the
|
||
MC68020, MC68030, and MC68040 support virtual memory and
|
||
segmentation. The MC68020 requires external hardware support
|
||
such as the MC68851 Paged Memory Management Unit coprocessor
|
||
which is typically used to perform address translations for
|
||
these systems. RTEMS does not support virtual memory or
|
||
segmentation on any of the MC68xxx family members.
|
||
|
||
Interrupt Processing
|
||
====================
|
||
|
||
Discussed in this section are the MC68xxx’s interrupt response and
|
||
control mechanisms as they pertain to RTEMS.
|
||
|
||
Vectoring of an Interrupt Handler
|
||
---------------------------------
|
||
|
||
Depending on whether or not the particular CPU supports a separate
|
||
interrupt stack, the MC68xxx family has two different interrupt handling
|
||
models.
|
||
|
||
Models Without Separate Interrupt Stacks
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Upon receipt of an interrupt the MC68xxx family members without separate
|
||
interrupt stacks automatically perform the following actions:
|
||
|
||
- To Be Written
|
||
|
||
Models With Separate Interrupt Stacks
|
||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||
|
||
Upon receipt of an interrupt the MC68xxx family members with separate
|
||
interrupt stacks automatically perform the following actions:
|
||
|
||
- saves the current status register (SR),
|
||
|
||
- clears the master/interrupt (M) bit of the SR to
|
||
indicate the switch from master state to interrupt state,
|
||
|
||
- sets the privilege mode to supervisor,
|
||
|
||
- suppresses tracing,
|
||
|
||
- sets the interrupt mask level equal to the level of the
|
||
interrupt being serviced,
|
||
|
||
- pushes an interrupt stack frame (ISF), which includes
|
||
the program counter (PC), the status register (SR), and the
|
||
format/exception vector offset (FVO) word, onto the supervisor
|
||
and interrupt stacks,
|
||
|
||
- switches the current stack to the interrupt stack and
|
||
vectors to an interrupt service routine (ISR). If the ISR was
|
||
installed with the interrupt_catch directive, then the RTEMS
|
||
interrupt handler will begin execution. The RTEMS interrupt
|
||
handler saves all registers which are not preserved according to
|
||
the calling conventions and invokes the application’s ISR.
|
||
|
||
A nested interrupt is processed similarly by these
|
||
CPU models with the exception that only a single ISF is placed
|
||
on the interrupt stack and the current stack need not be
|
||
switched.
|
||
|
||
The FVO word in the Interrupt Stack Frame is examined
|
||
by RTEMS to determine when an outer most interrupt is being
|
||
exited. Since the FVO is used by RTEMS for this purpose, the
|
||
user application code MUST NOT modify this field.
|
||
|
||
The following shows the Interrupt Stack Frame for
|
||
MC68xxx CPU models with separate interrupt stacks:
|
||
|
||
+----------------------+-----+
|
||
| Status Register | 0x0 |
|
||
+----------------------+-----+
|
||
| Program Counter High | 0x2 |
|
||
+----------------------+-----+
|
||
| Program Counter Low | 0x4 |
|
||
+----------------------+-----+
|
||
| Format/Vector Offset | 0x6 |
|
||
+----------------------+-----+
|
||
|
||
|
||
CPU Models Without VBR and RAM at 0
|
||
-----------------------------------
|
||
|
||
This is from a post by Zoltan Kocsi <zoltan@bendor.com.au> and is
|
||
a nice trick in certain situations. In his words:
|
||
|
||
I think somebody on this list asked about the interupt vector handling
|
||
w/o VBR and RAM at 0. The usual trick is to initialise the vector table
|
||
(except the first 2 two entries, of course) to point to the same location
|
||
BUT you also add the vector number times 0x1000000 to them. That is,
|
||
bits 31-24 contain the vector number and 23-0 the address of the common
|
||
handler. Since the PC is 32 bit wide but the actual address bus is only
|
||
24, the top byte will be in the PC but will be ignored when jumping onto
|
||
your routine.
|
||
|
||
Then your common interrupt routine gets this info by loading the PC
|
||
into some register and based on that info, you can jump to a vector in
|
||
a vector table pointed by a virtual VBR:
|
||
.. code:: c
|
||
|
||
//
|
||
// Real vector table at 0
|
||
//
|
||
.long initial_sp
|
||
.long initial_pc
|
||
.long myhandler+0x02000000
|
||
.long myhandler+0x03000000
|
||
.long myhandler+0x04000000
|
||
...
|
||
.long myhandler+0xff000000
|
||
//
|
||
// This handler will jump to the interrupt routine of which
|
||
// the address is stored at VBR[ vector_no ]
|
||
// The registers and stackframe will be intact, the interrupt
|
||
// routine will see exactly what it would see if it was called
|
||
// directly from the HW vector table at 0.
|
||
//
|
||
.comm VBR,4,2 // This defines the 'virtual' VBR
|
||
// From C: extern void \*VBR;
|
||
myhandler: // At entry, PC contains the full vector
|
||
move.l %d0,-(%sp) // Save d0
|
||
move.l %a0,-(%sp) // Save a0
|
||
lea 0(%pc),%a0 // Get the value of the PC
|
||
move.l %a0,%d0 // Copy it to a data reg, d0 is VV??????
|
||
swap %d0 // Now d0 is ????VV??
|
||
and.w #0xff00,%d0 // Now d0 is ????VV00 (1)
|
||
lsr.w #6,%d0 // Now d0.w contains the VBR table offset
|
||
move.l VBR,%a0 // Get the address from VBR to a0
|
||
move.l (%a0,%d0.w),%a0 // Fetch the vector
|
||
move.l 4(%sp),%d0 // Restore d0
|
||
move.l %a0,4(%sp) // Place target address to the stack
|
||
move.l (%sp)+,%a0 // Restore a0, target address is on TOS
|
||
ret // This will jump to the handler and
|
||
// restore the stack
|
||
(1) If 'myhandler' is guaranteed to be in the first 64K, e.g. just
|
||
after the vector table then that insn is not needed.
|
||
|
||
There are probably shorter ways to do this, but it I believe is enough
|
||
to illustrate the trick. Optimisation is left as an exercise to the
|
||
reader :-)
|
||
|
||
Interrupt Levels
|
||
----------------
|
||
|
||
Eight levels (0-7) of interrupt priorities are
|
||
supported by MC68xxx family members with level seven (7) being
|
||
the highest priority. Level zero (0) indicates that interrupts
|
||
are fully enabled. Interrupt requests for interrupts with
|
||
priorities less than or equal to the current interrupt mask
|
||
level are ignored.
|
||
|
||
Although RTEMS supports 256 interrupt levels, the
|
||
MC68xxx family only supports eight. RTEMS interrupt levels 0
|
||
through 7 directly correspond to MC68xxx interrupt levels. All
|
||
other RTEMS interrupt levels are undefined and their behavior is
|
||
unpredictable.
|
||
|
||
Default Fatal Error Processing
|
||
==============================
|
||
|
||
The default fatal error handler for this architecture disables processor
|
||
interrupts to level 7, places the error code in D0, and executes a``stop`` instruction to simulate a halt processor instruction.
|
||
|
||
Symmetric Multiprocessing
|
||
=========================
|
||
|
||
SMP is not supported.
|
||
|
||
Thread-Local Storage
|
||
====================
|
||
|
||
Thread-local storage is supported.
|
||
|
||
Board Support Packages
|
||
======================
|
||
|
||
System Reset
|
||
------------
|
||
|
||
An RTEMS based application is initiated or re-initiated when the MC68020
|
||
processor is reset. When the MC68020 is reset, the processor performs
|
||
the following actions:
|
||
|
||
- The tracing bits of the status register are cleared to
|
||
disable tracing.
|
||
|
||
- The supervisor interrupt state is entered by setting the
|
||
supervisor (S) bit and clearing the master/interrupt (M) bit of
|
||
the status register.
|
||
|
||
- The interrupt mask of the status register is set to
|
||
level 7 to effectively disable all maskable interrupts.
|
||
|
||
- The vector base register (VBR) is set to zero.
|
||
|
||
- The cache control register (CACR) is set to zero to
|
||
disable and freeze the processor cache.
|
||
|
||
- The interrupt stack pointer (ISP) is set to the value
|
||
stored at vector 0 (bytes 0-3) of the exception vector table
|
||
(EVT).
|
||
|
||
- The program counter (PC) is set to the value stored at
|
||
vector 1 (bytes 4-7) of the EVT.
|
||
|
||
- The processor begins execution at the address stored in
|
||
the PC.
|
||
|
||
Processor Initialization
|
||
------------------------
|
||
|
||
The address of the application’s initialization code should be stored in
|
||
the first vector of the EVT which will allow the immediate vectoring to
|
||
the application code. If the application requires that the VBR be some
|
||
value besides zero, then it should be set to the required value at this
|
||
point. All tasks share the same MC68020’s VBR value. Because interrupts
|
||
are enabled automatically by RTEMS as part of the context switch to the
|
||
first task, the VBR MUST be set by either RTEMS of the BSP before this
|
||
occurs ensure correct interrupt vectoring. If processor caching is
|
||
to be utilized, then it should be enabled during the reset application
|
||
initialization code.
|
||
|
||
In addition to the requirements described in the
|
||
Board Support Packages chapter of the Applications User’s
|
||
Manual for the reset code which is executed before the call to
|
||
initialize executive, the MC68020 version has the following
|
||
specific requirements:
|
||
|
||
- Must leave the S bit of the status register set so that
|
||
the MC68020 remains in the supervisor state.
|
||
|
||
- Must set the M bit of the status register to remove the
|
||
MC68020 from the interrupt state.
|
||
|
||
- Must set the master stack pointer (MSP) such that a
|
||
minimum stack size of MINIMUM_STACK_SIZE bytes is provided for
|
||
the initialize executive directive.
|
||
|
||
- Must initialize the MC68020’s vector table.
|
||
|
||
.. COMMENT: Copyright (c) 2014 embedded brains GmbH. All rights reserved.
|
||
|