OpenCores
URL https://opencores.org/ocsvn/openrisc/openrisc/trunk

Subversion Repositories openrisc

[/] [openrisc/] [trunk/] [rtos/] [ecos-2.0/] [doc/] [html/] [ref/] [hal-smp-support.html] - Blame information for rev 615

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
>SMP Support</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="HAL Interfaces"
23
HREF="hal-interfaces.html"><LINK
24
REL="PREVIOUS"
25
TITLE="Diagnostic Support"
26
HREF="hal-diagnostic-support.html"><LINK
27
REL="NEXT"
28
TITLE="Exception Handling"
29
HREF="hal-exception-handling.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-diagnostic-support.html"
58
ACCESSKEY="P"
59
>Prev</A
60
></TD
61
><TD
62
WIDTH="80%"
63
ALIGN="center"
64
VALIGN="bottom"
65
>Chapter 9. HAL Interfaces</TD
66
><TD
67
WIDTH="10%"
68
ALIGN="right"
69
VALIGN="bottom"
70
><A
71
HREF="hal-exception-handling.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-SMP-SUPPORT">SMP Support</H1
86
><P
87
>eCos contains support for limited Symmetric Multi-Processing
88
(SMP). This is only available on selected architectures and platforms.</P
89
><DIV
90
CLASS="SECTION"
91
><H2
92
CLASS="SECTION"
93
><A
94
NAME="AEN8275">Target Hardware Limitations</H2
95
><P
96
>To allow a reasonable implementation of SMP, and to reduce the
97
disruption to the existing source base, a number of assumptions have
98
been made about the features of the target hardware.</P
99
><P
100
></P
101
><UL
102
><LI
103
><P
104
>Modest multiprocessing. The typical number of CPUs supported is two
105
to four, with an upper limit around eight. While there are no
106
inherent limits in the code, hardware and algorithmic limitations
107
will probably become significant beyond this point.</P
108
></LI
109
><LI
110
><P
111
>SMP synchronization support. The hardware must supply a mechanism to
112
allow software on two CPUs to synchronize. This is normally provided
113
as part of the instruction set in the form of test-and-set,
114
compare-and-swap or load-link/store-conditional instructions. An
115
alternative approach is the provision of hardware semaphore
116
registers which can be used to serialize implementations of these
117
operations. Whatever hardware facilities are available, they are
118
used in eCos to implement spinlocks.</P
119
></LI
120
><LI
121
><P
122
>Coherent caches. It is assumed that no extra effort will be required
123
to access shared memory from any processor. This means that either
124
there are no caches, they are shared by all processors, or are
125
maintained in a coherent state by the hardware. It would be too
126
disruptive to the eCos sources if every memory access had to be
127
bracketed by cache load/flush operations. Any hardware that requires
128
this is not supported.</P
129
></LI
130
><LI
131
><P
132
>Uniform addressing. It is assumed that all memory that is
133
shared between CPUs is addressed at the same location from all
134
CPUs. Like non-coherent caches, dealing with CPU-specific address
135
translation is considered too disruptive to the eCos source
136
base. This does not, however, preclude systems with non-uniform
137
access costs for different CPUs.</P
138
></LI
139
><LI
140
><P
141
>Uniform device addressing. As with access to memory, it is assumed
142
that all devices are equally accessible to all CPUs. Since device
143
access is often made from thread contexts, it is not possible to
144
restrict access to device control registers to certain CPUs, since
145
there is currently no support for binding or migrating threads to CPUs.</P
146
></LI
147
><LI
148
><P
149
>Interrupt routing. The target hardware must have an interrupt
150
controller that can route interrupts to specific CPUs. It is
151
acceptable for all interrupts to be delivered to just one CPU, or
152
for some interrupts to be bound to specific CPUs, or for some
153
interrupts to be local to each CPU. At present dynamic routing,
154
where a different CPU may be chosen each time an interrupt is
155
delivered, is not supported. ECos cannot support hardware where all
156
interrupts are delivered to all CPUs simultaneously with the
157
expectation that software will resolve any conflicts.</P
158
></LI
159
><LI
160
><P
161
>Inter-CPU interrupts. A mechanism to allow one CPU to interrupt
162
another is needed. This is necessary so that events on one CPU can
163
cause rescheduling on other CPUs.</P
164
></LI
165
><LI
166
><P
167
>CPU Identifiers. Code running on a CPU must be able to determine
168
which CPU it is running on. The CPU Id is usually provided either in
169
a CPU status register, or in a register associated with the
170
inter-CPU interrupt delivery subsystem. ECos expects CPU Ids to be
171
small positive integers, although alternative representations, such
172
as bitmaps, can be converted relatively easily. Complex mechanisms
173
for getting the CPU Id cannot be supported. Getting the CPU Id must
174
be a cheap operation, since it is done often, and in performance
175
critical places such as interrupt handlers and the scheduler.</P
176
></LI
177
></UL
178
></DIV
179
><DIV
180
CLASS="SECTION"
181
><H2
182
CLASS="SECTION"
183
><A
184
NAME="AEN8295">HAL Support</H2
185
><P
186
>SMP support in any platform depends on the HAL supplying the
187
appropriate operations. All HAL SMP support is defined in the
188
<TT
189
CLASS="FILENAME"
190
>cyg/hal/hal_smp.h</TT
191
> header. Variant and platform
192
specific definitions will be in <TT
193
CLASS="FILENAME"
194
>cyg/hal/var_smp.h</TT
195
>
196
and <TT
197
CLASS="FILENAME"
198
>cyg/hal/plf_smp.h</TT
199
> respectively. These files
200
are include automatically by this header, so need not be included
201
explicitly.</P
202
><P
203
>SMP support falls into a number of functional groups.</P
204
><DIV
205
CLASS="SECTION"
206
><H3
207
CLASS="SECTION"
208
><A
209
NAME="AEN8302">CPU Control</H3
210
><P
211
>This group consists of descriptive and control macros for managing the
212
CPUs in an SMP system.</P
213
><P
214
></P
215
><DIV
216
CLASS="VARIABLELIST"
217
><DL
218
><DT
219
><TT
220
CLASS="LITERAL"
221
>HAL_SMP_CPU_TYPE</TT
222
></DT
223
><DD
224
><P
225
>A type that can contain a CPU id. A CPU id is
226
usually a small integer that is used to index
227
arrays of variables that are managed on an
228
per-CPU basis.</P
229
></DD
230
><DT
231
><TT
232
CLASS="LITERAL"
233
>HAL_SMP_CPU_MAX</TT
234
></DT
235
><DD
236
><P
237
>The maximum number of CPUs that can be
238
supported. This is used to provide the size of
239
any arrays that have an element per CPU.</P
240
></DD
241
><DT
242
><TT
243
CLASS="LITERAL"
244
>HAL_SMP_CPU_COUNT()</TT
245
></DT
246
><DD
247
><P
248
>Returns the number of CPUs currently
249
operational. This may differ from
250
HAL_SMP_CPU_MAX depending on the runtime
251
environment.</P
252
></DD
253
><DT
254
><TT
255
CLASS="LITERAL"
256
>HAL_SMP_CPU_THIS()</TT
257
></DT
258
><DD
259
><P
260
>Returns the CPU id of the current CPU.</P
261
></DD
262
><DT
263
><TT
264
CLASS="LITERAL"
265
>HAL_SMP_CPU_NONE</TT
266
></DT
267
><DD
268
><P
269
>A value that does not match any real CPU
270
id. This is uses where a CPU type variable
271
must be set to a null value.</P
272
></DD
273
><DT
274
><TT
275
CLASS="LITERAL"
276
>HAL_SMP_CPU_START( cpu )</TT
277
></DT
278
><DD
279
><P
280
>Starts the given CPU executing at a defined
281
HAL entry point. After performing any HAL
282
level initialization, the CPU calls up into
283
the kernel at <TT
284
CLASS="FUNCTION"
285
>cyg_kernel_cpu_startup()</TT
286
>.</P
287
></DD
288
><DT
289
><TT
290
CLASS="LITERAL"
291
>HAL_SMP_CPU_RESCHEDULE_INTERRUPT( cpu, wait )</TT
292
></DT
293
><DD
294
><P
295
>Sends the CPU a reschedule interrupt, and if
296
<TT
297
CLASS="PARAMETER"
298
><I
299
>wait</I
300
></TT
301
> is non-zero, waits for an
302
acknowledgment. The interrupted CPU should call
303
<TT
304
CLASS="FUNCTION"
305
>cyg_scheduler_set_need_reschedule()</TT
306
> in its DSR to
307
cause the reschedule to occur.</P
308
></DD
309
><DT
310
><TT
311
CLASS="LITERAL"
312
>HAL_SMP_CPU_TIMESLICE_INTERRUPT( cpu, wait )</TT
313
></DT
314
><DD
315
><P
316
>Sends the CPU a timeslice interrupt, and if
317
<TT
318
CLASS="PARAMETER"
319
><I
320
>wait</I
321
></TT
322
> is non-zero, waits for an
323
acknowledgment. The interrupted CPU should call
324
<TT
325
CLASS="FUNCTION"
326
>cyg_scheduler_timeslice_cpu()</TT
327
> to cause the
328
timeslice event to be processed.</P
329
></DD
330
></DL
331
></DIV
332
></DIV
333
><DIV
334
CLASS="SECTION"
335
><H3
336
CLASS="SECTION"
337
><A
338
NAME="AEN8351">Test-and-set Support</H3
339
><P
340
>Test-and-set is the foundation of the SMP synchronization
341
mechanisms.</P
342
><P
343
></P
344
><DIV
345
CLASS="VARIABLELIST"
346
><DL
347
><DT
348
><TT
349
CLASS="LITERAL"
350
>HAL_TAS_TYPE</TT
351
></DT
352
><DD
353
><P
354
>The type for all test-and-set variables. The
355
test-and-set macros only support operations on
356
a single bit (usually the least significant
357
bit) of this location. This allows for maximum
358
flexibility in the implementation.</P
359
></DD
360
><DT
361
><TT
362
CLASS="LITERAL"
363
>HAL_TAS_SET( tas, oldb )</TT
364
></DT
365
><DD
366
><P
367
>Performs a test and set operation on the
368
location <TT
369
CLASS="PARAMETER"
370
><I
371
>tas</I
372
></TT
373
>. <TT
374
CLASS="PARAMETER"
375
><I
376
>oldb</I
377
></TT
378
> will contain <TT
379
CLASS="LITERAL"
380
>true</TT
381
> if
382
the location was already set, and <TT
383
CLASS="LITERAL"
384
>false</TT
385
> if
386
it was clear.</P
387
></DD
388
><DT
389
><TT
390
CLASS="LITERAL"
391
>HAL_TAS_CLEAR( tas, oldb )</TT
392
></DT
393
><DD
394
><P
395
>Performs a test and clear operation on the
396
location <TT
397
CLASS="PARAMETER"
398
><I
399
>tas</I
400
></TT
401
>. <TT
402
CLASS="PARAMETER"
403
><I
404
>oldb</I
405
></TT
406
> will contain <TT
407
CLASS="LITERAL"
408
>true</TT
409
> if
410
the location was already set, and <TT
411
CLASS="LITERAL"
412
>false</TT
413
> if
414
it was clear.</P
415
></DD
416
></DL
417
></DIV
418
></DIV
419
><DIV
420
CLASS="SECTION"
421
><H3
422
CLASS="SECTION"
423
><A
424
NAME="AEN8378">Spinlocks</H3
425
><P
426
>Spinlocks provide inter-CPU locking. Normally they will be implemented
427
on top of the test-and-set mechanism above, but may also be
428
implemented by other means if, for example, the hardware has more
429
direct support for spinlocks.</P
430
><P
431
></P
432
><DIV
433
CLASS="VARIABLELIST"
434
><DL
435
><DT
436
><TT
437
CLASS="LITERAL"
438
>HAL_SPINLOCK_TYPE</TT
439
></DT
440
><DD
441
><P
442
>The type for all spinlock variables.</P
443
></DD
444
><DT
445
><TT
446
CLASS="LITERAL"
447
>HAL_SPINLOCK_INIT_CLEAR</TT
448
></DT
449
><DD
450
><P
451
>A value that may be assigned to a spinlock
452
variable to initialize it to clear.</P
453
></DD
454
><DT
455
><TT
456
CLASS="LITERAL"
457
>HAL_SPINLOCK_INIT_SET</TT
458
></DT
459
><DD
460
><P
461
>A value that may be assigned to a spinlock
462
variable to initialize it to set.</P
463
></DD
464
><DT
465
><TT
466
CLASS="LITERAL"
467
>HAL_SPINLOCK_SPIN( lock )</TT
468
></DT
469
><DD
470
><P
471
>The caller spins in a busy loop waiting for
472
the lock to become clear. It then sets it and
473
continues. This is all handled atomically, so
474
that there are no race conditions between CPUs.</P
475
></DD
476
><DT
477
><TT
478
CLASS="LITERAL"
479
>HAL_SPINLOCK_CLEAR( lock )</TT
480
></DT
481
><DD
482
><P
483
>The caller clears the lock. One of any waiting
484
spinners will then be able to proceed.</P
485
></DD
486
><DT
487
><TT
488
CLASS="LITERAL"
489
>HAL_SPINLOCK_TRY( lock, val )</TT
490
></DT
491
><DD
492
><P
493
>Attempts to set the lock. The value put in
494
<TT
495
CLASS="PARAMETER"
496
><I
497
>val</I
498
></TT
499
> will be <TT
500
CLASS="LITERAL"
501
>true</TT
502
> if the lock was
503
claimed successfully, and <TT
504
CLASS="LITERAL"
505
>false</TT
506
> if it was
507
not.</P
508
></DD
509
><DT
510
><TT
511
CLASS="LITERAL"
512
>HAL_SPINLOCK_TEST( lock, val )</TT
513
></DT
514
><DD
515
><P
516
>Tests the current value of the lock. The value
517
put in <TT
518
CLASS="PARAMETER"
519
><I
520
>val</I
521
></TT
522
> will be <TT
523
CLASS="LITERAL"
524
>true</TT
525
> if the lock is
526
claimed and <TT
527
CLASS="LITERAL"
528
>false</TT
529
> of it is clear.</P
530
></DD
531
></DL
532
></DIV
533
></DIV
534
><DIV
535
CLASS="SECTION"
536
><H3
537
CLASS="SECTION"
538
><A
539
NAME="AEN8423">Scheduler Lock</H3
540
><P
541
>The scheduler lock is the main protection for all kernel data
542
structures. By default the kernel implements the scheduler lock itself
543
using a spinlock. However, if spinlocks cannot be supported by the
544
hardware, or there is a more efficient implementation available, the
545
HAL may provide macros to implement the scheduler lock.</P
546
><P
547
></P
548
><DIV
549
CLASS="VARIABLELIST"
550
><DL
551
><DT
552
><TT
553
CLASS="LITERAL"
554
>HAL_SMP_SCHEDLOCK_DATA_TYPE</TT
555
></DT
556
><DD
557
><P
558
>A data type, possibly a structure, that
559
contains any data items needed by the
560
scheduler lock implementation. A variable of
561
this type will be instantiated as a static
562
member of the Cyg_Scheduler_SchedLock class
563
and passed to all the following macros.</P
564
></DD
565
><DT
566
><TT
567
CLASS="LITERAL"
568
>HAL_SMP_SCHEDLOCK_INIT( lock, data )</TT
569
></DT
570
><DD
571
><P
572
>Initialize the scheduler lock. The <TT
573
CLASS="PARAMETER"
574
><I
575
>lock</I
576
></TT
577
>
578
argument is the scheduler lock counter and the
579
<TT
580
CLASS="PARAMETER"
581
><I
582
>data</I
583
></TT
584
> argument is a variable of
585
HAL_SMP_SCHEDLOCK_DATA_TYPE type.</P
586
></DD
587
><DT
588
><TT
589
CLASS="LITERAL"
590
>HAL_SMP_SCHEDLOCK_INC( lock, data )</TT
591
></DT
592
><DD
593
><P
594
>Increment the scheduler lock. The first
595
increment of the lock from zero to one for any
596
CPU may cause it to wait until the lock is
597
zeroed by another CPU. Subsequent increments
598
should be less expensive since this CPU
599
already holds the lock.</P
600
></DD
601
><DT
602
><TT
603
CLASS="LITERAL"
604
>HAL_SMP_SCHEDLOCK_ZERO( lock, data )</TT
605
></DT
606
><DD
607
><P
608
>Zero the scheduler lock. This operation will
609
also clear the lock so that other CPUs may
610
claim it.</P
611
></DD
612
><DT
613
><TT
614
CLASS="LITERAL"
615
>HAL_SMP_SCHEDLOCK_SET( lock, data, new )</TT
616
></DT
617
><DD
618
><P
619
>Set the lock to a different value, in
620
<TT
621
CLASS="PARAMETER"
622
><I
623
>new</I
624
></TT
625
>. This is only called when the lock is
626
already known to be owned by the current CPU. It is never called to
627
zero the lock, or to increment it from zero.</P
628
></DD
629
></DL
630
></DIV
631
></DIV
632
><DIV
633
CLASS="SECTION"
634
><H3
635
CLASS="SECTION"
636
><A
637
NAME="AEN8455">Interrupt Routing</H3
638
><P
639
>The routing of interrupts to different CPUs is supported by two new
640
interfaces in hal_intr.h.</P
641
><P
642
>Once an interrupt has been routed to a new CPU, the existing vector
643
masking and configuration operations should take account of the CPU
644
routing. For example, if the operation is not invoked on the
645
destination CPU itself, then the HAL may need to arrange to transfer
646
the operation to the destination CPU for correct application.</P
647
><P
648
></P
649
><DIV
650
CLASS="VARIABLELIST"
651
><DL
652
><DT
653
><TT
654
CLASS="LITERAL"
655
>HAL_INTERRUPT_SET_CPU( vector, cpu )</TT
656
></DT
657
><DD
658
><P
659
>Route the interrupt for the given <TT
660
CLASS="PARAMETER"
661
><I
662
>vector</I
663
></TT
664
> to
665
the given <TT
666
CLASS="PARAMETER"
667
><I
668
>cpu</I
669
></TT
670
>. </P
671
></DD
672
><DT
673
><TT
674
CLASS="LITERAL"
675
>HAL_INTERRUPT_GET_CPU( vector, cpu )</TT
676
></DT
677
><DD
678
><P
679
>Set <TT
680
CLASS="PARAMETER"
681
><I
682
>cpu</I
683
></TT
684
> to the id of the CPU to which this
685
vector is routed.</P
686
></DD
687
></DL
688
></DIV
689
></DIV
690
></DIV
691
></DIV
692
><DIV
693
CLASS="NAVFOOTER"
694
><HR
695
ALIGN="LEFT"
696
WIDTH="100%"><TABLE
697
SUMMARY="Footer navigation table"
698
WIDTH="100%"
699
BORDER="0"
700
CELLPADDING="0"
701
CELLSPACING="0"
702
><TR
703
><TD
704
WIDTH="33%"
705
ALIGN="left"
706
VALIGN="top"
707
><A
708
HREF="hal-diagnostic-support.html"
709
ACCESSKEY="P"
710
>Prev</A
711
></TD
712
><TD
713
WIDTH="34%"
714
ALIGN="center"
715
VALIGN="top"
716
><A
717
HREF="ecos-ref.html"
718
ACCESSKEY="H"
719
>Home</A
720
></TD
721
><TD
722
WIDTH="33%"
723
ALIGN="right"
724
VALIGN="top"
725
><A
726
HREF="hal-exception-handling.html"
727
ACCESSKEY="N"
728
>Next</A
729
></TD
730
></TR
731
><TR
732
><TD
733
WIDTH="33%"
734
ALIGN="left"
735
VALIGN="top"
736
>Diagnostic Support</TD
737
><TD
738
WIDTH="34%"
739
ALIGN="center"
740
VALIGN="top"
741
><A
742
HREF="hal-interfaces.html"
743
ACCESSKEY="U"
744
>Up</A
745
></TD
746
><TD
747
WIDTH="33%"
748
ALIGN="right"
749
VALIGN="top"
750
>Exception Handling</TD
751
></TR
752
></TABLE
753
></DIV
754
></BODY
755
></HTML
756
>

powered by: WebSVN 2.1.0

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