Overview
========
The contents of this directory are as follows:

1) vfp_support

   Contains the user-modifiable portions of the VFP support code.
   Libraries are supplied as part of RVDS.

2) vfp_init

   Contains code to enable the VFP and setup the system to use the
   VFP support code

3) main.c

   A simple example application. This carries out three floating 
   point operations, the first two of which will be executed by the 
   VFP hardware, the other uses a denormalized number and
   will therefore bounce to the VFP support code to handle. This 
   provides a simple test that the VFP support code has been 
   successfully integrated into a system.

4) build1...build7

   Contain different build variants of the example application.

5) util
   
   Provides various utility files for assisting in configuration
   of the debug system when using VFP. These are described in
   section 5 of the application note.
   
6) AN133_VFPwithRVDS.pdf

   This applications note describes the VFP support code in detail.



Building the VFP support code and example application
=====================================================

Configuration
-------------
Before building the code (using the supplied makefiles) you
will first of all need to set the CPU and VFP that is being
used in your system. To do this open the file settings.txt
and change the VFP_VER and CORE values as appropriate. You may
also wish to change the FP, DEBUG and OPT settings too. Note 
that build 6 does not use the FP setting and uses --fpmode std.

If you do not have a make tool available, then a build.bat file
is supplied for each build variant of the example application.
The build.bat file will need to be edited in order to use your
required build options.

Build the VFP support code
--------------------------
You will now need to build the VFP support code. To do this,
go into the vfp_support subdirectory and use either the makefile
or build.bat (remembering to change the build options if 
necessary). This will create a library that can be used when 
building your application code.

Building the example application
--------------------------------
The example application makes use of four predefines to control
how it is built.

PATCH_UNDEF_VECTOR
- If true, then the function Install_VFPHandler() is included in
  the application to poke a branch instruction to the support 
  code into the undefined instruction entry of the vector table 
  (as described in section 3.2 of the application note).
- If false, then it is assumed that this function is not required
  and initialisation code will install the VFP support code 
  (using scatterloading).

WANT_CACHE_FLUSH
- Only available if also using PATCH_UNDEF_VECTOR.
- Only necessary if caches are enabled in the system.
- If true, the caches are cleaned after patching the vector table to 
  ensure coherency.
- If false then it is assumed that caches do not need to be cleaned
  as they are not used in the system.

SETUP_UNDEF_STACK
- If true, then the function Setup_Undef_Stack() is included in
  the application to set the stack up (as described in section
  3.3 of the application note).
- If false then it is assumed that this function is not required
  and initialisation code will set up some stack space for
  undefined mode.

INIT_CM10rev0_VFP
- If true, then the function CM_VFP_enable() is included in the
  application to enable the VFP hardware externally to the VFP
  itself (as described in section 3.4 of the application note).
  This will normally only be required for Integrator/CM10200
  (ARM1020T based).
- If false, then it is assumed that this function is not required
  and the VFP does not need to be enabled in this fashion.

Each of the builds of the example application makes use of a 
different combination of these predefines. Each build can be
built using the makefile or build.bat file contained within its
subdirectory. Note that you will need to ensure that you have
built the VFP support code before carrying out any builds of the 
example application.

Predefines are case sensitive.


Build descriptions
------------------

Builds 1-3 make use of different predefine/scatterloading combinations
Builds 4&5 are fully embedded versions for Integrator/AP. Build 4
implements a one region heap/stack model, build 5 implements a two
region model.
Build 6 is a demonstration of RunFast mode (no VFP library required)
Build 7 is a fully embedded version for the Versatile PB926EJ-S platform

Providing the correct processor and predefines are set in the settings 
file (when using makefiles) or in the build.bat files the examples will 
run on development boards as follows:

Integrator - builds 1-6 can be run
Versatile - builds 1,2,3,6 and 7 can be run

If compiled with fpmode ieee_full all builds will return the correct 
answers in the example application except build 6 in which the 
subnormal calculation will be flushed to zero so will return 0.

If the application stops after the second calculation undefined 
vector catch may need to be turned off to allow the application to
bounce to the support code.

Build 1
-------
Built with predefines PATCH_UNDEF_VECTOR and SETUP_UNDEF_STACK.
Suitable for running on a suitably configured ARMulator or on
an Integrator/CM with VFP (eg CM10200E). Note that if you wish to
run on an Integrator/CM10200 then you will need to add the 
predefine INIT_CM10rev0_VFP.

The application code is built to load and execute at the default
linker address of 0x8000. The application heap is placed at its
default location of directly after the application RW and ZI data. 
The application stack is also placed at its default location. 
For ARMulator, this will be as set up in the peripheral.ami file. 
For AXD with Multi-ICE, this will be at the address provided by 
AXD's internal variable $top_of_memory.  For RVD with Multi-ICE, 
this will be at the address provided by RVD's internal variable 
top_of_memory.

Build 2
-------
This is built with the predefine SETUP_UNDEF_STACK. Scatterloading
is used to set up the vector table. This build is suitable for 
running on a suitably configured ARMulator or on an Integrator/CM
with VFP (eg CM10200E). Again add the predefine INIT_CM10rev0_VFP
if appropriate.

The application code is built to load at 0x80000 (512KB). The
main part of the application will also execute at this address,
but the vector table will be copied down to address 0x0 by the
scatter initialization code in the C library. The RW/ZI data is
located during initialization to address 0x10000 (64KB).

The application heap is placed directly after the application
RW/ZI data. The application stack is placed at 0x40000 (256KB).
This is done in the function __user_initial_stackheap() provided 
in retarget.c.

Build 3
-------
This is built without predefines (though you may need to add the
predefine INIT_CM10rev0_VFP if appropriate). Scatterloading is 
used to setup the vector table and the addresses of the stacks
and heap.

The application code is built to load at 0x80000 (512KB). The
main part of the application will also execute at this address,
but the vector table will be copied down to address 0x0 by the
scatter initialization code in the C library. The RW/ZI data is
located during initialization to address 0x10000 (64KB).

The application heap is located using the execution region HEAP
in the scatter description file. The address of this is used in
the function __user_initial_stackheap() provided in retarget.c

The stacks for all modes are placed sequentially by init.s.
The start address for these stacks is located using the execution
region STACKS in the scatter description file. The function 
__user_initial_stackheap() provided in retarget.c leaves the
application mode stack unchanged from that setup in init.s.


Build 4
-------
This is built without predefines (though you may need to add the 
predefine INIT_CM10rev0_VFP if appropriate). Scatterloading is used to 
setup the vector table and the addresses of the stacks and heap.

The application code is built to load at 0x24000000 so that it can
be programmed into Flash on an Integrator/AP motherboard with
a suitable Integrator/CM mounted on it.

The main part of the application will also execute at this address,
but the vector table will be copied down to address 0x0 by the
scatter initialization code in the C library. The RW/ZI data is
located during initialization immediately above the vector table.

The application heap is located using the execution region HEAP
in the scatter description file. The address of this is used in
the function __user_initial_stackheap() provided in retarget.c

The stacks for all modes are placed sequentially by init.s.
The start address for these stacks is located using the execution
region STACKS in the scatter description file. The function 
__user_initial_stackheap() provided in retarget.c leaves the
application mode stack unchanged from that setup in init.s.

Application output is sent to the serial port rather than using
the debugger's semihosting functionality.

Build 5
-------
This is built without predefines (though you may need to add the
predefine INIT_CM10rev0_VFP if appropriate). Scatterloading is used to
setup the vector table and the addresses of the stacks and heap.

The application code is built to load at 0x24000000 so that it can
be programmed in to Flash on an Integrator/AP motherboard with
a suitable Integrator/CM mounted on it.

The main part of the application will also execute at this address,
but the vector table will be copied down to address 0x0 by the
scatter initialization code in the c library. The RW/ZI data is
located during initialization immediately above the vector table.

The heap and stacks are implemented as a two region model (the heap
and stacks can be located in different places and are checked against
limits rather than each other). The scatter file places the heap 
directly above the RW/ZI data and allocates a space in memory of
size 0x3000. The stacks are placed at address 0x40000 and are allocated
a memory of size -0x3000 implying that the space is located below
the stack pointer allowing it to grow downwards. The addresses
bounding these regions are used by the function __user_initial_stackheap().

The individual mode stacks are setup within the stacks regions by
init.s

Application output is sent to the serial port rather than using
the debugger's semihosting functionality.

Build 6
-------
This build makes use of cutdown fpinit.c and runfast.s files
to demonstrate runfast mode. Undefined mode does not need to be
setup as it is not used in this configuration and support code
other than these two files is not required. The predefine
INIT_CM10rev0 may need to be added if appropriate (i.e for Integrator/
CM10200).

Build 7
-------
This build is altered to run on the Versatile development board with
an ARM926EJ-S processor. There is a HOW TO in the build folder giving
a brief description of one way of programming the example to flash.

The application code is built to load at 0x34000000 so that it can
be programmed into NOR flash on the Versatile board.

The main part of the application will execute at 0x34000000, but the
vector table will be copied down to address 0x0 by the scatter
initialization code in the c library. The RW/ZI data is located
during initializations immediately above the vector table.

The heap and stacks are implemented as a two region model (the heap
and stacks can be located in different places and are checked against
limits rather than each other). The scatter file places the heap 
directly above the RW/ZI data and allocates a space in memory of
size 0x3000. The stacks are placed at address 0x40000 and are allocated
a memory of size -0x3000 implying that the space is located below
the stack pointer allowing it to grow downwards. The addresses
bounding these regions are used by the function __user_initial_stackheap().

The individual mode stacks are setup within the stacks regions by
init.s

Application output is sent to the serial port rather than using
the debugger's semihosting functionality.
