OpenCores
URL https://opencores.org/ocsvn/openrisc_2011-10-31/openrisc_2011-10-31/trunk

Subversion Repositories openrisc_2011-10-31

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [doc/] [html/] [ref/] [hal-porting-architecture.html] - Blame information for rev 314

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
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
>&lt;architecture&gt;.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
>&lt;architecture&gt;.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
>&lt;architecture&gt;.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/&lt;architecture&gt;-stub.h</TT
931
> and
932
<TT
933
CLASS="FILENAME"
934
>src/&lt;architecture&gt;-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/&lt;architecture&gt;-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/&lt;architecture&gt;-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/&lt;architecture&gt;-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
>&#13;    make {
1066
        &lt;PREFIX&gt;/lib/vectors.o : &lt;PACKAGE&gt;/src/vectors.S
1067
        $(CC) -Wp,-MD,vectors.tmp $(INCLUDE_PATH) $(CFLAGS) -c -o $@ $&lt;
1068
        @echo $@ ": \\" &gt; $(notdir $@).deps
1069
        @tail +2 vectors.tmp &gt;&gt; $(notdir $@).deps
1070
        @echo &gt;&gt; $(notdir $@).deps
1071
        @rm vectors.tmp
1072
    }
1073
 
1074
    make {
1075
        &lt;PREFIX&gt;/lib/target.ld: &lt;PACKAGE&gt;/src/i386.ld
1076
        $(CC) -E -P -Wp,-MD,target.tmp -DEXTRAS=1 -xc $(INCLUDE_PATH) $(CFLAGS) -o $@ $&lt;
1077
        @echo $@ ": \\" &gt; $(notdir $@).deps
1078
        @tail +2 target.tmp &gt;&gt; $(notdir $@).deps
1079
        @echo &gt;&gt; $(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
>&#13;    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
>&#13;    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
>&#13;    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
>

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.