X-Git-Url: https://git.kernelconcepts.de/?p=karo-tx-redboot.git;a=blobdiff_plain;f=doc%2Fhtml%2Fref%2Fhal-calling-if.html;fp=doc%2Fhtml%2Fref%2Fhal-calling-if.html;h=5985fc1a34465ff360d61a1096e2a558dede69c8;hp=0000000000000000000000000000000000000000;hb=2b5bec7716c03d42cfb16d8c98c9cea573bf6722;hpb=47412fc4bd1aefc0d5498bcb3860a9d727196f16 diff --git a/doc/html/ref/hal-calling-if.html b/doc/html/ref/hal-calling-if.html new file mode 100644 index 00000000..5985fc1a --- /dev/null +++ b/doc/html/ref/hal-calling-if.html @@ -0,0 +1,1432 @@ + + + + + + + + +Virtual Vectors (eCos/ROM Monitor Calling Interface) +
eCos Reference Manual
PrevChapter 11. Porting GuideNext

Virtual Vectors (eCos/ROM Monitor Calling Interface)

Some eCos platforms have supported full debugging capabilities via +CygMon since day one. Platforms of the architectures PowerPC, ARM, and +SH do not provide those features unless a GDB stub is included in the +application.

This is going to change. All platforms will (eventually) support +all the debugging features by relying on a ROM/RAM calling interface +(also referred to as virtual vector table) provided by the ROM +monitor. This calling interface is based on the tables used by libbsp +and is thus backwards compatible with the existing CygMon supported +platforms.

Virtual Vectors

What are virtual vectors, what do they do, and why are they +needed?

"Virtual vectors" is the name of a table located at a static +location in the target address space. This table contains 64 vectors +that point to service functions or data.

The fact that the vectors are always placed at the same location in +the address space means that both ROM and RAM startup configurations +can access these and thus the services pointed to.

The primary goal is to allow services to be provided by ROM +configurations (ROM monitors such as RedBoot in particular) with +clients in RAM configurations being able to use these +services.

Without the table of pointers this would be impossible since the +ROM and RAM applications would be linked separately - in effect having +separate name spaces - preventing direct references from one to the +other.

This decoupling of service from client is needed by RedBoot, +allowing among other things debugging of applications which do not +contain debugging client code (stubs).

Initialization (or Mechanism vs. Policy)

Virtual vectors are a mechanism for decoupling services +from clients in the address space.

The mechanism allows services to be implemented by a ROM +monitor, a RAM application, to be switched out at run-time, to be +disabled by installing pointers to dummy functions, etc.

The appropriate use of the mechanism is specified loosely by a +policy. The general policy dictates that the vectors are +initialized in whole by ROM monitors (built for ROM or RAM), or by +stand-alone applications.

For configurations relying on a ROM monitor environment, the policy +is to allow initialization on a service by service basis. The default +is to initialize all services, except COMMS services since these are +presumed to already be carrying a communication session to the +debugger / console which was used for launching the application. This +means that the bulk of the code gets tested in normal builds, and not +just once in a blue moon when building new stubs or a ROM +configuration.

The configuration options are written to comply with this policy by +default, but can be overridden by the user if desired. Defaults +are:

Pros and Cons of Virtual Vectors

There are pros and cons associated with the use of virtual +vectors. We do believe that the pros generally outweigh the cons by a +great margin, but there may be situations where the opposite is +true.

The use of the services are implemented by way of macros, meaning +that it is possible to circumvent the virtual vectors if +desired. There is (as yet) no implementation for doing this, but it is +possible.

Here is a list of pros and cons:

Pro: Allows debugging without including stubs

This is the primary reason for using virtual vectors. It + allows the ROM monitor to provide most of the debugging + infrastructure, requiring only the application to provide + hooks for asynchronous debugger interrupts and for accessing + kernel thread information.

Pro: Allows debugging to be initiated from arbitrary + channel

While this is only true where the application does not + actively override the debugging channel setup, it is a very + nice feature during development. In particular it makes it + possible to launch (and/or debug) applications via Ethernet + even though the application configuration does not contain + networking support.

Pro: Image smaller due to services being provided by ROM + monitor

All service functions except HAL IO are included in the + default configuration. But if these are all disabled the + image for download will be a little smaller. Probably + doesn't matter much for regular development, but it is a + worthwhile saving for the 20000 daily tests run in the Red + Hat eCos test farm.

Con: The vectors add a layer of indirection, increasing application + size and reducing performance.

The size increase is a fraction of what is required to + implement the services. So for RAM configurations there is + a net saving, while for ROM configurations there is a small + overhead.

The performance loss means little for most of the + services (of which the most commonly used is diagnostic IO + which happens via polled routines + anyway).

Con: The layer of indirection is another point of + failure.

The concern primarily being that of vectors being + trashed by rogue writes from bad code, causing a complete + loss of the service and possibly a crash. But this does + not differ much from a rogue write to anywhere else in the + address space which could cause the same amount of + mayhem. But it is arguably an additional point of failure + for the service in question.

Con: All the indirection stuff makes it harder to bring a HAL + up

This is a valid concern. However, seeing as most of the + code in question is shared between all HALs and should + remain unchanged over time, the risk of it being broken + when a new HAL is being worked on should be + minimal.

When starting a new port, be sure to implement the HAL + IO drivers according to the scheme used in other drivers, + and there should be no problem.

However, it is still possible to circumvent the vectors + if they are suspect of causing problems: simply change the + HAL_DIAG_INIT and HAL_DIAG_WRITE_CHAR macros to use the raw + IO functions.

Available services

The hal_if.h file in the common HAL defines the +complete list of available services. A few worth mentioning in +particular:

The COMMS channels

As all HAL IO happens via the COMMS channels these deserve to be +described in a little more detail. In particular the controls of where +diagnostic output is routed and how it is treated to allow for display +in debuggers.

Console and Debugging Channels

There are two COMMS channels - one for console IO and one for +debugging IO. They can be individually configured to use any of the +actual IO ports (serial or Ethernet) available on the platform.

The console channel is used for any IO initiated by calling the +diag_*() functions. Note that these should only be used during +development for debugging, assertion and possibly tracing +messages. All proper IO should happen via proper devices. This means +it should be possible to remove the HAL device drivers from production +configurations where assertions are disabled.

The debugging channel is used for communication between the +debugger and the stub which remotely controls the target for the +debugger (the stub runs on the target). This usually happens via some +protocol, encoding commands and replies in some suitable form.

Having two separate channels allows, e.g., for simple logging +without conflicts with the debugger or interactive IO which some +debuggers do not allow.

Mangling

As debuggers usually have a protocol using specialized commands +when communicating with the stub on the target, sending out text as +raw ASCII from the target on the same channel will either result in +protocol errors (with loss of control over the target) or the text may +just be ignored as junk by the debugger.

To get around this, some debuggers have a special command for text +output. Mangling is the process of encoding diagnostic ASCII text +output in the form specified by the debugger protocol.

When it is necessary to use mangling, i.e. when writing console +output to the same port used for debugging, a mangler function is +installed on the console channel which mangles the text and passes it +on to the debugger channel.

Controlling the Console Channel

Console output configuration is either inherited from the ROM +monitor launching the application, or it is specified by the +application. This is controlled by the new option +CYGSEM_HAL_VIRTUAL_VECTOR_INHERIT_CONSOLE which +defaults to enabled when the configuration is set to use a ROM +monitor.

If the user wants to specify the console configuration in the +application image, there are two new options that are used for +this.

Defaults are to direct diagnostic output via a mangler to the +debugging channel (CYGDBG_HAL_DIAG_TO_DEBUG_CHAN +enabled). The mangler type is controlled by the option +CYGSEM_HAL_DIAG_MANGLER. At present there are only +two mangler types:

GDB

This causes a mangler appropriate for debugging with GDB to be + installed on the console channel.

None

This causes a NULL mangler to be installed on the console + channel. It will redirect the IO to/from the debug channel + without mangling of the data. This option differs from setting + the console channel to the same IO port as the debugging + channel in that it will keep redirecting data to the debugging + channel even if that is changed to some other port.

Finally, by disabling CYGDBG_HAL_DIAG_TO_DEBUG_CHAN, the diagnostic +output is directed in raw form to the specified console IO port.

In summary this results in the following common configuration +scenarios for RAM startup configurations:

And for ROM startup configurations:

Footnote: Design Reasoning for Control of Console Channel

The current code for controlling the console channel is a +replacement for an older implementation which had some shortcomings +which addressed by the new implementation.

This is what the old implementation did: on initialization it would +check if the CDL configured console channel differed from the active +debug channel - and if so, set the console channel, thereby disabling +mangling.

The idea was that whatever channel was configured to be used for +console (i.e., diagnostic output) in the application was what should +be used. Also, it meant that if debug and console channels were +normally the same, a changed console channel would imply a request for +unmangled output.

But this prevented at least two things:

The calling Interface API

The calling interface API is defined by hal_if.h and hal_if.c in +hal/common.

The API provides a set of services. Different platforms, or +different versions of the ROM monitor for a single platform, may +implement fewer or extra service. The table has room for growth, and +any entries which are not supported map to a NOP-service (when called +it returns 0 (false)).

A client of a service should either be selected by configuration, +or have suitable fall back alternatives in case the feature is not +implemented by the ROM monitor.

Note:: Checking for unimplemented service when this may be a data +field/pointer instead of a function: suggest reserving the last entry +in the table as the NOP-service pointer. Then clients can compare a +service entry with this pointer to determine whether it's initialized +or not.

The header file cyg/hal/hal_if.h defines + the table layout and accessor macros (allowing primitive type + checking and alternative implementations should it become necessary).

The source file hal_if.c defines the table + initialization function. All HALs should call this during platform + initialization - the table will get initialized according to + configuration. Also defined here are wrapper functions which map + between the calling interface API and the API of the used eCos + functions.

Implemented Services

This is a brief description of the services, some of which are +described in further detail below.

VERSION

Version of table. Serves as a way to check for how many + features are available in the table. This is the index of the + last service in the table.

KILL_VECTOR

[Presently unused by the stub code, but initialized] This + vector defines a function to execute when the system receives + a kill signal from the debugger. It is initialized with the + reset function (see below), but the application (or eCos) can + override it if necessary.

CONSOLE_PROCS

The communication procedure table used for console IO + (see the Section called IO channels.

DEBUG_PROCS

The communication procedure table used for debugger IO + (see the Section called IO channels).

FLUSH_DCACHE

Flushes the data cache for the specified + region. Some implementations may flush the entire data cache.

FLUSH_ICACHE

Flushes (invalidates) the instruction cache + for the specified region. Some implementations may flush the + entire instruction cache.

SET_DEBUG_COMM

Change debugging communication channel.

SET_CONSOLE_COMM

Change console communication channel.

DBG_SYSCALL

Vector used to communication between debugger functions in + ROM and in RAM. RAM eCos configurations may install a function + pointer here which the ROM monitor uses to get thread + information from the kernel running in RAM.

RESET

Resets the board on call. If it is not possible to reset + the board from software, it will jump to the ROM entry point + which will perform a "software" reset of the board.

CONSOLE_INTERRUPT_FLAG

Set if a debugger interrupt request was detected while + processing console IO. Allows the actual breakpoint action to + be handled after return to RAM, ensuring proper backtraces + etc.

DELAY_US

Will delay the specified number of microseconds. The + precision is platform dependent to some extend - a small value + (<100us) is likely to cause bigger delays than requested.

FLASH_CFG_OP

For accessing configuration settings kept in flash memory.

INSTALL_BPT_FN

Installs a breakpoint at the specified address. This is + used by the asynchronous breakpoint support + (see ).

Compatibility

When a platform is changed to support the calling interface, +applications will use it if so configured. That means that if an +application is run on a platform with an older ROM monitor, the +service is almost guaranteed to fail.

For this reason, applications should only use Console Comm for HAL +diagnostics output if explicitly configured to do so +(CYGSEM_HAL_VIRTUAL_VECTOR_DIAG).

As for asynchronous GDB interrupts, the service will always be +used. This is likely to cause a crash under older ROM monitors, but +this crash may be caught by the debugger. The old workaround still +applies: if you need asynchronous breakpoints or thread debugging +under older ROM monitors, you may have to include the debugging +support when configuring eCos.

Implementation details

During the startup of a ROM monitor, the calling table will be +initialized. This also happens if eCos is configured not to rely on +a ROM monitor.

Note:: There is reserved space (256 bytes) for the vector +table whether it gets used or not. This may be something that we want +to change if we ever have to shave off every last byte for a given +target.

If thread debugging features are enabled, the function for accessing +the thread information gets registered in the table during startup of +a RAM startup configuration.

Further implementation details are described where the service itself +is described.

New Platform Ports

The hal_platform_init() function must call +hal_if_init().

The HAL serial driver must, when called via +cyg_hal_plf_comms_init() must initialize the +communication channels.

The reset() function defined in +hal_if.c will attempt to do a hardware reset, but +if this fails it will fall back to simply jumping to the reset +entry-point. On most platforms the startup initialization will go a +long way to reset the target to a sane state (there will be +exceptions, of course). For this reason, make sure to define +HAL_STUB_PLATFORM_RESET_ENTRY in plf_stub.h.

All debugging features must be in place in order for the debugging +services to be functional. See general platform porting notes.

New architecture ports

There are no specific requirements for a new architecture port in +order to support the calling interface, but the basic debugging +features must be in place. See general architecture porting notes.

IO channels

The calling interface provides procedure tables for all IO channels on +the platform. These are used for console (diagnostic) and debugger IO, +allowing a ROM monitor to provided all the needed IO routines. At +the same time, this makes it easy to switch console/debugger channels +at run-time (the old implementation had hardwired drivers for console +and debugger IO, preventing these to change at run-time).

The hal_if provides wrappers which interface these services to the +eCos infrastructure diagnostics routines. This is done in a way which +ensures proper string mangling of the diagnostics output when required +(e.g. O-packetization when using a GDB compatible ROM monitor).

Available Procedures

This is a brief description of the procedures

CH_DATA

Pointer to the controller IO base (or a pointer to a per-device + structure if more data than the IO base is required). All the + procedures below are called with this data item as the first + argument.

WRITE

Writes the buffer to the device.

READ

Fills a buffer from the device.

PUTC

Write a character to the device.

GETC

Read a character from the device.

CONTROL

Device feature control. Second argument specifies function:

DBG_ISR

ISR used to handle receive interrupts from the + device (see ).

GETC_TIMEOUT

Read a character from the device with timeout.

Usage

The standard eCos diagnostics IO functions use the channel +procedure table when CYGSEM_HAL_VIRTUAL_VECTOR_DIAG is enabled. That +means that when you use diag_printf (or the libc printf function) the +stream goes through the selected console procedure table. If you use +the virtual vector function SET_CONSOLE_COMM you can change the device +which the diagnostics output goes to at run-time.

You can also use the table functions directly if desired +(regardless of the CYGSEM_HAL_VIRTUAL_VECTOR_DIAG setting - assuming +the ROM monitor provides the services). Here is a small example which +changes the console to use channel 2, fetches the comm procs pointer +and calls the write function from that table, then restores the +console to the original channel:

#define T "Hello World!\n"
+
+int
+main(void)
+{
+    hal_virtual_comm_table_t* comm;
+    int cur = CYGACC_CALL_IF_SET_CONSOLE_COMM(CYGNUM_CALL_IF_SET_COMM_ID_QUERY_CURRENT);
+
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(2);
+
+    comm = CYGACC_CALL_IF_CONSOLE_PROCS();
+    CYGACC_COMM_IF_WRITE(*comm, T, strlen(T));
+
+    CYGACC_CALL_IF_SET_CONSOLE_COMM(cur);
+}

Beware that if doing something like the above, you should only do +it to a channel which does not have GDB at the other end: GDB ignores +raw data, so you would not see the output.

Compatibility

The use of this service is controlled by the option +CYGSEM_HAL_VIRTUAL_VECTOR_DIAG which is disabled per default on most +older platforms (thus preserving backwards compatibility with older +stubs). On newer ports, this option should always be set.

Implementation Details

There is an array of procedure tables (raw comm channels) for each +IO device of the platform which get initialized by the ROM monitor, or +optionally by a RAM startup configuration (allowing the RAM +configuration to take full control of the target). In addition to +this, there's a special table which is used to hold mangler +procedures.

The vector table defines which of these channels are selected for +console and debugging IO respectively: console entry can be empty, +point to mangler channel, or point to a raw channel. The debugger +entry should always point to a raw channel.

During normal console output (i.e., diagnostic output) the console +table will be used to handle IO if defined. If not defined, the debug +table will be used.

This means that debuggers (such as GDB) which require text streams +to be mangled (O-packetized in the case of GDB), can rely on the ROM +monitor install mangling IO routines in the special mangler table and +select this for console output. The mangler will pass the mangled data +on to the selected debugging channel.

If the eCos configuration specifies a different console channel +from that used by the debugger, the console entry will point to the +selected raw channel, thus overriding any mangler provided by the ROM +monitor.

See hal_if_diag_* routines in hal_if.c for more details of the stream +path of diagnostic output. See cyg_hal_gdb_diag_*() routines in +hal_stub.c for the mangler used for GDB communication.

New Platform Ports

Define CDL options CYGNUM_HAL_VIRTUAL_VECTOR_COMM_CHANNELS, +CYGNUM_HAL_VIRTUAL_VECTOR_DEBUG_CHANNEL, and +CYGNUM_HAL_VIRTUAL_VECTOR_CONSOLE_CHANNEL.

If CYGSEM_HAL_VIRTUAL_VECTOR_DIAG is set, make sure the infra diag +code uses the hal_if diag functions:

 #define HAL_DIAG_INIT() hal_if_diag_init()
+ #define HAL_DIAG_WRITE_CHAR(_c_) hal_if_diag_write_char(_c_)
+ #define HAL_DIAG_READ_CHAR(_c_) hal_if_diag_read_char(&_c_)

In addition to the above functions, the platform HAL must also +provide a function cyg_hal_plf_comms_init which initializes the +drivers and the channel procedure tables.

Most of the other functionality in the table is more or less +possible to copy unchanged from existing ports. Some care is necessary +though to ensure the proper handling of interrupt vectors and timeouts +for various devices handled by the same driver. See PowerPC/Cogent +platform HAL for an example implementation.

Note:: When vector table console code is not used, +the platform HAL must map the HAL_DIAG_INIT, HAL_DIAG_WRITE_CHAR and +HAL_DIAG_READ_CHAR macros directly to the low-level IO functions, +hardwired to use a compile-time configured channel.

Note:: On old ports the hardwired HAL_DIAG_INIT, +HAL_DIAG_WRITE_CHAR and +HAL_DIAG_READ_CHAR implementations will also +contain code to O-packetize the output for GDB. This should +not be adopted for new ports! On new ports the +ROM monitor is guaranteed to provide the necessary mangling via the +vector table. The hardwired configuration should be reserved for ROM +startups where achieving minimal image size is crucial.


PrevHomeNext
HAL StructureUpHAL Coding Conventions
\ No newline at end of file