1 <!-- Copyright (C) 2003 Red Hat, Inc. -->
2 <!-- This material may be distributed only subject to the terms -->
3 <!-- and conditions set forth in the Open Publication License, v1.0 -->
4 <!-- or later (the latest version is presently available at -->
5 <!-- http://www.opencontent.org/openpub/). -->
6 <!-- Distribution of the work or derivative of the work in any -->
7 <!-- standard (paper) book form is prohibited unless prior -->
8 <!-- permission is obtained from the copyright holder. -->
12 >Architecture HAL Porting</TITLE
13 ><meta name="MSSmartTagsPreventParsing" content="TRUE">
16 CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
19 TITLE="eCos Reference Manual"
20 HREF="ecos-ref.html"><LINK
22 TITLE=" Porting Guide"
23 HREF="hal-porting-guide.html"><LINK
25 TITLE="Variant HAL Porting"
26 HREF="hal-porting-variant.html"><LINK
28 TITLE="Future developments"
29 HREF="hal-future-developments.html"></HEAD
40 SUMMARY="Header navigation table"
49 >eCos Reference Manual</TH
57 HREF="hal-porting-variant.html"
65 >Chapter 11. Porting Guide</TD
71 HREF="hal-future-developments.html"
85 NAME="HAL-PORTING-ARCHITECTURE">Architecture HAL Porting</H1
87 >A new architecture HAL is the most complex HAL to write, and it the
88 least easily described. Hence this section is presently nothing more
89 than a place holder for the future.</P
95 NAME="AEN9793">HAL Architecture Porting Process</H2
97 >The easiest way to make a new architecture HAL is simply to copy an
98 existing architecture HAL of an, if possible, closely matching
99 architecture and change all the files to match the new
100 architecture. The MIPS architecture HAL should be used if possible, as
101 it has the appropriate layout and coding conventions. Other HALs
102 may deviate from that norm in various ways.</P
110 > eCos is written for GCC. It requires C and C++
111 compiler support as well as a few compiler features introduced during
112 eCos development - so compilers older than eCos may not provide these
113 features. Note that there is no C++ support for any 8 or 16 bit
114 CPUs. Before you can undertake an eCos port, you need the required
119 >The following gives a rough outline of the steps needed to create a
120 new architecture HAL. The exact order and set of steps needed will
121 vary greatly from architecture to architecture, so a lot of
122 flexibility is required. And of course, if the architecture HAL is to
123 be tested, it is necessary to do variant and platform ports for the
124 initial target simultaneously.</P
131 >Make a new directory for the new architecture under the
135 > directory in the source repository. Make an
139 > directory under this and populate this with
140 the standard set of package directories.</P
144 >Copy the CDL file from an example HAL changing its name to match the
145 new HAL. Edit the file, changing option names as appropriate. Delete
146 any options that are specific to the original HAL, and and any new
147 options that are necessary for the new architecture. This is likely to
148 be a continuing process during the development of the HAL. See <A
149 HREF="hal-porting-architecture.html#HAL-PORTING-ARCHITECTURE-CDL"
150 >the Section called <I
153 > for more details.</P
160 > file from an example
161 HAL. Within this file you need to change or define the following:</P
169 >HAL_SavedRegisters</SPAN
171 may need to reflect the save order of any group register save/restore
172 instructions, the interrupt and exception save and restore formats,
173 and the procedure calling conventions. It may also need to cater for
174 optional FPUs and other functional units. It can be quite difficult to
175 develop a layout that copes with all requirements.</P
179 >Define the bit manipulation routines,
182 >HAL_LSBIT_INDEX()</TT
186 >HAL_MSBIT_INDEX()</TT
187 >. If the architecture contains
188 instructions to perform these, or related, operations, then these
189 should be defined as inline assembler fragments. Otherwise make them
190 calls to functions.</P
196 >HAL_THREAD_INIT_CONTEXT()</TT
198 a restorable CPU context onto a stack pointer so that a later call to
201 >HAL_THREAD_LOAD_CONTEXT()</TT
205 >HAL_THREAD_SWITCH_CONTEXT()</TT
207 correctly. This macro needs to take account of the same optional
208 features of the architecture as the definition of
211 >HAL_SavedRegisters</SPAN
218 >HAL_THREAD_LOAD_CONTEXT()</TT
222 >HAL_THREAD_SWITCH_CONTEXT()</TT
223 >. These should just be
224 calls to functions in <TT
233 >HAL_REORDER_BARRIER()</TT
234 >. This prevents code
235 being moved by the compiler and is necessary in some order-sensitive
236 code. This macro is actually defined identically in all architecture,
237 so it can just be copied.</P
241 >Define breakpoint support. The macro
244 >HAL_BREAKPOINT(label)</TT
245 > needs to be an inline assembly
246 fragment that invokes a breakpoint. The breakpoint instruction should
247 be labeled with the <TT
259 >HAL_BREAKINST_SIZE</TT
260 > define the breakpoint
261 instruction for debugging purposes.</P
265 >Define GDB support. GDB views the registers of the target as a linear
266 array, with each register having a well defined offset. This array may
267 differ from the ordering defined in
270 >HAL_SavedRegisters</SPAN
274 >HAL_GET_GDB_REGISTERS()</TT
278 >HAL_SET_GDB_REGISTERS()</TT
279 > translate between the GDB
282 >HAL_SavedRegisters</SPAN
286 >HAL_THREAD_GET_SAVED_REGISTERS()</TT
288 stack pointer saved by the context switch macros into a pointer to a
291 >HAL_SavedRegisters</SPAN
292 > structure. Usually this is
293 a one-to-one translation, but this macro allows it to differ if
298 >Define long jump support. The type <SPAN
309 > provide the underlying implementation
321 >Define idle thread action. Generally the macro
324 >HAL_IDLE_THREAD_ACTION()</TT
325 > is defined to call a
333 >Define stack sizes. The macros
336 >CYGNUM_HAL_STACK_SIZE_MINIMUM</TT
340 >CYGNUM_HAL_STACK_SIZE_TYPICAL</TT
341 > should be defined to
342 the minimum size for any thread stack and a reasonable default for
343 most threads respectively. It is usually best to construct these out
344 of component sizes for the CPU save state and procedure call stack
345 usage. These definitions should not use anything other than numerical
346 values since they can be used from assembly code in some HALs.</P
350 >Define memory access macros. These macros provide translation between
351 cached and uncached and physical memory spaces. They usually consist
352 of masking out bits of the supplied address and ORing in alternative
357 >Define global pointer save/restore macros. These really only need
358 defining if the calling conventions of the architecture require a
359 global pointer (as does the MIPS architecture), they may be empty
360 otherwise. If it is necessary to define these, then take a look at the
361 MIPS implementation for an example.</P
370 > from an example HAL. Within this
371 file you should change or define the following:</P
377 >Define the exception vectors. These should be detailed in the
378 architecture specification. Essentially for each exception entry point
379 defined by the architecture there should be an entry in the VSR
380 table. The offsets of these VSR table entries should be defined here
383 >CYGNUM_HAL_VECTOR_*</TT
384 > definitions. The size of the
385 VSR table also needs to be defined here.</P
389 >Map any hardware exceptions to standard names. There is a group of
390 exception vector name of the form
393 >CYGNUM_HAL_EXCEPTION_*</TT
394 > that define a wide variety
395 of possible exceptions that many architectures raise. Generic code
396 detects whether the architecture can raise a given exception by
397 testing whether a given <TT
399 >CYGNUM_HAL_EXCEPTION_*</TT
401 definition is present. If it is present then its value is the vector
402 that raises that exception. This does not need to be a one-to-one
403 correspondence, and several <TT
405 >CYGNUM_HAL_EXCEPTION_*</TT
407 definitions may have the same value.</P
409 >Interrupt vectors are usually defined in the variant or platform
410 HALs. The interrupt number space may either be continuous with the VSR
411 number space, where they share a vector table (as in the i386) or may
412 be a separate space where a separate decode stage is used (as in MIPS
417 >Declare any static data used by the HAL to handle interrupts and
418 exceptions. This is usually three vectors for interrupts:
421 >hal_interrupt_handlers[]</TT
425 >hal_interrupt_data[]</TT
429 >hal_interrupt_objects[]</TT
430 >, which are sized according
431 to the interrupt vector definitions. In addition a definition for the
435 > should be made. These
436 vectors are normally defined in either <TT
447 >Define interrupt enable/disable macros. These are normally inline
448 assembly fragments to execute the instructions, or manipulate the CPU
449 register, that contains the CPU interrupt enable bit.</P
453 >A feature that many HALs support is the ability to execute DSRs on the
454 interrupt stack. This is not an essential feature, and is better left
455 unimplemented in the initial porting effort. If this is required, then
458 >HAL_INTERRUPT_STACK_CALL_PENDING_DSRS()</TT
460 should be defined to call a function in
468 >Define the interrupt and VSR attachment macros. If the same arrays as
469 for other HALs have been used for VSR and interrupt vectors, then
470 these macro can be copied across unchanged.</P
476 >A number of other header files also need to be filled in:</P
485 >. This file defines the basic types
486 used by eCos, together with the endianness and some other
487 characteristics. This file only really needs to contain definitions
488 if the architecture differs significantly from the defaults defined
499 >. This file contains macros for accessing
500 device IO registers. If the architecture uses memory mapped IO, then
501 these can be copied unchanged from an existing HAL such as MIPS. If
502 the architecture uses special IO instructions, then these macros must
503 be defined as inline assembler fragments. See the I386 HAL for an
504 example. PCI bus access macros are usually defined in the variant or
512 >. This file contains cache access
513 macros. If the architecture defines cache instructions, or control
514 registers, then the access macros should be defined here. Otherwise
515 they must be defined in the variant or platform HAL. Usually the cache
516 dimensions (total size, line size, ways etc.) are defined in the
527 ><architecture>.inc</TT
529 assembler headers used by <TT
539 ><architecture>.inc</TT
540 > is a general purpose
541 header that should contain things like register aliases, ABI
542 definitions and macros useful to general assembly
543 code. If there are no such definitions, then this file need not be
547 > contains macros for performing
548 various eCos related operations such as initializing the CPU, caches,
549 FPU etc. The definitions here may often be configured or overridden by
550 definitions in the variant or platform HALs. See the MIPS HAL for an
560 >. This is the most important file
561 in the HAL. It contains the CPU initialization code, exception and
562 interrupt handlers. While other HALs should be consulted for
563 structures and techniques, there is very little here that can be
564 copied over without major edits.</P
566 >The main pieces of code that need to be defined here are:</P
572 >Reset vector. This usually need to be positioned at the start of the
573 ROM or FLASH, so should be in a linker section of its own. It can then be
574 placed correctly by the linker script. Normally this code is little
575 more than a jump to the label <TT
582 >Exception vectors. These are the trampoline routines connected to the
583 hardware exception entry points that vector through the VSR table. In
584 many architectures these are adjacent to the reset vector, and should
585 occupy the same linker section. If the architecture allow the vectors
586 to be moved then it may be necessary for these trampolines to be
587 position independent so they can be relocated at runtime.</P
589 >The trampolines should do the minimum necessary to transfer control
590 from the hardware vector to the VSR pointed to by the matching table
591 entry. Exactly how this is done depends on the architecture. Usually
592 the trampoline needs to get some working registers by either saving
593 them to CPU special registers (e.g. PowerPC SPRs), using reserved
594 general registers (MIPS K0 and K1), using only memory based
595 operations (IA32), or just jumping directly (ARM). The VSR table index
596 to be used is either implicit in the entry point taken (PowerPC, IA32,
597 ARM), or must be determined from a CPU register (MIPS).</P
601 >Write kernel startup code. This is the location the reset vector jumps
602 to, and can be in the main text section of the executable, rather than
603 a special section. The code here should first initialize the CPU and other
604 hardware subsystems. The best approach is to use a set of macro
605 calls that are defined either in <TT
609 overridden in the variant or platform HALs. Other jobs that this code
610 should do are: initialize stack pointer; copy the data section from
611 ROM to RAM if necessary; zero the BSS; call variant and platform
612 initializers; call <TT
614 >cyg_hal_invoke_constructors()</TT
618 >initialize_stub()</TT
619 > if necessary. Finally it
624 HREF="hal-exception-handling.html#HAL-STARTUP"
625 >the Section called <I
632 >Write the default exception VSR. This VSR is installed in the VSR
633 table for all synchronous exception vectors. See <A
634 HREF="hal-default-synchronous-exception-handling.html"
635 >the Section called <I
636 >Default Synchronous Exception Handling</I
639 what this VSR does.</P
643 >Write the default interrupt VSR. This is installed in all VSR table
644 entries that correspond to external interrupts. See <A
645 HREF="hal-default-synchronous-exception-handling.html"
646 >the Section called <I
647 >Default Synchronous Exception Handling</I
650 what this VSR does.</P
657 >hal_interrupt_stack_call_pending_dsrs()</TT
659 function is defined in <TT
663 appear here. The purpose of this function is to call DSRs on the
664 interrupt stack rather than the current thread's stack. This is not an
665 essential feature, and may be left until later. However it interacts
666 with the stack switching that goes on in the interrupt VSR, so it may
667 make sense to write these pieces of code at the same time to ensure
670 >When this function is implemented it should do the following:</P
676 >Take a copy of the current SP and then switch to the interrupt stack.</P
680 >Save the old SP, together with the CPU status register (or whatever
681 register contains the interrupt enable status) and any other
682 registers that may be corrupted by a function call (such as any link
683 register) to locations in the interrupt stack.</P
687 >Enable interrupts.</P
693 >cyg_interrupt_call_pending_DSRs()</TT
695 kernel functions that actually calls any pending DSRs.</P
699 >Retrieve saved registers from the interrupt stack and switch back to
700 the current thread stack.</P
704 >Merge the interrupt enable state recorded in the save CPU status
705 register with the current value of the status register to restore the
706 previous enable state. If the status register does not contain any
707 other persistent state then this can be a simple restore of the
708 register. However if the register contains other state bits that might
709 have been changed by a DSR, then care must be taken not to disturb
716 >Define any data items needed. Typically <TT
720 may contain definitions for the VSR table, the interrupt tables and the
721 interrupt stack. Sometimes these are only default definitions that may
722 be overridden by the variant or platform HALs.</P
731 >. This file contains the context
733 HREF="hal-architecture-characterization.html#HAL-CONTEXT-SWITCH"
734 >the Section called <I
735 >Thread Context Switching</I
738 how these functions operate. This file may also contain the
739 implementation of <TT
753 >. This file contains any C
754 data and functions needed by the HAL. These might include:</P
762 >hal_interrupt_*[]</TT
763 >. In some HALs, if these arrays
764 are not defined in <TT
774 >cyg_hal_exception_handler()</TT
776 called from the exception VSR. It usually does extra decoding of the
777 exception and invokes any special handlers for things like FPU traps,
778 bus errors or memory exceptions. If there is nothing special to be
779 done for an exception, then it either calls into the GDB stubs, by
782 >__handle_exception()</TT
784 invokes the kernel by calling
787 >cyg_hal_deliver_exception()</TT
794 >hal_arch_default_isr()</TT
798 >hal_interrupt_handlers[]</TT
800 initialized with pointers to <TT
802 >hal_default_isr()</TT
804 which is defined in the common HAL. This function handles things like
805 Ctrl-C processing, but if that is not relevant, then it will call
808 >hal_arch_default_isr()</TT
809 >. Normally this function
810 should just return zero.</P
816 >cyg_hal_invoke_constructors()</TT
818 constructors for all static objects before the program starts. eCos
819 relies on these being called in the correct order for it to function
820 correctly. The exact way in which constructors are handled may differ
821 between architectures, although most use a simple table of function
822 pointers between labels <TT
829 > which must called in order from the
830 top down. Generally, this function can be copied directly from an
831 existing architecture HAL.</P
835 >Bit indexing functions. If the macros
838 >HAL_LSBIT_INDEX()</TT
842 >HAL_MSBIT_INDEX()</TT
843 > are defined as function calls,
844 then the functions should appear here. The main reason for doing this
845 is that the architecture does not have support for bit indexing and
846 these functions must provide the functionality by conventional
847 means. While the trivial implementation is a simple for loop, it is
848 expensive and non-deterministic. Better, constant time,
849 implementations can be found in several HALs (MIPS for example).</P
863 > then it should be defined to
864 call this function. While most of the time this function is called
865 with very small values, occasionally (particularly in some ethernet
866 drivers) it is called with values of several seconds. Hence the
867 function should take care to avoid overflow in any calculations.</P
873 >hal_idle_thread_action()</TT
874 >. This function is called
875 from the idle thread via the
878 >HAL_IDLE_THREAD_ACTION()</TT
880 defined. While normally this function does nothing, during development
881 this is often a good place to report various important system
882 parameters on LCDs, LED or other displays. This function can also
883 monitor system state and report any anomalies. If the architecture
887 > instruction then this is a good
888 place to put an inline assembly fragment to execute it. It is also a
889 good place to handle any power saving activity.</P
897 ><architecture>.ld</TT
899 this file may need to be moved to the variant HAL in the future, it
900 should initially be defined here, and only moved if necessary.</P
902 >This file defines a set of macros that are used by the platform
906 > files to generate linker scripts. Most GCC
907 toolchains are very similar so the correct approach is to copy the
908 file from an existing architecture and edit it. The main things that
909 will need editing are the <TT
913 and maybe the creation or allocation of extra sections to various
914 macros. Running the target linker with just the
918 > argument will cause it to output its
919 default linker script. This can be compared with the
923 > file and appropriate edits made.</P
927 >If GDB stubs are to be supported in RedBoot or eCos, then support must
928 be included for these. The most important of these are <TT
930 >include/<architecture>-stub.h</TT
934 >src/<architecture>-stub.c</TT
936 architecture HALs these files, and any support files they need, have
937 been derived from files supplied in <TT
941 part of the GDB toolchain package. If this is a totally new
942 architecture, this may not have been done, and they must be created
947 >include/<architecture>-stub.h</TT
949 contains definitions that are used by the GDB stubs to describe the
950 size, type, number and names of CPU registers. This information is
951 usually found in the GDB support files for the architecture. It also
952 contains prototypes for the functions exported by
955 >src/<architecture>-stub.c</TT
957 this is common to all architectures, it can be copied from some other
962 >src/<architecture>-stub.c</TT
964 functions exported by the header. Most of this is fairly straight
965 forward: the implementation in existing HALs should show exactly what
966 needs to be done. The only complex part is the support for
967 single-stepping. This is used a lot by GDB, so it cannot be
968 avoided. If the architecture has support for a trace or single-step
969 trap then that can be used for this purpose. If it does not then this
970 must be simulated by planting a breakpoint in the next
971 instruction. This can be quite involved since it requires some
972 analysis of the current instruction plus the state of the CPU to
973 determine where execution is going to go next.</P
982 NAME="HAL-PORTING-ARCHITECTURE-CDL">CDL Requirements</H2
984 >The CDL needed for any particular architecture HAL depends to a large
985 extent on the needs of that architecture. This includes issues such as
986 support for different variants, use of FPUs, MMUs and caches. The
987 exact split between the architecture, variant and platform HALs for
988 various features is also somewhat fluid. </P
990 >To give a rough idea about how the CDL for an architecture is
991 structured, we will take as an example the I386 CDL.</P
993 >This first section introduces the CDL package and placed it under the
994 main HAL package. Include files from this package will be put in the
998 > directory, and definitions from
999 this file will be placed in
1002 >include/pkgconf/hal_i386.h</TT
1007 > line specifies the files in the
1011 > directory that are to be compiled as part of
1020 CLASS="PROGRAMLISTING"
1021 >cdl_package CYGPKG_HAL_I386 {
1022 display "i386 architecture"
1026 define_header hal_i386.h
1028 The i386 architecture HAL package provides generic
1029 support for this processor architecture. It is also
1030 necessary to select a specific target platform HAL
1033 compile hal_misc.c context.S i386_stub.c hal_syscall.c</PRE
1038 >Next we need to generate some files using non-standard make rules. The
1042 >, which is not put into the
1043 library, but linked explicitly with all applications. The second is
1044 the generation of the <TT
1051 > and the startup-selected
1055 > file. Both of these are essentially
1056 boilerplate code that can be copied and edited.</P
1064 CLASS="PROGRAMLISTING"
1066 <PREFIX>/lib/vectors.o : <PACKAGE>/src/vectors.S
1067 $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(CFLAGS) -c -o $@ $<
1068 @echo $@ ": \\" > $(notdir $@).deps
1069 @tail +2 vectors.tmp >> $(notdir $@).deps
1070 @echo >> $(notdir $@).deps
1075 <PREFIX>/lib/target.ld: <PACKAGE>/src/i386.ld
1076 $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $<
1077 @echo $@ ": \\" > $(notdir $@).deps
1078 @tail +2 target.tmp >> $(notdir $@).deps
1079 @echo >> $(notdir $@).deps
1086 >The i386 is currently the only architecture that supports SMP. The
1087 following CDL simply enabled the HAL SMP support if
1088 required. Generally this will get enabled as a result of a
1092 > statement in the kernel. The
1096 > statement here turns off lazy FPU
1097 switching in the FPU support code, since it is inconsistent with SMP
1106 CLASS="PROGRAMLISTING"
1107 > cdl_component CYGPKG_HAL_SMP_SUPPORT {
1108 display "SMP support"
1110 requires { CYGHWR_HAL_I386_FPU_SWITCH_LAZY == 0 }
1112 cdl_option CYGPKG_HAL_SMP_CPU_MAX {
1113 display "Max number of CPUs supported"
1122 >The i386 HAL has optional FPU support, which is enabled by default. It
1123 can be disabled to improve system performance. There are two FPU
1124 support options: either to save and restore the FPU state on every
1125 context switch, or to only switch the FPU state when necessary.</P
1133 CLASS="PROGRAMLISTING"
1135 cdl_component CYGHWR_HAL_I386_FPU {
1136 display "Enable I386 FPU support"
1138 description "This component enables support for the
1139 I386 floating point unit."
1141 cdl_option CYGHWR_HAL_I386_FPU_SWITCH_LAZY {
1142 display "Use lazy FPU state switching"
1147 This option enables lazy FPU state switching.
1148 The default behaviour for eCos is to save and
1149 restore FPU state on every thread switch, interrupt
1150 and exception. While simple and deterministic, this
1151 approach can be expensive if the FPU is not used by
1152 all threads. The alternative, enabled by this option,
1153 is to use hardware features that allow the FPU state
1154 of a thread to be left in the FPU after it has been
1155 descheduled, and to allow the state to be switched to
1156 a new thread only if it actually uses the FPU. Where
1157 only one or two threads use the FPU this can avoid a
1158 lot of unnecessary state switching."
1165 >The i386 HAL also has support for different classes of CPU. In
1166 particular, Pentium class CPUs have extra functional units, and some
1167 variants of GDB expect more registers to be reported. These options
1168 enable these features. Generally these are enabled by
1172 > statements in variant or platform
1184 CLASS="PROGRAMLISTING"
1185 > cdl_component CYGHWR_HAL_I386_PENTIUM {
1186 display "Enable Pentium class CPU features"
1188 description "This component enables support for various
1189 features of Pentium class CPUs."
1191 cdl_option CYGHWR_HAL_I386_PENTIUM_SSE {
1192 display "Save/Restore SSE registers on context switch"
1197 This option enables SSE state switching. The default
1198 behaviour for eCos is to ignore the SSE registers.
1199 Enabling this option adds SSE state information to
1200 every thread context."
1203 cdl_option CYGHWR_HAL_I386_PENTIUM_GDB_REGS {
1204 display "Support extra Pentium registers in GDB stub"
1209 This option enables support for extra Pentium registers
1210 in the GDB stub. These are registers such as CR0-CR4, and
1211 all MSRs. Not all GDBs support these registers, so the
1212 default behaviour for eCos is to not include them in the
1213 GDB stub support code."
1220 >In the i386 HALs, the linker script is provided by the architecture
1221 HAL. In other HALs, for example MIPS, it is provided in the variant
1222 HAL. The following option provides the name of the linker script to
1223 other elements in the configuration system.</P
1231 CLASS="PROGRAMLISTING"
1232 > cdl_option CYGBLD_LINKER_SCRIPT {
1233 display "Linker script"
1236 calculated { "src/i386.ld" }
1242 >Finally, this interface indicates whether the platform supplied an
1243 implementation of the
1246 >hal_i386_mem_real_region_top()</TT
1248 does then it will contain a line of the form: <TT
1251 CYGINT_HAL_I386_MEM_REAL_REGION_TOP</TT
1252 >. This allows packages
1253 such as RedBoot to detect the presence of this function so that they
1262 CLASS="PROGRAMLISTING"
1263 > cdl_interface CYGINT_HAL_I386_MEM_REAL_REGION_TOP {
1264 display "Implementations of hal_i386_mem_real_region_top()"
1278 SUMMARY="Footer navigation table"
1289 HREF="hal-porting-variant.html"
1298 HREF="ecos-ref.html"
1307 HREF="hal-future-developments.html"
1317 >Variant HAL Porting</TD
1323 HREF="hal-porting-guide.html"
1331 >Future developments</TD