Mailbox RPi patch and rtems_cache_* probably broken on RPi
Pavel Pisa
ppisa4lists at pikron.com
Wed Jun 22 18:11:09 UTC 2016
Hello Mudit and Sebastian,
I have tested patch for reding board revision and it seems
to work as expected when called during board initialization.
They work even after bsp_memory_management_initialize()
and even in _Thread_Start_multitasking() function.
But mailbox fails after that in _Thread_Handler( void ),
this is when run in regular thread content.
I have found that when I disable MMU/cache completely
or call directly arm_cp15_data_cache_clean_and_invalidate()
to flush complete data cache before transfer then correct behavior
is restored.
This is strange because I think that cache is enabled even
in _Thread_Start_multitasking(). I have checked that problem
is not caused/restored by long delay inserted by complete cache flush.
I have tried to add "dumy" delay loop with repeating
RTEMS_COMPILER_MEMORY_BARRIER();
arm_cp15_drain_write_buffer();
but this does not help.
When
rtems_cache_flush_multiple_data_lines(buf, size);
rtems_cache_invalidate_multiple_data_lines(buf, size);
are replaced by
arm_cp15_data_cache_clean_and_invalidate()
all calls to mailbox exchange works.
May it be that rtems_cache_* influences only L1 cache
but then I do not see which rtems calls should be used
to synchronize access to memory with external devices/DMA
I have added some RTEMS_COMPILER_MEMORY_BARRIER(); to the code
and experienced with these in more places too but that did not
help.
This patch help me
----------------------------------------------------------------
diff --git a/c/src/lib/libbsp/arm/raspberrypi/misc/vc.c b/c/src/lib/libbsp/arm/raspberrypi/misc/vc.c
index d27668d..5e1de9e 100644
--- a/c/src/lib/libbsp/arm/raspberrypi/misc/vc.c
+++ b/c/src/lib/libbsp/arm/raspberrypi/misc/vc.c
@@ -34,6 +34,7 @@
static inline bool
bcm2835_mailbox_buffer_suceeded(const bcm2835_mbox_buf_hdr *hdr)
{
+ RTEMS_COMPILER_MEMORY_BARRIER();
return (hdr->buf_code == BCM2835_MBOX_BUF_CODE_REQUEST_SUCCEED);
}
@@ -58,11 +59,20 @@ bcm2835_mailbox_buffer_flush_and_invalidate(void *buf, size_t size)
sctlr_val = arm_cp15_get_control();
+ RTEMS_COMPILER_MEMORY_BARRIER();
arm_cp15_drain_write_buffer();
if (sctlr_val & (ARM_CP15_CTRL_C | ARM_CP15_CTRL_M)) {
- arm_cp15_drain_write_buffer();
+#if 0
+ /*
+ These architecture independent RTEMS API functions should work
+ but for some reason they are not enough
+ */
rtems_cache_flush_multiple_data_lines(buf, size);
rtems_cache_invalidate_multiple_data_lines(buf, size);
+#else
+ /* Flush complete data cache */
+ arm_cp15_data_cache_clean_and_invalidate();
+#endif
}
}
----------------------------------------------------------------
MBOX test/HACK in start multitasking
----------------------------------------------------------------
diff --git a/cpukit/score/src/threadstartmultitasking.c b/cpukit/score/src/threadstartmultitasking.c
index 291e42c..8c5b91d 100644
--- a/cpukit/score/src/threadstartmultitasking.c
+++ b/cpukit/score/src/threadstartmultitasking.c
@@ -20,6 +20,7 @@
#include <rtems/score/threadimpl.h>
#include <rtems/score/assert.h>
+#include <bsp/vc.h>
void _Thread_Start_multitasking( void )
{
@@ -44,6 +45,23 @@ void _Thread_Start_multitasking( void )
_CPU_SMP_Prepare_start_multitasking();
#endif
+ int res;
+ bcm2835_mailbox_get_fw_rev_entries fw_rev;
+ printk("bcm2835_mailbox_get_firmware_revision ...\n");
+ res = bcm2835_mailbox_get_firmware_revision(&fw_rev);
+ printk("bcm2835_mailbox_get_firmware_revision %d %d\n", res, fw_rev.fw_rev);
+
+ bcm2835_get_board_spec_entries board_spec;
+ printk("bcm2835_mailbox_get_board_model ...\n");
+ res = bcm2835_mailbox_get_board_model(&board_spec);
+ printk("bcm2835_mailbox_get_board_model %d %d\n", res, board_spec.spec);
+
+ bcm2835_get_board_spec_entries board_spec1;
+ printk("bcm2835_mailbox_get_board_revision ...\n");
+ res = bcm2835_mailbox_get_board_revision(&board_spec1);
+ printk("bcm2835_mailbox_get_board_revision %d %d\n", res, board_spec1.spec);
+
+
#if defined(_CPU_Start_multitasking)
_CPU_Start_multitasking( &heir->Registers );
#elif defined(RTEMS_SMP)
diff --git a/testsuites/samples/ticker/init.c b/testsuites/samples/ticker/init.c
----------------------------------------------------------------
Test/HACK to check functions from init thread
----------------------------------------------------------------
index 3f3cbd8..f09a6a6 100644
--- a/testsuites/samples/ticker/init.c
+++ b/testsuites/samples/ticker/init.c
@@ -13,9 +13,30 @@
#define CONFIGURE_INIT
#include "system.h"
+#include "bsp/vc.h"
const char rtems_test_name[] = "CLOCK TICK";
+void print_rev(void)
+{
+ int res;
+
+ bcm2835_mailbox_get_fw_rev_entries fw_rev;
+ printf("bcm2835_mailbox_get_firmware_revision ...\n");
+ res = bcm2835_mailbox_get_firmware_revision(&fw_rev);
+ printf("bcm2835_mailbox_get_firmware_revision %d %d\n", res, fw_rev.fw_rev);
+
+ bcm2835_get_board_spec_entries board_spec;
+ printf("bcm2835_mailbox_get_board_model ...\n");
+ res = bcm2835_mailbox_get_board_model(&board_spec);
+ printf("bcm2835_mailbox_get_board_model %d %d\n", res, board_spec.spec);
+
+ bcm2835_get_board_spec_entries board_spec1;
+ printf("bcm2835_mailbox_get_board_revision ...\n");
+ res = bcm2835_mailbox_get_board_revision(&board_spec1);
+ printf("bcm2835_mailbox_get_board_revision %d %d\n", res, board_spec1.spec);
+}
+
/*
* Keep the names and IDs in global variables so another task can use them.
*/
@@ -40,6 +61,11 @@ rtems_task Init(
time.second = 0;
time.ticks = 0;
+ print_rev();
+ print_rev();
+ print_rev();
+ print_rev();
+
status = rtems_clock_set( &time );
directive_failed( status, "clock get" );
----------------------------------------------------------------
If there is no objection I update
bcm2835_mailbox_buffer_flush_and_invalidate()
to call inefficient arm_cp15_data_cache_clean_and_invalidate();
to ensure that RPi development projects are not blocked.
I send Mudit changes to mainline as well if there is no
problem pointed by others.
Best wishes,
Pavel
More information about the devel
mailing list