TOC PREV NEXT INDEX DOC LIST MASTER INDEX



TDM Configuration Parameters

This chapter includes:


Introduction

Apex provides a full-featured, source-level, symbolic cross debugger, which implements the complete set of functions provided by the host version of the debugger. The debugger can be interfaced to the target either by an In-Circuit Emulator or by TDM. In addition to its debugging capabilities, TDM supplies the "channel" over which IO from the target to the host is implemented.

While TDM is executing, interrupts are disabled. When the target board executes other code (the kernel or application code), the interrupt mask is under the control of this code. This means that TDM has interrupts disabled while it is performing debugging and IO functions.

This section contains only the target-processor specific configuration information for users who wish to customize their configuration or create a new configuration. If you are using one of the board support packages supplied by Rational, use the configuration instructions in "Getting Started" in the Programming with Rational Apex.


TDM Configuration Files

The TDM configuration files contain the parameters that enable TDM to run as a stand-alone, bootable program on the target system.

The following sections provide details about each of the configuration parameters. The configuration parameters are dependent on your target processor. A separate discussion is provided for each of the supported Apex targets. Use the following list to access the information for your target processor.


PowerPC TDM Configuration Parameters

Policy/Switches file for the tdm_conf.ss subsystem.

The context switches for the views in the tdm_conf.ss subsystem have the following additional values:

The Board_Common.sw file contains all of the switches that are common to the BSP. The RUNTIMES switch is used to identify the archive libraries that are required to support TDM as opposed to a user program.

The linker description file is located locally in the tdm_conf.ss view.

Configuration Components

The TDM configuration components are in the v_tdm_conf.1.ada and v_tdm_conf.2.ada files:

Each of these components is discussed in detail below. To find any one of these components in the source files, search for the title string of the desired component. In the source file, the code for each component begins with a line similar to the following:

TDM Test Message

TDM writes this string to the serial port in response to reading Delete Control-d (16#7F#, 16#04#). This verifies that TDM is working and is used to identify which version of TDM is running.

Startup_Table Structure

The constant Startup_Table is declared in the body of this package. This aggregate is used to provide parameters to V_Start_Program, TDM's program startup routine. The table must be declared a constant.

The declaration of Startup_Table_T, the type of Startup_Table is in V_Tdm_Conf_I. The record fields and their interpretations follow.

Startup_Stack_Base

Startup_Stack_Base specifies the start address for the stack used during TDM initialization. The startup stack grows from this address towards low memory.

The startup stack is used when TDM is initialized and up until the first application program is loaded and executed. After this point, the only way to get back to TDM is to use a trap or interrupt, and TDM uses its own internal stack when entered this way.

Normally, the location of TDM's startup stack should be the same as the kernel program's startup stack, pointing to the byte just after the last byte of RAM. If your RAM goes from 0 to 1FF_FFFF (32 megabytes), then Startup_Stack_Base should be 16#200_0000#.

TDM requires less than 512 bytes of startup stack space.

Hardware_Initialization

Hardware_Initialization specifies the address of the routine to be called to initialize the system's hardware.

This routine is invoked prior to initializing TDM. The default value for Hardware_Initialization is the address of the default hardware initialization routine, V_Hardware_Initialization. For more information, see V_Immediate_Initialization and V_Hardware_Initialization Routines.

The value assigned to each component in the system startup table must be a literal, an address constant, or a value returned by the address attribute ('Address).

Memory_Map_Table Structure

The constant Memory_Map_Table is declared in the body of this package, and should be modified to indicate the memory layout for your board. TDM restricts memory access to only those locations encompassed by the memory partitions defined in this table. The declaration of this record's type is in the package V_Mem_Conf. The address of Memory_Map_Table should be assigned to the parameter Memory_Map_Image in the configuration table.

TDM Stack

An array is declared here to reserve space for TDM's stack area. TDM switches to this stack when entered. Space is also reserved for the initial user stack, which TDM sets up for the user program to use until it has established its own stack

Configure the sizes of these stacks by changing the constants Tdm_Stack_Size and Tdm_User_Stack_Size.

Interrupt Vector Table Structure

A software interrupt vector table is maintained in this file. Note that the kernel version of the interrupt vector table and TDM's must be compatible. The kernel is allowed to vector unhandled exceptions from its version of the table down to TDM using processor exception zero

Configuration_Table Structure

Configuration_Table is the record that describes the target system to TDM.

The parameters are grouped into six categories: stack, trap, memory map, TDM entry and return, miscellaneous, and interrupt configuration routines. Memory that can be accessed by TDM and the host debugger are defined by the memory map parameters. The Setup_Tdm_Entry_Callout and Setup_Tdm_Return_Callout parameters point to user-configurable routines that are used to implement any actions that must be performed whenever TDM is entered or exited.

Tdm_Stack_Base

Tdm_Stack_Base specifies the start address for the TDM stack. The TDM stack grows from this address towards low memory.

Tdm_Stack_Size

The size in bytes of the TDM stack

Tdm_User_Stack_Base

Tdm_User_Stack_Base specifies the start address for initial user stack. This stack is set up by TDM for the user program to use until it has established its own stack.

Tdm_User_Stack_Size

The size in bytes of the initial user stack.

Tdm_Software_Trap

Tdm_Software_Trap is the software trap used for entering TDM to have it perform a Cross_Io, Simple_Io or Halt service. Normally, Tdm_Software_Trap is set to Tdm_Trap.

Memory_Map_Size

Memory_Map_Size indicates the number of memory partitions. [Default: Memory_Map_Table'Length].

Memory_Map_Image

Memory_Map_Image indicates the starting address of the memory map table. The default Memory_Map_Image is Memory_Map_Table'Address. Memory_Map_Image can be set to System.Memory_Adress(0) to enable the entire virtual address space (16#0#..16#FFFF_FFFF#) to be accessible by TDM and the host debugger.

Setup_Tdm_Entry_Callout

Setup_Tdm_Entry_Callout is the address of the routine called to perform any operations that must occur upon entry to TDM. The routine is called immediately after TDM calls Disable_Get_Interrupt, which occurs when TDM is entered by a user application. [Default: V_Setup.Setup_Tdm_Entry'Address].

Setup_Tdm_Return_Callout

Setup_Tdm_Return_Callout is the Address of the routine called just before TDM starts execution of the application program. [Default: V_Setup.Setup_Tdm_Return'Address].

Test_Message_Size and Test_Message_Image

Test_Message_Size and Test_Message_Image define the TDM test message string.

Passthru_Callout

Passthru_Callout is the address of the routine called to scan, parse and execute a debugger pass command. See V_Passthru Routine.

Kernel_Start_Enabled and Kernel_Start_Address

If Kernel_Start_Enabled is True, at the conclusion of TDM, instead of waiting for a command from the host debugger, TDM jumps to the kernel program's starting address specified by Kernel_Start_Address.

When True, the kernel and user programs must already be loaded on the target.

Initial development begins with TDM downloading and debugging the kernel and user programs. As the application nears completion, the kernel and user programs join TDM as being loaded into ROM. Since the programs are already downloaded, TDM can transfer control to the kernel and user programs with no intervention by the host debugger. Before jumping to the kernel, TDM installs its exception/interrupt vectors, initializes the UART or ethernet and prepares itself to enter the application. The kernel and user programs replace the exception/interrupt vectors they handle. Control is only transferred back to TDM when the CPU generates an exception (such as address error) or receives an external interrupt (such as Control-C interrupt) for a vector with a handler in TDM that wasn't replaced by the kernel or user program. Using the Control-C interrupt, the host debugger can sync up with the application at a later time.

Memory_Write_Callout

Memory_Write_Callout is the address of the routine to be called when TDM is writing memory for purposes of downloading or setting breakpoints. This routine is defined in V_Mem_Support Routine.

Memory_Read_Callout

Memory_Read_Callout is the address of the routine to be called when TDM is reading memory for purposes of examining memory or memory mapped I/O. This routine is defined in V_Mem_Support Routine.

Memory_Fill_Callout

Memory_Fill_Callout is the address of the routine to be called when TDM is filling memory. This routine is defined in V_Mem_Support Routine.

Memory_Search_Callout

Memory_Search_Callout is the address of the routine to be called when TDM is searching memory. This routine is defined in V_Mem_Support Routine.

Reset_Tdm_Callout

Address of the procedure to call when TDM is reset.

Interrupt_Vector_Base

Interrupt_Vector_Base is the address of the Interrupt_Vector_Table. [Default: Interrupt_Vector_Table'Address]

Interrupt_Vector_Size

Interrupt_Vector_Size is the number of entries in the Interrupt_Vector_Table. [Default: Interrupt_Vector_Table'Length].

Hardware_Floating_Point

If True, hardware floating point is supported.

Exception Handling Routines

Processor exception handling is handled in the following way:

When exceptions occur, state is saved to certain registers and the processor begins execution at an address (exception vector) predetermined for each exception. The code at these addresses can be found in various e_*.v_exception_*.2.ada files and the location is specified by the linker options file Link.des. Most of these routines branch to V_Interrupt_Save_State. The reset vector branches to __start and the ZERO vector is not a processor exception but a way for the kernel to call down to TDM with a decoded exception.

V_Interrupt_Save_State saves the processor context and then calls V_Decode_Interrupt to call the appropriate handler..

V_Decode_Interrupt looks up the exception handler in the interrupt vector table and calls it. If there is no valid handler in the table, Process_Trap in TDM itself is called to invoke the TDM handler for the exception.

V_Restore_Context Routine

V_Restore_Context restores the processor context after processing an interrupt, trap, or SVC call. It's passed a pointer to the context record which needs to be restored.

The context record is normally created by the V_Interrupt_Save_State routine or by the kernel when branching through the zero vector. It makes it look, to the interrupted code, that nothing had happened (processor state wise). If information needs to be passed back to the interrupted routine (system call), then it is up to the caller of this routine to have initialized the registers in the context accordingly.

This procedure is called by the TDM archive library to restore the context.

V_Immediate_Initialization and V_Hardware_Initialization Routines

V_Immediate_Initialization performs any operations necessary to initialize the hardware prior to referencing RAM.

This routine is called before any RAM is referenced. It performs tasks such as mapping in memory pages, if necessary.

V_Hardware_Initialization performs any operations necessary to initialize the hardware prior to TDM's initialization.

This routine is called before TDM is initialized. This routine must not reference any entities which require elaboration, since it is called before any elaboration takes place.

The address of this routine should be assigned to the parameter Hardware_Initialization in the startup table.

Setup_Tdm_Entry and Setup_Tdm_Return routines

These functions are called by TDM when a user application enters or is resumed (started) from TDM. Code for any operations that are performed when the user application enters TDM or when TDM resumes or starts the user application must be included in the appropriate setup functions.

V_Start_Program Routine

Control is transferred to V_Start_Program to start the TDM program.

Note: V_Start_Program must be entered in supervisor state.

V_Start_Program performs the following actions:

1 . Initializes Machine State Register so that:

2 . Calls V_Immediate_Initialization to perform any initialization that is required before referencing RAM (such as mapping in required memory pages).

3 . Initializes TDM's startup stack.

4 . Calls the V_Hardware_Initialization routine to perform user-specified hardware initialization.

5 . Elaborates the specification and body of V_Tdm_Conf.

6 . Calls the V_Init_Trap_Table routine to initialize TDM's trap table.

7 . Calls the V_Boot routine to initialize TDM data structures and reset serial I/O using V_Serial_Support.Init.

8 . Elaborates the TDM program's packages,

9 . Calls the V_Execute routine to start execution of TDM. If the configuration parameter, Kernel_Start_Enabled is True, V_Execute jumps to the kernel program using the Kernel_Start_Address parameter. Otherwise, TDM waits for and processes commands sent from the host debugger.

Although this routine is included in the V_Tdm_Conf package, it should not be modified.

V_Reset_Tdm Routine

When a program is re-downloaded this routine is called. It is required that this routine re-initialize the processor's exception vector table by copying the exception vector code into the processors exception area. This is because the program being debugged may have written its own exception handling code into this area.

If other initialization is required to put the processor or board into a state that is more like the "reset" state this can be done here as well. This allows the program being run (normally the kernel) to have an environment more like the environment after a reset.

V_Passthru Routine

V_Passthru is called by TDM to scan, parse and execute a debugger pass command. Characters typed after the pass command are passed straight through. V_Passthru is called with the address and length of the string entered after the pass.

To display results, the routine Passthru_Put_Str and Passthru_Put_Chr must be called.

V_Serial_Support Routine

This package contains the routines required for TDM to interface to the target-specific serial I/O hardware. TDM communicates with the host through these routines. You must implement the bodies of these routines with code to drive the serial I/O hardware on your target. The configuration table supplies TDM with the address of each of these routines. See Configuration_Table Structure.


Warning: Do not modify the V_Serial_Support package specification. Modify only the package body.

TDM assumes a synchronous model of serial I/O with the host.

Init performs any initialization required by the target's serial port hardware, including programming the serial I/O ports. Init is called once during the TDM initialization and each time a file download to the target is completed.

Put takes a single parameter: a character represented by an 8-bit byte. Put loops until the serial output port is able to accept the character and then write the character to the port.

Get reads one byte, if available, from the serial input port and returns it as the parameter, b. If no byte is available, Get does not wait but returns immediately. If b contains a byte read from the port, the boolean parameter Got_Byte must be set to True. If no byte is available to be read, Got_Byte must be set to False.

V_Mem_Support Routine

This package provides a way to customize memory accesses made by TDM on behalf of the debugger or apex_execute. If there is hardware on your board that requires specific types of accesses (for example, single byte), these routines can be customized by using code that bases the type of access on the address being accessed.

Read is called by TDM to read memory and send the contents back to the host.

Write is called by TDM to write memory with new contents.

Fill is called by TDM to fill memory with a value.

Search is called by TDM to search memory for a pattern.


MIPS TDM Configuration Parameters

Policy/Switches file for the tdm_conf.ss subsystem.

The context switches for the views in the tdm_conf.ss subsystem have the following additional values:

The Board_Common.sw file contains all of the switches that are common to the BSP. The RUNTIMES switch is used to identify the archive libraries that are required to support the kernel as opposed to a user program.

The linker description file is located locally in the tdm_conf.ss view.

Configuration Components

The TDM configuration components are in the v_tdm_conf.1.ada and v_tdm_conf.2.ada files:

Each of these components is discussed in detail below. To find any one of these components in the source files, search for the title string of the desired component. In the source file, the code for each component begins with a line similar to the following:

TDM Test Message

TDM writes this string to the serial port in response to reading Delete Control-d (16#7f#, 16#04#). This verifies that TDM is working and is used to identify which version of TDM is running.

Startup_Table Structure

The package body v_tdm_conf.2.ada contains the declaration for the startup table.

Startup_Table must be declared as a constant, because the values in the table are used as soon as TDM starts, prior to TDM's elaboration. The value assigned to each field of the Startup_Table must be a literal, an address constant or a value returned by the address attribute ('Address). The table contains two fields, Startup_Stack_Base and Hardware_Initialization.

During initialization, TDM uses the stack with the base address of Startup_Stack_Base. This is the initial value of the stack pointer (register sp) used by TDM. The address you supply must point to the byte after the highest addressed byte of the stack. The stack grows towards low memory and the value in the stack pointer is always decremented before it is used.

To minimize the number of memory addresses used, the value of Startup_Stack_Base must match that of the kernel program's startup stack; the address of the byte just after the last byte of RAM in the system. For example, the default value, 16#8010_0000#, is for a system with one megabyte of RAM, RAM in the address range from 16#8000_0000# to 16#800F_FFFF#.

TDM requires less than 4096 bytes of startup stack space.

Hardware_Initialization is the address of the routine called to initialize the target system hardware. The default value is the address of V_Hardware_Initialization, which is the default hardware initialization routine.

Interrupt_Vector_Table Structure

The Interrupt_Vector_Table is used by TDM to determine which handler to use when a machine exception occurs. Machine exceptions include breakpoints, TDM I/O traps, bus errors, hardware interrupts, etc. Note that machine exceptions must not be confused with Ada exceptions which rely on a different mechanism.

Each Interrupt_Vector_Table entry is simply the address of the handler routine to be used.

All interrupt handlers linked in the TDM program must be implemented as TDM interrupt handler routines. This is easily be done by using the generic Interrupt_Handler. Normally, the only interrupt handler is V_Serial_Support's Process_Get_Interrupt.

All remaining exception types are caught by Tdm_Handler.

During initialization, TDM copies the code installed at the general and UTLB exception vector locations, presumably by the on-board PROM monitor, into a save area. An entry that is set to Krn_Cpu_Defs.Untouchable_Vector tells TDM to branch to the saved exception vector. For many PROM based monitors, setting the breakpoint vector IDs 032 .. 037 to Krn_Cpu_Defs.Untouchable_Vector enables you to debug TDM using the monitor.

Note: Since TDM modifies the exception vector locations after saving, you cannot rerun and debug TDM from its starting point without first starting the monitor which re-initializes the exception vector locations.

The interrupt mask returned by V_Decode_Interrupt is used when executing inside the interrupt handler. By default, the mask is set so that all higher priority interrupts are disabled.

Memory_Map_Table Structure

TDM restricts memory access to only those locations encompassed by the memory partitions defined in the Memory_Map_Table. This table inhibits the host debugger from hanging the board by inadvertently accessing I/O registers.

TDM Stack

An array is declared here to reserve space for TDM's stack area. TDM switches to this stack when entered. Space is also reserved for the initial user stack, which TDM sets up for the user program to use until it has established its own stack.

Configure the sizes of these stacks by changing the constants Tdm_Stack_Size and Tdm_User_Stack_Size.

Configuration_Table Structure

Configuration_Table is the record that describes the target system to TDM.

The parameters are grouped into six categories: stack, floating point, interrupt configuration, Memory_Map, the TDM entry and return routines, and miscellaneous. Use of the FPA is enabled or disabled by the floating point parameter. The interrupt configuration parameters are used to specify the address of the Interrupt_Vector_Table, its size, the break code used by TDM I/O services and the interrupt mask used to disable interrupts. Memory that can be accessed by TDM and the host debugger is defined by the memory map parameters. The Setup_Tdm_Entry_Callout and Setup_Tdm_Return_Callout parameters point to user-configurable routines that can be used to implement any actions that must be performed whenever TDM is entered or exited. The miscellaneous parameters specify the test message for a Delete Control-d, allow the kernel program to automatically be started at the conclusion of TDM initialization, and point to the routine for processing debugger passthru commands.

Tdm_Stack_Base

Tdm_Stack_Base specifies the start address for the TDM stack. TDM switches to this stack when it is entered. The TDM stack grows from this address towards low memory.

Tdm_Stack_Size

The size in bytes of the TDM stack

Tdm_User_Base

Tdm_User_Base specifies the start address for initial user stack. This stack is set up by TDM for the user program to use until it has established its own stack. The user stack grows from this address towards low memory.

Tdm_User_Stack_Size

The size in bytes of the initial user stack.

Hw_Flt_Enabled

For the MIPS I Family, Hw_Flt_Enabled must be set to True if the board has a Floating Point Coprocessor (FPC) used for executing FPops. For the MIPS II/III/IV/64 Family, Hw_Flt_Enabled must be set to True.

Interrupt_Vector_Base

Interrupt_Vector_Base tells TDM where in memory the interrupt vector table is located.

The value of Interrupt_Vector_Base must be aligned on a word boundary. It is set by default to Interrupt_Vector_Table'Address.

Interrupt_Vector_Size

Interrupt_Vector_Size tells TDM how many entries are in the interrupt vector table. It is set by default to Interrupt_Vector_Table'Length.

Tdm_Break_Code

Tdm_Break_Code tells TDM which code is used for TDM I/O traps.

It is set by default to V_Cpu_Conf.Break_Tdm which is 16#10#. If your software uses this break code for some other purpose, you are free to change Tdm_Break_Code to another value.

Disable_Int_Mask

Disable_Int_Mask tells TDM the mask to use when interrupts must be disabled.

By default, it is set to 16#00# (all disabled) but there are cases where you want to have some interrupts enabled. If you had a watchdog timer interrupt, for example, which must be serviced while in TDM, you can enable that particular interrupt to allow it through. This doesn't cause a problem since a watchdog timer interrupt handler does not be alter any of TDM's data.

Restore_Ef_Callout

Restore_Ef_Callout gives TDM the address of the routine to use to restore the "exception frame" (machine context) when returning to the user program for execution.

It is set to V_Restore_Ef'Address by default.

Install_Except_Callout

Install_Except_Callout is the address of the routine called to install TDM's general and UTLB exception vectors.

It is set to V_Install_Except'Address by default.

Memory_Map_Size

Memory_Map_Size indicates the number of memory partitions. The default Memory_Map_Size is Memory_Map_Table'Length.

Memory_Map_Image

Memory_Map_Image indicates the starting address of the memory map table. The default Memory_Map_Image is Memory_Map_Table'Address. Memory_Map_Image can be set to System.Memory_Address(0) to enable the entire virtual address space (16#0000_0000#..16#FFFF_FFFF#) to be accessible by TDM and the host debugger.

Setup_Tdm_Entry_Callout

Setup_Tdm_Entry_Callout is the address of the routine called to perform any operations that must occur upon entry to TDM. This routine is called immediately after TDM calls V_Serial_Support.Disable_Get_Interrupt, which occurs when TDM is entered by a user application.

The default value for Setup_Tdm_Entry_Callout is V_Setup.Setup_Tdm_Entry'Address.

Setup_Tdm_Return_Callout

Setup_Tdm_Return_Callout is the address of the routine called to perform any operations that must occur prior to resuming or starting a user application. This routine is called immediately prior to TDM calling V_Serial_Support.Enable_Get_Interrupt, which occurs in preparation to TDM resuming or starting a user application.

The default value for Setup_Tdm_Return_Callout is V_Setup.Setup_Tdm_Return'Address.

Test_Message_Size

Test_Message_Size indicates the length of the TDM test message. The default Test_Message_Size is Test_Message'Length.

Test_Message_Image

Test_Message_Image indicates the address of the TDM test message. The default Test_Message_Image is Test_Message'Address.

Passthru_Callout

Passthru_Callout is the address of the routine called to scan, parse, and execute a debugger pass command.

Kernel_Start_Enabled and Kernel_Start_Address

If Kernel_Start_Enabled is True, at the conclusion of TDM elaboration and initialization, instead of waiting for a command from the host debugger, TDM jumps to the kernel program's starting address specified by Kernel_Start_Address.

When True, the kernel and user programs must already be loaded on the target.

Initial development begins with TDM downloading and debugging the kernel and user programs. As the application nears completion, the kernel and user programs join TDM as being loaded into ROM. Since the programs are already downloaded, TDM can transfer control to the kernel and user programs with no intervention by the host debugger. Before jumping to the kernel, TDM installs its exception/interrupt vectors, initializes the UART or ethernet and prepares itself to enter the application. The kernel and user programs replace the exception/interrupt vectors they handle. Control is only transferred back to TDM when the CPU generates an exception (such as address error) or receives an external interrupt (such as Control-C interrupt) for a vector with a handler in TDM that wasn't replaced by the kernel or user program. Using the Control-C interrupt, the host debugger can sync up with the application at a later time.

Memory_Write_Callout

Memory_Write_Callout is the address of the routine to be called when TDM is writing memory for purposes of downloading or setting breakpoints. This routine is defined in V_Mem_Support Package.

Memory_Read_Callout

Memory_Read_Callout is the address of the routine to be called when TDM is reading memory for purposes of examining memory or memory mapped I/O. This routine is defined in V_Mem_Support Package.

Memory_Fill_Callout

Memory_Fill_Callout is the address of the routine to be called when TDM is filling memory. This routine is defined in V_Mem_Support Package.

Memory_Search_Callout

Memory_Search_Callout is the address of the routine to be called when TDM is searching memory. This routine is defined in V_Mem_Support Package.

Cp0_Register_Access

Cp0_Register_Access is an array which specifies if and how the 32 coprocessor 0 (system coprocessor) registers should be accessed by TDM. Although it is possible to specify that the status, bad_vaddr, epc, and cause registers not be READ-WRITE, it would be impossible for TDM not to access these registers and still work correctly. Therefore, the access values for these registers are ignored.

This parameter can be useful for variations of the MIPS chips which are missing some registers or have added new ones to which TDM wouldn't ordinarily allow access.

Miscellaneous Variables

These are some package level variables used by several of the routines.

V_Decode_Interrupt Routine

V_Decode_Interrupt is called by V_Gen_Except to determine which pending interrupt to process (if there is more than one) and the interrupt mask used while processing it. It first checks for interrupts which are not prioritized in the usual manner. For example, a floating point exception, which is signalled by an interrupt, is checked for first. For other interrupts, the prioritization goes from highest numbered interrupt to lowest, Int7 has the highest priority, while Sw0 has the lowest. The interrupt mask returned is set up so that only higher priority interrupts are enabled. If this behavior is not acceptable, you are free to alter this routine to suit your needs.

V_Rfe Routine (MIPS I Family only)

This routine is used to do the final register restorations and manipulations to return to the user program. It is configurable as to which of the two registers, k0 or k1, is used. Data statements are used to encode the jr and rfe instructions to keep the instruction scheduler from putting them in an incorrect order or placing nops between them.

V_Eret Routine (MIPS II/III/IV/64 Family only)

This routine is used to do the final register restorations and manipulations to return to the user program.

V_Restore_Ef Routine

V_Restore_Ef is used to restore most of the exception frame (context) before returning to the user program. It simply copies the registers from the exception frame to the registers and then jumps to V_Rfe (MIPS I Family) or V_Eret (MIPS II/III/IV/64 Family) for final processing.

V_Untouchable Routine

V_Untouchable is placed in the Interrupt_Vector_Table when it is desirable that a particular exception or interrupt not be fielded by TDM. In this case, TDM enables it to pass through using the exception vector present when TDM first started. Normally, this routine does not require any modification.

Exception Handling Routines

These two routines are used together for handling exceptions and interrupts. V_Gen_Except creates and fills the exception frame, while V_Gen_Except2 completes the processing. They are split into two routines as an optimization so that when it encounters an untouchable interrupt, the kernel, which has saved the exception frame, jumps into V_Gen_Except2 skipping TDM's exception frame fill. Normally, no modification is required here.

V_Utlb_Except Routine

This routine is used to field the one exception that is not routed through the Gen_Except vector, namely UTLB miss exceptions. Currently, this type of exception is never raised, since Apex does not use virtual memory. However, if a user program accidentally stumbles into mapped space (kuseg or kseg2), this exception is raised since the TLB is not initialized. The default implementation simply reroutes this exception through the general exception vector to subsequently be mapped to an entry in the Interrupt_Vector_Table.

V_Install_Except Routine

This routine is called to install TDM's general and UTLB exception vectors. It installs jumps to the above V_Gen_Except, V_Gen_Except2 and V_Utlb_Except routines. The jumps are located as follows:

16#8000_0000#
jumps to V_Utlb_Except
16#8000_0080#
jumps to V_Gen_Except (for MIPS I)
16#8000_0180#
jumps to V_Gen_Except (for MIPS II/III/IV)
16#8000_8090#
jumps to V_Gen_Except2

V_Start_Program Routine

Control is transferred to V_Start_Program to start the TDM program.

V_Start_Program performs the following actions:

1 . Initializes status register, so that the system coprocessor (CP0) and FPA (CP1) are usable and is in kernel mode. Initializes the cause register so that all interrupts are disabled.

2 . Calls the V_Immediate_Initialization routine to initialize the board before enabling interrupts and referencing RAM.

3 . Initializes the startup stack.

4 . Copies the static data section from ROM to RAM if ROM is being used.

5 . Zeroes TDM's BSS.

6 . Calls the V_Hardware_Initialization routine to perform user-specified hardware initialization.

7 . Hand-elaborates V_Tdm_Conf's specification and body.

8 . Calls the V_Boot routine to initialize TDM data structures, reset the FPA if present and reset serial I/O using V_Serial_Support.Init. Upon return, switched from startup stack to TDM's internal stack.

9 . Installs the general and UTLB exception vectors.

10 . Elaborates TDM's packages.

11 . Calls the V_Execute routine to start execution of TDM. If the configuration parameter, Kernel_Start_Enabled is True, V_Execute jumps to the kernel program using the Kernel_Start_Address parameter. Otherwise, TDM waits for and processes commands sent from the host debugger.

Immediate/Hardware Initialization Routines

V_Immediate_Initialization carries out initialization which must occur right away after reset. An example is board control registers which come up in unknown states.

If your stack needs some preparation, such as mapping in it's pages, do that here. This routine is called before any RAM is accessed.

Things are in a precarious state at this point:

1 . You have no stack

2 . Interrupts are disabled

3 . Register ra contains your return address. All other general purpose registers are considered dead by the calling routine and can be used freely.

V_Hardware_Initialization performs any operations necessary to initialize the hardware prior to TDM's initialization.

This routine is called with interrupts enabled. Refer to V_Start_Program() to see when it is called during TDM startup.

This routine must not reference any entities which require elaboration, since it is called before any elaboration takes place.

The address of this routine must be assigned to the parameter Hardware_Initialization in the startup table.

V_Serial_Support Package

V_Serial_Support defines the routines required for TDM to interface to the target-specific serial I/O hardware. TDM communicates with the host through these routines. You must implement the bodies of these routines with code to drive the serial I/O hardware on your target. These routines are made available to TDM by using pragma External_Name().


Warning: Do not modify the V_Serial_Support package specification. Modify only the package body.

TDM uses a synchronous model of serial I/O with the host. Interrupt handlers are not required except for the Control-C interrupt. TDM enables the interrupt capabilities of the input port so that a character sent from the host interrupts the target and puts TDM back in control. TDM calls Enable_Get_Interrupt to arm the Control-C interrupt whenever TDM starts the application running. The Control-C interrupt enables you to regain control of the target if your program enters an infinite loop.

Init performs any initialization required by the target's serial port hardware, including programming the serial I/O ports. Init is called once during the TDM initialization and each time a file download to the target is completed.

Put takes a single parameter: a character represented by an 8-bit byte. Put must loop until the serial output port is able to accept the character and then write the character to the port.

Get reads one byte, if available, from the serial input port and returns it as the out parameter, b. If no byte is available, Get does not wait but returns immediately. If b contains a byte read from the port, the boolean out parameter Got_Byte must be set to True. If no byte is available to be read, Got_Byte must be set to False.

Enable_Get_Interrupt enables the serial input port (the "get" port, as opposed to the "put" port) to generate an interrupt when a character is received. This need only involve changing status bits for the serial input hardware. If the Control-C interrupt is not supported this routine does not need modification.

TDM calls Disable_Get_Interrupt to disable interrupt driven input on the serial input port. TDM calls this procedure whenever TDM is entered by a breakpoint, single step trap or a TDM-handled exception.

The Control-C ISR handler calls Process_Get_Interrupt to deal with the Control-C interrupt. Process_Get_Interrupt disables the Control-C interrupt by calling Disable_Get_Interrupt, then notifies TDM of the interrupt by calling the interface procedure Post_Comm_Intr.

Process_Get_Interrupt is called only when application code is running on the target. When executing in TDM (for example, when the application is stopped at a breakpoint or during Cross_Io) interrupts are disabled and therefore Process_Get_Interrupt is not called. The address of Process_Get_Handler must be inserted into the Interrupt_Vector_Table, at the vector where the serial input port interrupts when a character is available. The default Interrupt_Vector_Table has Process_Get_Interrupt installed at vector 103 decimal.

V_Setup Package

Setup_Tdm_Entry is called by TDM just after TDM is entered from a breakpoint, user trap or TDM-handled exception. It must contain any actions that must be performed upon entry to TDM. This routine is normally null.

Setup_Tdm_Return is called by TDM just before it starts executing the user program. It must contain any actions that are performed before the user program is entered from TDM. User_Io is a flag that is set to true if it was called because of a user I/O trap. This routine is normally null.

V_Passthru Routine

V_Passthru is called by TDM to scan, parse and execute a debugger pass command. Characters typed after the pass command are passed straight through. V_Passthru is called with the address and length of the string entered after the pass.

To display results, the routines Passthur_Put_Chr and Passthru_Put_Str must be called.

V_Mem_Support Package

This package provides a way to customize memory accesses made by the debugger using TDM. If there is hardware on your board that requires specific types of accesses (for example, single byte), these routines can be customized by using code that bases the type of access on the address being accessed.

Read is called by TDM whenever memory outside of TDM is read.

Write is called by TDM whenever memory outside of TDM is written.

Fill is called by TDM whenever memory outside of TDM is filled.

Search is called by TDM whenever memory outside of TDM is searched.


RH32 TDM Configuration Parameters

Policy/Switches file for the tdm_conf.ss subsystem.

The context switches for the views in the tdm_conf.ss subsystem have the following additional values:

The board_common.sw file contains all of the switches that are common to the BSP. The RUNTIMES switch is used to identify the archive libraries that are required to support the kernel as opposed to a user program.

The linker description file is located locally in the tdm_conf.ss view.

Configuration Components

V_Tdm_Conf Configuration Components

The configuration components of the TDM configuration package are:

Each of these components is discussed in detail below. To find any one of these components in the source files search for the title string of the desired component. In the source file, the code for each component begins with a line similar to the following:

To configure the TDM program, modify the body of the package, v_tdm_conf.2.ada

TDM Test Message

TDM writes this string to the serial port in response to reading Delete Control-d (16#7f# 16#04#). This verifies that TDM is working and is used to identify which version of TDM is running.

Startup_Table Structure

The package body v_tdm_conf.2.ada contains the declaration for the startup table.

Startup_Table must be declared as a constant, because the values in the table are used as soon as TDM starts, prior to TDM's elaboration (see the V_Start_Program routine in v_tdm_conf.2.ada). The value assigned to each field of the Startup_Table must be a literal, an address constant or a value returned by the address attribute ('Address). The table contains two fields, Startup_Stack_Base and Hardware_Initialization.

During initialization, TDM uses the stack with the base address of Startup_Stack_Base. This is the initial value of the stack pointer (register sp) used by TDM. The address you supply must point to the byte after the highest addressed byte of the stack. The stack grows towards low memory and the value in the stack pointer is always decremented before it is used.

To minimize the number of memory addresses used, the value of Startup_Stack_Base must match that of the kernel program's startup stack; the address of the byte just after the last byte of RAM in the system. For example, the default value, 16#0010_0000#, is for a system with one megabyte of RAM, RAM in the address range from 16#0000_0000# to 16#000F_FFFF#.

TDM requires less than 4096 bytes of startup stack space.

Hardware_Initialization is the address of the routine called to initialize the target system hardware. The default value is the address of V_Hardware_Initialization, which is the default hardware initialization routine. See V_Immediate_Initialization and V_Hardware_Initialization Routines

Interrupt_Vector_Table Structure

The Interrupt_Vector_Table is used by TDM to determine which handler to use when a machine exception occurs. Machine exceptions include breakpoints, TDM I/O traps, bus errors, hardware interrupts, etc. Note that machine exceptions must not be confused with Ada exceptions which rely on a different mechanism.

Each Interrupt_Vector_Table entry is simply the address of the handler routine to be used.

All interrupt handlers linked in the TDM program must be implemented as TDM interrupt handler routines. This is easily be done by using the generic Interrupt_Handler which is declared in v_tdm_conf.1.ada. Normally, the only interrupt handler is V_Serial_Support's Process_Get_Interrupt.

All remaining exception types are caught by V_Tdm_Conf_I.Tdm_Handler.

During initialization, TDM copies the code installed at the general and UTLB exception vector locations, presumably by the on-board PROM monitor, into a save area. An entry that is set to Krn_Cpu_Defs.Untouchable_Vector tells TDM to branch to the saved exception vector. For many PROM based monitors, setting the breakpoint vector IDs 032 .. 037 to Krn_Cpu_Defs.Untouchable_Vector enables you to debug TDM using the monitor.

The interrupt mask returned by V_Decode_Interrupt is used when executing inside the interrupt handler. By default, the mask is set so that all higher priority interrupts are disabled.

Memory_Map_Table Structure

TDM restricts memory access to only those locations encompassed by the memory partitions defined in the Memory_Map_Table.

TDM Stack

An array is declared here to reserve space for TDM's stack area. TDM switches to this stack when entered. Space is also reserved for the initial user stack, which TDM sets up for the user program to use until it has established its own stack.

Configure the sizes of these stacks by changing the constants Tdm_Stack_Size and Tdm_User_Stack_Size.

Configuration_Table Structure

The Configuration_Table is the record that describes the target system to TDM.

The parameters are grouped into seven categories: stack, floating point, interrupt configuration, memory map, serial support, the TDM entry and return routines and miscellaneous. Use of the FPA is enabled or disabled by the floating point parameter. The interrupt configuration parameters are used to specify the address of the Interrupt_Vector_Table, its size, the break code used by TDM I/O services and the interrupt mask used to disable interrupts. Memory that can be accessed by TDM and the host debugger is defined by the memory map parameters. TDM uses the serial support parameters to interface to the serial port on the target, enabling the target to communicate with the host. The Setup_Tdm_Entry_Callout and Setup_Tdm_Return_Callout parameters point to user-configurable routines that can be used to implement any actions that must be performed whenever TDM is entered or exited.

Tdm_Stack_Base

Tdm_Stack_Base specifies the start address for the TDM stack. TDM switches to this stack when it is entered. The TDM stack grows from this address towards low memory.

Tdm_Stack_Size

The size in bytes of the TDM stack

Tdm_User_Stack_Base

Tdm_Stack_Base specifies the start address for initial user stack. This stack is set up by TDM for the user program to use until it has established its own stack. The user stack grows from this address towards low memory.

Tdm_User_Stack_Size

The size in bytes of the initial user stack.

Hw_Flt_Enabled

Hw_Flt_Enabled is always true for the RH32 processor.

Interrupt_Vector_Base

Interrupt_Vector_Base tells TDM where in memory the interrupt vector table is located.

The value of Interrupt_Vector_Base must be aligned on a word boundary. It is set by default to Interrupt_Vector_Table'Address.

Interrupt_Vector_Size

Interrupt_Vector_Size tells TDM how many entries are in the interrupt vector table. It is set by default to Interrupt_Vector_Table'Length.

Tdm_Break_Code

Tdm_Break_Code tells TDM which code is used for TDM I/O traps.

It is set by default to V_Cpu_Conf.Break_Tdm which is 33. If your software uses this break code for some other purpose, you are free to change it to another value.

Disable_Int_Mask

Disable_Int_Mask tells TDM the mask to use when interrupts must be disabled.

By default, it is set to 16#00# (all disabled) but there are cases where you want to have some interrupts enabled. If you had a watchdog timer interrupt, for example, which must be serviced while in TDM, you can enable that particular interrupt to allow it through. This doesn't cause a problem since a watchdog timer interrupt handler does not be alter any of TDM's data.

Restore_Ef_Callout

Restore_Ef_Callout gives TDM the address of the routine to use to restore the "exception frame" (machine context) when returning to the user program for execution.

It is set to V_Restore_Ef'Address by default.

Install_Except_Callout

Install_Except_Callout is the address of the routine called to install TDM's general and UTLB exception vectors.

It is set to V_Install_Except'Address by default.

Memory_Map_Size

Memory_Map_Size indicates the number of memory partitions. The default Memory_Map_Size is Memory_Map_Table'Length.

Memory_Map_Image

Memory_Map_Image indicates the starting address of the memory map table. As a shortcut, Memory_Map_Image can be set to System.Memory_Address(0) to enable the entire virtual address space (16#0000_0000#..16#FFFF_FFFF#) to be accessible by TDM and the host debugger.

Setup_Tdm_Entry_Callout

Setup_Tdm_Entry_Callout is the address of the routine called to perform any operations that must occur upon entry to TDM. This routine is called immediately after TDM calls V_Serial_Support.Disable_Get_Interrupt, which occurs when TDM is entered by a user application.

The default value for Setup_Tdm_Entry_Callout is V_Setup.Setup_Tdm_Entry'Address.

Setup_Tdm_Return_Callout

Setup_Tdm_Return_Callout is the address of the routine called to perform any operations that must occur prior to resuming or starting a user application. This routine is called immediately prior to TDM calling V_Serial_Support.Enable_Get_Interrupt, which occurs in preparation to TDM resuming or starting a user application.

Default value for Setup_Tdm_Return_Callout is V_Setup.Setup_Tdm_Return'Address.

Passthru_Callout

Passthru_Callout is the address of the routine called to scan, parse and execute a debugger pass command. For the subprogram interface, see V_Passthru Routine

Kernel_Start_Enabled and Kernel_Start_Address

If Kernel_Start_Enabled is True, at the conclusion of TDM elaboration and initialization, instead of waiting for a command from the host debugger, TDM jumps to the kernel program's starting address specified by Kernel_Start_Address.

When True, the kernel and user programs must already be loaded on the target.

Initial development begins with TDM downloading and debugging the kernel and user programs. As the application nears completion, the kernel and user programs join TDM as being loaded into ROM. Since the programs are already downloaded, TDM can transfer control to the kernel and user programs with no intervention by the host debugger. Before jumping to the kernel, TDM installs its exception/interrupt vectors, initializes the UART or ethernet and prepares itself to enter the application. The kernel and user programs replace the exception/interrupt vectors they handle. Control is only transferred back to TDM when the CPU generates an exception (such as address error) or receives an external interrupt (such as Control-C interrupt) for a vector with a handler in TDM that wasn't replaced by the kernel or user program. Using the Control-C interrupt, the host debugger can sync up with the application at a later time.

Previous product releases supported the V_Start2 alternative starting point that was called from the kernel program to initialize TDM. The above Kernel_Start_Enabled and Kernel_Start_Address parameters replace the functionality provided by V_Start2 and V_Start_Program2.

Memory_Write_Callout

Memory_Write_Callout is the address of the routine to be called when TDM is writing memory for purposes of downloading or setting breakpoints. This routine is defined in V_Mem_Support Package.

Memory_Read_Callout

Memory_Read_Callout is the address of the routine to be called when TDM is reading memory for purposes of examining memory or memory mapped I/O. This routine is defined in V_Mem_Support Package.

Memory_Fill_Callout

Memory_Fill_Callout is the address of the routine to be called when TDM is filling memory. This routine is defined in V_Mem_Support Package.

Memory_Search_Callout

Memory_Search_Callout is the address of the routine to be called when TDM is searching memory. This routine is defined in V_Mem_Support Package.

Miscellaneous Variables

These are some package level variables used by several of the routines.

V_Rfs Routine

This routine is used to do the final register restorations and manipulations to return to the user program.

V_Restore_Ef Routine

V_Restore_Ef is used to restore most of the exception frame (context) before returning to the user program. It simply copies the registers from the exception frame to the registers and then jumps to V_Rfs for final processing.

V_Untouchable Routine

V_Untouchable is placed in the Interrupt_Vector_Table when it is desirable that a particular exception or interrupt not be fielded by TDM. In this case, TDM enables it to pass through using the exception vector present when TDM first started. Normally, this routine does not require any modification.

V_Gen_Exception and V_Gen_Except2 Routines

These two routines are used together for handling exceptions and interrupts. V_Gen_Exception creates and fills the exception frame, while V_Gen_Except2 completes the processing. They are split into two routines as an optimization so that when it encounters an untouchable interrupt, the kernel, which has saved the exception frame, jumps into V_Gen_Except2 skipping TDM's exception frame fill. Normally, no modification is required here.

V_Install_Except Routine

This routine is called to install TDM's surprise vectors. It installs jumps to the appropriate surprise code. The jumps are located as follows:

16#0000_0010#
jumps to V_Power_Fail_Surprise
16#0000_0020#
jumps to V_Monitor_Surprise
16#0000_0030#
jumps to V_Exc_Surprise
16#0000_0040#
jumps to V_Int_Surprise
16#0000_0040#
jumps to V_Trap_Surprise
16#0000_0040#
jumps to V_Hw_Surprise

V_Start_Program Routine

Control is transferred to V_Start_Program to start the TDM program.

V_Start_Program performs the following actions:

1 . Initializes CPU status register, so that the interrupts are disabled and CPU is in kernel mode.

2 . Calls the V_Immediate_Initialization routine to initialize the board before enabling interrupts and referencing RAM.

3 . Initializes the startup stack.

4 . Copies the static data section from ROM to RAM if ROM is being used.

5 . Zeroes TDM's BSS.

6 . Calls the V_Hardware_Initialization routine to perform user-specified hardware initialization.

7 . Hand-elaborates V_Tdm_Conf's specification and body.

8 . Calls the V_Boot routine to initialize TDM data structures, reset the FPP and reset serial I/O using V_Serial_Support.Init. Upon return, switched from startup stack to TDM's internal stack.

9 . Installs the general exception vectors.

10 . Elaborates TDM's packages.

11 . Calls the V_Execute routine to start execution of TDM, whereby it waits for and processes commands sent from the host debugger.

V_Immediate_Initialization and V_Hardware_Initialization Routines

V_Immediate_Initialization carries out initialization which must occur right away after reset. An example is board control registers which come up in unknown states.

If your stack needs some preparation, such as mapping in its pages, do that here. This routine is called before any RAM is accessed.

Things are in a precarious state at this point:

1 . You have no stack

2 . Interrupts are disabled

3 . Register ra contains your return address. All other general purpose registers are considered dead by the calling routine and can be used freely.

V_Hardware_Initialization performs any operations necessary to initialize the hardware prior to TDM's initialization.

This routine is called with interrupts enabled. Refer to V_Start_Program() to see when it is called during TDM startup.

This routine must not reference any entities which require elaboration, since it is called before any elaboration takes place.

The address of this routine must be assigned to the parameter Hardware_Initialization in the startup table.

V_Serial_Support Package

V_Serial_Support defines the routines required for TDM to interface to the target-specific serial I/O hardware. TDM communicates with the host through these routines. You must implement the bodies of these routines with code to drive the serial I/O hardware on your target. The configuration table supplies TDM with the address of each of these routines.


Warning: Do not modify the V_Serial_Support package specification. Modify only the package body.

TDM uses a half duplex model of serial I/O with the host. Interrupt handlers are not required except for the Control-C interrupt. TDM enables the interrupt capabilities of the input port so that a character sent from the host interrupts the target and puts TDM back in control. TDM calls Enable_Get_Interrupt to arm the Control-C interrupt whenever TDM starts the application running. The Control-C interrupt enables you to regain control of the target if your program enters an infinite loop.

Init performs any initialization required by the target's serial port hardware, including programming the serial I/O ports. Init is called once during the TDM initialization and each time a file download to the target is completed.

Put takes a single parameter: a character represented by an 8-bit byte. Put must loop until the serial output port is able to accept the character and then write the character to the port.

Get reads one byte, if available, from the serial input port and returns it as the out parameter, b. If no byte is available, Get does not wait but returns immediately. If b contains a byte read from the port, the boolean out parameter Got_Byte must be set to True. If no byte is available to be read, Got_Byte must be set to False.

Enable_Get_Interrupt enables the serial input port (the "get" port, as opposed to the "put" port) to generate an interrupt when a character is received. This need only involve changing status bits for the serial input hardware. If the Control-C interrupt is not supported this routine does not need modification.

TDM calls Disable_Get_Interrupt to disable interrupt driven input on the serial input port. TDM calls this procedure whenever TDM is entered by a breakpoint, single step trap or a TDM-handled exception.

The Control-C ISR handler calls Process_Get_Interrupt to deal with the Control-C interrupt. Process_Get_Interrupt disables the Control-C interrupt by calling Disable_Get_Interrupt, then notifies TDM of the interrupt by calling the interface procedure V_Tdm_Conf_I.Post_Ctrl_C.

Process_Get_Interrupt is called only when application code is running on the target. When executing in TDM (for example, when the application is stopped at a breakpoint or during Cross_Io) interrupts are disabled and therefore Process_Get_Interrupt is not called.

Get_Handler is an instantiation of the TDM generic interrupt service routine, using Process_Get_Interrupt as the routine to handle the interrupt. The address of Get_Handler must be inserted into the Interrupt_Vector_Table, at the vector where the serial input port interrupts when a character is available.

V_Setup Package

V_Setup.Setup_Tdm_Entry is called by TDM just after TDM is entered from a breakpoint, user trap or TDM-handled exception. It must contain any actions that must be performed upon entry to TDM. This routine is normally null.

V_Setup.Setup_Tdm_Return(User_Io:Boolean) is called by TDM just before it starts executing the user program. It must contain any actions that are performed before the user program is entered from TDM. User_Io is a flag that is set to true if it was called because of a user I/O trap. This routine is normally null.

V_Passthru Routine

V_Passthru is called by TDM to scan, parse and execute a debugger pass command. Characters typed after the pass command are passed straight through. V_Passthru is called with the address and length of the string entered after the pass.

To display results, the routines V_Tdm_Conf_I.Passthru_Put_Chr and V_Tdm_Conf_I.Passthru_Put_Str must be called.

V_Mem_Support Package

This package provides a way to customize memory accesses made by the debugger using TDM. If there is hardware on your board that requires specific types of accesses (for example, single byte), these routines can be customized by using code that bases the type of access on the address being accessed.

Read is called by TDM whenever memory outside of TDM is read.

Write is called by TDM whenever memory outside of TDM is written.

Fill is called by TDM whenever memory outside of TDM is filled.

Search is called by TDM whenever memory outside of TDM is searched.


M68000 Family TDM Configuration Parameters

Policy/Switches file for the tdm_conf.ss subsystem.

The context switches for the views in the tdm_conf.ss subsystem have the following additional values:

The Board_Common.sw file contains all of the switches that are common to the BSP. The RUNTIMES switch is used to identify the archive libraries that are required to support the kernel as opposed to a user program.

The linker description file is located locally in the tdm_conf.ss view.

Configuration Components

The configuration components of the TDM configuration package are in the v_tdm_conf.1.ada and v_tdm_conf.2.ada files:

Each of these components is discussed in detail below. To find any one of these components in the source files, search for the title string of the desired component. In the source file, the code for each component begins with a line similar to the following:

TDM Test Message

TDM writes this string to the serial port in response to reading Delete Control-d (16#7f# 16#04#). This verifies that TDM is working and is used to identify which version of TDM is running.

Startup_Table Structure

The package body v_tdm_conf.2.ada contains the declaration for the startup table. The following code segment shows the type declaration from the interface package V_Tdm_Conf_I and then the declaration of the table.

Startup_Table must be declared as a constant, because the values in the table are used as soon as TDM starts, prior to the elaboration of TDM (see the V_Start_Program routine in v_tdm_conf.2.ada). The value assigned to each field of the Startup_Table must be a literal, an address constant or a value returned by the address attribute ('Address). The table contains two fields, Startup_Stack_Base and Hardware_Initialization.

During initialization, TDM uses the stack with the base address of Startup_Stack_Base. This is the initial value of the stack pointer (register ISP) used by TDM. The address you supply must point to the byte after the highest addressed byte of the stack. The stack grows towards low memory and the value in the stack pointer is always decremented before it is used.

To minimize the number of memory addresses used, the value of Startup_Stack_Base should match that of the startup stack of the kernel program; the address of the byte just after the last byte of RAM in the system. For example, the default value, 16#0040_0000#, is for a system with one megabyte of RAM, RAM in the address range from 0 to 16#0F_FFFF#.

TDM requires less than 512 bytes of startup stack space.

Hardware_Initialization is the address of the routine called to initialize the target system hardware. The default value is the address of V_Hardware_Initialization, which is the default hardware initialization routine. V_Hardware_Initialization Routine.

Interrupt_Vector_Table Structure

The Interrupt_Vector_Table structure defines an image of the initial contents of the processor's interrupt vector table. The Motorola M68000 family documentation calls this table the "Exception Vector Table".

Each entry of the table must contain one of the following values:

Table 2 shows the default state of the TDM interrupt vector table, Interrupt_Vector_Table, in v_tdm_conf.2.ada. The default values are the same for all M68000 processors but the exact description of the vector's purpose can vary. Consult the user`s manual for your processor for more information on exception vector assignments. TDM provides handlers for vectors 2, 3, 4, 8, 9, 14, the TDM cross I/O trap (defaults to vector 47) and the serial I/O get interrupt (defaults to vector 140).

Table 2 Default TDM Interrupt Vector Table
Vector
Default Value
Description
000
V_Tdm_Conf_I.Untouchable_Vector
Reset: Initial Supervisor/Interrupt SP
001
V_Tdm_Conf_I.Untouchable_Vector
Reset: Initial PC
002
V_Tdm_Conf_I.Bus_Handler'Address
Bus Error/Access Fault
003
V_Tdm_Conf_I.Address_Handler'
Address

Address Error
004
V_Tdm_Conf_I.Illegal_Handler' Address
Illegal Instruction
005
V_Default_Isr'Address
Integer Zero Divide *
006
V_Default_Isr'Address
CHK, CHK2 Instructions *
007
V_Default_Isr'Address
cpTRAPcc, FPTRAPcc, TRAPcc, TRAPV *
008
V_Tdm_Conf_I.Privilege_Handler'
Address

Privilege Violation
009
V_Tdm_Conf_I.Trace_Handler'
Address

Trace
010
V_Default_Isr'Address
Line 1010 Emulator
011
V_Default_Isr'Address
Line 1111 Emulator
012
V_Default_Isr'Address
Hardware Breakpoint (CPU32)
013
V_Default_Isr'Address
Coprocessor Protocol Violation
014
V_Tdm_Conf.I.Format_Handler'
Address

Format Error
015
V_Default_Isr'Address
Uninitialized Interrupt
016..023
V_Default_Isr'Address
(Unassigned, Reserved)
024
V_Default_Isr'Address
Spurious Interrupt
025
V_Default_Isr'Address
Level 1 Interrupt Auto Vector
026
V_Default_Isr'Address
Level 2 Interrupt Auto Vector
027
V_Default_Isr'Address
Level 3 Interrupt Auto Vector
028
V_Default_Isr'Address
Level 4 Interrupt Auto Vector
029
V_Default_Isr'Address
Level 5 Interrupt Auto Vector
030
V_Default_Isr'Address
Level 6 Interrupt Auto Vector
031
V_Default_Isr'Address
Level 7 Interrupt Auto Vector
032
V_Default_Isr'Address
Trap 00: Default for Entering Kernel
033..046
V_Default_Isr'Address
Trap 01 Through Trap 14
047
V_Tdm_Conf_I.Trap_Handler'
Address

Trap 15: Default Vector for TDM
048
V_Default_Isr'Address
FP Branch of Set on Unordered Condition
049
V_Default_Isr'Address
FP Inexact Result
050
V_Default_Isr'Address
FP Divide by Zero *
051
V_Default_Isr'Address
FP Underflow
052
V_Default_Isr'Address
FP Operand Error *
053
V_Default_Isr'Address
FP Overflow *
054
V_Default_Isr'Address
FP Signaling NAN *
055
V_Default_Isr'Address
FP Unimplemented Data Type
056
V_Default_Isr'Address
PMMU Configuration
057
V_Default_Isr'Address
PMMU Illegal Operation
058
V_Default_Isr'Address
Access Level Vioaltion
059..063
V_Default_Isr'Address
(Unassigned, Reserved)
064..139
V_Default_Isr'Address
User-defined Vectors
140
V_Serial_Support.Get_Handler'
Address

Control-C Get Interrupt
141..255
V_Default_Isr'Address
User-defined Vectors
* Handled in the Kernel


Warning: If the trap number for TDM must be changed, you must also change the kernel's Interrupt_Vector_Table and the V_Traps package in the user library.

All interrupt handlers linked with TDM must be implemented as TDM interrupt handler routines, as required by TDM. This is easily done by using the generic V_Interrupt_Handler, which is declared in the V_Tdm_Conf_I package.

The address of the interrupt vector table image is passed to TDM in the configuration table field Interrupt_Vector_Image. If this field is assigned the constant V_Tdm_Conf_I.Untouchable_Table, the Interrupt_Vector_Table structure is ignored. Otherwise, during initialization TDM constructs a new processor interrupt vector table from the values in the Interrupt_Vector_Table. If an entry in the Interrupt_Vector_Table is assigned the value Untouchable_Vector, TDM preserves the entry from the currently active interrupt vector table.

The base address of the new interrupt vector table is specified in the configuration table field Vector_Base_Register. Refer to the section on the Configuration_Table structure for more information on the fields Vector_Base_Register and Interrupt_Vector_Image.

Some hardware implementations map multiple functions to the same interrupt vector. A handler for such an interrupt needs to read an I/O register to indicate the source of the interrupt. This can be a problem when the logic for the different functions reside in different programs, for example: serial I/O in TDM, clock in kernel, input handler in user program.

The above problem is solved by having user defined pseudo interrupt vectors in addition to the hardware interrupt vectors. The handler attached to the hardware vector dispatches to one of these pseudo vectors. The size of the Interrupt_Vector_Table can be extended beyond 256 entries to store these pseudo vectors.

An example using pseudo interrupt vectors follows:

User installs its miscellaneous input handler with the Rational Exec service: V_Interrupts.Attach_Isr(258, Input_Isr'Address);

Note: code for a pseudo handler, is the same as if the hardware interrupt had vectored directly to it.

TDM Stack

An array is declared here to reserve space for TDM's stack area. TDM switches to this stack when entered.

Configure the size of the TDM stack by changing the constant Tdm_Stack_Size.

Configuration_Table Structure

Following is the Configuration_Table,which is the record that describes the target system to TDM.

The parameters are grouped into four categories: stack, interrupt configuration, TDM entry and return routines and miscellaneous. The interrupt configuration parameters deal with the VBR register and the interrupt vector table. The Setup_Tdm_Entry_Callout and Setup_Tdm_Return_Callout parameters point to user-configurable routines used to implement any actions that must be performed whenever TDM is entered or exited.

Tdm_Stack_Base

Tdm_Stack_Base specifies the start address for the TDM stack. TDM switches to this stack when it is entered. The TDM stack grows from this address towards low memory.

Tdm_Stack_Size

The size in bytes of the TDM stack

Tdm_User_Stack_Base

Tdm_User_Stack_Base specifies the start address for initial user stack. This stack is set up by TDM for the user program to use until it has established its own stack. The TDM stack grows from this address towards low memory.

Tdm_User_Stack_Size

The size in bytes of the initial user stack.

Vector_Base_Register

The initial value of the Vector_Base_Register tells TDM where in memory to place the interrupt vector table. During initialization, TDM first builds the table at this address and then loads the VBR register with the address of this table.

The constant V_Tdm_Conf_I.Untouchable_Vbr should be given as the initial Vector_Base_Register value if the VBR register must not be changed during TDM initialization. In this case, TDM builds the vector table "in place," modifying the vectors in the currently active interrupt vector table (the table pointed to by the current VBR register).

If the value given by the Vector_Base_Register parameter differs from the initial value of the VBR, then the value of any vector specified as untouchable in the Interrupt_Vector_Table is copied from the currently active vector table to the new interrupt vector table.

Not all M68000 family processors have a VBR, in which case the value of this parameter is ignored and the table is built "in place" at address 0.

The default Vector_Base_Register is address 0.

Interrupt_Vector_Size

Interrupt_Vector_Size indicates the number of interrupt vectors in the interrupt vector table. This number must equal Interrupt_Vector_Table'Length.

Interrupt_Vector_Size tells TDM how many vectors are supposed to be in the table.

Because TDM supports pseudo interrupts, Interrupt_Vector_Size can be larger than 256.

Interrupt_Vector_Image

The interrupt vector table that is defined by Interrupt_Vector_Table is treated as a read-only version of the interrupt vector table. TDM makes a copy of Interrupt_Vector_Table and it is the copy, not the original, that is actually used. We refer to the original Interrupt_Vector_Table as the image from which copies are made.

Interrupt_Vector_Image tells TDM the starting address of the interrupt vector table image defined in Interrupt_Vector_Table. During initialization, TDM copies the contents of the image into what becomes the actual interrupt vector table.

If no copying is to take place, for example if the interrupt vector table resides in ROM, then Interrupt_Vector_Image must be set to V_Tdm_Conf_I.Untouchable_Table.

The default Interrupt_Vector_Image is Interrupt_Vector_Table'Address.

Setup_Tdm_Entry_Callout

Setup_Tdm_Entry_Callout is the address of the routine called to perform any operations that must occur upon entry to TDM. This routine is called immediately prior to TDM calling. V_Serial_Support.Disable_Get_Interrupt, which occurs when TDM is entered from a user application.

The default value for Setup_Tdm_Entry_Callout is V_Setup.Setup_Tdm_Entry'Address.

Setup_Tdm_Return_Callout

Setup_Tdm_Return_Callout is the address of the routine called to perform any operations that must occur prior to resuming or starting a user application. This routine is called immediately prior to TDM calling V_Serial_Support.Enable_Get_Interrupt, which occurs in preparation to TDM resuming or starting a user application.

Default value for Setup_Tdm_Return_Callout is V_Setup.Setup_Tdm_Return'Address.

Passthru_Callout

Passthru_Callout is the address of the routine that must be called to scan, parse and execute a debugger pass command. See V_Passthru for the subprogram interface.

Tdm_Idle_Callout

Tdm_Idle_Callout is the address of a procedure (with no parameters) repetitively called while TDM waits for serial input from the host. Setting Tdm_Idle_Callout to System.No_Addr, the default, indicates no idle callout.

Kernel_Start_Enabled and Kernel_Start_Address

If Kernel_Start_Enabled is True, at the conclusion of TDM elaboration and initialization, instead of waiting for a command from the host debugger, TDM jumps to the kernel program's starting address specified by Kernel_Start_Address.

When True, the kernel and user programs must already be loaded on the target.

Initial development begins with TDM downloading and debugging the kernel and user programs. As the application nears completion, the kernel and user programs join TDM as being loaded into ROM. Since the programs are already downloaded, TDM can transfer control to the kernel and user programs with no intervention by the host debugger. Before jumping to the kernel, TDM installs its exception/interrupt vectors, initializes the UART or ethernet and prepares itself to enter the application. The kernel and user programs replace the exception/interrupt vectors they handle. Control is only transferred back to TDM when the CPU generates an exception (such as address error) or receives an external interrupt (such as Control-C interrupt) for a vector with a handler in TDM that wasn't replaced by the kernel or user program. Using the Control-C interrupt, the host debugger can sync up with the application at a later time.

Previous product releases supported the V_Start2 alternative starting point that was called from the kernel program to initialize TDM. The above Kernel_Start_Enabled and Kernel_Start_Address parameters replace the functionality provided by V_Start2 and V_Start_Program2.

Memory_Write_Callout

Memory_Write_Callout is the address of the routine to be called when TDM is writing memory for purposes of downloading or setting breakpoints. This routine is defined in package V_Mem_Support described in V_Mem_Support Package.

Memory_Read_Callout

Memory_Read_Callout is the address of the routine to be called when TDM is reading memory for purposes of examining memory or memory mapped I/O. This routine is defined in package V_Mem_Support described in V_Mem_Support Package.

Memory_Fill_Callout

Memory_Fill_Callout is the address of the routine to be called when TDM is filling memory. This routine is defined in package V_Mem_Support described in V_Mem_Support Package.

V_Hardware_Initialization Routine

V_Hardware_Initialization performs any operations necessary to initialize the target system prior to TDM initialization. This routine is called before TDM is initialized, so it should not call any of the routines declared in V_Tdm_Conf_I. Also, because V_Hardware_Initialization is called before any elaboration takes place, it can not reference any TDM entities that require elaboration. The address of V_Hardware_Initialization must be assigned to the Hardware_Initialization field of the startup table.

V_Default_Isr Routine

V_Default_Isr is the TDM default interrupt service routine (ISR) and must be installed as the handler for unexpected interrupts. The address of this routine must be assigned to each unused interrupt vector in the interrupt vector table.

The default implementation of V_Default_Isr is a jump to V_Tdm_Conf_I.Unexpected_Handler, which notifies the debugger that an unexpected interrupt has occurred. The debugger prints a message and the exception frame pushed onto the stack by the processor.

V_Serial_Support Package

V_Serial_Support defines the routines required for TDM to interface to the target-specific serial I/O hardware. TDM communicates with the host through these routines. You must implement the bodies of these routines with code to drive the serial I/O hardware on your target. These routines are made available to TDM by using pragma External_Name().

TDM assumes a synchronous model of serial I/O with the host. Interrupt handlers are not required except for the Control-C interrupt. TDM enables the interrupt capabilities of the input port so that a character sent from the host interrupts the target and puts TDM back in control. TDM calls Enable_Get_Interrupt to arm the Control-C interrupt whenever TDM starts the application running. The Control-C interrupt enables you to regain control of the target if your program enters an infinite loop.

Following is package V_Serial_Support, with all comments removed.

Init performs any initialization required by the target's serial port hardware, including programming the serial I/O ports. Init is called once during the TDM initialization and each time a file download to the target is completed.

Put takes a single parameter: a character represented by an 8-bit byte. Put loops until the serial output port is able to accept the character and then write the character to the port.

Get reads one byte, if available, from the serial input port and returns it as the out parameter, b. If no byte is available, Get does not wait but returns immediately. If b contains a byte read from the port, the boolean out parameter Got_Byte must be set to True. If no byte is available to be read, set Got_Byte to False.

Enable_Get_Interrupt enables the serial input port (the Get port, as opposed to the Put port) to generate an interrupt when a character is received. This need only involve changing status bits for the serial input hardware. If the Control-C interrupt is not going to be supported, then this routine does not need modification.

TDM calls Disable_Get_Interrupt to disable interrupt driven input on the serial input port. TDM calls this procedure whenever TDM is entered by a breakpoint, single step trap or a TDM-handled exception.

The Control-C ISR handler calls Process_Get_Interrupt to deal with the Control-C interrupt. Process_Get_Interrupt disables the Control-C interrupt by calling Disable_Get_Interrupt, then notifies TDM of the interrupt by calling the interface procedure V_Tdm_Conf_I.Post_Comm_Intr.

Process_Get_Interrupt is called only when application code is running on the target. When executing in TDM (for example, when the application is stopped at a breakpoint or during Cross_Io) interrupts are disabled and therefore Process_Get_Interrupt is not called.

Get_Handler is an instantiation of the TDM generic interrupt service routine, using Process_Get_Interrupt as the routine to handle the interrupt. The address of Get_Handler must be inserted into the Interrupt_Vector_Table, at the vector where the serial input port interrupts when a character is available. The default Interrupt_Vector_Table (shown in Interrupt_Vector_Table Structure) has Get_Handler installed at vector 140 decimal.


Warning: Do not modify the V_Serial_Support package specification. Modify only the package body.

V_Setup Package

package V_Setup contains procedures called by TDM when a user application enters or is resumed (started) from TDM.

V_Setup.Setup_Tdm_Entry is called by TDM just after TDM is entered from a breakpoint, user trap, or TDM-handled exception. It must contain any actions that must be performed upon entry to TDM. This routine is normally null.

V_Setup.Setup_Tdm_Return is called by TDM just before it starts executing the user program. It should contain any actions that must be performed before the user program is entered from TDM. For example, if the processor has an instruction cache and it is enabled, you must clear the cache before resuming or starting the application. TDM sets and removes breakpoints by writing a breakpoint opcode into target memory. Clearing the cache removes any stale instructions and forces the processor to fetch fresh instructions from memory.

V_Start_Program Routine

V_Start_Program is the main initialization routine for TDM. It is provided primarily for reference, so that someone wanting to understand more about what happens during initialization of TDM can study this routine. The kernel has a similar routine, as does the user program.

V_Start_Program performs the following actions:

1 . Initializes TDM's startup stack. Sets up the SP register and the TDM initial call frame (register A6).

2 . Copies the static data section from ROM to RAM if ROM is being used.

3 . Zeroes TDM's Bss.

4 . Calls the V_Hardware_Initialization routine to perform user-specified hardware initialization.

5 . Calls the V_Boot routine to initialize TDM data structures, such as vector table, reset the mc68881/mc68882 if present, and initializes the communications hardware.

6 . Elaborates TDM's packages.

7 . Calls the V_Execute routine to start execution of TDM. If the configuration parameter, Kernel_Start_Enabled is True, V_Execute jumps to the kernel program using the Kernel_Start_Address parameter. Otherwise, TDM waits for and processes commands sent from the host debugger.


Warning: Do not modify V_Start_Program. V_Start enables you to insert necessary initialization, so that it occurs before V_Start_Program is called.

V_Passthru Routine

V_Passthru is called by TDM to scan, parse and execute a debugger pass command. Characters typed after the pass command are passed straight through. V_Passthru is called with the address and length of the string entered after the pass.

To display results, the routines V_Tdm_Conf_I.Passthru_Put_Chr and V_Tdm_Conf_I.Passthru_Put_Str must be called.

V_Mem_Support Package

This package provides a way to customize memory accesses made by the debugger with TDM. If there is hardware on your board that requires specific types of accesses (for example, single byte), these routines can be customized by using code that bases the type of access on the address being accessed.

Read is called by TDM whenever memory outside of TDM is read.

Write is called by TDM whenever memory outside of TDM is written.

Fill is called by TDM whenever memory outside of TDM is filled.

Search is called by TDM whenever memory outside of TDM is searched.


i386 Family TDM Configuration Parameters

Policy/Switches file for the tdm_conf.ss subsystem.

The context switches for the views in the tdm_conf.ss subsystem have the following additional values:

The Board_Common.sw file contains all of the switches that are common to the BSP. The RUNTIMES switch is used to identify the archive libraries that are required to support the kernel as opposed to a user program.

The linker description file is located locally in the tdm_conf.ss view.

The TDM configuration package, V_Tdm_Conf contains the parameters that enable TDM to run as a stand-alone, bootable program on the target system.

The following section provides details about each of the configuration parameters. To get an overview of a simple configuration, consult Building a Custom Configuration.

V_Tdm_Conf Configuration Components

In the source file of the package specification, v_tdm_conf.1.ada, use any editor to search for the title string of the desired configuration component. In these files each component starts with an Ada comment line like this:

TDM Test Message

TDM writes this string to the serial port in response to reading Delete Control-d (16#7f# 16#04#). This verifies that TDM is working and is used to identify which version of TDM is running.

TDM Stack

The package body v_tdm_conf.2.ada contains the declaration for TDM's stack.

Startup_Stack_Base must be declared as a constant, because the value is used as soon as TDM starts, prior to TDM elaboration (see the V_Start_Program routine in v_tdm_conf.2.ada).

During initialization, TDM uses the stack with the base address of Startup_Stack_Base, which is the initial value of the stack pointer (register ESP) used by TDM. The address you supply must point to the byte after the highest addressed byte of the stack. The stack grows towards low memory and the value in the stack pointer is always decremented before it is used.

We recommend that the value of Startup_Stack_Base be the same as the kernel program's startup stack; the address of the byte just after the last byte of RAM in the system. For example, the default value, 16#0010_0000#, is for a system with one megabyte of RAM, RAM in the address range from 0 to 16#0F_FFFF#.

TDM requires less than 512 bytes of startup stack space.

Note: The startup stack area is used before and during execution of the V_Memory_Initialization procedure. The top of RAM may not be accessible until V_Memory_Initialization returns. This applies to the Intel iSBC 486/133 SE board, where the top of real mode RAM is 16#000D_FFFF# before V_Memory_Initialization puts the board into protected mode. For boards with 1MB of RAM, top of RAM is 16#000F_FFFF# after memory initialization. See also V_Memory_Initialization and V_Hardware_Initialization Routines.

Null_Handler_Table and Interrupt_Vector_Table Structures

The Interrupt_Vector_Table specifies the initial contents of each descriptor in the processor's Interrupt Descriptor Table (IDT).

Each entry of the table must contain one of the following values:

During initialization, TDM builds its IDT using the Interrupt_Vector_Table values. The IDT structure is an array of interrupt gate descriptors.

Note: An interrupt gate resets the interrupt flag (IF) before jumping to the interrupt handler procedure, preventing another interrupt from interfering with the handler.

The Interrupt Vector Table is passed to TDM as a component of the Configuration_Table.

_The Interrupt_Vector_Table's type is an array of addresses:

Table 3 shows the default state of the TDM interrupt vector table, Interrupt_Vector_Table, in v_tdm_conf.1.ada. An asterisk (*) by the vector description indicates a vector that is handled by the kernel.

The address of Interrupt_Vector_Table must be assigned to the field Interrupt_Vector_Image in the configuration table, which is discussed in the next section.

All interrupt handlers linked with TDM must be implemented as TDM interrupt handler routines, following the rules required by TDM. This is easily done by using the generic interrupt_handler, which is declared in v_tdm_conf.1.ada.

`
Table 3 Default TDM Interrupt Vector Table
Vector
Default Value
Description
000
V_Tdm_Conf_I.Default_ Vector
Divide Error *
001
V_Tdm_Conf_I.Debug_Handler'
Address

Debug Exceptions
002
V_Tdm_Conf_I.Default_Vector
Non-maskable Interrupt
003
V_Tdm_Conf_I.Breakpoint_Handler'
Address

Breakpoint
004
V_Tdm_Conf_I.Default_Vector
Overflow *
005
V_Tdm_Conf_I.Default_Vector
Bounds Check *
006
V_Tdm_Conf_I.Default_Vector
Invalid Opcode *
007
V_Tdm_Conf_I.Default_Vector
Coprocessor Not Available *
008
V_Tdm_Conf_I.Default_Vector
Double Fault
009
V_Tdm_Conf_I.Default_Vector
Reserved
010
V_Tdm_Conf_I.Default_Vector
Invalid TSS
011
V_Tdm_Conf_I.Default_Vector
Segment Not Present
012
V_Tdm_Conf_I.Default_Vector
Stack Exception
013
V_Tdm_Conf_I.Default_Vector
General Protection
014
V_Tdm_Conf_I.Page_Fault_Handler'
Address

Page Fault
015
V_Tdm_Conf_I.Default_Vector
Reserved
016
V_Tdm_Conf_I.Default_Vector
Coprocessor Error *
017..31
V_Tdm_Conf_I.Default_Vector
Reserved
032
V_Tdm_Conf_I.Default_Vector
Kernel Trap Interrupt *
033
V_Tdm_Conf_I.Trap_Handler'
Address

DEFAULT Vector for TDM entry from kernel
034..053
V_Tdm_Conf_I.Default_Vector
Available for External Interrupts
054
V_Serial_Support.Get_Handler'
Address

Control-C Get Interrupt
055..255
V_Tdm_Conf_I.Default_Vector
Available for External Interrupts
* Handled in the Kernel

TDM provides the interrupt handlers for vectors 1, 3 and 14, the TDM cross I/O trap (vector 33 by default). These handlers are all declared in the V_Tdm_Conf_I package.

Note: If the interrupt number for TDM must be changed, you must also change the kernel's Interrupt_Vector_Table and the V_Traps package in the user library.

If a vector has a value of Untouchable_Vector, TDM copies the entire descriptor record (all 8 bytes, not just the offset field) from IDT, pointed to by the Monitor_Idt_Base configuration.

If a vector has a Default_Vector, TDM puts the address of its corresponding Null_Handler_Table entry into the descriptor's offset field. If memory is not set aside for the Null_Handler_Table, wherein the Null_Handler_Base configuration parameter is set to V_Tdm_Conf_I.No_Null_Handler, then the User_Default_Unknown_Isr configuration parameter value is stored in the descriptor offset field.

The Null_Handler_Table is a table of 8-byte null-interrupt handlers. Each handler captures its own interrupt number. The Null_Handler_Table is set up during kernel initialization. This is required because the i386 Family does not include the interrupt number as part of the interrupt's stack frame. The following code is generated for each interrupt vector entry:

where Unhandled_Interrupt_Address is set to the configuration parameter User_Default_ISR.

The address of the corresponding Null_Handler_Table entry is placed in the Interrupt Descriptor Table's (IDT) offset field for each Default_Vector entry in the Interrupt_Vector_Table.

The address of Null_Handler_Table must be assigned to the field Null_Handler_Base in the configuration table. The length of Null_Handler_Table must be identical to the length of the Interrupt_Vector_Table. If you don't want to capture the interrupt number for an unhandled interrupt, set Null_Handler_Base to V_Tdm_Conf_I.No_Null_Handler and declare Null_Handler_Table as a null array.

Memory_Map_Table Structure

The Memory_Map_Table defines the memory layout for your board. TDM restricts memory access to only those locations encompassed by the memory partitions defined in this table. Additionally, you can restrict memory access to write-only or read-only.

The package body v_tdm_conf.2.ada contains the declaration for the Memory_Map_Table.

If you want the cross debugger to access more than the first megabyte of RAM on your board, you must change the default configuration. Assign the address of Memory_Map_Table to the field Memory_Map_Image in the configuration table.

The kernel program's configuration package body, v_krn_conf.2.ada, also has a Memory_Map_Table structure. However, the kernel's usage of the structure differs from TDM's usage. TDM first checks its Memory_Map_Table structure before referencing any board memory on behalf of host debugger requests. In this way, TDM avoids referencing non-existent memory and possibly hanging the system. The kernel on the other hand, uses its Memory_Map_Table to set up the i386 Family page tables. The i386 generates a Page Fault exception interrupt for any reference outside of the specified memory partitions.

For example, let's say you configure the TDM Memory_Map_Table structure to enable the entire address space to be referenced and then configure the kernel's Memory_Map_Table structure to enable only the first megabyte of the address space to be referenced. A cross debugger request to access memory above one megabyte results in a Page Fault exception. However, if the TDM Page_Default_Handler is installed, TDM returns an illegal memory reference response to the cross debugger —— the response that occurs if TDM had consulted its Memory_Map_Table structure and detected an out of range memory reference.

Configuration_Table Structure

The Configuration_Table is the record that describes the target system to TDM.

The parameters are grouped into a number of categories: stack, GDT and TSS, interrupt configuration, memory map, monitor configuration, floating point, serial support and miscellaneous. GDT and TSS parameters specify where these i386 data structures are to be located in memory. Interrupt configuration parameters deal with building and locating the IDT data structure. Memory map parameters specify the length and location of the memory map table. Monitor configuration parameters specify the location of the board monitor's GDT and IDT. The floating point parameter indicates the presence of an 80287 or 80387 math coprocessor on the board.

TDM uses the serial support parameters to interface to the serial port on the target, enabling the target to communicate with the host. The interface that TDM requires for serial support is described in V_Serial_Support Package.

Gdt_Base

Gdt_Base tells TDM where in memory to place the Global Descriptor Table (GDT). The GDT is initialized with entries from the Gdt_Image. The Gdt_Limit is 199 (16#c7#), meaning that 200 bytes are required.

Tss_Base

Tss_Base tells TDM where in memory to place the Task State Segment (TSS). The TSS is initialized with entries from the Tss_Image and its limit is 103 (16#67#), requiring 200 bytes.

TDM and the kernel are configured to use only a single i386 task. Consequently, this is the only TSS necessary. The base field of the TSS descriptor in the GDT is set to Tss_Base.

Interrupt_Vector_Size

Interrupt_Vector_Size indicates the number of interrupt vectors in the interrupt vector table. This number must equal Interrupt_Vector_Table'Length.

Interrupt_Vector_Size tells TDM how many vectors are supposed to be in the table.

Interrupt_Vector_Image

Interrupt_Vector_Image tells TDM the starting address of the interrupt vector table image defined in Interrupt_Vector_Table. During initialization, TDM copies the contents of the image into the offset field of the IDT's interrupt gate descriptors.

The default Interrupt_Vector_Image is Interrupt_Vector_Table'Address.

Idt_Base

Idt_Base tells TDM where in memory to place the Interrupt Descriptor Table (IDT). The linear base address component of the IDTR register is loaded with the value of Idt_Base. Although the constant V_Tdm_Conf_I.Untouchable_Idt can be given if the base address of the monitor's IDT should be used in place of Idt_Base, the Idt_Limit is always reevaluated using Interrupt_Vector_Size and is calculated by this formula:

The IDT requires Interrupt_Vector_Size * 8 bytes of memory and is initialized using the Interrupt_Vector_Table.

Null_Handler_Base

Null_Handler_Base indicates the starting location of the null handler table, which is modified at runtime to contain generated i386 code used for capturing the ID of unexpected interrupts. The value V_Tdm_Conf_I.No_Null_Handler can be given if you don't care to capture the interrupt ID before processing an unexpected interrupt.

The default Null_Handler_Base is Null_Handler_Table'Address.

User_Default_Isr

User_Default_Isr contains the address of the handler for unexpected interrupts. The runtime generated code in the Null_Handler_Table jumps to this handler after pushing the ID of the unexpected interrupt onto the stack.

The default User_Default_ISR is V_Default_Isr'Address.

User_Default_Unknown_Isr

User_Default_Unknown_Isr contains the address of a secondary handler for unexpected interrupts. This handler is used when no Null_Handler_Table exists (Null_Handler_Base = V_Tdm_Conf_I.No_Null_Handler.

The default User_Default_Unknown_Isr is V_Default_Unknown_Isr'Address.

Init_Interrupt_Callout

Init_Interrupt_Callout contains the address of the routine that is called to initialize board-specific external interrupts, such as the board's interrupt controller, whenever you reset TDM. TDM calls this routine once during initialization and whenever the host sends a reset command to TDM, which occurs immediately before a VOX file is downloaded.

The default Init_Interrupt_Callout is V_Init_Interrupt'Address.

Memory_Map_Size

Memory_Map_Size indicates the number of memory partitions in the Memory_Map_Table.

The default Memory_Map_Size is Memory_Map_Table'Length.

Memory_Map_Image

Memory_Map_Image tells TDM the starting address of the memory partitions defined by Memory_Map_Table.

The default Memory_Map_Image is Memory_Map_Table'Address.

Monitor_Gdt_Base

If the board has a ROM-based monitor, use the monitor to debug TDM. Such a monitor has previously-initialized descriptors in the GDT and IDT for its own use. These descriptors must be copied into TDM's GDT and IDT. This parameter and the following three parameters, specify the location and number of descriptors in the board monitor's GDT and IDT.

Monitor_Gdt_Base is the base address of the board monitor's GDT. Default Monitor_Gdt_Base is V_Tdm_Conf_I.NO_GDT (no monitor GDT).

Monitor_Gdt_Length

Monitor_Gdt_Length specifies the number of monitor GDT entries (starting with GDT(0)) that are copied into TDM's GDT. An upper limit of 20 is imposed upon the length.

Default Monitor_Gdt_Length is 0, which is, copy no monitor GDT entries.

Monitor_Idt_Base

Monitor_Idt_Base is the base address of the board monitor's IDT. Early in the TDM initialization, the linear base address component of the IDT register is set to this value. This enables the board monitor's debugger to be used during initialization, after TDM's GDT is built and loaded. When TDM later builds and loads its IDT, Untouchable_Vector entries are copied from the monitor's IDT.

If TDM is started in i386 protected mode, specify the value V_Tdm_Conf_I.Untouchable_Idt for Monitor_Idt_Base if the current IDTR is used.

The default Monitor_Idt_Base is V_Tdm_Conf_I.NO_IDT, indicating no monitor IDT.

Monitor_Idt_Length

Monitor_Idt_Length specifies the length of the board monitor's IDT. Early in the TDM initialization, the limit component of the IDTR register is set to this value. The limit is calculated by the equation

If Monitor_Idt_Base is set to V_Tdm_Conf_I.Untouchable_Idt, Monitor_Idt_Length is ignored. The default Monitor_Idt_Length is 0, indicating no monitor IDT.

Hw_Flt_Enabled

Hw_Flt_Enabled is set to True if the board has an 80287 or 80387 math coprocessor or on-chip floating point (pentium processors, for example). If Hw_Flt_Enabled is False, TDM executes no floating point math coprocessor instructions.

Setup_Tdm_Entry_Callout

Setup_Tdm_Entry_Callout is the address of the routine called to perform any operations that must occur upon entry to TDM. This routine is called immediately after TDM calls Disable_Interrupt, which occurs when TDM is entered by a user application.

The default value for Setup_Tdm_Entry_Callout is V_Setup.Setup_Tdm_Entry'Address.

Setup_Tdm_Return_Callout

Setup_Tdm_Return_Callout is the address of the routine called to perform any operations that must occur prior to resuming or starting a user application. This routine is called immediately prior to TDM calling Enable_Interrupt, which occurs in preparation to TDM resuming or starting a user application.

Default value for Setup_Tdm_Return_Callout is V_Setup.Setup_Tdm_Return'Address.

Test_Message_Size

Test_Message_Size represents the length of the TDM test message. The default Test_Message_Size is Test_Message'Length

Test_Message_Image

Test_Message_Image is the starting location of the TDM test message. The default Test_Message_Image is Test_Message'Address.

Passthru_Callout

Passthru_Callout is the address of the routine called to scan, parse and execute a debugger pass command. See V_Passthru For the subprogram interface, see V_Passthru Routine.

Kernel_Start_Enabled and Kernel_Start_Address

If Kernel_Start_Enabled is True, at the conclusion of TDM elaboration and initialization, instead of waiting for a command from the host debugger, TDM jumps to the kernel program's starting address specified by Kernel_Start_Address.

When True, the kernel and user programs must already be loaded on the target.

Initial development begins with TDM downloading and debugging the kernel and user programs. As the application nears completion, the kernel and user programs join TDM as being loaded into ROM. Since the programs are already downloaded, TDM can transfer control to the kernel and user programs with no intervention by the host debugger. Before jumping to the kernel, TDM installs its exception/interrupt vectors, initializes the UART or ethernet and prepares itself to enter the application. The kernel and user programs replace the exception/interrupt vectors they handle. Control is only transferred back to TDM when the CPU generates an exception (such as address error) or receives an external interrupt (such as Control-C interrupt) for a vector with a handler in TDM that wasn't replaced by the kernel or user program. Using the Control-C interrupt, the host debugger can sync up with the application at a later time.

Previous product releases supported the V_Start2 alternative starting point that was called from the kernel program to initialize TDM. The above Kernel_Start_Enabled and Kernel_Start_Address parameters replace the functionality provided by V_Start2 and V_Start_Program2.

Memory_Write_Callout

Memory_Write_Callout is the address of the routine to be called when TDM is writing memory for purposes of downloading or setting breakpoints. This routine is defined in package V_Mem_Support described in V_Mem_Support Package.

Memory_Read_Callout

Memory_Read_Callout is the address of the routine to be called when TDM is reading memory for purposes of examining memory or memory mapped I/O. This routine is defined in package V_Mem_Support described in V_Mem_Support Package.

Memory_Fill_Callout

Memory_Fill_Callout is the address of the routine to be called when TDM is filling memory. This routine is defined in package V_Mem_Support described in V_Mem_Support Package.

Memory_Search_Callout

Memory_Search_Callout is the address of the routine to be called when TDM is searching memory. This routine is defined in package V_Mem_Support described in V_Mem_Support Package.

Miscellaneous Startup Variables

This component contains miscellaneous variables used by the startup machine code for initializing the IDT, GDT and math coprocessor.

Do not modify these variables.

Gdt_Image and Tss_Image Structures

Tables for initializing TDM GDT and TSS are declared in v_tdm_conf.2.ada. You do not normally need to modify these structures.

V_Memory_Initialization and V_Hardware_Initialization Routines

V_Memory_Initialization performs any operations necessary to initialize the target memory prior to RAM being initialized from ROM. This routine is called prior to the TDM initialization and should not make any calls to TDM. Because it is called prior to any elaborations, V_Memory_Initialization must not reference any entities that require elaboration.

The address of V_Memory_Initialization must be assigned to the Memory_Initialization field of the startup table.

V_Hardware_Initialization performs any operations necessary to initialize the target system prior to the TDM initialization. This routine is called before TDM is initialized, so it must not call any of the routines declared in V_Tdm_Conf_I. Also, because V_Hardware_Initialization is called before any elaboration takes place, it cannot reference any TDM entities that require elaboration. The address of V_Hardware_Initialization must be assigned to the Hardware_Initialization field of the startup table. For additional details, see Startup_Table Structure

V_Default_Isr and V_Default_Unknown_Isr Routines

V_Default_Isr is the TDM default interrupt service routine (ISR). Implementation of V_Default_Isr is a jump to V_Tdm_Conf_I.Unexpected_Handler, which notifies the debugger that an unexpected interrupt has occurred. The debugger prints a message containing the ID of the unexpected interrupt. Register values that are displayed by the debugger reflect the CPU state at the time of the interrupt.

Note: The runtime-generated code placed in the null handler table jumps to this routine after it pushes the interrupt number on to the stack.

V_Default_Unknown_Isr is a secondary ISR and is used only when no null handler table exists (Null_Handler_Base = V_Tdm_Conf_I.No_Null_Handler). This routine is implemented by a jump to V_Default_Isr with V_Cpu_Conf.Unknown_Intr_Number (10#17#) pushed onto the stack.

V_Init_Interrupt Routine

V_Init_Interrupt is the routine called to do board specific interrupt initialization. Normally, V_Init_Interrupt initializes the board's interrupt controller.

Note: V_Init_Interrupt for the Intel iSBC 486/133 board is configured to initialize the Intel 8259 Programmable Interrupt Controller (PIC).

TDM calls this routine once during initialization, as well as anytime the host sends a reset command to TDM, which occurs immediately before a VOX file is downloaded. The address of this routine must be assigned to the Init_Interrupt_Callout field of the configuration table.

V_Serial_Support Package

V_Serial_Support defines the routines required for TDM to interface to the target-specific serial I/O hardware. TDM communicates with the host through these routines. You must modify the bodies of these routines to reflect the serial I/O hardware on your target. The configuration table supplies TDM with the address of each of these routines.

Note: Do not modify the V_Serial_Support package specification. Modify only the package body.

TDM assumes a synchronous model of serial I/O with the host. Interrupt handlers are not required except for the Control-C interrupt. For this one case, TDM wants to enable the interrupt capabilities of the input port, so that a character sent from the host interrupts the target and puts TDM back in control. TDM calls Enable_Get_Interrupt to arm the Control-C interrupt whenever TDM starts the application running. The Control-C interrupt enables you to regain control of the target if your program enters an infinite loop.

Package V_Serial_Support is shown below with all of the comments removed, so you can see with a glance the routines that are in the package.

Init performs any initialization required by the target's serial port hardware, including programming the serial I/O ports. Init is called once during the TDM initialization and each time a file download to the target is completed.

Put is passed in an 8-bit byte, b. Put loops until the serial output port is able to accept the character and then write the character to the port.

Enable_Get_Interrupt enables interrupt driven input on the serial input port (the "get" port, as opposed to the "put" port). This need only involve changing status bits for the serial input hardware. Because TDM calls Enable_Get_Interrupt every time it starts or resumes executing the application, this is the logical place to perform operations that must be performed prior to each start or resumption of the application.

If the Control-C interrupt is not supported and there are no operations that must be performed prior to each start or resumption of an application, this routine does not need modification.

TDM calls Disable_Get_Interrupt to disable interrupt driven input on the serial input port. TDM calls this procedure whenever TDM is entered by a breakpoint, a single step trap or a TDM-handled exception. This routine is not called if TDM is entered with a Control-C interrupt.

The Control-C ISR handler calls Process_Get_Interrupt to deal with the Control-C interrupt. The default version works without modification, it reads the 2-character sequence (16#7f#, 16#03#) that caused the Control-C interrupt, to clear the serial port. Then Process_Get_Interrupt disables the Control-C interrupt by calling Disable_Get_Interrupt. Finally, it notifies TDM of the interrupt by calling the interface procedure V_Tdm_Conf_I.Post_Ctrl_C.

Process_Get_Interrupt is called only when application code is running on the target. When executing in TDM (for example, when the application is stopped at a breakpoint or during Cross_Io) interrupts are disabled and therefore Process_Get_Interrupt is not called.

Get_Handler is an instantiation of the TDM generic interrupt service routine, using Process_Get_Interrupt as the routine to handle the interrupt. The address of Get_Handler must be inserted into the Interrupt_Vector_Table, at the vector where the serial input port interrupts when a character is available. The default Interrupt_Vector_Table (shown in Table 3 ) has Get_Handler installed at vector 84 decimal, which is where the Intel iSBC 486/133 board's serial input port is programmed to interrupt.

V_Setup Package

The package V_Setup defines two routines used when control is transferred between TDM and the application program.

The procedure Setup_Tdm_Entry is called immediately after TDM is entered from user space. Any operations which must be performed at that time should be included in this procedure.

The procedure Setup_Tdm_Return is called just before TDM starts execution of the application program. Any operations which must be performed before continuing execution of the application program should be included in this procedure.

V_Start_Program Routine

V_Start_Program is the main initialization routine for TDM. It is provided primarily for reference, so that someone wanting to understand more about what happens during initialization of TDM can study this routine. The kernel has a similar routine, as does the user program.(See Package V_Cpu_Init and Initial Program Execution for the protected mode entry code).

V_Start_Program performs these actions:

1 . Initialize TDM startup stack.

2 . Calls the V_Memory_Initialization routine to perform user-specified memory initialization.

3 . Copies the static data section from ROM to RAM, if ROM is being used.

4 . Explicitly elaborates V_Tdm_Conf's specification and body.

5 . Initializes TDM TSS, GDT and LDT. If a monitor IDT is present, V_Start_Program loads the monitor IDT.

6 . Transfers control to Init_Program, which:

7 . Calls the V_Hardware_Initialization routine to perform user-specified hardware initialization.

8 . If Hw_Flt_Enabled is True, initializes the math coprocessor.

9 . Calls the V_Boot routine to initialize the IDT, resets the interrupt controller using the Init_Interrupt_Callout and resets the serial I/O using the Init_Serial_Callout.

10 . Elaborates the remaining TDM program packages.

11 . Calls the V_Execute routine to put TDM into its main loop, where it waits for and processes commands sent from the host.


Warning: Do not modify V_Start_Program. V_START enables you to insert necessary initialization, so that it occurs before V_Start_Program is called.

Package V_Cpu_Init and Initial Program Execution

When an i386 Family processor is reset, it begins execution in real-address-mode. The "real-mode" execution provides emulation for the older (for example, 8086) processors in the family. In this mode, addresses are composed of a 20-bit segment base and a 16-bit offset. In addition the default operand size in real-mode is 16-bits.

The Apex compiler and runtime are designed for the more capable protected-mode (supported by the i386 and later processors). The default operand size is 32 bits and for memory organization Apex uses the "flat" addressing model (with 32-bit addresses).

Since Apex does not support real-mode execution, the processor must be switched to protected-mode before TDM or the kernel (or an application) is started. To effect this switch, a small amount of code, found in the package V_Cpu_Init (in the same tdm_conf.ss or krn_conf.ss view as TDM or the kernel) is placed at the beginning of TDM and the kernel.

The entry point routine for TDM and the kernel (V_Start) contains code which determines the current execution mode (real or protected) and then calls the appropriate routine in V_Cpu_Init to insure that the processor is in protected, 32-bit address/operand, mode before V_Start_Program is called (in V_Tdm_Conf for TDM and V_Krn_Conf for the kernel).

V_Passthru Routine

V_Passthru is called by TDM to scan, parse and execute a debugger pass command. Characters typed after the pass command are passed straight through. V_Passthru is called with the address and length of the string entered after the pass.

To display results, the routines V_Tdm_Conf_I.Passthru_Put_Chr and V_Tdm_Conf_I.Passthru_Put_Str must be called.

V_Mem_Support Package

This package provides a way to customize memory accesses made by the debugger with TDM. If there is hardware on your board that requires specific types of accesses (for example, single byte), these routines can be customized by using code that bases the type of access on the address being accessed.

Read is called by TDM whenever memory outside of TDM is read.

Write is called by TDM whenever memory outside of TDM is written.

Fill is called by TDM whenever memory outside of TDM is filled.

Search is called by TDM whenever memory outside of TDM is searched.


Rational Software Corporation 
http://www.rational.com
support@rational.com
techpubs@rational.com
Copyright © 1993-2002, Rational Software Corporation. All rights reserved.
TOC PREV NEXT INDEX DOC LIST MASTER INDEX TECHNOTES APEX TIPS