1 |
28 |
unneback |
<!-- 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. -->
|
9 |
|
|
<HTML
|
10 |
|
|
><HEAD
|
11 |
|
|
><TITLE
|
12 |
|
|
>Architecture HAL Porting</TITLE
|
13 |
|
|
><meta name="MSSmartTagsPreventParsing" content="TRUE">
|
14 |
|
|
<META
|
15 |
|
|
NAME="GENERATOR"
|
16 |
|
|
CONTENT="Modular DocBook HTML Stylesheet Version 1.76b+
|
17 |
|
|
"><LINK
|
18 |
|
|
REL="HOME"
|
19 |
|
|
TITLE="eCos Reference Manual"
|
20 |
|
|
HREF="ecos-ref.html"><LINK
|
21 |
|
|
REL="UP"
|
22 |
|
|
TITLE=" Porting Guide"
|
23 |
|
|
HREF="hal-porting-guide.html"><LINK
|
24 |
|
|
REL="PREVIOUS"
|
25 |
|
|
TITLE="Variant HAL Porting"
|
26 |
|
|
HREF="hal-porting-variant.html"><LINK
|
27 |
|
|
REL="NEXT"
|
28 |
|
|
TITLE="Future developments"
|
29 |
|
|
HREF="hal-future-developments.html"></HEAD
|
30 |
|
|
><BODY
|
31 |
|
|
CLASS="SECTION"
|
32 |
|
|
BGCOLOR="#FFFFFF"
|
33 |
|
|
TEXT="#000000"
|
34 |
|
|
LINK="#0000FF"
|
35 |
|
|
VLINK="#840084"
|
36 |
|
|
ALINK="#0000FF"
|
37 |
|
|
><DIV
|
38 |
|
|
CLASS="NAVHEADER"
|
39 |
|
|
><TABLE
|
40 |
|
|
SUMMARY="Header navigation table"
|
41 |
|
|
WIDTH="100%"
|
42 |
|
|
BORDER="0"
|
43 |
|
|
CELLPADDING="0"
|
44 |
|
|
CELLSPACING="0"
|
45 |
|
|
><TR
|
46 |
|
|
><TH
|
47 |
|
|
COLSPAN="3"
|
48 |
|
|
ALIGN="center"
|
49 |
|
|
>eCos Reference Manual</TH
|
50 |
|
|
></TR
|
51 |
|
|
><TR
|
52 |
|
|
><TD
|
53 |
|
|
WIDTH="10%"
|
54 |
|
|
ALIGN="left"
|
55 |
|
|
VALIGN="bottom"
|
56 |
|
|
><A
|
57 |
|
|
HREF="hal-porting-variant.html"
|
58 |
|
|
ACCESSKEY="P"
|
59 |
|
|
>Prev</A
|
60 |
|
|
></TD
|
61 |
|
|
><TD
|
62 |
|
|
WIDTH="80%"
|
63 |
|
|
ALIGN="center"
|
64 |
|
|
VALIGN="bottom"
|
65 |
|
|
>Chapter 11. Porting Guide</TD
|
66 |
|
|
><TD
|
67 |
|
|
WIDTH="10%"
|
68 |
|
|
ALIGN="right"
|
69 |
|
|
VALIGN="bottom"
|
70 |
|
|
><A
|
71 |
|
|
HREF="hal-future-developments.html"
|
72 |
|
|
ACCESSKEY="N"
|
73 |
|
|
>Next</A
|
74 |
|
|
></TD
|
75 |
|
|
></TR
|
76 |
|
|
></TABLE
|
77 |
|
|
><HR
|
78 |
|
|
ALIGN="LEFT"
|
79 |
|
|
WIDTH="100%"></DIV
|
80 |
|
|
><DIV
|
81 |
|
|
CLASS="SECTION"
|
82 |
|
|
><H1
|
83 |
|
|
CLASS="SECTION"
|
84 |
|
|
><A
|
85 |
|
|
NAME="HAL-PORTING-ARCHITECTURE">Architecture HAL Porting</H1
|
86 |
|
|
><P
|
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
|
90 |
|
|
><DIV
|
91 |
|
|
CLASS="SECTION"
|
92 |
|
|
><H2
|
93 |
|
|
CLASS="SECTION"
|
94 |
|
|
><A
|
95 |
|
|
NAME="AEN9793">HAL Architecture Porting Process</H2
|
96 |
|
|
><P
|
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
|
103 |
|
|
><DIV
|
104 |
|
|
CLASS="NOTE"
|
105 |
|
|
><BLOCKQUOTE
|
106 |
|
|
CLASS="NOTE"
|
107 |
|
|
><P
|
108 |
|
|
><B
|
109 |
|
|
>Note: </B
|
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
|
115 |
|
|
compiler support.</P
|
116 |
|
|
></BLOCKQUOTE
|
117 |
|
|
></DIV
|
118 |
|
|
><P
|
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
|
125 |
|
|
><P
|
126 |
|
|
></P
|
127 |
|
|
><OL
|
128 |
|
|
TYPE="1"
|
129 |
|
|
><LI
|
130 |
|
|
><P
|
131 |
|
|
>Make a new directory for the new architecture under the
|
132 |
|
|
<TT
|
133 |
|
|
CLASS="FILENAME"
|
134 |
|
|
>hal</TT
|
135 |
|
|
> directory in the source repository. Make an
|
136 |
|
|
<TT
|
137 |
|
|
CLASS="FILENAME"
|
138 |
|
|
>arch</TT
|
139 |
|
|
> directory under this and populate this with
|
140 |
|
|
the standard set of package directories.</P
|
141 |
|
|
></LI
|
142 |
|
|
><LI
|
143 |
|
|
><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
|
151 |
|
|
>CDL Requirements</I
|
152 |
|
|
></A
|
153 |
|
|
> for more details.</P
|
154 |
|
|
></LI
|
155 |
|
|
><LI
|
156 |
|
|
><P
|
157 |
|
|
>Copy the <TT
|
158 |
|
|
CLASS="FILENAME"
|
159 |
|
|
>hal_arch.h</TT
|
160 |
|
|
> file from an example
|
161 |
|
|
HAL. Within this file you need to change or define the following:</P
|
162 |
|
|
><P
|
163 |
|
|
></P
|
164 |
|
|
><UL
|
165 |
|
|
><LI
|
166 |
|
|
><P
|
167 |
|
|
>Define the <SPAN
|
168 |
|
|
CLASS="STRUCTNAME"
|
169 |
|
|
>HAL_SavedRegisters</SPAN
|
170 |
|
|
> structure. This
|
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
|
176 |
|
|
></LI
|
177 |
|
|
><LI
|
178 |
|
|
><P
|
179 |
|
|
>Define the bit manipulation routines,
|
180 |
|
|
<TT
|
181 |
|
|
CLASS="LITERAL"
|
182 |
|
|
>HAL_LSBIT_INDEX()</TT
|
183 |
|
|
> and
|
184 |
|
|
<TT
|
185 |
|
|
CLASS="LITERAL"
|
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
|
191 |
|
|
></LI
|
192 |
|
|
><LI
|
193 |
|
|
><P
|
194 |
|
|
>Define <TT
|
195 |
|
|
CLASS="LITERAL"
|
196 |
|
|
>HAL_THREAD_INIT_CONTEXT()</TT
|
197 |
|
|
>. This initializes
|
198 |
|
|
a restorable CPU context onto a stack pointer so that a later call to
|
199 |
|
|
<TT
|
200 |
|
|
CLASS="LITERAL"
|
201 |
|
|
>HAL_THREAD_LOAD_CONTEXT()</TT
|
202 |
|
|
> or
|
203 |
|
|
<TT
|
204 |
|
|
CLASS="LITERAL"
|
205 |
|
|
>HAL_THREAD_SWITCH_CONTEXT()</TT
|
206 |
|
|
> will execute it
|
207 |
|
|
correctly. This macro needs to take account of the same optional
|
208 |
|
|
features of the architecture as the definition of
|
209 |
|
|
<SPAN
|
210 |
|
|
CLASS="STRUCTNAME"
|
211 |
|
|
>HAL_SavedRegisters</SPAN
|
212 |
|
|
>.</P
|
213 |
|
|
></LI
|
214 |
|
|
><LI
|
215 |
|
|
><P
|
216 |
|
|
>Define <TT
|
217 |
|
|
CLASS="LITERAL"
|
218 |
|
|
>HAL_THREAD_LOAD_CONTEXT()</TT
|
219 |
|
|
> and
|
220 |
|
|
<TT
|
221 |
|
|
CLASS="LITERAL"
|
222 |
|
|
>HAL_THREAD_SWITCH_CONTEXT()</TT
|
223 |
|
|
>. These should just be
|
224 |
|
|
calls to functions in <TT
|
225 |
|
|
CLASS="FILENAME"
|
226 |
|
|
>context.S</TT
|
227 |
|
|
>.</P
|
228 |
|
|
></LI
|
229 |
|
|
><LI
|
230 |
|
|
><P
|
231 |
|
|
>Define <TT
|
232 |
|
|
CLASS="LITERAL"
|
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
|
238 |
|
|
></LI
|
239 |
|
|
><LI
|
240 |
|
|
><P
|
241 |
|
|
>Define breakpoint support. The macro
|
242 |
|
|
<TT
|
243 |
|
|
CLASS="LITERAL"
|
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
|
248 |
|
|
CLASS="PARAMETER"
|
249 |
|
|
><I
|
250 |
|
|
>label</I
|
251 |
|
|
></TT
|
252 |
|
|
>
|
253 |
|
|
argument. <TT
|
254 |
|
|
CLASS="LITERAL"
|
255 |
|
|
>HAL_BREAKINST</TT
|
256 |
|
|
> and
|
257 |
|
|
<TT
|
258 |
|
|
CLASS="LITERAL"
|
259 |
|
|
>HAL_BREAKINST_SIZE</TT
|
260 |
|
|
> define the breakpoint
|
261 |
|
|
instruction for debugging purposes.</P
|
262 |
|
|
></LI
|
263 |
|
|
><LI
|
264 |
|
|
><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
|
268 |
|
|
<SPAN
|
269 |
|
|
CLASS="STRUCTNAME"
|
270 |
|
|
>HAL_SavedRegisters</SPAN
|
271 |
|
|
>. The macros
|
272 |
|
|
<TT
|
273 |
|
|
CLASS="LITERAL"
|
274 |
|
|
>HAL_GET_GDB_REGISTERS()</TT
|
275 |
|
|
> and
|
276 |
|
|
<TT
|
277 |
|
|
CLASS="LITERAL"
|
278 |
|
|
>HAL_SET_GDB_REGISTERS()</TT
|
279 |
|
|
> translate between the GDB
|
280 |
|
|
array and the <SPAN
|
281 |
|
|
CLASS="STRUCTNAME"
|
282 |
|
|
>HAL_SavedRegisters</SPAN
|
283 |
|
|
> structure.
|
284 |
|
|
The <TT
|
285 |
|
|
CLASS="LITERAL"
|
286 |
|
|
>HAL_THREAD_GET_SAVED_REGISTERS()</TT
|
287 |
|
|
> translates a
|
288 |
|
|
stack pointer saved by the context switch macros into a pointer to a
|
289 |
|
|
<SPAN
|
290 |
|
|
CLASS="STRUCTNAME"
|
291 |
|
|
>HAL_SavedRegisters</SPAN
|
292 |
|
|
> structure. Usually this is
|
293 |
|
|
a one-to-one translation, but this macro allows it to differ if
|
294 |
|
|
necessary.</P
|
295 |
|
|
></LI
|
296 |
|
|
><LI
|
297 |
|
|
><P
|
298 |
|
|
>Define long jump support. The type <SPAN
|
299 |
|
|
CLASS="TYPE"
|
300 |
|
|
>hal_jmp_buf</SPAN
|
301 |
|
|
> and the
|
302 |
|
|
functions <TT
|
303 |
|
|
CLASS="FUNCTION"
|
304 |
|
|
>hal_setjmp()</TT
|
305 |
|
|
> and
|
306 |
|
|
<TT
|
307 |
|
|
CLASS="LITERAL"
|
308 |
|
|
>hal_longjmp()</TT
|
309 |
|
|
> provide the underlying implementation
|
310 |
|
|
of the C library <TT
|
311 |
|
|
CLASS="FUNCTION"
|
312 |
|
|
>setjmp()</TT
|
313 |
|
|
> and
|
314 |
|
|
<TT
|
315 |
|
|
CLASS="FUNCTION"
|
316 |
|
|
>longjmp()</TT
|
317 |
|
|
>.</P
|
318 |
|
|
></LI
|
319 |
|
|
><LI
|
320 |
|
|
><P
|
321 |
|
|
>Define idle thread action. Generally the macro
|
322 |
|
|
<TT
|
323 |
|
|
CLASS="LITERAL"
|
324 |
|
|
>HAL_IDLE_THREAD_ACTION()</TT
|
325 |
|
|
> is defined to call a
|
326 |
|
|
function in <TT
|
327 |
|
|
CLASS="FILENAME"
|
328 |
|
|
>hal_misc.c</TT
|
329 |
|
|
>.</P
|
330 |
|
|
></LI
|
331 |
|
|
><LI
|
332 |
|
|
><P
|
333 |
|
|
>Define stack sizes. The macros
|
334 |
|
|
<TT
|
335 |
|
|
CLASS="LITERAL"
|
336 |
|
|
>CYGNUM_HAL_STACK_SIZE_MINIMUM</TT
|
337 |
|
|
> and
|
338 |
|
|
<TT
|
339 |
|
|
CLASS="LITERAL"
|
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
|
347 |
|
|
></LI
|
348 |
|
|
><LI
|
349 |
|
|
><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
|
353 |
|
|
address bits.</P
|
354 |
|
|
></LI
|
355 |
|
|
><LI
|
356 |
|
|
><P
|
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
|
362 |
|
|
></LI
|
363 |
|
|
></UL
|
364 |
|
|
></LI
|
365 |
|
|
><LI
|
366 |
|
|
><P
|
367 |
|
|
>Copy <TT
|
368 |
|
|
CLASS="FILENAME"
|
369 |
|
|
>hal_intr.h</TT
|
370 |
|
|
> from an example HAL. Within this
|
371 |
|
|
file you should change or define the following:</P
|
372 |
|
|
><P
|
373 |
|
|
></P
|
374 |
|
|
><UL
|
375 |
|
|
><LI
|
376 |
|
|
><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
|
381 |
|
|
by <TT
|
382 |
|
|
CLASS="LITERAL"
|
383 |
|
|
>CYGNUM_HAL_VECTOR_*</TT
|
384 |
|
|
> definitions. The size of the
|
385 |
|
|
VSR table also needs to be defined here.</P
|
386 |
|
|
></LI
|
387 |
|
|
><LI
|
388 |
|
|
><P
|
389 |
|
|
>Map any hardware exceptions to standard names. There is a group of
|
390 |
|
|
exception vector name of the form
|
391 |
|
|
<TT
|
392 |
|
|
CLASS="LITERAL"
|
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
|
398 |
|
|
CLASS="LITERAL"
|
399 |
|
|
>CYGNUM_HAL_EXCEPTION_*</TT
|
400 |
|
|
>
|
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
|
404 |
|
|
CLASS="LITERAL"
|
405 |
|
|
>CYGNUM_HAL_EXCEPTION_*</TT
|
406 |
|
|
>
|
407 |
|
|
definitions may have the same value.</P
|
408 |
|
|
><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
|
413 |
|
|
or PowerPC).</P
|
414 |
|
|
></LI
|
415 |
|
|
><LI
|
416 |
|
|
><P
|
417 |
|
|
>Declare any static data used by the HAL to handle interrupts and
|
418 |
|
|
exceptions. This is usually three vectors for interrupts:
|
419 |
|
|
<TT
|
420 |
|
|
CLASS="LITERAL"
|
421 |
|
|
>hal_interrupt_handlers[]</TT
|
422 |
|
|
>,
|
423 |
|
|
<TT
|
424 |
|
|
CLASS="LITERAL"
|
425 |
|
|
>hal_interrupt_data[]</TT
|
426 |
|
|
> and
|
427 |
|
|
<TT
|
428 |
|
|
CLASS="LITERAL"
|
429 |
|
|
>hal_interrupt_objects[]</TT
|
430 |
|
|
>, which are sized according
|
431 |
|
|
to the interrupt vector definitions. In addition a definition for the
|
432 |
|
|
VSR table, <TT
|
433 |
|
|
CLASS="LITERAL"
|
434 |
|
|
>hal_vsr_table[]</TT
|
435 |
|
|
> should be made. These
|
436 |
|
|
vectors are normally defined in either <TT
|
437 |
|
|
CLASS="FILENAME"
|
438 |
|
|
>vectors.S</TT
|
439 |
|
|
>
|
440 |
|
|
or <TT
|
441 |
|
|
CLASS="FILENAME"
|
442 |
|
|
>hal_misc.c</TT
|
443 |
|
|
>.</P
|
444 |
|
|
></LI
|
445 |
|
|
><LI
|
446 |
|
|
><P
|
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
|
450 |
|
|
></LI
|
451 |
|
|
><LI
|
452 |
|
|
><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
|
456 |
|
|
the macro <TT
|
457 |
|
|
CLASS="LITERAL"
|
458 |
|
|
>HAL_INTERRUPT_STACK_CALL_PENDING_DSRS()</TT
|
459 |
|
|
>
|
460 |
|
|
should be defined to call a function in
|
461 |
|
|
<TT
|
462 |
|
|
CLASS="FILENAME"
|
463 |
|
|
>vectors.S</TT
|
464 |
|
|
>.</P
|
465 |
|
|
></LI
|
466 |
|
|
><LI
|
467 |
|
|
><P
|
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
|
471 |
|
|
></LI
|
472 |
|
|
></UL
|
473 |
|
|
></LI
|
474 |
|
|
><LI
|
475 |
|
|
><P
|
476 |
|
|
>A number of other header files also need to be filled in:</P
|
477 |
|
|
><P
|
478 |
|
|
></P
|
479 |
|
|
><UL
|
480 |
|
|
><LI
|
481 |
|
|
><P
|
482 |
|
|
><TT
|
483 |
|
|
CLASS="FILENAME"
|
484 |
|
|
>basetype.h</TT
|
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
|
489 |
|
|
in <TT
|
490 |
|
|
CLASS="FILENAME"
|
491 |
|
|
>cyg_type.h</TT
|
492 |
|
|
></P
|
493 |
|
|
></LI
|
494 |
|
|
><LI
|
495 |
|
|
><P
|
496 |
|
|
><TT
|
497 |
|
|
CLASS="FILENAME"
|
498 |
|
|
>hal_io.h</TT
|
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
|
505 |
|
|
platform HALs.</P
|
506 |
|
|
></LI
|
507 |
|
|
><LI
|
508 |
|
|
><P
|
509 |
|
|
><TT
|
510 |
|
|
CLASS="FILENAME"
|
511 |
|
|
>hal_cache.h</TT
|
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
|
517 |
|
|
variant HAL.</P
|
518 |
|
|
></LI
|
519 |
|
|
><LI
|
520 |
|
|
><P
|
521 |
|
|
><TT
|
522 |
|
|
CLASS="FILENAME"
|
523 |
|
|
>arch.inc</TT
|
524 |
|
|
> and
|
525 |
|
|
<TT
|
526 |
|
|
CLASS="FILENAME"
|
527 |
|
|
><architecture>.inc</TT
|
528 |
|
|
>. These files are
|
529 |
|
|
assembler headers used by <TT
|
530 |
|
|
CLASS="FILENAME"
|
531 |
|
|
>vectors.S</TT
|
532 |
|
|
> and
|
533 |
|
|
<TT
|
534 |
|
|
CLASS="FILENAME"
|
535 |
|
|
>context.S</TT
|
536 |
|
|
>.
|
537 |
|
|
<TT
|
538 |
|
|
CLASS="FILENAME"
|
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
|
544 |
|
|
provided. <TT
|
545 |
|
|
CLASS="FILENAME"
|
546 |
|
|
>arch.inc</TT
|
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
|
551 |
|
|
example of this.</P
|
552 |
|
|
></LI
|
553 |
|
|
></UL
|
554 |
|
|
></LI
|
555 |
|
|
><LI
|
556 |
|
|
><P
|
557 |
|
|
>Write <TT
|
558 |
|
|
CLASS="FILENAME"
|
559 |
|
|
>vectors.S</TT
|
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
|
565 |
|
|
><P
|
566 |
|
|
>The main pieces of code that need to be defined here are:</P
|
567 |
|
|
><P
|
568 |
|
|
></P
|
569 |
|
|
><UL
|
570 |
|
|
><LI
|
571 |
|
|
><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
|
576 |
|
|
CLASS="LITERAL"
|
577 |
|
|
>_start</TT
|
578 |
|
|
>.</P
|
579 |
|
|
></LI
|
580 |
|
|
><LI
|
581 |
|
|
><P
|
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
|
588 |
|
|
><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
|
598 |
|
|
></LI
|
599 |
|
|
><LI
|
600 |
|
|
><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
|
606 |
|
|
CLASS="FILENAME"
|
607 |
|
|
>arch.inc</TT
|
608 |
|
|
> or
|
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
|
613 |
|
|
CLASS="FUNCTION"
|
614 |
|
|
>cyg_hal_invoke_constructors()</TT
|
615 |
|
|
>;
|
616 |
|
|
call <TT
|
617 |
|
|
CLASS="FUNCTION"
|
618 |
|
|
>initialize_stub()</TT
|
619 |
|
|
> if necessary. Finally it
|
620 |
|
|
should call <TT
|
621 |
|
|
CLASS="FUNCTION"
|
622 |
|
|
>cyg_start()</TT
|
623 |
|
|
>. See <A
|
624 |
|
|
HREF="hal-exception-handling.html#HAL-STARTUP"
|
625 |
|
|
>the Section called <I
|
626 |
|
|
>HAL Startup</I
|
627 |
|
|
> in Chapter 10</A
|
628 |
|
|
> for details.</P
|
629 |
|
|
></LI
|
630 |
|
|
><LI
|
631 |
|
|
><P
|
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
|
637 |
|
|
> in Chapter 10</A
|
638 |
|
|
> for details of
|
639 |
|
|
what this VSR does.</P
|
640 |
|
|
></LI
|
641 |
|
|
><LI
|
642 |
|
|
><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
|
648 |
|
|
> in Chapter 10</A
|
649 |
|
|
> for details of
|
650 |
|
|
what this VSR does.</P
|
651 |
|
|
></LI
|
652 |
|
|
><LI
|
653 |
|
|
><P
|
654 |
|
|
>Write
|
655 |
|
|
<TT
|
656 |
|
|
CLASS="FUNCTION"
|
657 |
|
|
>hal_interrupt_stack_call_pending_dsrs()</TT
|
658 |
|
|
>. If this
|
659 |
|
|
function is defined in <TT
|
660 |
|
|
CLASS="FILENAME"
|
661 |
|
|
>hal_arch.h</TT
|
662 |
|
|
> then it should
|
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
|
668 |
|
|
consistency.</P
|
669 |
|
|
><P
|
670 |
|
|
>When this function is implemented it should do the following:</P
|
671 |
|
|
><P
|
672 |
|
|
></P
|
673 |
|
|
><UL
|
674 |
|
|
><LI
|
675 |
|
|
><P
|
676 |
|
|
>Take a copy of the current SP and then switch to the interrupt stack.</P
|
677 |
|
|
></LI
|
678 |
|
|
><LI
|
679 |
|
|
><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
|
684 |
|
|
></LI
|
685 |
|
|
><LI
|
686 |
|
|
><P
|
687 |
|
|
>Enable interrupts.</P
|
688 |
|
|
></LI
|
689 |
|
|
><LI
|
690 |
|
|
><P
|
691 |
|
|
>Call <TT
|
692 |
|
|
CLASS="FUNCTION"
|
693 |
|
|
>cyg_interrupt_call_pending_DSRs()</TT
|
694 |
|
|
>. This is a
|
695 |
|
|
kernel functions that actually calls any pending DSRs.</P
|
696 |
|
|
></LI
|
697 |
|
|
><LI
|
698 |
|
|
><P
|
699 |
|
|
>Retrieve saved registers from the interrupt stack and switch back to
|
700 |
|
|
the current thread stack.</P
|
701 |
|
|
></LI
|
702 |
|
|
><LI
|
703 |
|
|
><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
|
710 |
|
|
these.</P
|
711 |
|
|
></LI
|
712 |
|
|
></UL
|
713 |
|
|
></LI
|
714 |
|
|
><LI
|
715 |
|
|
><P
|
716 |
|
|
>Define any data items needed. Typically <TT
|
717 |
|
|
CLASS="FILENAME"
|
718 |
|
|
>vectors.S</TT
|
719 |
|
|
>
|
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
|
723 |
|
|
></LI
|
724 |
|
|
></UL
|
725 |
|
|
></LI
|
726 |
|
|
><LI
|
727 |
|
|
><P
|
728 |
|
|
>Write <TT
|
729 |
|
|
CLASS="FILENAME"
|
730 |
|
|
>context.S</TT
|
731 |
|
|
>. This file contains the context
|
732 |
|
|
switch code. See <A
|
733 |
|
|
HREF="hal-architecture-characterization.html#HAL-CONTEXT-SWITCH"
|
734 |
|
|
>the Section called <I
|
735 |
|
|
>Thread Context Switching</I
|
736 |
|
|
> in Chapter 9</A
|
737 |
|
|
> for details of
|
738 |
|
|
how these functions operate. This file may also contain the
|
739 |
|
|
implementation of <TT
|
740 |
|
|
CLASS="FUNCTION"
|
741 |
|
|
>hal_setjmp()</TT
|
742 |
|
|
> and
|
743 |
|
|
<TT
|
744 |
|
|
CLASS="FUNCTION"
|
745 |
|
|
>hal_longjmp()</TT
|
746 |
|
|
>.</P
|
747 |
|
|
></LI
|
748 |
|
|
><LI
|
749 |
|
|
><P
|
750 |
|
|
>Write <TT
|
751 |
|
|
CLASS="FILENAME"
|
752 |
|
|
>hal_misc.c</TT
|
753 |
|
|
>. This file contains any C
|
754 |
|
|
data and functions needed by the HAL. These might include:</P
|
755 |
|
|
><P
|
756 |
|
|
></P
|
757 |
|
|
><UL
|
758 |
|
|
><LI
|
759 |
|
|
><P
|
760 |
|
|
><TT
|
761 |
|
|
CLASS="VARNAME"
|
762 |
|
|
>hal_interrupt_*[]</TT
|
763 |
|
|
>. In some HALs, if these arrays
|
764 |
|
|
are not defined in <TT
|
765 |
|
|
CLASS="FILENAME"
|
766 |
|
|
>vectors.S</TT
|
767 |
|
|
> then they must be
|
768 |
|
|
defined here.</P
|
769 |
|
|
></LI
|
770 |
|
|
><LI
|
771 |
|
|
><P
|
772 |
|
|
><TT
|
773 |
|
|
CLASS="FUNCTION"
|
774 |
|
|
>cyg_hal_exception_handler()</TT
|
775 |
|
|
>. This function is
|
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
|
780 |
|
|
calling <TT
|
781 |
|
|
CLASS="FUNCTION"
|
782 |
|
|
>__handle_exception()</TT
|
783 |
|
|
>, or
|
784 |
|
|
invokes the kernel by calling
|
785 |
|
|
<TT
|
786 |
|
|
CLASS="FUNCTION"
|
787 |
|
|
>cyg_hal_deliver_exception()</TT
|
788 |
|
|
>.</P
|
789 |
|
|
></LI
|
790 |
|
|
><LI
|
791 |
|
|
><P
|
792 |
|
|
><TT
|
793 |
|
|
CLASS="FUNCTION"
|
794 |
|
|
>hal_arch_default_isr()</TT
|
795 |
|
|
>. The
|
796 |
|
|
<TT
|
797 |
|
|
CLASS="VARNAME"
|
798 |
|
|
>hal_interrupt_handlers[]</TT
|
799 |
|
|
> array is usually
|
800 |
|
|
initialized with pointers to <TT
|
801 |
|
|
CLASS="FILENAME"
|
802 |
|
|
>hal_default_isr()</TT
|
803 |
|
|
>,
|
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
|
806 |
|
|
<TT
|
807 |
|
|
CLASS="FUNCTION"
|
808 |
|
|
>hal_arch_default_isr()</TT
|
809 |
|
|
>. Normally this function
|
810 |
|
|
should just return zero.</P
|
811 |
|
|
></LI
|
812 |
|
|
><LI
|
813 |
|
|
><P
|
814 |
|
|
><TT
|
815 |
|
|
CLASS="FUNCTION"
|
816 |
|
|
>cyg_hal_invoke_constructors()</TT
|
817 |
|
|
>. This calls the
|
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
|
823 |
|
|
CLASS="LITERAL"
|
824 |
|
|
>__CTOR_LIST__</TT
|
825 |
|
|
> and
|
826 |
|
|
<TT
|
827 |
|
|
CLASS="LITERAL"
|
828 |
|
|
>__CTOR_END__</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
|
832 |
|
|
></LI
|
833 |
|
|
><LI
|
834 |
|
|
><P
|
835 |
|
|
>Bit indexing functions. If the macros
|
836 |
|
|
<TT
|
837 |
|
|
CLASS="LITERAL"
|
838 |
|
|
>HAL_LSBIT_INDEX()</TT
|
839 |
|
|
> and
|
840 |
|
|
<TT
|
841 |
|
|
CLASS="LITERAL"
|
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
|
850 |
|
|
></LI
|
851 |
|
|
><LI
|
852 |
|
|
><P
|
853 |
|
|
><TT
|
854 |
|
|
CLASS="FUNCTION"
|
855 |
|
|
>hal_delay_us()</TT
|
856 |
|
|
>. If the macro
|
857 |
|
|
<TT
|
858 |
|
|
CLASS="LITERAL"
|
859 |
|
|
>HAL_DELAY_US()</TT
|
860 |
|
|
> is defined in <TT
|
861 |
|
|
CLASS="FILENAME"
|
862 |
|
|
>hal_intr.h</TT
|
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
|
868 |
|
|
></LI
|
869 |
|
|
><LI
|
870 |
|
|
><P
|
871 |
|
|
><TT
|
872 |
|
|
CLASS="FUNCTION"
|
873 |
|
|
>hal_idle_thread_action()</TT
|
874 |
|
|
>. This function is called
|
875 |
|
|
from the idle thread via the
|
876 |
|
|
<TT
|
877 |
|
|
CLASS="LITERAL"
|
878 |
|
|
>HAL_IDLE_THREAD_ACTION()</TT
|
879 |
|
|
> macro, if so
|
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
|
884 |
|
|
supports a <TT
|
885 |
|
|
CLASS="LITERAL"
|
886 |
|
|
>halt</TT
|
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
|
890 |
|
|
></LI
|
891 |
|
|
></UL
|
892 |
|
|
></LI
|
893 |
|
|
><LI
|
894 |
|
|
><P
|
895 |
|
|
>Create the <TT
|
896 |
|
|
CLASS="FILENAME"
|
897 |
|
|
><architecture>.ld</TT
|
898 |
|
|
> file. While
|
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
|
901 |
|
|
><P
|
902 |
|
|
>This file defines a set of macros that are used by the platform
|
903 |
|
|
<TT
|
904 |
|
|
CLASS="LITERAL"
|
905 |
|
|
>.ldi</TT
|
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
|
910 |
|
|
CLASS="LITERAL"
|
911 |
|
|
>OUTPUT_FORMAT()</TT
|
912 |
|
|
> directive
|
913 |
|
|
and maybe the creation or allocation of extra sections to various
|
914 |
|
|
macros. Running the target linker with just the
|
915 |
|
|
<TT
|
916 |
|
|
CLASS="LITERAL"
|
917 |
|
|
>--verbose</TT
|
918 |
|
|
> argument will cause it to output its
|
919 |
|
|
default linker script. This can be compared with the
|
920 |
|
|
<TT
|
921 |
|
|
CLASS="LITERAL"
|
922 |
|
|
>.ld</TT
|
923 |
|
|
> file and appropriate edits made.</P
|
924 |
|
|
></LI
|
925 |
|
|
><LI
|
926 |
|
|
><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
|
929 |
|
|
CLASS="FILENAME"
|
930 |
|
|
>include/<architecture>-stub.h</TT
|
931 |
|
|
> and
|
932 |
|
|
<TT
|
933 |
|
|
CLASS="FILENAME"
|
934 |
|
|
>src/<architecture>-stub.c</TT
|
935 |
|
|
>. In all existing
|
936 |
|
|
architecture HALs these files, and any support files they need, have
|
937 |
|
|
been derived from files supplied in <TT
|
938 |
|
|
CLASS="LITERAL"
|
939 |
|
|
>libgloss</TT
|
940 |
|
|
>, as
|
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
|
943 |
|
|
from scratch.</P
|
944 |
|
|
><P
|
945 |
|
|
><TT
|
946 |
|
|
CLASS="FILENAME"
|
947 |
|
|
>include/<architecture>-stub.h</TT
|
948 |
|
|
>
|
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
|
953 |
|
|
<TT
|
954 |
|
|
CLASS="FILENAME"
|
955 |
|
|
>src/<architecture>-stub.c</TT
|
956 |
|
|
>; however, since
|
957 |
|
|
this is common to all architectures, it can be copied from some other
|
958 |
|
|
HAL.</P
|
959 |
|
|
><P
|
960 |
|
|
><TT
|
961 |
|
|
CLASS="FILENAME"
|
962 |
|
|
>src/<architecture>-stub.c</TT
|
963 |
|
|
> implements the
|
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
|
974 |
|
|
></LI
|
975 |
|
|
></OL
|
976 |
|
|
></DIV
|
977 |
|
|
><DIV
|
978 |
|
|
CLASS="SECTION"
|
979 |
|
|
><H2
|
980 |
|
|
CLASS="SECTION"
|
981 |
|
|
><A
|
982 |
|
|
NAME="HAL-PORTING-ARCHITECTURE-CDL">CDL Requirements</H2
|
983 |
|
|
><P
|
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
|
989 |
|
|
><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
|
992 |
|
|
><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
|
995 |
|
|
<TT
|
996 |
|
|
CLASS="FILENAME"
|
997 |
|
|
>include/cyg/hal</TT
|
998 |
|
|
> directory, and definitions from
|
999 |
|
|
this file will be placed in
|
1000 |
|
|
<TT
|
1001 |
|
|
CLASS="FILENAME"
|
1002 |
|
|
>include/pkgconf/hal_i386.h</TT
|
1003 |
|
|
>. The
|
1004 |
|
|
<TT
|
1005 |
|
|
CLASS="LITERAL"
|
1006 |
|
|
>compile</TT
|
1007 |
|
|
> line specifies the files in the
|
1008 |
|
|
<TT
|
1009 |
|
|
CLASS="FILENAME"
|
1010 |
|
|
>src</TT
|
1011 |
|
|
> directory that are to be compiled as part of
|
1012 |
|
|
this package.</P
|
1013 |
|
|
><TABLE
|
1014 |
|
|
BORDER="5"
|
1015 |
|
|
BGCOLOR="#E0E0F0"
|
1016 |
|
|
WIDTH="70%"
|
1017 |
|
|
><TR
|
1018 |
|
|
><TD
|
1019 |
|
|
><PRE
|
1020 |
|
|
CLASS="PROGRAMLISTING"
|
1021 |
|
|
>cdl_package CYGPKG_HAL_I386 {
|
1022 |
|
|
display "i386 architecture"
|
1023 |
|
|
parent CYGPKG_HAL
|
1024 |
|
|
hardware
|
1025 |
|
|
include_dir cyg/hal
|
1026 |
|
|
define_header hal_i386.h
|
1027 |
|
|
description "
|
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
|
1031 |
|
|
package."
|
1032 |
|
|
|
1033 |
|
|
compile hal_misc.c context.S i386_stub.c hal_syscall.c</PRE
|
1034 |
|
|
></TD
|
1035 |
|
|
></TR
|
1036 |
|
|
></TABLE
|
1037 |
|
|
><P
|
1038 |
|
|
>Next we need to generate some files using non-standard make rules. The
|
1039 |
|
|
first is <TT
|
1040 |
|
|
CLASS="FILENAME"
|
1041 |
|
|
>vectors.S</TT
|
1042 |
|
|
>, which is not put into the
|
1043 |
|
|
library, but linked explicitly with all applications. The second is
|
1044 |
|
|
the generation of the <TT
|
1045 |
|
|
CLASS="FILENAME"
|
1046 |
|
|
>target.ld</TT
|
1047 |
|
|
> file from
|
1048 |
|
|
<TT
|
1049 |
|
|
CLASS="FILENAME"
|
1050 |
|
|
>i386.ld</TT
|
1051 |
|
|
> and the startup-selected
|
1052 |
|
|
<TT
|
1053 |
|
|
CLASS="FILENAME"
|
1054 |
|
|
>.ldi</TT
|
1055 |
|
|
> file. Both of these are essentially
|
1056 |
|
|
boilerplate code that can be copied and edited.</P
|
1057 |
|
|
><TABLE
|
1058 |
|
|
BORDER="5"
|
1059 |
|
|
BGCOLOR="#E0E0F0"
|
1060 |
|
|
WIDTH="70%"
|
1061 |
|
|
><TR
|
1062 |
|
|
><TD
|
1063 |
|
|
><PRE
|
1064 |
|
|
CLASS="PROGRAMLISTING"
|
1065 |
|
|
> make {
|
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
|
1071 |
|
|
@rm vectors.tmp
|
1072 |
|
|
}
|
1073 |
|
|
|
1074 |
|
|
make {
|
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
|
1080 |
|
|
@rm target.tmp
|
1081 |
|
|
}</PRE
|
1082 |
|
|
></TD
|
1083 |
|
|
></TR
|
1084 |
|
|
></TABLE
|
1085 |
|
|
><P
|
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
|
1089 |
|
|
<TT
|
1090 |
|
|
CLASS="LITERAL"
|
1091 |
|
|
>requires</TT
|
1092 |
|
|
> statement in the kernel. The
|
1093 |
|
|
<TT
|
1094 |
|
|
CLASS="LITERAL"
|
1095 |
|
|
>requires</TT
|
1096 |
|
|
> statement here turns off lazy FPU
|
1097 |
|
|
switching in the FPU support code, since it is inconsistent with SMP
|
1098 |
|
|
operation.</P
|
1099 |
|
|
><TABLE
|
1100 |
|
|
BORDER="5"
|
1101 |
|
|
BGCOLOR="#E0E0F0"
|
1102 |
|
|
WIDTH="70%"
|
1103 |
|
|
><TR
|
1104 |
|
|
><TD
|
1105 |
|
|
><PRE
|
1106 |
|
|
CLASS="PROGRAMLISTING"
|
1107 |
|
|
> cdl_component CYGPKG_HAL_SMP_SUPPORT {
|
1108 |
|
|
display "SMP support"
|
1109 |
|
|
default_value 0
|
1110 |
|
|
requires { CYGHWR_HAL_I386_FPU_SWITCH_LAZY == 0 }
|
1111 |
|
|
|
1112 |
|
|
cdl_option CYGPKG_HAL_SMP_CPU_MAX {
|
1113 |
|
|
display "Max number of CPUs supported"
|
1114 |
|
|
flavor data
|
1115 |
|
|
default_value 2
|
1116 |
|
|
}
|
1117 |
|
|
}</PRE
|
1118 |
|
|
></TD
|
1119 |
|
|
></TR
|
1120 |
|
|
></TABLE
|
1121 |
|
|
><P
|
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
|
1126 |
|
|
><TABLE
|
1127 |
|
|
BORDER="5"
|
1128 |
|
|
BGCOLOR="#E0E0F0"
|
1129 |
|
|
WIDTH="70%"
|
1130 |
|
|
><TR
|
1131 |
|
|
><TD
|
1132 |
|
|
><PRE
|
1133 |
|
|
CLASS="PROGRAMLISTING"
|
1134 |
|
|
>
|
1135 |
|
|
cdl_component CYGHWR_HAL_I386_FPU {
|
1136 |
|
|
display "Enable I386 FPU support"
|
1137 |
|
|
default_value 1
|
1138 |
|
|
description "This component enables support for the
|
1139 |
|
|
I386 floating point unit."
|
1140 |
|
|
|
1141 |
|
|
cdl_option CYGHWR_HAL_I386_FPU_SWITCH_LAZY {
|
1142 |
|
|
display "Use lazy FPU state switching"
|
1143 |
|
|
flavor bool
|
1144 |
|
|
default_value 1
|
1145 |
|
|
|
1146 |
|
|
description "
|
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."
|
1159 |
|
|
}
|
1160 |
|
|
}</PRE
|
1161 |
|
|
></TD
|
1162 |
|
|
></TR
|
1163 |
|
|
></TABLE
|
1164 |
|
|
><P
|
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
|
1169 |
|
|
<TT
|
1170 |
|
|
CLASS="LITERAL"
|
1171 |
|
|
>requires</TT
|
1172 |
|
|
> statements in variant or platform
|
1173 |
|
|
packages, or in <TT
|
1174 |
|
|
CLASS="LITERAL"
|
1175 |
|
|
>.ecm</TT
|
1176 |
|
|
> files.</P
|
1177 |
|
|
><TABLE
|
1178 |
|
|
BORDER="5"
|
1179 |
|
|
BGCOLOR="#E0E0F0"
|
1180 |
|
|
WIDTH="70%"
|
1181 |
|
|
><TR
|
1182 |
|
|
><TD
|
1183 |
|
|
><PRE
|
1184 |
|
|
CLASS="PROGRAMLISTING"
|
1185 |
|
|
> cdl_component CYGHWR_HAL_I386_PENTIUM {
|
1186 |
|
|
display "Enable Pentium class CPU features"
|
1187 |
|
|
default_value 0
|
1188 |
|
|
description "This component enables support for various
|
1189 |
|
|
features of Pentium class CPUs."
|
1190 |
|
|
|
1191 |
|
|
cdl_option CYGHWR_HAL_I386_PENTIUM_SSE {
|
1192 |
|
|
display "Save/Restore SSE registers on context switch"
|
1193 |
|
|
flavor bool
|
1194 |
|
|
default_value 0
|
1195 |
|
|
|
1196 |
|
|
description "
|
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."
|
1201 |
|
|
}
|
1202 |
|
|
|
1203 |
|
|
cdl_option CYGHWR_HAL_I386_PENTIUM_GDB_REGS {
|
1204 |
|
|
display "Support extra Pentium registers in GDB stub"
|
1205 |
|
|
flavor bool
|
1206 |
|
|
default_value 0
|
1207 |
|
|
|
1208 |
|
|
description "
|
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."
|
1214 |
|
|
}
|
1215 |
|
|
}</PRE
|
1216 |
|
|
></TD
|
1217 |
|
|
></TR
|
1218 |
|
|
></TABLE
|
1219 |
|
|
><P
|
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
|
1224 |
|
|
><TABLE
|
1225 |
|
|
BORDER="5"
|
1226 |
|
|
BGCOLOR="#E0E0F0"
|
1227 |
|
|
WIDTH="70%"
|
1228 |
|
|
><TR
|
1229 |
|
|
><TD
|
1230 |
|
|
><PRE
|
1231 |
|
|
CLASS="PROGRAMLISTING"
|
1232 |
|
|
> cdl_option CYGBLD_LINKER_SCRIPT {
|
1233 |
|
|
display "Linker script"
|
1234 |
|
|
flavor data
|
1235 |
|
|
no_define
|
1236 |
|
|
calculated { "src/i386.ld" }
|
1237 |
|
|
}</PRE
|
1238 |
|
|
></TD
|
1239 |
|
|
></TR
|
1240 |
|
|
></TABLE
|
1241 |
|
|
><P
|
1242 |
|
|
>Finally, this interface indicates whether the platform supplied an
|
1243 |
|
|
implementation of the
|
1244 |
|
|
<TT
|
1245 |
|
|
CLASS="FUNCTION"
|
1246 |
|
|
>hal_i386_mem_real_region_top()</TT
|
1247 |
|
|
> function. If it
|
1248 |
|
|
does then it will contain a line of the form: <TT
|
1249 |
|
|
CLASS="LITERAL"
|
1250 |
|
|
>implements
|
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
|
1254 |
|
|
may call it.</P
|
1255 |
|
|
><TABLE
|
1256 |
|
|
BORDER="5"
|
1257 |
|
|
BGCOLOR="#E0E0F0"
|
1258 |
|
|
WIDTH="70%"
|
1259 |
|
|
><TR
|
1260 |
|
|
><TD
|
1261 |
|
|
><PRE
|
1262 |
|
|
CLASS="PROGRAMLISTING"
|
1263 |
|
|
> cdl_interface CYGINT_HAL_I386_MEM_REAL_REGION_TOP {
|
1264 |
|
|
display "Implementations of hal_i386_mem_real_region_top()"
|
1265 |
|
|
}
|
1266 |
|
|
|
1267 |
|
|
}</PRE
|
1268 |
|
|
></TD
|
1269 |
|
|
></TR
|
1270 |
|
|
></TABLE
|
1271 |
|
|
></DIV
|
1272 |
|
|
></DIV
|
1273 |
|
|
><DIV
|
1274 |
|
|
CLASS="NAVFOOTER"
|
1275 |
|
|
><HR
|
1276 |
|
|
ALIGN="LEFT"
|
1277 |
|
|
WIDTH="100%"><TABLE
|
1278 |
|
|
SUMMARY="Footer navigation table"
|
1279 |
|
|
WIDTH="100%"
|
1280 |
|
|
BORDER="0"
|
1281 |
|
|
CELLPADDING="0"
|
1282 |
|
|
CELLSPACING="0"
|
1283 |
|
|
><TR
|
1284 |
|
|
><TD
|
1285 |
|
|
WIDTH="33%"
|
1286 |
|
|
ALIGN="left"
|
1287 |
|
|
VALIGN="top"
|
1288 |
|
|
><A
|
1289 |
|
|
HREF="hal-porting-variant.html"
|
1290 |
|
|
ACCESSKEY="P"
|
1291 |
|
|
>Prev</A
|
1292 |
|
|
></TD
|
1293 |
|
|
><TD
|
1294 |
|
|
WIDTH="34%"
|
1295 |
|
|
ALIGN="center"
|
1296 |
|
|
VALIGN="top"
|
1297 |
|
|
><A
|
1298 |
|
|
HREF="ecos-ref.html"
|
1299 |
|
|
ACCESSKEY="H"
|
1300 |
|
|
>Home</A
|
1301 |
|
|
></TD
|
1302 |
|
|
><TD
|
1303 |
|
|
WIDTH="33%"
|
1304 |
|
|
ALIGN="right"
|
1305 |
|
|
VALIGN="top"
|
1306 |
|
|
><A
|
1307 |
|
|
HREF="hal-future-developments.html"
|
1308 |
|
|
ACCESSKEY="N"
|
1309 |
|
|
>Next</A
|
1310 |
|
|
></TD
|
1311 |
|
|
></TR
|
1312 |
|
|
><TR
|
1313 |
|
|
><TD
|
1314 |
|
|
WIDTH="33%"
|
1315 |
|
|
ALIGN="left"
|
1316 |
|
|
VALIGN="top"
|
1317 |
|
|
>Variant HAL Porting</TD
|
1318 |
|
|
><TD
|
1319 |
|
|
WIDTH="34%"
|
1320 |
|
|
ALIGN="center"
|
1321 |
|
|
VALIGN="top"
|
1322 |
|
|
><A
|
1323 |
|
|
HREF="hal-porting-guide.html"
|
1324 |
|
|
ACCESSKEY="U"
|
1325 |
|
|
>Up</A
|
1326 |
|
|
></TD
|
1327 |
|
|
><TD
|
1328 |
|
|
WIDTH="33%"
|
1329 |
|
|
ALIGN="right"
|
1330 |
|
|
VALIGN="top"
|
1331 |
|
|
>Future developments</TD
|
1332 |
|
|
></TR
|
1333 |
|
|
></TABLE
|
1334 |
|
|
></DIV
|
1335 |
|
|
></BODY
|
1336 |
|
|
></HTML
|
1337 |
|
|
>
|