Ticket #1925: i386-Patch.txt

File i386-Patch.txt, 35.8 KB (added by Jennifer Averett, on 09/30/11 at 18:53:18)

convert console to libchip style console

Line 
1Index: c/src/lib/libbsp/i386/pc386/Makefile.am
2===================================================================
3RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/Makefile.am,v
4retrieving revision 1.60
5diff -u -r1.60 Makefile.am
6--- c/src/lib/libbsp/i386/pc386/Makefile.am     19 Jun 2011 21:16:36 -0000      1.60
7+++ c/src/lib/libbsp/i386/pc386/Makefile.am     27 Jul 2011 18:43:54 -0000
8@@ -31,6 +31,11 @@
9     ../../shared/include/irq-generic.h \
10     ../../shared/include/irq-info.h
11 
12+if HAS_SMP
13+include_bsp_HEADERS += ../../i386/shared/irq/apic.h
14+include_bsp_HEADERS += ../../i386/shared/smp/smp-imps.h
15+endif
16+
17 include_HEADERS += include/crt.h
18 nodist_include_HEADERS += ../../shared/include/coverhd.h
19 
20@@ -109,8 +114,19 @@
21 libbsp_a_SOURCES += ide/idecfg.c ide/ide.c
22 
23 if HAS_SMP
24-libbsp_a_SOURCES += ../../shared/smp/getcpuid.c ../../shared/smp/smp_stub.c \
25-    ../../shared/smp/bspsmp_wait_for.c
26+libbsp_a_SOURCES += ../../i386/shared/smp/getcpuid.c
27+libbsp_a_SOURCES += ../../i386/shared/smp/smp-imps.c
28+
29+project_lib_DATA += appstart.$(OBJEXT)
30+appcpustart.$(OBJEXT): start/start16.S
31+       $(CPPASCOMPILE) $(AM_CPPFLAGS) -DSMP_SECONDARY_CORE -o $@ -c $<
32+
33+appstart.$(OBJEXT): appcpustart.$(OBJEXT)
34+       $(LD) -N -T $(top_srcdir)/startup/linkcmds \
35+           -Ttext 0x70000 -e app_processor_start -nostdlib \
36+           -o appstart_tmp.exe $<
37+       $(OBJCOPY) -O binary appstart_tmp.exe appstart.bin
38+       $(OBJCOPY) -I binary -O elf32-i386 -B i386 appstart.bin $@
39 endif
40 
41 if HAS_NETWORKING
42@@ -144,6 +160,11 @@
43 libbsp_a_LIBADD = ../../../libcpu/@RTEMS_CPU@/cache.rel \
44     ../../../libcpu/@RTEMS_CPU@/page.rel \
45     ../../../libcpu/@RTEMS_CPU@/score.rel
46+
47+if HAS_SMP
48+libbsp_a_LIBADD += appstart.$(OBJEXT)
49+endif
50+
51 # We only build the Network library if HAS_NETWORKING was defined
52 # dec21140 is supported via libchip
53 if HAS_NETWORKING
54Index: c/src/lib/libbsp/i386/pc386/configure.ac
55===================================================================
56RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/configure.ac,v
57retrieving revision 1.41
58diff -u -r1.41 configure.ac
59--- c/src/lib/libbsp/i386/pc386/configure.ac    16 Mar 2011 20:05:13 -0000      1.41
60+++ c/src/lib/libbsp/i386/pc386/configure.ac    27 Jul 2011 18:43:54 -0000
61@@ -85,6 +85,12 @@
62 [Always defined when on a pc386 to enable the pc386 support for
63  determining the CPU core number in an SMP configuration.])
64 
65+## The PC386 BSP supports SMP configurations if this is enabled.
66+RTEMS_BSPOPTS_SET([BSP_HAS_SMP],[*],[1])
67+RTEMS_BSPOPTS_HELP([BSP_HAS_SMP],
68+[Always defined when on a pc386 to enable the pc386 support for
69+ determining the CPU core number in an SMP configuration.])
70+
71 ## if this is an i386, does gas have good code16 support?
72 RTEMS_I386_GAS_CODE16
73 AM_CONDITIONAL(RTEMS_GAS_CODE16,[test "$RTEMS_GAS_CODE16" = "yes"])
74Index: c/src/lib/libbsp/i386/pc386/preinstall.am
75===================================================================
76RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/preinstall.am,v
77retrieving revision 1.10
78diff -u -r1.10 preinstall.am
79--- c/src/lib/libbsp/i386/pc386/preinstall.am   14 Mar 2011 14:57:00 -0000      1.10
80+++ c/src/lib/libbsp/i386/pc386/preinstall.am   27 Jul 2011 18:43:54 -0000
81@@ -73,6 +73,15 @@
82        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/irq-info.h
83 PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/irq-info.h
84 
85+if HAS_SMP
86+$(PROJECT_INCLUDE)/bsp/apic.h: ../../i386/shared/irq/apic.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
87+       $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/apic.h
88+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/apic.h
89+
90+$(PROJECT_INCLUDE)/bsp/smp-imps.h: ../../i386/shared/smp/smp-imps.h $(PROJECT_INCLUDE)/bsp/$(dirstamp)
91+       $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/bsp/smp-imps.h
92+PREINSTALL_FILES += $(PROJECT_INCLUDE)/bsp/smp-imps.h
93+endif
94 $(PROJECT_INCLUDE)/crt.h: include/crt.h $(PROJECT_INCLUDE)/$(dirstamp)
95        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/crt.h
96 PREINSTALL_FILES += $(PROJECT_INCLUDE)/crt.h
97@@ -122,6 +131,11 @@
98        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/uart.h
99 PREINSTALL_FILES += $(PROJECT_INCLUDE)/uart.h
100 
101+if HAS_SMP
102+$(PROJECT_LIB)/appstart.$(OBJEXT): appstart.$(OBJEXT) $(PROJECT_LIB)/$(dirstamp)
103+       $(INSTALL_DATA) $< $(PROJECT_LIB)/appstart.$(OBJEXT)
104+TMPINSTALL_FILES += $(PROJECT_LIB)/appstart.$(OBJEXT)
105+endif
106 if HAS_NETWORKING
107 $(PROJECT_INCLUDE)/wd80x3.h: include/wd80x3.h $(PROJECT_INCLUDE)/$(dirstamp)
108        $(INSTALL_DATA) $< $(PROJECT_INCLUDE)/wd80x3.h
109Index: c/src/lib/libbsp/i386/pc386/clock/ckinit.c
110===================================================================
111RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/clock/ckinit.c,v
112retrieving revision 1.24
113diff -u -r1.24 ckinit.c
114--- c/src/lib/libbsp/i386/pc386/clock/ckinit.c  10 Mar 2010 17:16:01 -0000      1.24
115+++ c/src/lib/libbsp/i386/pc386/clock/ckinit.c  27 Jul 2011 18:43:54 -0000
116@@ -18,7 +18,7 @@
117  *  found in the file LICENSE in this distribution or at
118  *  http://www.rtems.com/license/LICENSE.
119  *
120- *  $Id: ckinit.c,v 1.24 2010/03/10 17:16:01 joel Exp $
121+ *  $Id$
122  */
123 
124 #include <bsp.h>
125@@ -234,6 +234,8 @@
126   }
127   pc386_clock_click_count = US_TO_TICK(pc386_microseconds_per_isr);
128 
129+  BSP_irq_enable_at_i8259s( BSP_PERIODIC_TIMER - BSP_IRQ_VECTOR_BASE );
130+
131   #if 0
132     printk( "configured usecs per tick=%d \n",
133       rtems_configuration_get_microseconds_per_tick() );
134@@ -271,15 +273,33 @@
135 rtems_isr Clock_isr(
136   rtems_vector_number vector
137 );
138+
139+bool Clock_isr_enabled = false;
140+void Clock_isr_handler(
141+  rtems_irq_hdl_param param
142+)
143+{
144+  if ( Clock_isr_enabled )
145+    Clock_isr( 0 );
146+}
147+
148 static rtems_irq_connect_data clockIrqData = {
149   BSP_PERIODIC_TIMER,
150-  (void *)Clock_isr,
151+  Clock_isr_handler,
152   0,
153   clockOn,
154   clockOff,
155   clockIsOn
156 };
157 
158+void Clock_driver_install_handler(void)
159+{
160+  if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
161+    printk("Unable to install system clock ISR handler\n");
162+    rtems_fatal_error_occurred(1);
163+  }
164+}
165+
166 void Clock_driver_support_initialize_hardware(void)
167 {
168   bool use_tsc = false;
169@@ -318,11 +338,7 @@
170     Clock_driver_nanoseconds_since_last_tick
171   );
172 
173-  if (!BSP_install_rtems_irq_handler (&clockIrqData)) {
174-    printk("Unable to initialize system clock\n");
175-    rtems_fatal_error_occurred(1);
176-  }
177-
178+  Clock_isr_enabled = true;
179 }
180 
181 #define Clock_driver_support_shutdown_hardware() \
182Index: c/src/lib/libbsp/i386/pc386/start/start16.S
183===================================================================
184RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/start/start16.S,v
185retrieving revision 1.14
186diff -u -r1.14 start16.S
187--- c/src/lib/libbsp/i386/pc386/start/start16.S 20 Jul 2011 16:50:19 -0000      1.14
188+++ c/src/lib/libbsp/i386/pc386/start/start16.S 27 Jul 2011 18:43:54 -0000
189@@ -37,35 +37,57 @@
190 | Constants
191 +----------------------------------------------------------------------------*/
192 
193+#if defined(SMP_SECONDARY_CORE)
194+.set PROT_CODE_SEG, 0x08        # offset of code segment descriptor into GDT
195+#else
196 .set PROT_CODE_SEG, 0x0         # offset of code segment descriptor into GDT
197+#endif
198+
199 .set PROT_DATA_SEG, 0x10        # offset of code segment descriptor into GDT
200 .set CR0_PE,        1           # protected mode flag on CR0 register
201 .set HDRSTART,      HEADERADDR  # address of start of bin2boot header
202 .set HDROFF,        0x24        # offset into bin2boot header of start32 addr
203 .set STACKOFF,      0x200-0x10  # offset to load into %esp, from start of image
204 
205- /* #define NEW_GAS */
206+/* #define NEW_GAS */
207+#ifdef NEW_GAS
208+  #define LJMPL ljmpl
209+#else
210+  #define LJMPL ljmp
211+#endif
212+
213 /*----------------------------------------------------------------------------+
214 | CODE section
215 +----------------------------------------------------------------------------*/
216 
217 .text
218-
219+#if defined(SMP_SECONDARY_CORE)
220+        .globl app_processor_start                # entry point
221+app_processor_start:
222+#else
223         .globl _start16         # entry point
224         .globl start16
225 start16:
226 _start16:
227+#endif
228 
229 .code16
230         cli                     # DISABLE INTERRUPTS!!!
231+#if defined(SMP_SECONDARY_CORE)
232+        jmp     1f
233+       .align 4
234+app_cpu_start:
235+       .long   0
236+app_cpu_stack:
237+       .long   0
238+1:
239+#endif
240+        movw    %cs, %ax                   # Initialize the rest of
241+        movw    %ax, %ds                   #   segment registers
242+        movw    %ax, %es
243+        movw    %ax, %ss
244 
245-        movw    %cs, %ax        #
246-        movw    %ax, %ds        # set the rest of real mode registers
247-        movw    %ax, %es        #
248-        movw    %ax, %ss        #
249-
250-#if (RTEMS_VIDEO_80x50 == 1)
251-
252+#if !defined(SMP_SECONDARY_CODE) && (RTEMS_VIDEO_80x50 == 1)
253         movl    $0x0040,%eax    # use 32 bit constant to ensure 16 MSB=0
254         mov     %ax,%es
255         movw    %es:0x4a, %ax   # get 16 bit number of columns
256@@ -87,26 +109,30 @@
257         movb    $0x01, %ah      # define cursor (scan lines 0 to 7)
258         movw    $0x0007, %cx
259         int     $0x10
260-
261 1:
262-#endif /* RTEMS_VIDEO_80x50 */
263+#endif /* !SMP_SECONDARY_CODE and RTEMS_VIDEO_80x50 */
264 
265         /*---------------------------------------------------------------------+
266         | Bare PC machines boot in real mode! We have to turn protected mode on.
267         +---------------------------------------------------------------------*/
268 
269+#if defined(SMP_SECONDARY_CORE)
270+        lgdt    gdtptr - app_processor_start  # load Global Descriptor Table
271+#else
272         lgdt    gdtptr - start16        # load Global Descriptor Table
273+#endif /* SMP_SECONDARY_CORE */
274+
275         movl    %cr0, %eax
276         orl     $CR0_PE, %eax
277         movl    %eax, %cr0              # turn on protected mode
278-
279-#ifdef NEW_GAS
280-        ljmpl   $PROT_CODE_SEG, $1f     # flush prefetch queue, and reload %cs
281+#if defined(SMP_SECONDARY_CORE)
282+        LJMPL   $PROT_CODE_SEG, $2f     # flush prefetch queue, and reload %cs
283 #else
284-        ljmp    $PROT_CODE_SEG, $1f     # flush prefetch queue, and reload %cs
285+        LJMPL   $PROT_CODE_SEG, $2f     # flush prefetch queue, and reload %cs
286 #endif
287 .code32
288-1:
289+2:
290+
291         /*---------------------------------------------------------------------+
292         | load the other segment registers
293         +---------------------------------------------------------------------*/
294@@ -114,8 +140,13 @@
295         movw    %ax, %ds
296         movw    %ax, %es
297         movw    %ax, %ss
298+#if defined(SMP_SECONDARY_CORE)
299+        movl    app_cpu_stack, %esp            # stack pointer
300+        movl    app_cpu_stack, %ebp            # base pointer
301+ #else
302         movl    $start16 + STACKOFF, %esp       # set up stack pointer
303         addl    $start16 + STACKOFF, %ebp       # set up stack pointer
304+#endif  /* SMP_SECONDARY_CORE */
305 
306         /*---------------------------------------------------------------------+
307         | we have to enable A20 in order to access memory above 1MByte
308@@ -132,9 +163,14 @@
309         call    pc386_delay
310         call    pc386_delay
311 
312-        movl    %cs:HDRSTART + HDROFF, %eax     #
313-        pushl   %eax                            # jump to start of 32 bit code
314-        ret                                     #
315+#if defined(SMP_SECONDARY_CORE)
316+        movl    app_cpu_start, %eax             # jump to app CPU start
317+#else
318+        movl    %cs:HDRSTART + HDROFF, %eax     # jump to start of 32 bit code
319+#endif  /* SMP_SECONDARY_CORE */
320+        pushl   %eax                           
321+        ret                                   
322+
323 
324 /*----------------------------------------------------------------------------+
325 | pc386_delay
326Index: c/src/lib/libbsp/i386/pc386/startup/bspstart.c
327===================================================================
328RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/startup/bspstart.c,v
329retrieving revision 1.50
330diff -u -r1.50 bspstart.c
331--- c/src/lib/libbsp/i386/pc386/startup/bspstart.c      28 Jan 2011 20:35:34 -0000      1.50
332+++ c/src/lib/libbsp/i386/pc386/startup/bspstart.c      27 Jul 2011 18:43:54 -0000
333@@ -27,10 +27,11 @@
334 | *  http://www.rtems.com/license/LICENSE.
335 | **************************************************************************
336 |
337-|  $Id: bspstart.c,v 1.50 2011/01/28 20:35:34 joel Exp $
338+|  $Id$
339 +--------------------------------------------------------------------------*/
340 
341 #include <bsp.h>
342+#include <bsp/irq.h>
343 #include <rtems/pci.h>
344 #include <libcpu/cpuModel.h>
345 
346@@ -40,6 +41,7 @@
347 extern void Calibrate_loop_1ms(void);
348 extern void rtems_irq_mngt_init(void);
349 extern void bsp_size_memory(void);
350+void Clock_driver_install_handler(void);
351 
352 /*-------------------------------------------------------------------------+
353 |         Function: bsp_start
354@@ -80,6 +82,8 @@
355       printk("PCI bus: could not initialize PCI BIOS interface\n");
356   }
357 
358+  Clock_driver_install_handler();
359+
360   bsp_ide_cmdline_init();
361 
362 } /* bsp_start */
363Index: c/src/lib/libbsp/i386/pc386/startup/ldsegs.S
364===================================================================
365RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/pc386/startup/ldsegs.S,v
366retrieving revision 1.20
367diff -u -r1.20 ldsegs.S
368--- c/src/lib/libbsp/i386/pc386/startup/ldsegs.S        28 Jan 2011 20:35:34 -0000      1.20
369+++ c/src/lib/libbsp/i386/pc386/startup/ldsegs.S        27 Jul 2011 18:43:54 -0000
370@@ -32,7 +32,7 @@
371 | *  http://www.rtems.com/license/LICENSE.
372 | **************************************************************************
373 |
374-|  $Id: ldsegs.S,v 1.20 2011/01/28 20:35:34 joel Exp $
375+|  $Id: ldsegs.S,v 1.2 2011/04/01 15:50:05 jennifer Exp $
376 +--------------------------------------------------------------------------*/
377 
378 #include <rtems/asm.h>
379@@ -96,7 +96,7 @@
380 SYM (_load_segments):
381 
382        lgdt SYM(gdtdesc)
383-       lidt SYM(idtdesc)
384+       lidt SYM(IDT_Descriptor)
385 
386        /* Load CS, flush prefetched queue */
387        ljmp $0x8, $next_step
388@@ -211,7 +211,8 @@
389 +--------------------------------------------------------------------------*/
390 
391        .p2align 4
392-SYM(idtdesc):
393+       PUBLIC(IDT_Descriptor)
394+SYM(IDT_Descriptor):
395        .word  (256*8 - 1)
396        .long  SYM (Interrupt_descriptor_table)
397 
398Index: c/src/lib/libbsp/i386/shared/irq/irq_asm.S
399===================================================================
400RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/shared/irq/irq_asm.S,v
401retrieving revision 1.25
402diff -u -r1.25 irq_asm.S
403--- c/src/lib/libbsp/i386/shared/irq/irq_asm.S  11 Apr 2011 17:16:50 -0000      1.25
404+++ c/src/lib/libbsp/i386/shared/irq/irq_asm.S  27 Jul 2011 18:43:54 -0000
405@@ -11,7 +11,7 @@
406  *  found in found in the file LICENSE in this distribution or at
407  *  http://www.rtems.com/license/LICENSE.
408  *
409- *  $Id: irq_asm.S,v 1.25 2011/04/11 17:16:50 joel Exp $
410+ *  $Id: irq_asm.S,v 1.4 2011/06/09 21:12:54 joel Exp $
411  */
412 
413 #include <rtems/asm.h>
414@@ -32,7 +32,7 @@
415 #define EBP_OFF 12       /* code restoring ebp/esp relies on */
416 #define ESP_OFF 16       /* esp being on top of ebp!         */
417 #ifdef __SSE__
418-/* need to be on 16 byte boundary for SSE */
419+/* need to be on 16 byte boundary for SSE, add 12 to do that */
420 #define FRM_SIZ (20+12+512)
421 #define SSE_OFF 32
422 #else
423@@ -46,17 +46,9 @@
424         *  Before this was point is reached the vectors unique
425         *  entry point did the following:
426         *
427-        *     1. saved scratch registers registers eax edx ecx"
428+        *     1. saved scratch registers registers eax edx ecx
429         *     2. put the vector number in ecx.
430         *
431-        * BEGINNING OF ESTABLISH SEGMENTS
432-        *
433-        *  WARNING: If an interrupt can occur when the segments are
434-        *           not correct, then this is where we should establish
435-        *           the segments.  In addition to establishing the
436-        *           segments, it may be necessary to establish a stack
437-        *           in the current data area on the outermost interrupt.
438-        *
439         *  NOTE:  If the previous values of the segment registers are
440         *         pushed, do not forget to adjust SAVED_REGS.
441         *
442@@ -104,9 +96,48 @@
443        ldmxcsr ARG_OFF(esp)            /* clean-slate MXCSR              */
444 #endif
445 
446+.check_stack_switch:
447+       movl      esp, ebp                  /* ebp = previous stack pointer */
448+#if defined(RTEMS_SMP) && defined(BSP_HAS_SMP)
449+       movl     $SYM(_Per_CPU_Information_p), ebx
450+       call     SYM(bsp_smp_processor_id)
451+       mov      (ebx,eax,4), ebx
452+        pushl    ecx
453+        call     SYM(_ISR_SMP_Enter)
454+        popl     ecx
455+        cmpl     $0, eax
456+        jne      .i8259
457+        movl     PER_CPU_INTERRUPT_STACK_HIGH(ebx), esp
458+       
459+#else
460+       movl     $SYM(_Per_CPU_Information), ebx
461+
462+       /*
463+         *  Is this the outermost interrupt?
464+        *  Switch stacks if necessary
465+        */
466+       cmpl      $0, PER_CPU_ISR_NEST_LEVEL(ebx)
467+       jne       nested                    /* No, then continue */
468+       movl      PER_CPU_INTERRUPT_STACK_HIGH(ebx), esp
469+
470+       /*
471+        *  We want to insure that the old stack pointer is in ebp
472+        *  By saving it on every interrupt, all we have to do is
473+        *  movl ebp->esp near the end of every interrupt.
474+        */
475+
476+nested:
477+       incl      PER_CPU_ISR_NEST_LEVEL(ebx)  /* one nest level deeper */
478+       incl      SYM (_Thread_Dispatch_disable_level) /* disable multitasking */
479+#endif
480+        /*
481+         *  i8259 Management
482+         */
483+
484+.i8259:
485         /* Do not disable any 8259 interrupts if this isn't from one */
486        cmp       ecx, 16               /* is this a PIC IRQ? */
487-       jge       .check_stack_switch
488+       jge       .end_of_i8259
489 
490        /*
491         * acknowledge the interrupt
492@@ -136,44 +167,7 @@
493        outb      $PIC_SLAVE_COMMAND_IO_PORT
494 .master:
495        outb      $PIC_MASTER_COMMAND_IO_PORT
496-
497-       /*
498-        *  Now switch stacks if necessary
499-        */
500-
501-PUBLIC (ISR_STOP)
502-ISR_STOP:
503-.check_stack_switch:
504-       movl      esp, ebp                  /* ebp = previous stack pointer */
505-#if defined(RTEMS_SMP) && defined(BSP_HAS_SMP)
506-       movl     $SYM(_Per_CPU_Information_p), ebx
507-       call     SYM(bsp_smp_processor_id)
508-       mov      (ebx,eax,4), ebx
509-#else
510-       movl     $SYM(_Per_CPU_Information), ebx
511-#endif
512-
513-       /* is this the outermost interrupt? */
514-       cmpl      $0, PER_CPU_ISR_NEST_LEVEL(ebx)
515-       jne       nested                    /* No, then continue */
516-       movl      PER_CPU_INTERRUPT_STACK_HIGH(ebx), esp
517-
518-       /*
519-        *  We want to insure that the old stack pointer is in ebp
520-        *  By saving it on every interrupt, all we have to do is
521-        *  movl ebp->esp near the end of every interrupt.
522-        */
523-
524-nested:
525-       incl      PER_CPU_ISR_NEST_LEVEL(ebx)  /* one nest level deeper */
526-       incl      SYM (_Thread_Dispatch_disable_level) /* disable multitasking */
527-
528-        /*
529-         * GCC versions starting with 4.3 no longer place the cld
530-         * instruction before string operations.  We  need to ensure
531-         * it is set correctly for ISR handlers.
532-         */
533-        cld
534+.end_of_i8259:
535 
536        /*
537         * re-enable interrupts at processor level as the current
538@@ -216,8 +210,14 @@
539        outb      $PIC_MASTER_IMR_IO_PORT
540        movb      ah, al
541        outb      $PIC_SLAVE_IMR_IO_PORT
542-
543 .dont_restore_i8259:
544+
545+
546+#if defined(RTEMS_SMP) && defined(BSP_HAS_SMP)
547+        call    SYM(_ISR_SMP_Exit)
548+       testl   eax, eax
549+       je      .exit
550+#else
551        decl      PER_CPU_ISR_NEST_LEVEL(ebx)  /* one less ISR nest level */
552                                            /* If interrupts are nested, */
553                                            /*   then dispatching is disabled */
554@@ -231,6 +231,7 @@
555                                            /* Is task switch necessary? */
556        jne       .schedule                 /* Yes, then call the scheduler */
557        jmp       .exit                     /* No, exit */
558+#endif
559 
560 .schedule:
561        /*
562Index: c/src/lib/libbsp/i386/shared/smp/smp-imps.c
563===================================================================
564RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/shared/smp/smp-imps.c,v
565retrieving revision 1.3
566diff -u -r1.3 smp-imps.c
567--- c/src/lib/libbsp/i386/shared/smp/smp-imps.c 18 Jul 2011 16:33:30 -0000      1.3
568+++ c/src/lib/libbsp/i386/shared/smp/smp-imps.c 27 Jul 2011 18:43:54 -0000
569@@ -47,6 +47,16 @@
570 #define _SMP_IMPS_C
571 
572 /*
573+ *  Includes here
574+ */
575+#if 0
576+#define IMPS_DEBUG
577+#endif
578+
579+#include <bsp/apic.h>
580+#include <bsp/smp-imps.h>
581+
582+/*
583  *  XXXXX  The following absolutely must be defined!!!
584  *
585  *  The "KERNEL_PRINT" could be made a null macro with no danger, of
586@@ -63,17 +73,69 @@
587 #define UDELAY(x)             /* delay roughly at least "x" microsecs */
588 #define TEST_BOOTED(x)        /* test bootaddr x to see if CPU started */
589 #define READ_MSR_LO(x)        /* Read MSR low function */
590-#endif
591+#else
592+#include <string.h>
593+#include <unistd.h>
594+#include <rtems.h>
595+#include <rtems/bspsmp.h>
596+#include <rtems/bspIo.h>
597+#include <libcpu/cpu.h>
598+
599+extern void _pc386_delay(void);
600+
601+/* #define KERNEL_PRINT(_format)       printk(_format) */
602+
603+static void CMOS_WRITE_BYTE(
604+  unsigned int  offset,
605+  unsigned char value
606+)
607+{
608+  if ( offset < 128 ) {
609+    outport_byte( 0x70, offset );
610+    outport_byte( 0x71, value );
611+  } else {
612+    outport_byte( 0x72, offset );
613+    outport_byte( 0x73, value );
614+  }
615+}
616 
617-/*
618- *  Includes here
619- */
620+static unsigned char CMOS_READ_BYTE(
621+  unsigned int  offset
622+)
623+{
624+  unsigned char value;
625+  if ( offset < 128 ) {
626+    outport_byte( 0x70, offset );
627+    inport_byte( 0x71, value );
628+  } else {
629+    outport_byte( 0x72, offset );
630+    inport_byte( 0x73, value );
631+  }
632+  return value;
633+}
634 
635-#define IMPS_DEBUG
636+#define PHYS_TO_VIRTUAL(_x)    _x
637+#define VIRTUAL_TO_PHYS(_x)    _x
638+static void UDELAY(int x)
639+{ int _i = x;
640+  while ( _i-- )
641+    _pc386_delay();
642+}
643+
644+#define READ_MSR_LO(_x) \
645+  (unsigned int)(read_msr(_x) & 0xffffffff)
646 
647-#include "apic.h"
648-#include "smp-imps.h"
649+#define TEST_BOOTED(_cpu) \
650+  (_Per_CPU_Information[_cpu].state == RTEMS_BSP_SMP_CPU_INITIALIZED)
651 
652+static inline unsigned long long read_msr(unsigned int msr)
653+{
654+  unsigned long long value;
655+
656+  asm volatile("rdmsr" : "=A" (value) : "c" (msr));
657+  return value;
658+}
659+#endif
660 
661 /*
662  *  Defines that are here so as not to be in the global header file.
663@@ -92,7 +154,6 @@
664 
665 #define DEF_ENTRIES  23
666 
667-static int lapic_dummy = 0;
668 static struct {
669   imps_processor proc[2];
670   imps_bus bus[2];
671@@ -132,10 +193,12 @@
672 volatile int imps_release_cpus = 0;
673 int imps_enabled = 0;
674 int imps_num_cpus = 1;
675-unsigned imps_lapic_addr = ((unsigned)(&lapic_dummy)) - LAPIC_ID;
676 unsigned char imps_cpu_apic_map[IMPS_MAX_CPUS];
677 unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS];
678 
679+/* now defined in getcpuid.c */
680+extern unsigned imps_lapic_addr;
681+
682 /*
683  *  MPS checksum function
684  *
685@@ -180,10 +243,10 @@
686  *  This must be modified to perform whatever OS-specific initialization
687  *  that is required.
688  */
689-static int
690+int
691 boot_cpu(imps_processor *proc)
692 {
693-  int apicid = proc->apic_id, success = 1, to;
694+  int apicid = proc->apic_id, success = 1;
695   unsigned bootaddr, accept_status;
696   unsigned bios_reset_vector = PHYS_TO_VIRTUAL(BIOS_RESET_VECTOR);
697 
698@@ -195,10 +258,19 @@
699    * under the 1MB boundary.
700    */
701 
702-  extern char patch_code_start[];
703-  extern char patch_code_end[];
704+  uint32_t *reset;
705+
706   bootaddr = (512-64)*1024;
707-  memcpy((char *)bootaddr, patch_code_start, patch_code_end - patch_code_start);
708+  reset= (uint32_t *)bootaddr;
709+
710+  memcpy(
711+    (char *) bootaddr,
712+    _binary_appstart_bin_start,
713+    (size_t)_binary_appstart_bin_size
714+  );
715+
716+  reset[1] = (uint32_t)rtems_smp_secondary_cpu_initialize;
717+  reset[2] = (uint32_t)_Per_CPU_Information[apicid].interrupt_stack_high;
718 
719   /*
720    *  Generic CPU startup sequence starts here.
721@@ -214,8 +286,9 @@
722 
723   /* assert INIT IPI */
724   send_ipi(
725-    apicid, LAPIC_ICR_TM_LEVEL | LAPIC_ICR_LEVELASSERT | LAPIC_ICR_DM_INIT);
726-
727+    apicid,
728+    LAPIC_ICR_TM_LEVEL | LAPIC_ICR_LEVELASSERT | LAPIC_ICR_DM_INIT
729+  );
730   UDELAY(10000);
731 
732   /* de-assert INIT IPI */
733@@ -238,14 +311,17 @@
734   /*
735    *  Check to see if other processor has started.
736    */
737-  to = 0;
738-  while (!TEST_BOOTED(bootaddr) && to++ < 100)
739-    UDELAY(10000);
740-  if (to >= 100) {
741-    KERNEL_PRINT(("CPU Not Responding, DISABLED"));
742+  bsp_smp_wait_for(
743+    (volatile unsigned int *)&_Per_CPU_Information[imps_num_cpus].state,
744+    RTEMS_BSP_SMP_CPU_INITIALIZED,
745+    1600
746+  );
747+  if ( _Per_CPU_Information[imps_num_cpus].state ==
748+        RTEMS_BSP_SMP_CPU_INITIALIZED )
749+    printk("#%d  Application Processor (AP)", imps_num_cpus);
750+  else {
751+    printk("CPU Not Responding, DISABLED");
752     success = 0;
753-  } else {
754-    KERNEL_PRINT(("#%d  Application Processor (AP)", imps_num_cpus));
755   }
756 
757   /*
758@@ -260,7 +336,7 @@
759   CMOS_WRITE_BYTE(CMOS_RESET_CODE, 0);
760   *((volatile unsigned *) bios_reset_vector) = 0;
761 
762-  KERNEL_PRINT(("\n"));
763+  printk("\n");
764 
765   return success;
766 }
767@@ -273,14 +349,13 @@
768 {
769   int apicid = proc->apic_id;
770 
771-  KERNEL_PRINT(("  Processor [APIC id %d ver %d]:  ",
772-          apicid, proc->apic_ver));
773+  printk("  Processor [APIC id %d ver %d]: ", apicid, proc->apic_ver);
774   if (!(proc->flags & IMPS_FLAG_ENABLED)) {
775-    KERNEL_PRINT(("DISABLED\n"));
776+    printk("DISABLED\n");
777     return;
778   }
779   if (proc->flags & (IMPS_CPUFLAG_BOOT)) {
780-    KERNEL_PRINT(("#0  BootStrap Processor (BSP)\n"));
781+    printk("#0  BootStrap Processor (BSP)\n");
782     return;
783   }
784   if (boot_cpu(proc)) {
785@@ -301,7 +376,7 @@
786 
787   memcpy(str, bus->bus_type, 6);
788   str[6] = 0;
789-  KERNEL_PRINT(("  Bus id %d is %s\n", bus->id, str));
790+  printk("  Bus id %d is %s\n", bus->id, str);
791 
792   /*  XXXXX  add OS-specific code here */
793 }
794@@ -309,13 +384,13 @@
795 static void
796 add_ioapic(imps_ioapic *ioapic)
797 {
798-  KERNEL_PRINT(("  I/O APIC id %d ver %d, address: 0x%x  ",
799-          ioapic->id, ioapic->ver, ioapic->addr));
800+  printk("  I/O APIC id %d ver %d, address: 0x%x  ",
801+          ioapic->id, ioapic->ver, ioapic->addr);
802   if (!(ioapic->flags & IMPS_FLAG_ENABLED)) {
803-    KERNEL_PRINT(("DISABLED\n"));
804+    printk("DISABLED\n");
805     return;
806   }
807-  KERNEL_PRINT(("\n"));
808+  printk("\n");
809 
810   /*  XXXXX  add OS-specific code here */
811 }
812@@ -326,7 +401,10 @@
813   while (count-- > 0) {
814     switch (*((unsigned char *)start)) {
815     case IMPS_BCT_PROCESSOR:
816-      add_processor((imps_processor *)start);
817+      if ( imps_num_cpus < rtems_configuration_smp_maximum_processors ) {
818+       add_processor((imps_processor *)start);
819+      } else
820+        imps_num_cpus++;
821       start += 12;  /* 20 total */
822       break;
823     case IMPS_BCT_BUS:
824@@ -350,6 +428,15 @@
825     }
826     start += 8;
827   }
828+  if ( imps_num_cpus > rtems_configuration_smp_maximum_processors ) {
829+    printk(
830+      "WARNING!! Found more CPUs (%d) than configured for (%d)!!\n",
831+      imps_num_cpus - 1,
832+      rtems_configuration_smp_maximum_processors
833+    );
834+    imps_num_cpus = rtems_configuration_smp_maximum_processors;
835+    return;
836+  }
837 }
838 
839 static int
840@@ -360,8 +447,8 @@
841     = (imps_cth *) PHYS_TO_VIRTUAL(fps_ptr->cth_ptr);
842 
843   if (fps_ptr->feature_info[0] > IMPS_FPS_DEFAULT_MAX) {
844-    KERNEL_PRINT(("    Invalid MP System Configuration type %d\n",
845-            fps_ptr->feature_info[0]));
846+    printk("    Invalid MP System Configuration type %d\n",
847+            fps_ptr->feature_info[0]);
848     return 1;
849   }
850 
851@@ -369,17 +456,17 @@
852     sum = get_checksum((unsigned)local_cth_ptr,
853                                    local_cth_ptr->base_length);
854     if (local_cth_ptr->sig != IMPS_CTH_SIGNATURE || sum) {
855-      KERNEL_PRINT(
856-        ("    Bad MP Config Table sig 0x%x and/or checksum 0x%x\n",
857+      printk(
858+        "    Bad MP Config Table sig 0x%x and/or checksum 0x%x\n",
859         (unsigned)(fps_ptr->cth_ptr),
860-        sum)
861+        sum
862       );
863       return 1;
864     }
865     if (local_cth_ptr->spec_rev != fps_ptr->spec_rev) {
866-      KERNEL_PRINT(
867-        ("    Bad MP Config Table sub-revision # %d\n",
868-        local_cth_ptr->spec_rev)
869+      printk(
870+        "    Bad MP Config Table sub-revision # %d\n",
871+        local_cth_ptr->spec_rev
872       );
873       return 1;
874     }
875@@ -389,12 +476,12 @@
876               local_cth_ptr->extended_length)
877              + local_cth_ptr->extended_checksum) & 0xFF;
878       if (sum) {
879-        KERNEL_PRINT(("    Bad Extended MP Config Table checksum 0x%x\n", sum));
880+        printk("    Bad Extended MP Config Table checksum 0x%x\n", sum);
881         return 1;
882       }
883     }
884   } else if (!fps_ptr->feature_info[0]) {
885-    KERNEL_PRINT(("    Missing configuration information\n"));
886+    printk("    Missing configuration information\n");
887     return 1;
888   }
889 
890@@ -410,15 +497,15 @@
891     = (imps_cth *)PHYS_TO_VIRTUAL(fps_ptr->cth_ptr);
892   char *str_ptr;
893 
894-  KERNEL_PRINT(("Intel MultiProcessor Spec 1.%d BIOS support detected\n",
895-          fps_ptr->spec_rev));
896+  printk("Intel MultiProcessor Spec 1.%d BIOS support detected\n",
897+          fps_ptr->spec_rev);
898 
899   /*
900    *  Do all checking of errors which would definitely
901    *  lead to failure of the SMP boot here.
902    */
903   if (imps_bad_bios(fps_ptr)) {
904-    KERNEL_PRINT(("    Disabling MPS support\n"));
905+    printk("    Disabling MPS support\n");
906     return;
907   }
908 
909@@ -432,10 +519,10 @@
910   } else {
911     imps_lapic_addr = LAPIC_ADDR_DEFAULT;
912   }
913-  KERNEL_PRINT(("    APIC config: \"%s mode\"    Local APIC address: 0x%x\n",
914-          str_ptr, imps_lapic_addr));
915+  printk("    APIC config: \"%s mode\"    Local APIC address: 0x%x\n",
916+          str_ptr, imps_lapic_addr);
917   if (imps_lapic_addr != (READ_MSR_LO(0x1b) & 0xFFFFF000)) {
918-    KERNEL_PRINT(("Inconsistent Local APIC address, Disabling SMP support\n"));
919+    printk("Inconsistent Local APIC address, Disabling SMP support\n");
920     return;
921   }
922   imps_lapic_addr = PHYS_TO_VIRTUAL(imps_lapic_addr);
923@@ -455,7 +542,7 @@
924     str1[8] = 0;
925     memcpy(str2, local_cth_ptr->prod_id, 12);
926     str2[12] = 0;
927-    KERNEL_PRINT(("  OEM id: %s  Product id: %s\n", str1, str2));
928+    printk("  OEM id: %s  Product id: %s\n", str1, str2);
929     cth_start = ((unsigned) local_cth_ptr) + sizeof(imps_cth);
930     cth_count = local_cth_ptr->entry_count;
931   } else {
932@@ -518,8 +605,7 @@
933 static int
934 imps_scan(unsigned start, unsigned length)
935 {
936-  IMPS_DEBUG_PRINT(("Scanning from 0x%x for %d bytes\n",
937-        start, length));
938+  printk("Scanning from 0x%x for %d bytes\n", start, length);
939 
940   while (length > 0) {
941     imps_fps *fps_ptr = (imps_fps *) PHYS_TO_VIRTUAL(start);
942@@ -528,7 +614,7 @@
943      && fps_ptr->length == 1
944      && (fps_ptr->spec_rev == 1 || fps_ptr->spec_rev == 4)
945      && !get_checksum(start, 16)) {
946-      IMPS_DEBUG_PRINT(("Found MP Floating Structure Pointer at %x\n", start));
947+      printk("Found MP Floating Structure Pointer at %x\n", start);
948       imps_read_bios(fps_ptr);
949       return 1;
950     }
951@@ -540,6 +626,7 @@
952   return 0;
953 }
954 
955+#if !defined(__rtems__)
956 /*
957  *  This is the primary function to "force" SMP support, with
958  *  the assumption that you have consecutively numbered APIC ids.
959@@ -550,7 +637,7 @@
960   int apicid, i;
961   imps_processor p;
962 
963-  KERNEL_PRINT(("Intel MultiProcessor \"Force\" Support\n"));
964+  printk("Intel MultiProcessor \"Force\" Support\n");
965 
966   imps_lapic_addr = (READ_MSR_LO(0x1b) & 0xFFFFF000);
967   imps_lapic_addr = PHYS_TO_VIRTUAL(imps_lapic_addr);
968@@ -580,6 +667,7 @@
969 
970   return imps_num_cpus;
971 }
972+#endif
973 
974 /*
975  *  This is the primary function for probing for MPS compatible hardware
976@@ -661,3 +749,116 @@
977   return 0;
978 }
979 
980+/*
981+ *  RTEMS SMP BSP Support
982+ */
983+void smp_apic_ack(void)
984+{
985+  (void) IMPS_LAPIC_READ(LAPIC_SPIV);  /* dummy read */
986+  IMPS_LAPIC_WRITE(LAPIC_EOI, 0 );     /* ACK the interrupt */
987+}
988+
989+rtems_isr ap_ipi_isr(
990+  rtems_vector_number vector
991+)
992+{
993+  smp_apic_ack();
994+
995+  rtems_smp_process_interrupt();
996+}
997+
998+#include <rtems/irq.h>
999+
1000+static rtems_irq_connect_data apIPIIrqData = {
1001+  16,
1002+  (void *)ap_ipi_isr,
1003+  0,
1004+  NULL,            /* On */
1005+  NULL,            /* Off */
1006+  NULL,            /* IsOn */
1007+};
1008+
1009+extern void bsp_reset(void);
1010+void ipi_install_irq(void)
1011+{
1012+  if (!BSP_install_rtems_irq_handler (&apIPIIrqData)) {
1013+    printk("Unable to initialize IPI\n");
1014+    bsp_reset();
1015+  }
1016+}
1017+
1018+#ifdef __SSE__
1019+extern void enable_sse(void);
1020+#endif
1021+
1022+/* pc386 specific initialization */
1023+void bsp_smp_secondary_cpu_initialize(int cpu)
1024+{
1025+  int apicid;
1026+
1027+  asm volatile( "lidt IDT_Descriptor" );
1028+
1029+  apicid = IMPS_LAPIC_READ(LAPIC_SPIV);
1030+  IMPS_LAPIC_WRITE(LAPIC_SPIV, apicid|LAPIC_SPIV_ENABLE_APIC);
1031+
1032+#ifdef __SSE__
1033+  enable_sse();
1034+#endif
1035+}
1036+
1037+#include <rtems/bspsmp.h>
1038+int bsp_smp_initialize(
1039+  int maximum
1040+)
1041+{
1042+  int cores;
1043+  /* XXX need to deal with finding too many cores */
1044+
1045+  cores = imps_probe();
1046+
1047+  if ( cores > 1 )
1048+    ipi_install_irq();
1049+  return cores;
1050+}
1051+
1052+void bsp_smp_interrupt_cpu(
1053+  int cpu
1054+)
1055+{
1056+  send_ipi( cpu, 0x30 );
1057+}
1058+
1059+void bsp_smp_broadcast_interrupt(void)
1060+{
1061+  /* Single broadcast interrupt */
1062+  send_ipi( 0, LAPIC_ICR_DS_ALLEX | 0x30 );
1063+}
1064+
1065+void bsp_smp_wait_for(
1066+  volatile unsigned int *address,
1067+  unsigned int           desired,
1068+  int                    maximum_usecs
1069+)
1070+{
1071+  int iterations;
1072+  volatile int i;
1073+  volatile unsigned int *p = (volatile unsigned int *)address;
1074+
1075+  for (iterations=0 ;  iterations < maximum_usecs ; iterations++ ) {
1076+    if ( *p == desired )
1077+      break;
1078+    #ifdef __SSE3__
1079+      __builtin_ia32_monitor( (const void *)address, 0, 0 );
1080+      if ( *p == desired )
1081+        break;
1082+      __builtin_ia32_mwait( 0, 0 );
1083+    #endif
1084+
1085+    /*
1086+     *  Until i386 ms delay does not depend upon the clock we
1087+     *  will use this less sophisticated delay.
1088+     */
1089+    for(i=5000; i>0; i--)
1090+      ;
1091+  }
1092+}
1093Index: c/src/lib/libbsp/i386/shared/smp/smp-imps.h
1094===================================================================
1095RCS file: /usr1/CVS/rtems/c/src/lib/libbsp/i386/shared/smp/smp-imps.h,v
1096retrieving revision 1.3
1097diff -u -r1.3 smp-imps.h
1098--- c/src/lib/libbsp/i386/shared/smp/smp-imps.h 18 Jul 2011 16:33:30 -0000      1.3
1099+++ c/src/lib/libbsp/i386/shared/smp/smp-imps.h 27 Jul 2011 18:43:54 -0000
1100@@ -37,6 +37,22 @@
1101  *  Intel literature center.
1102  */
1103 
1104+/*
1105+ *  This file is based upon code by Eric Boleyn as documented above. 
1106+ *  RTEMS support was added and minimal other changes were made. 
1107+ *  This should make it easier to compare this file with the original
1108+ *  version.
1109+ *
1110+ *  COPYRIGHT (c) 2011.
1111+ *  On-Line Applications Research Corporation (OAR).
1112+ *
1113+ *  The license and distribution terms for this file may be
1114+ *  found in the file LICENSE in this distribution or at
1115+ *  http://www.rtems.com/license/LICENSE.
1116+ *
1117+ *  $Id$
1118+ */
1119+
1120 #ifndef _SMP_IMPS_H
1121 #define _SMP_IMPS_H
1122 
1123@@ -194,47 +210,14 @@
1124  */
1125 
1126 /*
1127- *  "imps_enabled" is non-zero if the probe sequence found IMPS
1128- *  information and was successful.
1129- */
1130-extern int imps_enabled;
1131-
1132-/*
1133- *  This contains the local APIC hardware address.
1134- */
1135-extern unsigned imps_lapic_addr;
1136-
1137-/*
1138- *  This represents the number of CPUs found.
1139- */
1140-extern int imps_num_cpus;
1141-
1142-/*
1143  *  These map from virtual cpu numbers to APIC id's and back.
1144  */
1145 extern unsigned char imps_cpu_apic_map[IMPS_MAX_CPUS];
1146 extern unsigned char imps_apic_cpu_map[IMPS_MAX_CPUS];
1147 
1148-/*
1149- *  This is the primary function for probing for Intel MPS 1.1/1.4
1150- *  compatible hardware and BIOS information.  While probing the CPUs
1151- *  information returned from the BIOS, this also starts up each CPU
1152- *  and gets it ready for use.
1153- *
1154- *  Call this during the early stages of OS startup, before memory can
1155- *  be messed up.
1156- *
1157- *  Returns N if IMPS information was found (for number of CPUs started)
1158- *  and is valid, else 0.
1159- */
1160-int imps_probe(void);
1161-
1162-/*
1163- *  This one is used as a "force" function.  Give it the number of CPUs
1164- *  to start, and it will assume a certain number and try it.
1165- */
1166-int imps_force(int ncpus);
1167-
1168+/* base address of application processor reset code at 0x70000 */
1169+extern char _binary_appstart_bin_start[];
1170+extern char _binary_appstart_bin_size[];
1171 
1172 /*
1173  *  Defines that use variables