Minimal SMP program for the Zynq?

Jonathan Brandmeyer jonathan.brandmeyer at gmail.com
Thu May 7 16:52:58 UTC 2015


I've managed to get Xilinx XMD to put up a pair of gdbservers such that I
can inspect the target and see what's wrong[2].  The system has deadlocked
with both cores waiting for an event from the other one.

I've been reading the RTEMS Zynq BSP source code, and I do not see how CPU1
gets its start address.  The Zynq manual [1] describes that the CPU0
application should place the start address in 0xfffffff0 and sev to wake up
the other core, which ultimately jumps to the requested start address.
However, it appears by my reading of the assembly code that the address has
never been loaded, since the start address pointer just forms a loop by
pointing back to the original wfe instruction.

What should the start address be to start up RTEMS on the second core?
Beware that it must be an ARM mode instruction, since 'bl' is used to make
the jump, rather than 'blx'.  I noticed that my application code is
compiled in Thumb mode.

Thanks,
Jonathan Brandmeyer

[1] UG585, Section 6.1.10

[2] GDB Traces:

First off, CPU1 has the following code injected into it:

   0xffffff20:    dsb    sy
   0xffffff24:    wfe
   0xffffff28:    b    0xffffff20
   0xffffff2c:    dsb    sy
   0xffffff30:    wfe
=> 0xffffff34:    mvn    r0, #15
   0xffffff38:    ldr    lr, [r0]
   0xffffff3c:    cmn    lr, #212    ; 0xd4
   0xffffff40:    beq    0xffffff2c
   0xffffff44:    mcr    15, 0, r0, cr7, cr5, {0}
   0xffffff48:    mcr    15, 0, r0, cr7, cr5, {6}
   0xffffff4c:    mcr    15, 0, r0, cr8, cr7, {0}
   0xffffff50:    mov    r4, #0
   0xffffff54:    mcr    15, 0, r4, cr1, cr0, {0}
   0xffffff58:    bx    lr

   0xfffffff0 contains value 0xffffff2c
0xfffffff0 has type void (*)(void), and is used by the Zynq boot ROM to
receive an address to start executing.

And CPU0 is waiting on CPU1:

gdb) bt full
#0  _ARM_Data_memory_barrier ()
    at
../../cpukit/../../../xilinx_zynq_zedboard/lib/include/rtems/score/cpu.h:303
No locals.
#1  _CPU_SMP_Processor_event_receive ()
    at
../../cpukit/../../../xilinx_zynq_zedboard/lib/include/rtems/score/cpu.h:541
No locals.
#2  _Per_CPU_State_wait_for_non_initial_state (cpu_index=cpu_index at entry=1,
timeout_in_ns=57999,
    timeout_in_ns at entry=0)
    at
../../../../../../rtems/c/src/../../cpukit/score/src/percpustatewait.c:50
        state = PER_CPU_STATE_INITIAL
#3  0x0011ae0a in _CPU_SMP_Start_processor (cpu_index=cpu_index at entry=1)
    at
../../../../../../../../rtems/c/src/lib/libbsp/arm/xilinx-zynq/startup/bspsmp.c:23
No locals.
#4  0x00110516 in _SMP_Start_processors (cpu_count=2)
    at ../../../../../../rtems/c/src/../../cpukit/score/src/smp.c:42
        started = <optimized out>
        cpu_index = 1
#5  _SMP_Handler_initialize () at
../../../../../../rtems/c/src/../../cpukit/score/src/smp.c:99
        cpu_max = <optimized out>
        cpu_count = <optimized out>
        cpu_index = <optimized out>
#6  0x0010c814 in rtems_initialize_data_structures ()
    at ../../../../../../rtems/c/src/../../cpukit/sapi/src/exinit.c:138
No locals.
#7  0x00104934 in boot_card (cmdline=<optimized out>)
    at
../../../../../../../../rtems/c/src/lib/libbsp/arm/xilinx-zynq/../../shared/bootcard.c:92
No locals.
#8  0x00104112 in bsp_vector_table_copy_done ()
    at
../../../../../../../../rtems/c/src/lib/libbsp/arm/xilinx-zynq/../shared/start/start.S:279
No locals.


On Wed, May 6, 2015 at 9:19 PM, Jonathan Brandmeyer <
jonathan.brandmeyer at gmail.com> wrote:

> The enclosed program is intended to run on the Microzed platform with SMP
> support enabled.  It is a POSIX version of the ticker sample program, and
> it does run in single-core mode.  However, if the #defines for
> CONFIGURE_SMP_APPLICATION and CONFIGURE_SMP_MAXIMUM_PROCESSORS are left
> uncommented, the application does not run at all.  It does not reach the
> first printf that marks entry into POSIX_Init().
>
> The RTEMS BSP was built with
> $ ../rtems/configure --prefix=$HOME/Programs/rtems_4_11 --enable-posix
> --enable-smp --disable-networking --enable-cxx --enable-tests=samples
> --enable-rtemsbsp="xilinx_zynq_zedboard" --target=arm-rtems4.11
>
> I didn't see anything special in the Zynq manuals about the bitstream
> design or FSBL configuration that needs changes to support SMP operation.
> Unfortunately, my attempts to GDB into the target through OpenOCD have
> failed, such that I cannot tell where RTEMS has locked up.
>
> Any ideas would be greatly appreciated.
>
> Thanks,
> Jonathan
>
>
> #include <bsp.h>
> #include <stdlib.h>
> #include <stdio.h>
>
> void *POSIX_Init(void *args);
> void *ticker_threadfunc(void *closure);
>
> #define CONFIGURE_SMP_APPLICATION
> #define CONFIGURE_SMP_MAXIMUM_PROCESSORS 2
> #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER
> #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER
>
> #define CONFIGURE_UNIFIED_WORK_AREAS
> #define CONFIGURE_UNLIMITED_OBJECTS
> #define CONFIGURE_POSIX_INIT_THREAD_TABLE
>
> #define CONFIGURE_INIT
> #include <rtems/confdefs.h>
>
> void *
> POSIX_Init(void *args)
> {
>     printf("Entry to POSIX_Init\n");
>     const char *names[] = {
>         "TAI1",
>         "TAI2",
>         "TAI3",
>         NULL,
>     };
>     pthread_t threads[4];
>     for (unsigned i = 0; names[i] != NULL; ++i) {
>         pthread_create(&threads[i], NULL, ticker_threadfunc, (void
> *)names[i]);
>         // Spread the tasks' start times out a pinch.
>         sleep(2);
>     }
>
>     // Verify SMP operation.
>     printf("Running on %lu cores\n", rtems_get_processor_count());
>
>     for (unsigned i = 0; names[i] != NULL; ++i) {
>         pthread_join(threads[i], NULL);
>         printf("joined with thread %d\n", i);
>     }
>     printf("Exiting\n");
>     // Huh.  The following does not behave as expected.  Instead of calling
>     // exit(), nothing happens.
>     // pthread_exit(NULL);
>     exit(EXIT_SUCCESS);
>     return NULL;
> }
>
> #include <stdbool.h>
> #include <time.h>
> #include <unistd.h>
>
> void *
> ticker_threadfunc(void *closure)
> {
>     const char *threadname = closure;
>
>     struct timespec begin;
>     clock_gettime(CLOCK_REALTIME, &begin);
>     while (true) {
>         struct timespec now;
>         clock_gettime(CLOCK_REALTIME, &now);
>
>         struct tm formatted_now;
>         gmtime_r(&now.tv_sec, &formatted_now);
>         printf("%s: %04d-%02d-%02d %02d:%02d:%02d\n",
>                 threadname,
>                 formatted_now.tm_year,
>                 formatted_now.tm_mon,
>                 formatted_now.tm_mday,
>                 formatted_now.tm_hour,
>                 formatted_now.tm_min,
>                 formatted_now.tm_sec);
>
>         sleep(5);
>         if (now.tv_sec - begin.tv_sec >= 30) {
>             pthread_exit(NULL);
>         }
>     }
>     // Unreachable.
>     return NULL;
> }
>
>
>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/users/attachments/20150507/c8f4b3c9/attachment.html>


More information about the users mailing list