A variant port can be a fairly limited job, but can also
require quite a lot of work. A variant HAL describes how a specific
CPU variant differs from the generic CPU architecture. The variant HAL
can re-define cache, MMU, interrupt, and other features which override
the default implementation provided by the architecture HAL.
Doing a variant port requires a preexisting architecture HAL port. It
is also likely that a platform port will have to be done at the same
time if it is to be tested.
The easiest way to make a new variant HAL is simply to copy an
existing variant HAL and change all the files to match the new
variant. If this is the first variant for an architecture, it may be
hard to decide which parts should be put in the variant - knowledge of
other variants of the architecture is required.
Looking at existing variant HALs (e.g., MIPS tx39, tx49) may be a
help - usually things such as caching, interrupt and exception
handling differ between variants. Initialization code, and code for
handling various core components (FPU, DSP, MMU, etc.) may also differ
or be missing altogether on some variants. Linker scripts may also require
specific variant versions.
Note: Some CPU variants may require specific compiler
support. That support must be in place before you can undertake the
eCos variant port.
The CDL in a variant HAL tends to depend on the exact functionality
supported by the variant. If it implements some of the devices
described in the platform HAL, then the CDL for those will be here
rather than there (for example the real-time clock).
There may also be CDL to select options in the architecture HAL to
configure it to a particular architectural variant.
Each variant needs an entry in the ecos.db
file. This is the one for the SH3:
package CYGPKG_HAL_SH_SH3 {
alias { "SH3 architecture" hal_sh_sh3 }
directory hal/sh/sh3
script hal_sh_sh3.cdl
hardware
description "
The SH3 (SuperH 3) variant HAL package provides generic
support for SH3 variant CPUs."
}
As you can see, it is very similar to the platform entry.
The variant CDL file will contain a package entry named for the
architecture and variant, matching the package name in the
ecos.db file. Here is the initial part of the
MIPS VR4300 CDL file:
cdl_package CYGPKG_HAL_MIPS_VR4300 {
display "VR4300 variant"
parent CYGPKG_HAL_MIPS
implements CYGINT_HAL_MIPS_VARIANT
hardware
include_dir cyg/hal
define_header hal_mips_vr4300.h
description "
The VR4300 variant HAL package provides generic support
for this processor architecture. It is also necessary to
select a specific target platform HAL package."
This defines the package, placing it under the MIPS architecture
package in the hierarchy. The implements line
indicates that this is a MIPS variant. The architecture package uses
this to check that exactly one variant is configured in.
The variant defines some options that cause the architecture HAL to
configure itself to support this variant.
These tell the architecture that this is a 64 bit MIPS architecture,
that it has a floating point unit, and that we are going to use it in
64 bit mode rather than 32 bit mode.
The CDL file finishes off with some build options.
The define_proc causes the architecture
configuration file to be included into the configuration file for the
variant. The compile causes the single source file
for this variant, var_misc.c to be compiled. The
make command emits makefile rules to combine the
linker script with the .ldi file to generate
target.ld. Finally, in the MIPS HALs, the main
linker script is defined in the variant, rather than the architecture,
so CYGBLD_LINKER_SCRIPT is defined here.
The main area where the variant is likely to be involved is in cache
support. Often the only thing that distinguishes one CPU variant from
another is the size of its caches.
In architectures such as the MIPS and PowerPC where cache instructions
are part of the ISA, most of the actual cache operations are
implemented in the architecture HAL. In this case the variant HAL only
needs to define the cache dimensions. The following are the cache
dimensions defined in the MIPS VR4300 variant
var_cache.h.
// Data cache
#define HAL_DCACHE_SIZE (8*1024) // Size of data cache in bytes
#define HAL_DCACHE_LINE_SIZE 16 // Size of a data cache line
#define HAL_DCACHE_WAYS 1 // Associativity of the cache
// Instruction cache
#define HAL_ICACHE_SIZE (16*1024) // Size of cache in bytes
#define HAL_ICACHE_LINE_SIZE 32 // Size of a cache line
#define HAL_ICACHE_WAYS 1 // Associativity of the cache
#define HAL_DCACHE_SETS (HAL_DCACHE_SIZE/(HAL_DCACHE_LINE_SIZE*HAL_DCACHE_WAYS))
#define HAL_ICACHE_SETS (HAL_ICACHE_SIZE/(HAL_ICACHE_LINE_SIZE*HAL_ICACHE_WAYS))
Additional cache macros, or overrides for the defaults, may also
appear in here. While some architectures have instructions for
managing cache lines, overall enable/disable operations may be handled
via variant specific registers. If so then
var_cache.h should also define the
HAL_XCACHE_ENABLE() and
HAL_XCACHE_DISABLE() macros.
If there are any generic features that the variant does not support
(cache locking is a typical example) then
var_cache.h may need to disable definitions of
certain operations. It is architecture dependent exactly how this is
done.