]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - doc/html/ref/hal-smp-support.html
RedBoot TX53 Release 2012-02-15
[karo-tx-redboot.git] / doc / html / ref / hal-smp-support.html
1 <!-- Copyright (C) 2003 Red Hat, Inc.                                -->
2 <!-- This material may be distributed only subject to the terms      -->
3 <!-- and conditions set forth in the Open Publication License, v1.0  -->
4 <!-- or later (the latest version is presently available at          -->
5 <!-- http://www.opencontent.org/openpub/).                           -->
6 <!-- Distribution of the work or derivative of the work in any       -->
7 <!-- standard (paper) book form is prohibited unless prior           -->
8 <!-- permission is obtained from the copyright holder.               -->
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 >