Browse Source

Merge branch 'master' of https://github.com/RT-Thread/rt-thread into fix_bug_of_dataqueue

qiyongzhong0 4 years ago
parent
commit
77f0814992
100 changed files with 8301 additions and 474 deletions
  1. 10 0
      bsp/ls2kdev/drivers/board.c
  2. 23 0
      bsp/ls2kdev/drivers/ls2k1000.h
  3. 3 0
      bsp/nrf5x/libraries/drivers/SConscript
  4. 162 0
      bsp/nrf5x/libraries/drivers/drv_rtc.c
  5. 33 0
      bsp/nrf5x/nrf52832/board/Kconfig
  6. 34 1
      bsp/nrf5x/nrf52840/board/Kconfig
  7. 197 384
      bsp/stm32/libraries/HAL_Drivers/drv_gpio.c
  8. 9 18
      bsp/stm32/libraries/HAL_Drivers/drv_gpio.h
  9. 1 0
      bsp/stm32/stm32mp157a-st-discovery/.config
  10. 12 16
      bsp/stm32/stm32mp157a-st-discovery/.cproject
  11. 19 19
      bsp/stm32/stm32mp157a-st-discovery/README.md
  12. 58 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/ipcc.h
  13. 39 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/mbox_ipcc.h
  14. 58 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/openamp.h
  15. 242 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/openamp_conf.h
  16. 134 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/openamp_log.h
  17. 43 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/rsc_table.h
  18. 182 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/mbox_ipcc.c
  19. 176 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/openamp.c
  20. 102 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/openamp_log.c
  21. 174 0
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/rsc_table.c
  22. 10 4
      bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
  23. 6 0
      bsp/stm32/stm32mp157a-st-discovery/board/Kconfig
  24. 25 0
      bsp/stm32/stm32mp157a-st-discovery/board/SConscript
  25. 12 8
      bsp/stm32/stm32mp157a-st-discovery/board/board.c
  26. 15 13
      bsp/stm32/stm32mp157a-st-discovery/board/board.h
  27. 27 11
      bsp/stm32/stm32mp157a-st-discovery/board/linker_scripts/link.icf
  28. 292 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/drv_openamp.c
  29. 41 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/drv_openamp.h
  30. 58 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/dma.c
  31. 46 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/alloc.h
  32. 24 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/assert.h
  33. 32 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/atomic.h
  34. 57 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/cache.h
  35. 25 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler.h
  36. 123 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/gcc/atomic.h
  37. 27 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/gcc/compiler.h
  38. 27 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/iar/compiler.h
  39. 289 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/iar/errno.h
  40. 137 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/mdk-arm/errno.h
  41. 73 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/condition.h
  42. 50 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/config.h
  43. 17 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/cpu.h
  44. 176 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/device.h
  45. 79 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/dma.h
  46. 24 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/errno.h
  47. 354 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/io.h
  48. 116 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/irq.h
  49. 102 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/list.h
  50. 93 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/log.h
  51. 87 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/mutex.h
  52. 15 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/processor/arm/atomic.h
  53. 17 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/processor/arm/cpu.h
  54. 83 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/shmem.h
  55. 44 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/sleep.h
  56. 71 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/spinlock.h
  57. 148 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/sys.h
  58. 39 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/alloc.h
  59. 28 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/assert.h
  60. 40 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/cache.h
  61. 72 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/condition.h
  62. 65 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/cortexm/sys.h
  63. 44 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/io.h
  64. 34 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/irq.h
  65. 52 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/log.h
  66. 79 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/mutex.h
  67. 38 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/sleep.h
  68. 61 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/sys.h
  69. 41 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/time.h
  70. 152 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/utilities.h
  71. 76 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/version.h
  72. 34 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/init.c
  73. 139 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/io.c
  74. 62 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/log.c
  75. 48 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/shmem.c
  76. 167 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/st_device.c
  77. 39 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/alloc.h
  78. 28 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/assert.h
  79. 40 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/cache.h
  80. 49 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/condition.c
  81. 68 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/condition.h
  82. 77 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/cortexm/sys.c
  83. 65 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/cortexm/sys.h
  84. 32 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_device.c
  85. 28 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_init.c
  86. 31 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_io.c
  87. 279 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_irq.c
  88. 34 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_irq.h
  89. 18 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_shmem.c
  90. 19 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_time.c
  91. 44 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/io.h
  92. 52 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/log.h
  93. 79 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/mutex.h
  94. 38 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/sleep.h
  95. 63 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/sys.h
  96. 27 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/version.c
  97. 71 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/open-amp/lib/include/openamp/compiler.h
  98. 428 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/open-amp/lib/include/openamp/elf_loader.h
  99. 17 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/open-amp/lib/include/openamp/open_amp.h
  100. 871 0
      bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/open-amp/lib/include/openamp/remoteproc.h

+ 10 - 0
bsp/ls2kdev/drivers/board.c

@@ -16,15 +16,22 @@
 #include "exception.h"
 #include "drv_uart.h"
 #include "board.h"
+#include "ls2k1000.h"
+
 /**
  * this function will reset CPU
  *
  */
 void rt_hw_cpu_reset(void)
 {
+    WDT_EN = 0x01;
+    WDT_TIMER = 0x01;
+    WDT_SET = 0x01;
     rt_kprintf("reboot system...\n");
     while (1);
 }
+MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_reset, reboot, reset cpu);
+
 
 /**
  * this function will shutdown CPU
@@ -32,10 +39,13 @@ void rt_hw_cpu_reset(void)
  */
 void rt_hw_cpu_shutdown(void)
 {
+    PM1_STS &= 0xffffffff;
+    PM1_CNT = 0x3c00;
     rt_kprintf("shutdown...\n");
 
     while (1);
 }
+MSH_CMD_EXPORT_ALIAS(rt_hw_cpu_shutdown, poweroff, shutdown cpu);
 
 
 /**

+ 23 - 0
bsp/ls2kdev/drivers/ls2k1000.h

@@ -3,6 +3,7 @@
 
 #include <mips.h>
 #include "interrupt.h"
+#include <rthw.h>
 
 #define APB_BASE         CKSEG1ADDR(0xbfe00000)
 
@@ -24,6 +25,28 @@
 
 #define GEN_CONFIG0_REG  (0xFFFFFFFFBfe10420)
 
+
+/*
+ * General PM Configuration Register
+ */
+#define PMCON_BASE          (APB_BASE | (0x7 << 12))
+
+/*
+ * Power Management1 Configuration Registers
+ */
+#define PM1_BASE            (PMCON_BASE + 0x0C)
+#define PM1_STS             HWREG32(PM1_BASE)
+#define PM1_EN              HWREG32(PM1_BASE + 0x04)
+#define PM1_CNT             HWREG32(PM1_BASE + 0x08)
+	
+/*
+ * Watch Dog Configuration Registers
+ */
+#define WDT_BASE            (PMCON_BASE + 0x30)
+#define WDT_EN              HWREG32(WDT_BASE)
+#define WDT_SET             HWREG32(WDT_BASE + 0x04)
+#define WDT_TIMER           HWREG32(WDT_BASE + 0x08)
+
 void rt_hw_timer_handler(void);
 void rt_hw_uart_init(void);
 

+ 3 - 0
bsp/nrf5x/libraries/drivers/SConscript

@@ -32,6 +32,9 @@ if GetDepend(['BSP_USING_PWM']):
 if GetDepend(['BSP_USING_WDT']):
     src += ['drv_wdt.c']
 
+if GetDepend(['BSP_USING_ONCHIP_RTC']):
+    src += ['drv_rtc.c']
+
 path =  [cwd]
 
 group = DefineGroup('Drivers', src, depend = [''], CPPPATH = path)

+ 162 - 0
bsp/nrf5x/libraries/drivers/drv_rtc.c

@@ -0,0 +1,162 @@
+/*
+ * Copyright (c) 2006-2018, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date         Author        Notes
+ * 2020-09-08   Chenyingchun  first version
+ */
+
+#include "board.h"
+#include <rtthread.h>
+#include <rtdevice.h>
+
+#include <nrfx_rtc.h>
+#include <nrfx_clock.h>
+
+#ifdef BSP_USING_ONCHIP_RTC
+
+#define LOG_TAG             "drv.rtc"
+#define DBG_LVL              DBG_LOG
+#include <rtdbg.h>
+
+/* 2018-01-30 14:44:50 = RTC_TIME_INIT(2018, 1, 30, 14, 44, 50)  */
+#define RTC_TIME_INIT(year, month, day, hour, minute, second)        \
+    {.tm_year = year - 1900, .tm_mon = month - 1, .tm_mday = day, .tm_hour = hour, .tm_min = minute, .tm_sec = second}
+
+#ifndef ONCHIP_RTC_TIME_DEFAULT
+#define ONCHIP_RTC_TIME_DEFAULT                    RTC_TIME_INIT(2018, 1, 1, 0, 0 ,0)
+#endif
+
+#ifndef RTC_INSTANCE_ID
+#define RTC_INSTANCE_ID (2)
+#endif
+
+#define TICK_FREQUENCE_HZ        (RT_TICK_PER_SECOND)     // RTC tick frequence, in HZ
+
+static struct rt_device rtc;
+static time_t init_time;
+static uint32_t tick = 0;
+
+static void rtc_callback(nrfx_rtc_int_type_t int_type)
+{
+    static uint32_t count = 0;
+    
+    if (int_type == NRFX_RTC_INT_TICK)
+    {
+       count++;
+       if((count % TICK_FREQUENCE_HZ) == 0)
+       {
+            tick++;
+       }
+    }
+}
+
+static rt_err_t rt_rtc_config(struct rt_device *dev)
+{
+    #define SYSTICK_CLOCK_HZ    (32768UL)
+    #define RTC_PRESCALER       ((uint32_t) (NRFX_ROUNDED_DIV(SYSTICK_CLOCK_HZ, TICK_FREQUENCE_HZ) - 1))
+
+    const nrfx_rtc_t rtc_instance = NRFX_RTC_INSTANCE(RTC_INSTANCE_ID);
+    nrf_clock_lf_src_set(NRF_CLOCK, (nrf_clock_lfclk_t)NRFX_CLOCK_CONFIG_LF_SRC);
+    nrfx_clock_lfclk_start();
+
+    //Initialize RTC instance
+    nrfx_rtc_config_t config = NRFX_RTC_DEFAULT_CONFIG;
+    config.prescaler = RTC_PRESCALER;
+
+    nrfx_rtc_init(&rtc_instance, &config, rtc_callback);
+
+    nrfx_rtc_tick_enable(&rtc_instance, true);
+
+    //Power on RTC instance
+    nrfx_rtc_enable(&rtc_instance);
+
+    return RT_EOK;
+}
+
+static rt_err_t rt_rtc_control(rt_device_t dev, int cmd, void *args)
+{
+    time_t *time;
+    RT_ASSERT(dev != RT_NULL);
+
+    switch (cmd)
+    {
+        case RT_DEVICE_CTRL_RTC_GET_TIME:
+        {
+            time = (time_t *) args;
+            *time = init_time + tick;
+            break;
+        }
+        case RT_DEVICE_CTRL_RTC_SET_TIME:
+        {
+            time = (time_t *) args;
+            init_time = *time - tick;
+            break;
+        }
+    }
+    return RT_EOK;
+}
+
+
+#ifdef RT_USING_DEVICE_OPS
+const static struct rt_device_ops rtc_ops =
+{
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    RT_NULL,
+    rt_rtc_control
+};
+#endif
+
+static rt_err_t rt_hw_rtc_register(rt_device_t device, const char *name, rt_uint32_t flag)
+{
+    struct tm time_new = ONCHIP_RTC_TIME_DEFAULT;
+
+    RT_ASSERT(device != RT_NULL);
+
+    init_time = mktime(&time_new);
+    if (rt_rtc_config(device) != RT_EOK)
+    {
+        return -RT_ERROR;
+    }
+#ifdef RT_USING_DEVICE_OPS
+    device->ops         = &rtc_ops;
+#else
+    device->init        = RT_NULL;
+    device->open        = RT_NULL;
+    device->close       = RT_NULL;
+    device->read        = RT_NULL;
+    device->write       = RT_NULL;
+    device->control     = rt_rtc_control;
+#endif
+    device->type        = RT_Device_Class_RTC;
+    device->rx_indicate = RT_NULL;
+    device->tx_complete = RT_NULL;
+    device->user_data   = RT_NULL;
+
+    /* register a character device */
+    rt_device_register(device, name, flag);
+
+    return RT_EOK;
+}
+
+int rt_hw_rtc_init(void)
+{
+    rt_err_t result;
+    result = rt_hw_rtc_register(&rtc, "rtc", RT_DEVICE_FLAG_RDWR);
+    if (result != RT_EOK)
+    {
+        LOG_E("rtc register err code: %d", result);
+        return result;
+    }
+    LOG_D("rtc init success");
+    return RT_EOK;
+}
+INIT_DEVICE_EXPORT(rt_hw_rtc_init);
+
+#endif /* BSP_USING_ONCHIP_RTC */
+

+ 33 - 0
bsp/nrf5x/nrf52832/board/Kconfig

@@ -313,6 +313,39 @@ endif
         int
         default 1
     endif
+
+    menuconfig BSP_USING_ONCHIP_RTC
+    bool "Enable RTC"
+    select RT_USING_RTC
+    select RT_USING_LIBC
+    default n
+    if BSP_USING_ONCHIP_RTC
+        config NRFX_CLOCK_ENABLED
+        int 
+        default 1
+        config NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY
+        int
+        default 7
+        config NRFX_RTC_ENABLED
+        int 
+        default 1
+        config NRFX_RTC0_ENABLED
+        int
+        default 1
+        config NRFX_RTC1_ENABLED
+        int
+        default 1
+        config NRFX_RTC2_ENABLED
+        int
+        default 1
+        config RTC_INSTANCE_ID
+        int 
+        default 2
+        config RTC_INSTANCE_ID
+            int "select RTC instance id, must be 0, 1, 2"
+            range 0 2
+            default 2
+    endif
 endmenu
 
 endmenu

+ 34 - 1
bsp/nrf5x/nrf52840/board/Kconfig

@@ -346,8 +346,41 @@ menu "On-chip Peripheral Drivers"
         int
         default 1
     endif
-endmenu
 
+    menuconfig BSP_USING_ONCHIP_RTC
+    bool "Enable RTC"
+    select RT_USING_RTC
+    select RT_USING_LIBC
+    default n
+    if BSP_USING_ONCHIP_RTC
+        config NRFX_CLOCK_ENABLED
+        int 
+        default 1
+        config NRFX_CLOCK_DEFAULT_CONFIG_IRQ_PRIORITY
+        int
+        default 7
+        config NRFX_RTC_ENABLED
+        int 
+        default 1
+        config NRFX_RTC0_ENABLED
+        int
+        default 1
+        config NRFX_RTC1_ENABLED
+        int
+        default 1
+        config NRFX_RTC2_ENABLED
+        int
+        default 1
+        config RTC_INSTANCE_ID
+        int 
+        default 2
+        config RTC_INSTANCE_ID
+            int "select RTC instance id, must be 0, 1, 2"
+            range 0 2
+            default 2
+    endif
+
+endmenu
 
 choice
 prompt "BLE STACK"

+ 197 - 384
bsp/stm32/libraries/HAL_Drivers/drv_gpio.c

@@ -8,7 +8,8 @@
  * 2018-11-06     balanceTWK        first version
  * 2019-04-23     WillianChan       Fix GPIO serial number disorder
  * 2020-06-16     thread-liu        add STM32MP1
- * 2020-09-01     thread-liu        add GPIOZ  
+ * 2020-09-01     thread-liu        add GPIOZ
+ * 2020-09-18     geniusgogo        optimization design pin-index algorithm
  */
 
 #include <board.h>
@@ -16,225 +17,53 @@
 
 #ifdef RT_USING_PIN
 
-static const struct pin_index pins[] = 
-{
-#if defined(GPIOA)
-    __STM32_PIN(0 ,  A, 0 ),
-    __STM32_PIN(1 ,  A, 1 ),
-    __STM32_PIN(2 ,  A, 2 ),
-    __STM32_PIN(3 ,  A, 3 ),
-    __STM32_PIN(4 ,  A, 4 ),
-    __STM32_PIN(5 ,  A, 5 ),
-    __STM32_PIN(6 ,  A, 6 ),
-    __STM32_PIN(7 ,  A, 7 ),
-    __STM32_PIN(8 ,  A, 8 ),
-    __STM32_PIN(9 ,  A, 9 ),
-    __STM32_PIN(10,  A, 10),
-    __STM32_PIN(11,  A, 11),
-    __STM32_PIN(12,  A, 12),
-    __STM32_PIN(13,  A, 13),
-    __STM32_PIN(14,  A, 14),
-    __STM32_PIN(15,  A, 15),
-#if defined(GPIOB)
-    __STM32_PIN(16,  B, 0),
-    __STM32_PIN(17,  B, 1),
-    __STM32_PIN(18,  B, 2),
-    __STM32_PIN(19,  B, 3),
-    __STM32_PIN(20,  B, 4),
-    __STM32_PIN(21,  B, 5),
-    __STM32_PIN(22,  B, 6),
-    __STM32_PIN(23,  B, 7),
-    __STM32_PIN(24,  B, 8),
-    __STM32_PIN(25,  B, 9),
-    __STM32_PIN(26,  B, 10),
-    __STM32_PIN(27,  B, 11),
-    __STM32_PIN(28,  B, 12),
-    __STM32_PIN(29,  B, 13),
-    __STM32_PIN(30,  B, 14),
-    __STM32_PIN(31,  B, 15),
-#if defined(GPIOC)
-    __STM32_PIN(32,  C, 0),
-    __STM32_PIN(33,  C, 1),
-    __STM32_PIN(34,  C, 2),
-    __STM32_PIN(35,  C, 3),
-    __STM32_PIN(36,  C, 4),
-    __STM32_PIN(37,  C, 5),
-    __STM32_PIN(38,  C, 6),
-    __STM32_PIN(39,  C, 7),
-    __STM32_PIN(40,  C, 8),
-    __STM32_PIN(41,  C, 9),
-    __STM32_PIN(42,  C, 10),
-    __STM32_PIN(43,  C, 11),
-    __STM32_PIN(44,  C, 12),
-    __STM32_PIN(45,  C, 13),
-    __STM32_PIN(46,  C, 14),
-    __STM32_PIN(47,  C, 15),
-#if defined(GPIOD)
-    __STM32_PIN(48,  D, 0),
-    __STM32_PIN(49,  D, 1),
-    __STM32_PIN(50,  D, 2),
-    __STM32_PIN(51,  D, 3),
-    __STM32_PIN(52,  D, 4),
-    __STM32_PIN(53,  D, 5),
-    __STM32_PIN(54,  D, 6),
-    __STM32_PIN(55,  D, 7),
-    __STM32_PIN(56,  D, 8),
-    __STM32_PIN(57,  D, 9),
-    __STM32_PIN(58,  D, 10),
-    __STM32_PIN(59,  D, 11),
-    __STM32_PIN(60,  D, 12),
-    __STM32_PIN(61,  D, 13),
-    __STM32_PIN(62,  D, 14),
-    __STM32_PIN(63,  D, 15),
-#if defined(GPIOE)
-    __STM32_PIN(64,  E, 0),
-    __STM32_PIN(65,  E, 1),
-    __STM32_PIN(66,  E, 2),
-    __STM32_PIN(67,  E, 3),
-    __STM32_PIN(68,  E, 4),
-    __STM32_PIN(69,  E, 5),
-    __STM32_PIN(70,  E, 6),
-    __STM32_PIN(71,  E, 7),
-    __STM32_PIN(72,  E, 8),
-    __STM32_PIN(73,  E, 9),
-    __STM32_PIN(74,  E, 10),
-    __STM32_PIN(75,  E, 11),
-    __STM32_PIN(76,  E, 12),
-    __STM32_PIN(77,  E, 13),
-    __STM32_PIN(78,  E, 14),
-    __STM32_PIN(79,  E, 15),
-#if defined(GPIOF)
-    __STM32_PIN(80,  F, 0),
-    __STM32_PIN(81,  F, 1),
-    __STM32_PIN(82,  F, 2),
-    __STM32_PIN(83,  F, 3),
-    __STM32_PIN(84,  F, 4),
-    __STM32_PIN(85,  F, 5),
-    __STM32_PIN(86,  F, 6),
-    __STM32_PIN(87,  F, 7),
-    __STM32_PIN(88,  F, 8),
-    __STM32_PIN(89,  F, 9),
-    __STM32_PIN(90,  F, 10),
-    __STM32_PIN(91,  F, 11),
-    __STM32_PIN(92,  F, 12),
-    __STM32_PIN(93,  F, 13),
-    __STM32_PIN(94,  F, 14),
-    __STM32_PIN(95,  F, 15),
-#if defined(GPIOG)
-    __STM32_PIN(96,  G, 0),
-    __STM32_PIN(97,  G, 1),
-    __STM32_PIN(98,  G, 2),
-    __STM32_PIN(99,  G, 3),
-    __STM32_PIN(100, G, 4),
-    __STM32_PIN(101, G, 5),
-    __STM32_PIN(102, G, 6),
-    __STM32_PIN(103, G, 7),
-    __STM32_PIN(104, G, 8),
-    __STM32_PIN(105, G, 9),
-    __STM32_PIN(106, G, 10),
-    __STM32_PIN(107, G, 11),
-    __STM32_PIN(108, G, 12),
-    __STM32_PIN(109, G, 13),
-    __STM32_PIN(110, G, 14),
-    __STM32_PIN(111, G, 15),
-#if defined(GPIOH)
-    __STM32_PIN(112, H, 0),
-    __STM32_PIN(113, H, 1),
-    __STM32_PIN(114, H, 2),
-    __STM32_PIN(115, H, 3),
-    __STM32_PIN(116, H, 4),
-    __STM32_PIN(117, H, 5),
-    __STM32_PIN(118, H, 6),
-    __STM32_PIN(119, H, 7),
-    __STM32_PIN(120, H, 8),
-    __STM32_PIN(121, H, 9),
-    __STM32_PIN(122, H, 10),
-    __STM32_PIN(123, H, 11),
-    __STM32_PIN(124, H, 12),
-    __STM32_PIN(125, H, 13),
-    __STM32_PIN(126, H, 14),
-    __STM32_PIN(127, H, 15),
-#if defined(GPIOI)
-    __STM32_PIN(128, I, 0),
-    __STM32_PIN(129, I, 1),
-    __STM32_PIN(130, I, 2),
-    __STM32_PIN(131, I, 3),
-    __STM32_PIN(132, I, 4),
-    __STM32_PIN(133, I, 5),
-    __STM32_PIN(134, I, 6),
-    __STM32_PIN(135, I, 7),
-    __STM32_PIN(136, I, 8),
-    __STM32_PIN(137, I, 9),
-    __STM32_PIN(138, I, 10),
-    __STM32_PIN(139, I, 11),
-    __STM32_PIN(140, I, 12),
-    __STM32_PIN(141, I, 13),
-    __STM32_PIN(142, I, 14),
-    __STM32_PIN(143, I, 15),
-#if defined(GPIOJ)
-    __STM32_PIN(144, J, 0),
-    __STM32_PIN(145, J, 1),
-    __STM32_PIN(146, J, 2),
-    __STM32_PIN(147, J, 3),
-    __STM32_PIN(148, J, 4),
-    __STM32_PIN(149, J, 5),
-    __STM32_PIN(150, J, 6),
-    __STM32_PIN(151, J, 7),
-    __STM32_PIN(152, J, 8),
-    __STM32_PIN(153, J, 9),
-    __STM32_PIN(154, J, 10),
-    __STM32_PIN(155, J, 11),
-    __STM32_PIN(156, J, 12),
-    __STM32_PIN(157, J, 13),
-    __STM32_PIN(158, J, 14),
-    __STM32_PIN(159, J, 15),
-#if defined(GPIOK)
-    __STM32_PIN(160, K, 0),
-    __STM32_PIN(161, K, 1),
-    __STM32_PIN(162, K, 2),
-    __STM32_PIN(163, K, 3),
-    __STM32_PIN(164, K, 4),
-    __STM32_PIN(165, K, 5),
-    __STM32_PIN(166, K, 6),
-    __STM32_PIN(167, K, 7),
-    __STM32_PIN(168, K, 8),
-    __STM32_PIN(169, K, 9),
-    __STM32_PIN(170, K, 10),
-    __STM32_PIN(171, K, 11),
-    __STM32_PIN(172, K, 12),
-    __STM32_PIN(173, K, 13),
-    __STM32_PIN(174, K, 14),
-    __STM32_PIN(175, K, 15),
+#define PIN_NUM(port, no) (((((port) & 0xFu) << 4) | ((no) & 0xFu)))
+#define PIN_PORT(pin) ((uint8_t)(((pin) >> 4) & 0xFu))
+#define PIN_NO(pin) ((uint8_t)((pin) & 0xFu))
+
+#if defined(SOC_SERIES_STM32MP1)
 #if defined(GPIOZ)
-    __STM32_PIN(176, Z, 0),
-    __STM32_PIN(177, Z, 1),
-    __STM32_PIN(178, Z, 2),
-    __STM32_PIN(179, Z, 3),
-    __STM32_PIN(180, Z, 4),
-    __STM32_PIN(181, Z, 5),
-    __STM32_PIN(182, Z, 6),
-    __STM32_PIN(183, Z, 7),
-    __STM32_PIN(184, Z, 8),
-    __STM32_PIN(185, Z, 9),
-    __STM32_PIN(186, Z, 10),
-    __STM32_PIN(187, Z, 11),
-    __STM32_PIN(188, Z, 12),
-    __STM32_PIN(189, Z, 13),
-    __STM32_PIN(190, Z, 14),
-    __STM32_PIN(191, Z, 15),
-#endif /* defined(GPIOZ) */
-#endif /* defined(GPIOK) */
-#endif /* defined(GPIOJ) */
-#endif /* defined(GPIOI) */
-#endif /* defined(GPIOH) */
-#endif /* defined(GPIOG) */
-#endif /* defined(GPIOF) */
-#endif /* defined(GPIOE) */
-#endif /* defined(GPIOD) */
-#endif /* defined(GPIOC) */
-#endif /* defined(GPIOB) */
-#endif /* defined(GPIOA) */
-};
+#define gpioz_port_base (175) /* PIN_STPORT_MAX * 16 - 16 */
+#define PIN_STPORT(pin) ((pin > gpioz_port_base) ? ((GPIO_TypeDef *)(GPIOZ_BASE )) : ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin)))))
+#else
+#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x1000u * PIN_PORT(pin)))))
+#endif /* GPIOZ */
+#else
+#define PIN_STPORT(pin) ((GPIO_TypeDef *)(GPIOA_BASE + (0x400u * PIN_PORT(pin))))
+#endif /* SOC_SERIES_STM32MP1 */
+
+#define PIN_STPIN(pin) ((uint16_t)(1u << PIN_NO(pin)))
+
+#if defined(GPIOZ)
+#define __STM32_PORT_MAX 12u
+#elif defined(GPIOK)
+#define __STM32_PORT_MAX 11u
+#elif defined(GPIOJ)
+#define __STM32_PORT_MAX 10u
+#elif defined(GPIOI)
+#define __STM32_PORT_MAX 9u
+#elif defined(GPIOH)
+#define __STM32_PORT_MAX 8u
+#elif defined(GPIOG)
+#define __STM32_PORT_MAX 7u
+#elif defined(GPIOF)
+#define __STM32_PORT_MAX 6u
+#elif defined(GPIOE)
+#define __STM32_PORT_MAX 5u
+#elif defined(GPIOD)
+#define __STM32_PORT_MAX 4u
+#elif defined(GPIOC)
+#define __STM32_PORT_MAX 3u
+#elif defined(GPIOB)
+#define __STM32_PORT_MAX 2u
+#elif defined(GPIOA)
+#define __STM32_PORT_MAX 1u
+#else
+#define __STM32_PORT_MAX 0u
+#error Unsupported STM32 GPIO peripheral.
+#endif
+
+#define PIN_STPORT_MAX __STM32_PORT_MAX
 
 static const struct pin_irq_map pin_irq_map[] =
 {
@@ -254,7 +83,7 @@ static const struct pin_irq_map pin_irq_map[] =
     {GPIO_PIN_12, EXTI4_15_IRQn},
     {GPIO_PIN_13, EXTI4_15_IRQn},
     {GPIO_PIN_14, EXTI4_15_IRQn},
-    {GPIO_PIN_15, EXTI4_15_IRQn}, 
+    {GPIO_PIN_15, EXTI4_15_IRQn},
 #elif defined(SOC_SERIES_STM32MP1)
     {GPIO_PIN_0, EXTI0_IRQn},
     {GPIO_PIN_1, EXTI1_IRQn},
@@ -271,7 +100,7 @@ static const struct pin_irq_map pin_irq_map[] =
     {GPIO_PIN_12, EXTI12_IRQn},
     {GPIO_PIN_13, EXTI13_IRQn},
     {GPIO_PIN_14, EXTI14_IRQn},
-    {GPIO_PIN_15, EXTI15_IRQn}, 
+    {GPIO_PIN_15, EXTI15_IRQn},
 #else
     {GPIO_PIN_0, EXTI0_IRQn},
     {GPIO_PIN_1, EXTI1_IRQn},
@@ -311,33 +140,15 @@ static struct rt_pin_irq_hdr pin_irq_hdr_tab[] =
     {-1, 0, RT_NULL, RT_NULL},
     {-1, 0, RT_NULL, RT_NULL},
 };
-static uint32_t pin_irq_enable_mask=0;
+static uint32_t pin_irq_enable_mask = 0;
 
 #define ITEM_NUM(items) sizeof(items) / sizeof(items[0])
-static const struct pin_index *get_pin(uint8_t pin)
-{
-    const struct pin_index *index;
-
-    if (pin < ITEM_NUM(pins))
-    {
-        index = &pins[pin];
-        if (index->index == -1)
-            index = RT_NULL;
-    }
-    else
-    {
-        index = RT_NULL;
-    }
-
-    return index;
-};
 
 static rt_base_t stm32_pin_get(const char *name)
 {
     rt_base_t pin = 0;
     int hw_port_num, hw_pin_num = 0;
-    int i, name_len = 1;
-    int mul = 1;
+    int i, name_len;
 
     name_len = rt_strlen(name);
 
@@ -359,68 +170,58 @@ static rt_base_t stm32_pin_get(const char *name)
         return -RT_EINVAL;
     }
 
-    for (i = name_len - 1; i > 2; i--)
+    for (i = 3; i < name_len; i++)
     {
-        hw_pin_num += ((int)(name[i] - '0') * mul);
-        mul = mul * 10;
+        hw_pin_num *= 10;
+        hw_pin_num += name[i] - '0';
     }
 
-    pin = 16 * hw_port_num + hw_pin_num;
+    pin = PIN_NUM(hw_port_num, hw_pin_num);
 
-    if (pin < ITEM_NUM(pins))
-    {
-        return pin;
-    }
-    else
-    {
-        return -RT_EINVAL;
-    }
+    return pin;
 }
 
 static void stm32_pin_write(rt_device_t dev, rt_base_t pin, rt_base_t value)
 {
-    const struct pin_index *index;
+    GPIO_TypeDef *gpio_port;
+    uint16_t gpio_pin;
 
-    index = get_pin(pin);
-    if (index == RT_NULL)
+    if (PIN_PORT(pin) < PIN_STPORT_MAX)
     {
-        return;
-    }
+        gpio_port = PIN_STPORT(pin);
+        gpio_pin = PIN_STPIN(pin);
 
-    HAL_GPIO_WritePin(index->gpio, index->pin, (GPIO_PinState)value);
+        HAL_GPIO_WritePin(gpio_port, gpio_pin, (GPIO_PinState)value);
+    }
 }
 
 static int stm32_pin_read(rt_device_t dev, rt_base_t pin)
 {
-    int value;
-    const struct pin_index *index;
-
-    value = PIN_LOW;
+    GPIO_TypeDef *gpio_port;
+    uint16_t gpio_pin;
+    int value = PIN_LOW;
 
-    index = get_pin(pin);
-    if (index == RT_NULL)
+    if (PIN_PORT(pin) < PIN_STPORT_MAX)
     {
-        return value;
+        gpio_port = PIN_STPORT(pin);
+        gpio_pin = PIN_STPIN(pin);
+        value = HAL_GPIO_ReadPin(gpio_port, gpio_pin);
     }
 
-    value = HAL_GPIO_ReadPin(index->gpio, index->pin);
-
     return value;
 }
 
 static void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
 {
-    const struct pin_index *index;
     GPIO_InitTypeDef GPIO_InitStruct;
 
-    index = get_pin(pin);
-    if (index == RT_NULL)
+    if (PIN_PORT(pin) >= PIN_STPORT_MAX)
     {
         return;
     }
 
     /* Configure GPIO_InitStructure */
-    GPIO_InitStruct.Pin = index->pin;
+    GPIO_InitStruct.Pin = PIN_STPIN(pin);
     GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
     GPIO_InitStruct.Pull = GPIO_NOPULL;
     GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
@@ -456,7 +257,7 @@ static void stm32_pin_mode(rt_device_t dev, rt_base_t pin, rt_base_t mode)
         GPIO_InitStruct.Pull = GPIO_NOPULL;
     }
 
-    HAL_GPIO_Init(index->gpio, &GPIO_InitStruct);
+    HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct);
 }
 
 rt_inline rt_int32_t bit2bitno(rt_uint32_t bit)
@@ -485,16 +286,15 @@ rt_inline const struct pin_irq_map *get_pin_irq_map(uint32_t pinbit)
 static rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
                                      rt_uint32_t mode, void (*hdr)(void *args), void *args)
 {
-    const struct pin_index *index;
     rt_base_t level;
     rt_int32_t irqindex = -1;
 
-    index = get_pin(pin);
-    if (index == RT_NULL)
+    if (PIN_PORT(pin) >= PIN_STPORT_MAX)
     {
-        return RT_ENOSYS;
+        return -RT_ENOSYS;
     }
-    irqindex = bit2bitno(index->pin);
+
+    irqindex = bit2bitno(PIN_STPIN(pin));
     if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
     {
         return RT_ENOSYS;
@@ -502,9 +302,9 @@ static rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
 
     level = rt_hw_interrupt_disable();
     if (pin_irq_hdr_tab[irqindex].pin == pin &&
-            pin_irq_hdr_tab[irqindex].hdr == hdr &&
-            pin_irq_hdr_tab[irqindex].mode == mode &&
-            pin_irq_hdr_tab[irqindex].args == args)
+        pin_irq_hdr_tab[irqindex].hdr == hdr &&
+        pin_irq_hdr_tab[irqindex].mode == mode &&
+        pin_irq_hdr_tab[irqindex].args == args)
     {
         rt_hw_interrupt_enable(level);
         return RT_EOK;
@@ -525,16 +325,15 @@ static rt_err_t stm32_pin_attach_irq(struct rt_device *device, rt_int32_t pin,
 
 static rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
 {
-    const struct pin_index *index;
     rt_base_t level;
     rt_int32_t irqindex = -1;
 
-    index = get_pin(pin);
-    if (index == RT_NULL)
+    if (PIN_PORT(pin) >= PIN_STPORT_MAX)
     {
-        return RT_ENOSYS;
+        return -RT_ENOSYS;
     }
-    irqindex = bit2bitno(index->pin);
+
+    irqindex = bit2bitno(PIN_STPIN(pin));
     if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
     {
         return RT_ENOSYS;
@@ -558,21 +357,19 @@ static rt_err_t stm32_pin_dettach_irq(struct rt_device *device, rt_int32_t pin)
 static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
                                      rt_uint32_t enabled)
 {
-    const struct pin_index *index;
     const struct pin_irq_map *irqmap;
     rt_base_t level;
     rt_int32_t irqindex = -1;
     GPIO_InitTypeDef GPIO_InitStruct;
 
-    index = get_pin(pin);
-    if (index == RT_NULL)
+    if (PIN_PORT(pin) >= PIN_STPORT_MAX)
     {
-        return RT_ENOSYS;
+        return -RT_ENOSYS;
     }
 
     if (enabled == PIN_IRQ_ENABLE)
     {
-        irqindex = bit2bitno(index->pin);
+        irqindex = bit2bitno(PIN_STPIN(pin));
         if (irqindex < 0 || irqindex >= ITEM_NUM(pin_irq_map))
         {
             return RT_ENOSYS;
@@ -589,7 +386,7 @@ static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
         irqmap = &pin_irq_map[irqindex];
 
         /* Configure GPIO_InitStructure */
-        GPIO_InitStruct.Pin = index->pin;        
+        GPIO_InitStruct.Pin = PIN_STPIN(pin);
         GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
         switch (pin_irq_hdr_tab[irqindex].mode)
         {
@@ -606,7 +403,7 @@ static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
             GPIO_InitStruct.Mode = GPIO_MODE_IT_RISING_FALLING;
             break;
         }
-        HAL_GPIO_Init(index->gpio, &GPIO_InitStruct);
+        HAL_GPIO_Init(PIN_STPORT(pin), &GPIO_InitStruct);
 
         HAL_NVIC_SetPriority(irqmap->irqno, 5, 0);
         HAL_NVIC_EnableIRQ(irqmap->irqno);
@@ -616,7 +413,7 @@ static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
     }
     else if (enabled == PIN_IRQ_DISABLE)
     {
-        irqmap = get_pin_irq_map(index->pin);
+        irqmap = get_pin_irq_map(PIN_STPIN(pin));
         if (irqmap == RT_NULL)
         {
             return RT_ENOSYS;
@@ -624,57 +421,57 @@ static rt_err_t stm32_pin_irq_enable(struct rt_device *device, rt_base_t pin,
 
         level = rt_hw_interrupt_disable();
 
-        HAL_GPIO_DeInit(index->gpio, index->pin);
+        HAL_GPIO_DeInit(PIN_STPORT(pin), PIN_STPIN(pin));
 
         pin_irq_enable_mask &= ~irqmap->pinbit;
 #if defined(SOC_SERIES_STM32F0) || defined(SOC_SERIES_STM32G0)
-        if (( irqmap->pinbit>=GPIO_PIN_0 )&&( irqmap->pinbit<=GPIO_PIN_1 ))
+        if ((irqmap->pinbit >= GPIO_PIN_0) && (irqmap->pinbit <= GPIO_PIN_1))
         {
-            if(!(pin_irq_enable_mask&(GPIO_PIN_0|GPIO_PIN_1)))
-            {    
+            if (!(pin_irq_enable_mask & (GPIO_PIN_0 | GPIO_PIN_1)))
+            {
                 HAL_NVIC_DisableIRQ(irqmap->irqno);
             }
         }
-        else if (( irqmap->pinbit>=GPIO_PIN_2 )&&( irqmap->pinbit<=GPIO_PIN_3 ))
+        else if ((irqmap->pinbit >= GPIO_PIN_2) && (irqmap->pinbit <= GPIO_PIN_3))
         {
-            if(!(pin_irq_enable_mask&(GPIO_PIN_2|GPIO_PIN_3)))
-            {    
+            if (!(pin_irq_enable_mask & (GPIO_PIN_2 | GPIO_PIN_3)))
+            {
                 HAL_NVIC_DisableIRQ(irqmap->irqno);
             }
         }
-        else if (( irqmap->pinbit>=GPIO_PIN_4 )&&( irqmap->pinbit<=GPIO_PIN_15 ))
+        else if ((irqmap->pinbit >= GPIO_PIN_4) && (irqmap->pinbit <= GPIO_PIN_15))
         {
-            if(!(pin_irq_enable_mask&(GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|
-                                      GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15)))
-            {    
+            if (!(pin_irq_enable_mask & (GPIO_PIN_4 | GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9 |
+                                         GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)))
+            {
                 HAL_NVIC_DisableIRQ(irqmap->irqno);
             }
-        }    
+        }
         else
         {
             HAL_NVIC_DisableIRQ(irqmap->irqno);
-        }         
-#else      
-        if (( irqmap->pinbit>=GPIO_PIN_5 )&&( irqmap->pinbit<=GPIO_PIN_9 ))
+        }
+#else
+        if ((irqmap->pinbit >= GPIO_PIN_5) && (irqmap->pinbit <= GPIO_PIN_9))
         {
-            if(!(pin_irq_enable_mask&(GPIO_PIN_5|GPIO_PIN_6|GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9)))
-            {    
+            if (!(pin_irq_enable_mask & (GPIO_PIN_5 | GPIO_PIN_6 | GPIO_PIN_7 | GPIO_PIN_8 | GPIO_PIN_9)))
+            {
                 HAL_NVIC_DisableIRQ(irqmap->irqno);
             }
         }
-        else if (( irqmap->pinbit>=GPIO_PIN_10 )&&( irqmap->pinbit<=GPIO_PIN_15 ))
+        else if ((irqmap->pinbit >= GPIO_PIN_10) && (irqmap->pinbit <= GPIO_PIN_15))
         {
-            if(!(pin_irq_enable_mask&(GPIO_PIN_10|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14|GPIO_PIN_15)))
-            {    
+            if (!(pin_irq_enable_mask & (GPIO_PIN_10 | GPIO_PIN_11 | GPIO_PIN_12 | GPIO_PIN_13 | GPIO_PIN_14 | GPIO_PIN_15)))
+            {
                 HAL_NVIC_DisableIRQ(irqmap->irqno);
             }
         }
         else
         {
             HAL_NVIC_DisableIRQ(irqmap->irqno);
-        }        
-#endif          
-        rt_hw_interrupt_enable(level);  
+        }
+#endif
+        rt_hw_interrupt_enable(level);
     }
     else
     {
@@ -754,100 +551,116 @@ void EXTI4_15_IRQHandler(void)
 }
 
 #elif defined(SOC_STM32MP157A)
-void EXTI0_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
-   rt_interrupt_leave();
+void EXTI0_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
+    rt_interrupt_leave();
 }
 
-void EXTI1_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
-   rt_interrupt_leave();
+void EXTI1_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
+    rt_interrupt_leave();
 }
 
-void EXTI2_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
-   rt_interrupt_leave();
+void EXTI2_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
+    rt_interrupt_leave();
 }
 
-void EXTI3_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
-   rt_interrupt_leave();
+void EXTI3_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
+    rt_interrupt_leave();
 }
 
-void EXTI4_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
-   rt_interrupt_leave();
+void EXTI4_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_4);
+    rt_interrupt_leave();
 }
 
-void EXTI5_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
-   rt_interrupt_leave();
+void EXTI5_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_5);
+    rt_interrupt_leave();
 }
 
-void EXTI6_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
-   rt_interrupt_leave();
+void EXTI6_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_6);
+    rt_interrupt_leave();
 }
 
-void EXTI7_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
-   rt_interrupt_leave();
+void EXTI7_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
+    rt_interrupt_leave();
 }
 
-void EXTI8_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
-   rt_interrupt_leave();
+void EXTI8_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_8);
+    rt_interrupt_leave();
 }
 
-void EXTI9_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
-   rt_interrupt_leave();
+void EXTI9_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_9);
+    rt_interrupt_leave();
 }
 
-void EXTI10_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
-   rt_interrupt_leave();
+void EXTI10_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
+    rt_interrupt_leave();
 }
 
-void EXTI11_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
-   rt_interrupt_leave();
+void EXTI11_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_11);
+    rt_interrupt_leave();
 }
 
-void EXTI12_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
-   rt_interrupt_leave();
+void EXTI12_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_12);
+    rt_interrupt_leave();
 }
 
-void EXTI13_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
-   rt_interrupt_leave();
+void EXTI13_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_13);
+    rt_interrupt_leave();
 }
 
-void EXTI14_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
-   rt_interrupt_leave();
+void EXTI14_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_14);
+    rt_interrupt_leave();
 }
 
-void EXTI15_IRQHandler(void) {
-   rt_interrupt_enter(); 
-   HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
-   rt_interrupt_leave();
+void EXTI15_IRQHandler(void)
+{
+    rt_interrupt_enter();
+    HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_15);
+    rt_interrupt_leave();
 }
 
 #else
@@ -916,15 +729,15 @@ int rt_hw_pin_init(void)
 #if defined(__HAL_RCC_GPIOA_CLK_ENABLE)
     __HAL_RCC_GPIOA_CLK_ENABLE();
 #endif
-    
+
 #if defined(__HAL_RCC_GPIOB_CLK_ENABLE)
     __HAL_RCC_GPIOB_CLK_ENABLE();
 #endif
-    
+
 #if defined(__HAL_RCC_GPIOC_CLK_ENABLE)
     __HAL_RCC_GPIOC_CLK_ENABLE();
 #endif
-    
+
 #if defined(__HAL_RCC_GPIOD_CLK_ENABLE)
     __HAL_RCC_GPIOD_CLK_ENABLE();
 #endif

+ 9 - 18
bsp/stm32/libraries/HAL_Drivers/drv_gpio.h

@@ -8,6 +8,7 @@
  * 2018-11-06     balanceTWK        first version
  * 2020-06-16     thread-liu        add stm32mp1
  * 2020-09-01     thread-liu        add GPIOZ 
+ * 2020-09-18     geniusgogo        optimization design pin-index algorithm
  */
 
 #ifndef __DRV_GPIO_H__
@@ -16,6 +17,10 @@
 #include <drv_common.h>
 #include <board.h>
 
+#ifdef __cplusplus
+extern "C" {
+#endif
+
 #define __STM32_PORT(port)  GPIO##port##_BASE
 
 #if defined(SOC_SERIES_STM32MP1)
@@ -24,24 +29,6 @@
 #define GET_PIN(PORTx,PIN) (rt_base_t)((16 * ( ((rt_base_t)__STM32_PORT(PORTx) - (rt_base_t)GPIOA_BASE)/(0x0400UL) )) + PIN)
 #endif
 
-#define __STM32_PIN(index, gpio, gpio_index)                                \
-    {                                                                       \
-        index, GPIO##gpio, GPIO_PIN_##gpio_index                            \
-    }
-
-#define __STM32_PIN_RESERVE                                                 \
-    {                                                                       \
-        -1, 0, 0                                                            \
-    }
-
-/* STM32 GPIO driver */
-struct pin_index
-{
-    int index;
-    GPIO_TypeDef *gpio;
-    uint32_t pin;
-};
-
 struct pin_irq_map
 {
     rt_uint16_t pinbit;
@@ -50,5 +37,9 @@ struct pin_irq_map
 
 int rt_hw_pin_init(void);
 
+#ifdef __cplusplus
+}
+#endif
+
 #endif /* __DRV_GPIO_H__ */
 

+ 1 - 0
bsp/stm32/stm32mp157a-st-discovery/.config

@@ -426,6 +426,7 @@ CONFIG_BSP_USING_STLINK_TO_USART=y
 # CONFIG_BSP_USING_PMIC is not set
 # CONFIG_BSP_USING_PWR is not set
 # CONFIG_BSP_USING_RCC is not set
+# CONFIG_BSP_USING_OPENAMP is not set
 
 #
 # On-chip Peripheral Drivers

File diff suppressed because it is too large
+ 12 - 16
bsp/stm32/stm32mp157a-st-discovery/.cproject


+ 19 - 19
bsp/stm32/stm32mp157a-st-discovery/README.md

@@ -37,25 +37,25 @@ For more details about this board, please refer to the ST official documentation
 
 Each peripheral supporting condition for this BSP is as follows:
 
-| On-board Peripheral            | **Support** |     **Remark**      |
-| :----------------------------- | :---------: | :-----------------: |
-| USB TO UART                    |     YES     |                     |
-| PWR                            |     YES     |                     |
-| RCC                            |     YES     |                     |
-| SD Card (SDMMC)                |     NO      |                     |
-| ETH                            |     NO      |                     |
-| AUDIO                          |     NO      |                     |
-| **On-chip Peripheral Drivers** | **Support** |     **Remark**      |
-| GPIO                           |     YES     |  GPIOA-GPIOK, GPIOZ |
-| UART                           |     YES     |   UART4 (ST-Link)   |
-| EXTI                           |     YES     |                     |
-| SPI                            |     YES     |                     |
-| TIM                            |     YES     |                     |
-| LPTIM                          |     YES     |                     |
-| I2C                            |     YES     | Software & Hardware |
-| ADC                            |     YES     |                     |
-| DAC                            |     YES     |                     |
-| WWDG                           |     YES     |                     |
+| On-board Peripheral            | **Support** |     **Remark**     |
+| :----------------------------- | :---------: | :----------------: |
+| USB TO UART                    |     YES     |                    |
+| PWR                            |     YES     |                    |
+| RCC                            |     YES     |                    |
+| SD Card (SDMMC)                |     NO      |                    |
+| ETH                            |     NO      |                    |
+| AUDIO                          |     NO      |                    |
+| **On-chip Peripheral Drivers** | **Support** |     **Remark**     |
+| GPIO                           |     YES     | GPIOA-GPIOK, GPIOZ |
+| UART                           |     YES     |  UART4 (ST-Link)   |
+| EXTI                           |     YES     |                    |
+| SPI                            |     YES     |                    |
+| TIM                            |     YES     |                    |
+| LPTIM                          |     YES     |                    |
+| I2C                            |     YES     |      Software      |
+| ADC                            |     YES     |                    |
+| DAC                            |     YES     |                    |
+| WWDG                           |     YES     |                    |
 
 ## Execution Instruction
 

+ 58 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/ipcc.h

@@ -0,0 +1,58 @@
+/**
+  ******************************************************************************
+  * File Name          : IPCC.h
+  * Description        : This file provides code for the configuration
+  *                      of the IPCC instances.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under Ultimate Liberty license
+  * SLA0044, the "License"; You may not use this file except in compliance with
+  * the License. You may obtain a copy of the License at:
+  *                             www.st.com/SLA0044
+  *
+  ******************************************************************************
+  */
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __ipcc_H
+#define __ipcc_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#include "main.h"
+
+/* USER CODE BEGIN Includes */
+
+/* USER CODE END Includes */
+
+extern IPCC_HandleTypeDef hipcc;
+
+/* USER CODE BEGIN Private defines */
+
+/* USER CODE END Private defines */
+
+void MX_IPCC_Init(void);
+
+/* USER CODE BEGIN Prototypes */
+
+/* USER CODE END Prototypes */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__ ipcc_H */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 39 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/mbox_ipcc.h

@@ -0,0 +1,39 @@
+/**
+  ******************************************************************************
+  * @file    mbox_ipcc.h
+  * @author  MCD Application Team
+  * @brief   Header for mbox_ipcc.c module
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics. 
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the 
+  * License. You may obtain a copy of the License at:
+  *                       opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+#ifndef MBOX_IPCC_H_
+#define MBOX_IPCC_H_
+
+/* USER CODE BEGIN firstSection */
+/* can be used to modify / undefine following code or add new definitions */
+/* USER CODE END firstSection */
+
+/* Includes ------------------------------------------------------------------*/
+/* Exported types ------------------------------------------------------------*/
+/* Exported constants --------------------------------------------------------*/
+/* Exported functions ------------------------------------------------------- */
+int MAILBOX_Notify(void *priv, uint32_t id);
+int MAILBOX_Init(void);
+int MAILBOX_Poll(struct virtio_device *vdev);
+
+/* USER CODE BEGIN lastSection */
+/* can be used to modify / undefine previous code or add new definitions */
+/* USER CODE END lastSection */
+
+#endif /* MBOX_IPCC_H_ */

+ 58 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/openamp.h

@@ -0,0 +1,58 @@
+/**
+  ******************************************************************************
+  * @file   openamp.h
+  * @brief  Header for openamp applications
+  * @author  MCD Application Team
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics. 
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the 
+  * License. You may obtain a copy of the License at:
+  *                       opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __openamp_H
+#define __openamp_H
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+#include "openamp/open_amp.h"
+#include "openamp_conf.h"
+
+#define OPENAMP_send  rpmsg_send
+#define OPENAMP_destroy_ept rpmsg_destroy_ept
+
+/* Initialize the openamp framework*/
+int MX_OPENAMP_Init(int RPMsgRole, rpmsg_ns_bind_cb ns_bind_cb);
+
+/* Deinitialize the openamp framework*/
+void OPENAMP_DeInit(void);
+
+/* Initialize the endpoint struct*/
+void OPENAMP_init_ept(struct rpmsg_endpoint *ept);
+
+/* Create and register the endpoint */
+int OPENAMP_create_endpoint(struct rpmsg_endpoint *ept, const char *name,
+                            uint32_t dest, rpmsg_ept_cb cb,
+                            rpmsg_ns_unbind_cb unbind_cb);
+
+/* Check for new rpmsg reception */
+void OPENAMP_check_for_message(void);
+
+/* Wait loop on endpoint ready ( message dest address is know)*/
+void OPENAMP_Wait_EndPointready(struct rpmsg_endpoint *rp_ept);
+
+#ifdef __cplusplus
+}
+#endif
+#endif /*__openamp_H */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 242 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/openamp_conf.h

@@ -0,0 +1,242 @@
+/**
+  ******************************************************************************
+  * @file    openamp_conf.h
+  * @author  MCD Application Team
+  * @brief   Configuration file for OpenAMP MW
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics. 
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the 
+  * License. You may obtain a copy of the License at:
+  *                       opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/* Define to prevent recursive inclusion -------------------------------------*/
+#ifndef __OPENAMP_CONF__H__
+#define __OPENAMP_CONF__H__
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/* Includes ------------------------------------------------------------------*/
+#if defined (__LOG_TRACE_IO_) || defined(__LOG_UART_IO_)
+#include "openamp_log.h"
+#endif
+
+ /* ########################## Mailbox Interface Selection ############################## */
+ /**
+   * @brief This is the list of Mailbox interface  to be used in the OpenAMP MW
+   *        Please note that not all interfaces are supported by a STM32 device
+   */
+#define MAILBOX_IPCC_IF_ENABLED
+//#define MAILBOX_HSEM_IF_ENABLED
+
+ /* Includes ------------------------------------------------------------------*/
+ /**
+   * @brief Include Maibox interface  header file
+   */
+
+#ifdef MAILBOX_IPCC_IF_ENABLED
+#include "mbox_ipcc.h"
+#endif /* MAILBOX_IPCC_IF_ENABLED */
+
+#ifdef MAILBOX_HSEM_IF_ENABLED
+#include "mbox_hsem.h"
+#endif /* MAILBOX_HSEM_IF_ENABLED */
+
+ /* ########################## Virtual Diver Module Selection ############################## */
+ /**
+   * @brief This is the list of modules to be used in the OpenAMP Virtual driver module
+   *        Please note that virtual driver are not supported on all stm32 families
+   */
+//#define VIRTUAL_UART_MODULE_ENABLED
+//#define VIRTUAL_I2C_MODULE_ENABLED
+
+ /* Includes ------------------------------------------------------------------*/
+ /**
+   * @brief Include Virtual Driver module's  header file
+   */
+
+#ifdef VIRTUAL_UART_MODULE_ENABLED
+#include "virt_uart.h"
+#endif /* VIRTUAL_UART_MODULE_ENABLED */
+
+#ifdef VIRTUAL_I2C_MODULE_ENABLED
+#include "virt_i2c.h"
+#endif /* VIRTUAL_I2C_MODULE_ENABLED */
+
+ /* ########################## Linux Master Selection ############################## */
+ /**
+  * @brief Due to Linux compatibility, it's important to distinguish if the MASTER is Linux or not.
+  *        In that case, the LINUX_RPROC_MASTER define is required
+  */
+#define LINUX_RPROC_MASTER
+
+/* USER CODE BEGIN INCLUDE */
+
+/* USER CODE END INCLUDE */
+
+/** @addtogroup OPENAMP_MW
+  * @{
+  */
+
+/** @defgroup OPENAMP_CONF OPENAMP_CONF
+  * @brief Configuration file for Openamp mw
+  * @{
+  */
+
+/** @defgroup OPENAMP_CONF_Exported_Variables OPENAMP_CONF_Exported_Variables
+  * @brief Public variables.
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup OPENAMP_CONF_Exported_Defines OPENAMP_CONF_Exported_Defines
+  * @brief Defines for configuration of the Openamp mw
+  * @{
+  */
+
+#if defined (__ICCARM__)
+/*
+ * For IAR, the .icf file should contain the following lines:
+ * define symbol __OPENAMP_region_start__ = BASE_ADDRESS; (0x38000400 for example)
+ * define symbol __OPENAMP_region_size__   = MEM_SIZE; (0xB000 as example)
+ *
+ * export symbol __OPENAMP_region_start__;
+ * export symbol __OPENAMP_region_size__;
+ */
+extern const uint32_t  __OPENAMP_region_start__;
+extern const uint8_t  __OPENAMP_region_size__;
+#define SHM_START_ADDRESS       ((metal_phys_addr_t)&__OPENAMP_region_start__)
+#define SHM_SIZE        ((size_t)&__OPENAMP_region_size__)
+
+#elif defined(__CC_ARM)
+/*
+ * For MDK-ARM, the scatter file .sct should contain the following line:
+ * LR_IROM1 ....  {
+ *  ...
+ *   __OpenAMP_SHMEM__ 0x38000400  EMPTY 0x0000B000 {} ; Shared Memory area used by OpenAMP
+ *  }
+ *
+ */
+extern unsigned int Image$$__OpenAMP_SHMEM__$$Base;
+extern unsigned int Image$$__OpenAMP_SHMEM__$$ZI$$Length;
+#define SHM_START_ADDRESS (unsigned int)&Image$$__OpenAMP_SHMEM__$$Base
+#define SHM_SIZE          ((size_t)&Image$$__OpenAMP_SHMEM__$$ZI$$Length)
+
+#else
+/*
+ * for GCC add the following content to the .ld file:
+ * MEMORY
+ * {
+ * ...
+ * OPEN_AMP_SHMEM (xrw) : ORIGIN = 0x38000400, LENGTH = 63K
+ * }
+ * __OPENAMP_region_start__  = ORIGIN(OPEN_AMP_SHMEM);
+ * __OPENAMP_region_end__ = ORIGIN(OPEN_AMP_SHMEM) + LENGTH(OPEN_AMP_SHMEM);
+ *
+ * using the LENGTH(OPEN_AMP_SHMEM) to set the SHM_SIZE lead to a crash thus we
+ * use the start and end address.
+ */
+
+extern int __OPENAMP_region_start__[];  /* defined by linker script */
+extern int __OPENAMP_region_end__[];    /* defined by linker script */
+
+#define SHM_START_ADDRESS       ((metal_phys_addr_t)__OPENAMP_region_start__)
+#define SHM_SIZE                (size_t)((void *)__OPENAMP_region_end__ - (void *) __OPENAMP_region_start__)
+
+#endif
+
+#if defined LINUX_RPROC_MASTER
+#define VRING_RX_ADDRESS        -1        /* allocated by Master processor: CA7 */
+#define VRING_TX_ADDRESS        -1        /* allocated by Master processor: CA7 */
+#define VRING_BUFF_ADDRESS      -1        /* allocated by Master processor: CA7 */
+#define VRING_ALIGNMENT         16        /* fixed to match with linux constraint */
+#define VRING_NUM_BUFFS         16		  /* number of rpmsg buffer */
+#else
+
+#define VRING_RX_ADDRESS     0x10040000             /* allocated by Master processor: CA7 */
+#define VRING_TX_ADDRESS     0x10040400             /* allocated by Master processor: CA7 */
+#define VRING_BUFF_ADDRESS   0x10040800             /* allocated by Master processor: CA7 */
+#define VRING_ALIGNMENT      16         /* fixed to match with 4k page alignement requested by linux  */
+#define VRING_NUM_BUFFS      16             /* number of rpmsg buffer */
+#endif
+/* Fixed parameter */
+#define NUM_RESOURCE_ENTRIES 2
+#define VRING_COUNT          2
+#define VDEV_ID              0xFF
+#define VRING0_ID            0              /* VRING0 ID (master to remote) fixed to 0 for linux compatibility*/
+#define VRING1_ID            1              /* VRING1 ID (remote to master) fixed to 1 for linux compatibility  */
+
+/**
+  * @}
+  */
+
+/** @defgroup OPENAMP_CONF_Exported_Macros OPENAMP_CONF_Exported_Macros
+  * @brief Aliases.
+  * @{
+  */
+
+/* DEBUG macros */
+
+#if defined (__LOG_TRACE_IO_) || defined(__LOG_UART_IO_)
+  #define OPENAMP_log_dbg               log_dbg
+  #define OPENAMP_log_info              log_info
+  #define OPENAMP_log_warn              log_warn
+  #define OPENAMP_log_err               log_err
+#else
+  #define OPENAMP_log_dbg(...)
+  #define OPENAMP_log_info(...)
+  #define OPENAMP_log_warn(...)
+  #define OPENAMP_log_err(...)
+#endif
+
+/**
+  * @}
+  */
+
+/** @defgroup OPENAMP_CONF_Exported_Types OPENAMP_CONF_Exported_Types
+  * @brief Types.
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @defgroup OPENAMP_CONF_Exported_FunctionsPrototype OPENAMP_CONF_Exported_FunctionsPrototype
+  * @brief Declaration of public functions for OpenAMP mw.
+  * @{
+  */
+
+/* Exported functions -------------------------------------------------------*/
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __OPENAMP_CONF__H__ */
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 134 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/openamp_log.h

@@ -0,0 +1,134 @@
+/**
+  ******************************************************************************
+  * @file    log.h
+  * @author  MCD Application Team
+  * @brief   logging services
+  ******************************************************************************
+  *
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics. 
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the 
+  * License. You may obtain a copy of the License at:
+  *                       opensource.org/licenses/BSD-3-Clause
+  *
+  *
+  ******************************************************************************
+  */
+
+/** @addtogroup LOG
+  * @{
+  */
+
+/** @addtogroup stm32mp1xx_Log
+  * @{
+  */
+
+/**
+  * @brief Define to prevent recursive inclusion
+  */
+#ifndef __LOG_STM32MP1XX_H
+#define __LOG_STM32MP1XX_H
+
+#ifdef __cplusplus
+ extern "C" {
+#endif
+
+/** @addtogroup STM32MP1xx_Log_Includes
+  * @{
+  */
+#include "stm32mp1xx_hal.h"
+/**
+  * @}
+  */
+
+/** @addtogroup STM32MP1xx_Log_Exported_Constants
+  * @{
+  */
+#if defined (__LOG_TRACE_IO_)
+#define SYSTEM_TRACE_BUF_SZ 2048
+#endif
+
+#define LOGQUIET 0
+#define	LOGERR	  1
+#define	LOGWARN  2
+#define	LOGINFO  3
+#define	LOGDBG   4
+
+#ifndef LOGLEVEL
+#define LOGLEVEL LOGINFO
+#endif
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32MP1xx_Log_Exported_types
+  * @{
+  */
+#if defined (__LOG_TRACE_IO_)
+extern char system_log_buf[SYSTEM_TRACE_BUF_SZ]; /*!< buffer for debug traces */
+#endif /* __LOG_TRACE_IO_ */
+/**
+  * @}
+  */
+
+/** @addtogroup STM32MP1xx_Log_Exported_Macros
+  * @{
+  */
+#if defined (__LOG_TRACE_IO_) || defined(__LOG_UART_IO_)
+#if LOGLEVEL >= LOGDBG
+#define log_dbg(fmt, ...)  printf("[%05ld.%03ld][DBG  ]" fmt, HAL_GetTick()/1000, HAL_GetTick() % 1000, ##__VA_ARGS__)
+#else
+#define log_dbg(fmt, ...)
+#endif
+#if LOGLEVEL >= LOGINFO
+#define log_info(fmt, ...) printf("[%05ld.%03ld][INFO ]" fmt, HAL_GetTick()/1000, HAL_GetTick() % 1000, ##__VA_ARGS__)
+#else
+#define log_info(fmt, ...)
+#endif
+#if LOGLEVEL >= LOGWARN
+#define log_warn(fmt, ...) printf("[%05ld.%03ld][WARN ]" fmt, HAL_GetTick()/1000, HAL_GetTick() % 1000, ##__VA_ARGS__)
+#else
+#define log_warn(fmt, ...)
+#endif
+#if LOGLEVEL >= LOGERR
+#define log_err(fmt, ...)  printf("[%05ld.%03ld][ERR  ]" fmt, HAL_GetTick()/1000, HAL_GetTick() % 1000, ##__VA_ARGS__)
+#else
+#define log_err(fmt, ...)
+#endif
+#else
+#define log_dbg(fmt, ...)
+#define log_info(fmt, ...)
+#define log_warn(fmt, ...)
+#define log_err(fmt, ...)
+#endif /* __LOG_TRACE_IO_ */
+/**
+  * @}
+  */
+
+/** @addtogroup STM32MP1xx_Log_Exported_Functions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /*__LOG_STM32MP1XX_H */
+
+/**
+  * @}
+  */
+
+/**
+  * @}
+  */
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 43 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Inc/rsc_table.h

@@ -0,0 +1,43 @@
+/*
+ * Copyright (c) 2019 STMicroelectronics.
+ * All rights reserved.
+ *
+ * This software component is licensed by ST under BSD 3-Clause license,
+ * the "License"; You may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at:
+ *                       opensource.org/licenses/BSD-3-Clause
+ *
+ */
+
+/* This file populates resource table for BM remote
+ * for use by the Linux Master */
+
+#ifndef RSC_TABLE_H_
+#define RSC_TABLE_H_
+
+#include "openamp/open_amp.h"
+#include "openamp_conf.h"
+
+/* Place resource table in special ELF section */
+//#define __section_t(S)          __attribute__((__section__(#S)))
+//#define __resource              __section_t(.resource_table)
+
+/* Resource table for the given remote */
+struct shared_resource_table {
+	unsigned int version;
+	unsigned int num;
+	unsigned int reserved[2];
+	unsigned int offset[NUM_RESOURCE_ENTRIES];
+	/* text carveout entry */
+
+	/* rpmsg vdev entry */
+	struct fw_rsc_vdev vdev;
+	struct fw_rsc_vdev_vring vring0;
+	struct fw_rsc_vdev_vring vring1;
+	struct fw_rsc_trace cm_trace;
+};
+
+void resource_table_init(int RPMsgRole, void **table_ptr, int *length);
+
+#endif /* RSC_TABLE_H_ */
+

+ 182 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/mbox_ipcc.c

@@ -0,0 +1,182 @@
+/**
+  ******************************************************************************
+  * @file    mbox_ipcc.c
+  * @author  MCD Application Team
+  * @brief   This file provides code for the configuration
+  *                      of the mailbox_ipcc_if.c MiddleWare.
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics. 
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the 
+  * License. You may obtain a copy of the License at:
+  *                       opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/*
+ * Channel direction and usage:
+ *
+ *  ========   <-- new msg ---=============--------<------   =======
+ * ||      ||                || CHANNEL 1 ||                ||     ||
+ * ||  A7  ||  ------->-------=============--- buf free-->  || M4  ||
+ * ||      ||                                               ||     ||
+ * ||master||  <-- buf free---=============--------<------  ||slave||
+ * ||      ||                || CHANNEL 2 ||                ||     ||
+ *  ========   ------->-------=============----new msg -->   =======
+ */
+
+/* Includes ------------------------------------------------------------------*/
+#include "openamp/open_amp.h"
+#include "stm32mp1xx_hal.h"
+#include "openamp_conf.h"
+
+/* Within 'USER CODE' section, code will be kept by default at each generation */
+/* USER CODE BEGIN 0 */
+
+/* USER CODE END 0 */
+
+/* Private define ------------------------------------------------------------*/
+#define MASTER_CPU_ID    0
+#define REMOTE_CPU_ID    1
+#define IPCC_CPU_A7      MASTER_CPU_ID
+#define IPCC_CPU_M4      REMOTE_CPU_ID
+#define RX_NO_MSG        0
+#define RX_NEW_MSG       1
+#define RX_BUF_FREE      2
+
+/* Private variables ---------------------------------------------------------*/
+extern IPCC_HandleTypeDef hipcc;
+int msg_received_ch1 = RX_NO_MSG;
+int msg_received_ch2 = RX_NO_MSG;
+uint32_t vring0_id = 0; /* used for channel 1 */
+uint32_t vring1_id = 1; /* used for channel 2 */
+
+/* Private function prototypes -----------------------------------------------*/
+void IPCC_channel1_callback(IPCC_HandleTypeDef * hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir);
+void IPCC_channel2_callback(IPCC_HandleTypeDef * hipcc, uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir);
+
+/**
+  * @brief  Initialize MAILBOX with IPCC peripheral
+  * @param  None
+  * @retval : Operation result
+  */
+int MAILBOX_Init(void)
+{
+
+  if (HAL_IPCC_ActivateNotification(&hipcc, IPCC_CHANNEL_1, IPCC_CHANNEL_DIR_RX,
+          IPCC_channel1_callback) != HAL_OK) {
+	  OPENAMP_log_err("%s: ch_1 RX fail\n", __func__);
+    return -1;
+  }
+
+  if (HAL_IPCC_ActivateNotification(&hipcc, IPCC_CHANNEL_2, IPCC_CHANNEL_DIR_RX,
+          IPCC_channel2_callback) != HAL_OK) {
+	  OPENAMP_log_err("%s: ch_2 RX fail\n", __func__);
+    return -1;
+  }
+
+  return 0;
+}
+
+/**
+  * @brief  Initialize MAILBOX with IPCC peripheral
+  * @param  virtio device
+  * @retval : Operation result
+  */
+int MAILBOX_Poll(struct virtio_device *vdev)
+{
+  /* If we got an interrupt, ask for the corresponding virtqueue processing */
+
+  if (msg_received_ch1 == RX_BUF_FREE) {
+    OPENAMP_log_dbg("Running virt0 (ch_1 buf free)\r\n");
+    rproc_virtio_notified(vdev, VRING0_ID);
+    msg_received_ch1 = RX_NO_MSG;
+    return 0;
+  }
+
+  if (msg_received_ch2 == RX_NEW_MSG) {
+    OPENAMP_log_dbg("Running virt1 (ch_2 new msg)\r\n");
+    rproc_virtio_notified(vdev, VRING1_ID);
+    msg_received_ch2 = RX_NO_MSG;
+
+    /* The OpenAMP framework does not notify for free buf: do it here */
+      rproc_virtio_notified(NULL, VRING1_ID);
+    return 0;
+  }
+
+  return -1;
+}
+
+/**
+  * @brief  Callback function called by OpenAMP MW to notify message processing
+  * @param  VRING id
+  * @retval Operation result
+  */
+int MAILBOX_Notify(void *priv, uint32_t id)
+{
+  uint32_t channel;
+  (void)priv;
+
+  /* Called after virtqueue processing: time to inform the remote */
+  if (id == VRING0_ID) {
+    channel = IPCC_CHANNEL_1;
+    OPENAMP_log_dbg("Send msg on ch_1\r\n");
+  }
+  else if (id == VRING1_ID) {
+    /* Note: the OpenAMP framework never notifies this */
+    channel = IPCC_CHANNEL_2;
+    OPENAMP_log_dbg("Send 'buff free' on ch_2\r\n");
+  }
+  else {
+    OPENAMP_log_err("invalid vring (%d)\r\n", (int)id);
+    return -1;
+  }
+
+  /* Check that the channel is free (otherwise wait until it is) */
+  if (HAL_IPCC_GetChannelStatus(&hipcc, channel, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED) {
+    OPENAMP_log_dbg("Waiting for channel to be freed\r\n");
+    while (HAL_IPCC_GetChannelStatus(&hipcc, channel, IPCC_CHANNEL_DIR_TX) == IPCC_CHANNEL_STATUS_OCCUPIED)
+      ;
+  }
+
+  /* Inform A7 (either new message, or buf free) */
+  HAL_IPCC_NotifyCPU(&hipcc, channel, IPCC_CHANNEL_DIR_TX);
+  
+  return 0;
+}
+
+/* Private function  ---------------------------------------------------------*/
+/* Callback from IPCC Interrupt Handler: Master Processor informs that there are some free buffers */
+void IPCC_channel1_callback(IPCC_HandleTypeDef * hipcc,
+         uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
+{
+  if (msg_received_ch1 != RX_NO_MSG)
+    OPENAMP_log_dbg("IPCC_channel1_callback: previous IRQ not treated (status = %d)\r\n", msg_received_ch1);
+
+  msg_received_ch1 = RX_BUF_FREE;
+
+  /* Inform A7 that we have received the 'buff free' msg */
+  OPENAMP_log_dbg("Ack 'buff free' message on ch1\r\n");
+  HAL_IPCC_NotifyCPU(hipcc, ChannelIndex, IPCC_CHANNEL_DIR_RX);
+}
+
+/* Callback from IPCC Interrupt Handler: new message received from Master Processor */
+void IPCC_channel2_callback(IPCC_HandleTypeDef * hipcc,
+         uint32_t ChannelIndex, IPCC_CHANNELDirTypeDef ChannelDir)
+{
+  if (msg_received_ch2 != RX_NO_MSG)
+    OPENAMP_log_dbg("IPCC_channel2_callback: previous IRQ not treated (status = %d)\r\n", msg_received_ch2);
+
+  msg_received_ch2 = RX_NEW_MSG;
+
+  /* Inform A7 that we have received the new msg */
+  OPENAMP_log_dbg("Ack new message on ch2\r\n");
+  HAL_IPCC_NotifyCPU(hipcc, ChannelIndex, IPCC_CHANNEL_DIR_RX);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 176 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/openamp.c

@@ -0,0 +1,176 @@
+/**
+  ******************************************************************************
+  * @file   openamp.c
+  * @author  MCD Application Team
+  * @brief  Code for openamp applications
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics. 
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the 
+  * License. You may obtain a copy of the License at:
+  *                       opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+#include "openamp.h"
+#include "rsc_table.h"
+#include "metal/sys.h"
+#include "metal/device.h"
+/* Private define ------------------------------------------------------------*/
+
+#define SHM_DEVICE_NAME         "STM32_SHM"
+
+/* Globals */
+
+static struct metal_io_region *shm_io;
+static struct metal_io_region *rsc_io;
+static struct shared_resource_table *rsc_table;
+static struct rpmsg_virtio_shm_pool shpool;
+static struct rpmsg_virtio_device rvdev;
+
+static metal_phys_addr_t shm_physmap;
+
+struct metal_device shm_device = {
+  .name = SHM_DEVICE_NAME,
+  .num_regions = 2,
+  .regions = {
+      {.virt = NULL}, /* shared memory */
+      {.virt = NULL}, /* rsc_table memory */
+  },
+  .node = { NULL },
+  .irq_num = 0,
+  .irq_info = NULL
+};
+
+static int OPENAMP_shmem_init(int RPMsgRole)
+{
+  int status = 0;
+  struct metal_device *device;
+  struct metal_init_params metal_params = METAL_INIT_DEFAULTS;
+  void* rsc_tab_addr;
+  int rsc_size;
+
+  metal_init(&metal_params);
+
+  status = metal_register_generic_device(&shm_device);
+  if (status != 0) {
+    return status;
+  }
+
+  status = metal_device_open("generic", SHM_DEVICE_NAME, &device);
+  if (status != 0) {
+    return status;
+  }
+
+  shm_physmap = SHM_START_ADDRESS;
+  metal_io_init(&device->regions[0], (void *)SHM_START_ADDRESS, &shm_physmap,
+                SHM_SIZE, -1, 0, NULL);
+
+  shm_io = metal_device_io_region(device, 0);
+  if (shm_io == NULL) {
+    return -1;
+  }
+
+  /* Initialize resources table variables */
+  resource_table_init(RPMsgRole, &rsc_tab_addr, &rsc_size);
+  rsc_table = (struct shared_resource_table *)rsc_tab_addr;
+  if (!rsc_table)
+  {
+    return -1;
+  }
+
+  metal_io_init(&device->regions[1], rsc_table,
+               (metal_phys_addr_t *)rsc_table, rsc_size, -1U, 0, NULL);
+
+  rsc_io = metal_device_io_region(device, 1);
+  if (rsc_io == NULL) {
+    return -1;
+  }
+
+  return 0;
+}
+
+int MX_OPENAMP_Init(int RPMsgRole, rpmsg_ns_bind_cb ns_bind_cb)
+{
+  struct fw_rsc_vdev_vring *vring_rsc;
+  struct virtio_device *vdev;
+  int status = 0;
+
+  MAILBOX_Init();
+
+  /* Libmetal Initilalization */
+  status = OPENAMP_shmem_init(RPMsgRole);
+  if(status)
+  {
+    return status;
+  }
+
+  vdev = rproc_virtio_create_vdev(RPMsgRole, VDEV_ID, &rsc_table->vdev,
+                                  rsc_io, NULL, MAILBOX_Notify, NULL);
+  if (vdev == NULL)
+  {
+    return -1;
+  }
+
+  rproc_virtio_wait_remote_ready(vdev);
+  vring_rsc = &rsc_table->vring0;
+  status = rproc_virtio_init_vring(vdev, 0, vring_rsc->notifyid,
+                                   (void *)vring_rsc->da, shm_io,
+                                   vring_rsc->num, vring_rsc->align);
+  if (status != 0)
+  {
+    return status;
+  }
+  vring_rsc = &rsc_table->vring1;
+  status = rproc_virtio_init_vring(vdev, 1, vring_rsc->notifyid,
+                                   (void *)vring_rsc->da, shm_io,
+                                   vring_rsc->num, vring_rsc->align);
+  if (status != 0)
+  {
+    return status;
+  }
+
+  rpmsg_virtio_init_shm_pool(&shpool, (void *)VRING_BUFF_ADDRESS,
+                             (size_t)SHM_SIZE);
+  rpmsg_init_vdev(&rvdev, vdev, ns_bind_cb, shm_io, &shpool);
+
+  return 0;
+}
+
+void OPENAMP_DeInit()
+{
+  rpmsg_deinit_vdev(&rvdev);
+
+  metal_finish();
+}
+
+void OPENAMP_init_ept(struct rpmsg_endpoint *ept)
+{
+  rpmsg_init_ept(ept, "", RPMSG_ADDR_ANY, RPMSG_ADDR_ANY, NULL, NULL);
+}
+
+int OPENAMP_create_endpoint(struct rpmsg_endpoint *ept, const char *name,
+                            uint32_t dest, rpmsg_ept_cb cb,
+                            rpmsg_ns_unbind_cb unbind_cb)
+{
+  return rpmsg_create_ept(ept, &rvdev.rdev, name, RPMSG_ADDR_ANY, dest, cb,
+		          unbind_cb);
+}
+
+void OPENAMP_check_for_message(void)
+{
+  MAILBOX_Poll(rvdev.vdev);
+}
+
+void OPENAMP_Wait_EndPointready(struct rpmsg_endpoint *rp_ept)
+{
+  while(!is_rpmsg_ept_ready(rp_ept))
+  MAILBOX_Poll(rvdev.vdev);
+}
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 102 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/openamp_log.c

@@ -0,0 +1,102 @@
+/**
+  ******************************************************************************
+  * @file    log.c
+  * @author  MCD Application Team
+  * @brief   Ressource table
+  *
+  *   This file provides services for logging
+  *
+  ******************************************************************************
+  *
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics. 
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the 
+  * License. You may obtain a copy of the License at:
+  *                       opensource.org/licenses/BSD-3-Clause
+  *
+  *
+  ******************************************************************************
+  */
+/** @addtogroup LOG
+  * @{
+  */
+
+/** @addtogroup STM32MP1xx_log
+  * @{
+  */
+
+/** @addtogroup STM32MP1xx_Log_Private_Includes
+  * @{
+  */
+#include "openamp_log.h"
+/**
+  * @}
+  */
+
+/** @addtogroup STM32MP1xx_Log_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup STM32MP1xx_Log_Private_Defines
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+#if defined (__LOG_TRACE_IO_)
+char system_log_buf[SYSTEM_TRACE_BUF_SZ];
+
+__weak void log_buff(int ch)
+{
+  /* Place your implementation of fputc here */
+  /* e.g. write a character to the USART1 and Loop until the end of transmission */
+ static int offset = 0;
+
+	if (offset + 1 >= SYSTEM_TRACE_BUF_SZ)
+		offset = 0;
+
+	system_log_buf[offset] = ch;
+	system_log_buf[offset++ + 1] = '\0';
+}
+
+#endif
+
+#if defined ( __CC_ARM) || (__ARMCC_VERSION) && (__ARMCC_VERSION >= 6010050)
+#define PUTCHAR_PROTOTYPE int stdout_putchar(int ch)
+#elif __GNUC__
+/* With GCC/RAISONANCE, small log_info (option LD Linker->Libraries->Small log_info
+   set to 'Yes') calls __io_putchar() */
+#define PUTCHAR_PROTOTYPE int __attribute__(( weak )) __io_putchar(int ch)
+#else
+#define PUTCHAR_PROTOTYPE int __attribute__(( weak )) fputc(int ch, FILE *f)
+#endif /* __GNUC__ */
+
+#if defined (__LOG_UART_IO_) || defined (__LOG_TRACE_IO_)
+PUTCHAR_PROTOTYPE
+{
+  /* Place your implementation of fputc here */
+  /* e.g. write a character to the USART1 and Loop until the end of transmission */
+#if defined (__LOG_UART_IO_)
+extern UART_HandleTypeDef huart;
+  HAL_UART_Transmit(&huart, (uint8_t *)&ch, 1, HAL_MAX_DELAY);
+#endif
+#if defined (__LOG_TRACE_IO_)
+	log_buff(ch);
+#endif
+	return ch;
+}
+#else
+/* No printf output */
+#endif
+
+/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

+ 174 - 0
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/rsc_table.c

@@ -0,0 +1,174 @@
+/**
+  ******************************************************************************
+  * @file    rsc_table.c
+  * @author  MCD Application Team
+  * @brief   Ressource table
+  *
+  *   This file provides a default resource table requested by remote proc to
+  *  load the elf file. It also allows to add debug trace using a shared buffer.
+  *
+  ******************************************************************************
+  * @attention
+  *
+  * <h2><center>&copy; Copyright (c) 2019 STMicroelectronics. 
+  * All rights reserved.</center></h2>
+  *
+  * This software component is licensed by ST under BSD 3-Clause license,
+  * the "License"; You may not use this file except in compliance with the
+  * License. You may obtain a copy of the License at:
+  *                       opensource.org/licenses/BSD-3-Clause
+  *
+  ******************************************************************************
+  */
+
+/** @addtogroup RSC_TABLE
+  * @{
+  */
+
+/** @addtogroup resource_table
+  * @{
+  */
+
+/** @addtogroup resource_table_Private_Includes
+  * @{
+  */
+
+#if defined(__ICCARM__) || defined (__CC_ARM)
+#include <stddef.h> /* needed  for offsetof definition*/
+#endif
+#include "rsc_table.h"
+#include "openamp/open_amp.h"
+
+/**
+  * @}
+  */
+
+/** @addtogroup resource_table_Private_TypesDefinitions
+  * @{
+  */
+
+/**
+  * @}
+  */
+
+/** @addtogroup resource_table_Private_Defines
+  * @{
+  */
+
+/* Place resource table in special ELF section */
+#if defined(__GNUC__)
+#define __section_t(S)          __attribute__((__section__(#S)))
+#define __resource              __section_t(.resource_table)
+#endif
+
+#if defined (LINUX_RPROC_MASTER)
+ #ifdef VIRTIO_MASTER_ONLY
+  #define CONST
+ #else
+  #define CONST const
+ #endif
+#else
+ #define CONST
+#endif
+
+#define RPMSG_IPU_C0_FEATURES       1
+#define VRING_COUNT         		2
+
+/* VirtIO rpmsg device id */
+#define VIRTIO_ID_RPMSG_            7
+
+#if defined (__LOG_TRACE_IO_)
+extern char system_log_buf[];
+#endif
+
+#if defined(__GNUC__)
+#if !defined (__CC_ARM) && !defined (LINUX_RPROC_MASTER)
+
+/* Since GCC is not initializing the resource_table at startup, it is declared as volatile to avoid compiler optimization
+ * for the CM4 (see resource_table_init() below)
+ */
+volatile struct shared_resource_table __resource __attribute__((used))  resource_table;
+#else
+CONST struct shared_resource_table __resource __attribute__((used)) resource_table = {
+#endif
+#elif defined(__ICCARM__)
+__root CONST struct shared_resource_table resource_table @ ".resource_table" = {
+#endif
+
+#if defined(__ICCARM__) || defined (__CC_ARM) || defined (LINUX_RPROC_MASTER)
+	.version = 1,
+#if defined (__LOG_TRACE_IO_)
+	.num = 2,
+#else
+	.num = 1,
+#endif
+	.reserved = {0, 0},
+	.offset = {
+		offsetof(struct shared_resource_table, vdev),
+		offsetof(struct shared_resource_table, cm_trace),
+	},
+
+	/* Virtio device entry */
+	.vdev= {
+		RSC_VDEV, VIRTIO_ID_RPMSG_, 0, RPMSG_IPU_C0_FEATURES, 0, 0, 0,
+		VRING_COUNT, {0, 0},
+	},
+
+	/* Vring rsc entry - part of vdev rsc entry */
+	.vring0 = {VRING_TX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING0_ID, 0},
+	.vring1 = {VRING_RX_ADDRESS, VRING_ALIGNMENT, VRING_NUM_BUFFS, VRING1_ID, 0},
+
+#if defined (__LOG_TRACE_IO_)
+	.cm_trace = {
+		RSC_TRACE,
+		(uint32_t)system_log_buf, SYSTEM_TRACE_BUF_SZ, 0, "cm4_log",
+	},
+#endif
+} ;
+#endif
+
+void resource_table_init(int RPMsgRole, void **table_ptr, int *length)
+{
+
+#if !defined (LINUX_RPROC_MASTER)
+#if defined (__GNUC__) && ! defined (__CC_ARM)
+#ifdef VIRTIO_MASTER_ONLY
+
+    /*
+     * Currently the GCC linker doesn't initialize the resource_table global variable at startup
+     * it is done here by the master application.
+     */
+	memset(&resource_table, '\0', sizeof(struct shared_resource_table));
+	resource_table.num = 1;
+	resource_table.version = 1;
+	resource_table.offset[0] = offsetof(struct shared_resource_table, vdev);
+
+	resource_table.vring0.da = VRING_TX_ADDRESS;
+	resource_table.vring0.align = VRING_ALIGNMENT;
+	resource_table.vring0.num = VRING_NUM_BUFFS;
+	resource_table.vring0.notifyid = VRING0_ID;
+
+	resource_table.vring1.da = VRING_RX_ADDRESS;
+	resource_table.vring1.align = VRING_ALIGNMENT;
+	resource_table.vring1.num = VRING_NUM_BUFFS;
+	resource_table.vring1.notifyid = VRING1_ID;
+
+	resource_table.vdev.type = RSC_VDEV;
+	resource_table.vdev.id = VIRTIO_ID_RPMSG_;
+	resource_table.vdev.num_of_vrings=VRING_COUNT;
+	resource_table.vdev.dfeatures = RPMSG_IPU_C0_FEATURES;
+#else
+
+	/* For the slave application let's wait until the resource_table is correctly initialized */
+	while(resource_table.vring1.da != VRING_RX_ADDRESS)
+	{
+
+	}
+#endif
+#endif
+#endif
+
+  (void)RPMsgRole;
+  *length = sizeof(resource_table);
+  *table_ptr = (void *)&resource_table;
+}

+ 10 - 4
bsp/stm32/stm32mp157a-st-discovery/board/CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c

@@ -73,6 +73,11 @@ void HAL_MspInit(void)
   /* System interrupt init*/
 
   /* USER CODE BEGIN MspInit 1 */
+#if !defined(BSP_USING_OPENAMP)
+    __HAL_RCC_SYSRAM_CLK_ENABLE();
+    __HAL_RCC_RETRAM_CLK_ENABLE();
+#endif
+
     HAL_NVIC_SetPriority(RCC_WAKEUP_IRQn, 0, 0);
     HAL_NVIC_EnableIRQ(RCC_WAKEUP_IRQn);
     __HAL_RCC_ENABLE_IT(RCC_IT_WKUP);
@@ -284,7 +289,7 @@ void HAL_LPTIM_MspInit(LPTIM_HandleTypeDef* hlptim)
   /** Initializes the peripherals clock 
   */
     PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_LPTIM1;
-    PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSE;
+    PeriphClkInit.Lptim1ClockSelection = RCC_LPTIM1CLKSOURCE_LSI;
     if (HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) != HAL_OK)
     {
       Error_Handler();
@@ -531,12 +536,13 @@ void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
     __HAL_RCC_GPIOF_CLK_ENABLE();
     /**SPI5 GPIO Configuration    
     PF9     ------> SPI5_MOSI
+    PF8     ------> SPI5_MISO
     PF7     ------> SPI5_SCK 
     */
-    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_7;
+    GPIO_InitStruct.Pin = GPIO_PIN_9|GPIO_PIN_8|GPIO_PIN_7;
     GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
-    GPIO_InitStruct.Pull = GPIO_NOPULL;
-    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_MEDIUM;
+    GPIO_InitStruct.Pull = GPIO_PULLUP;
+    GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH;
     GPIO_InitStruct.Alternate = GPIO_AF5_SPI5;
     HAL_GPIO_Init(GPIOF, &GPIO_InitStruct);
 

+ 6 - 0
bsp/stm32/stm32mp157a-st-discovery/board/Kconfig

@@ -32,6 +32,12 @@ menu "Onboard Peripheral Drivers"
     config BSP_USING_RCC
         bool "Enable rcc use sample"
         default n
+
+    config BSP_USING_OPENAMP
+        bool "Enable OpenAMP"
+        select RT_USING_OPENAMP
+        default n
+
 endmenu
 
 menu "On-chip Peripheral Drivers"

+ 25 - 0
bsp/stm32/stm32mp157a-st-discovery/board/SConscript

@@ -13,6 +13,9 @@ CubeMX_Config/Common/System/system_stm32mp1xx.c
 CubeMX_Config/CM4/Src/stm32mp1xx_hal_msp.c
 ''')
 
+if GetDepend(['BSP_USING_SPI5']):
+    src += Glob('ports/spi_sample.c')
+
 if GetDepend(['BSP_USING_RCC']):
     src += Glob('ports/drv_rcc.c')
 
@@ -34,10 +37,32 @@ if GetDepend(['BSP_USING_TIM14']):
 if GetDepend(['BSP_USING_PMIC']):
     src += Glob('ports/drv_pmic.c')
 
+if GetDepend(['BSP_USING_OPENAMP']):
+    src +=  Glob('CubeMX_Config/CM4/Src/ipcc.c')
+    src +=  Glob('CubeMX_Config/CM4/Src/openamp.c')
+    src +=  Glob('CubeMX_Config/CM4/Src/openamp_log.c')
+    src +=  Glob('CubeMX_Config/CM4/Src/mbox_ipcc.c')
+    src +=  Glob('CubeMX_Config/CM4/Src/rsc_table.c')
+    src +=  Glob('ports/OpenAMP/libmetal/lib/*.c')
+    src +=  Glob('ports/OpenAMP/libmetal/lib/system/generic/*.c')
+    src +=  Glob('ports/OpenAMP/libmetal/lib/system/generic/cortexm/*.c')
+    src +=  Glob('ports/OpenAMP/open-amp/lib/rpmsg/*.c')
+    src +=  Glob('ports/OpenAMP/open-amp/lib/remoteproc/*.c')
+    src +=  Glob('ports/OpenAMP/open-amp/lib/virtio/*.c')
+    src +=  Glob('ports/OpenAMP/virtual_driver/*.c')
+    src +=  Glob('ports/OpenAMP/drv_openamp.c')
+
 path =  [cwd]
 path += [cwd + '/CubeMX_Config/CM4/Inc']
 path += [cwd + '/ports']
 
+if GetDepend(['BSP_USING_OPENAMP']):
+    path += [cwd + '/ports/OpenAMP']
+    path += [cwd + '/ports/OpenAMP/open-amp/lib/include']
+    path += [cwd + '/ports/OpenAMP/libmetal/lib/include']
+    path += [cwd + '/ports/OpenAMP/virtual_driver']
+    path += [cwd + '/CubeMX_Config/CM4/Inc']
+
 startup_path_prefix = SDK_LIB
 
 if rtconfig.CROSS_TOOL == 'gcc':

+ 12 - 8
bsp/stm32/stm32mp157a-st-discovery/board/board.c

@@ -28,13 +28,17 @@ void SystemClock_Config(void)
     
     /**Initializes the CPU, AHB and APB busses clocks 
     */
-    RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_HSE
-        |RCC_OSCILLATORTYPE_LSE;
-    RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS_DIG;
-    RCC_OscInitStruct.LSEState = RCC_LSE_ON;
-    RCC_OscInitStruct.HSIState = RCC_HSI_ON;
-    RCC_OscInitStruct.HSICalibrationValue = 16;
-    RCC_OscInitStruct.HSIDivValue = RCC_HSI_DIV1;
+  RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI|RCC_OSCILLATORTYPE_LSI
+                              |RCC_OSCILLATORTYPE_HSE|RCC_OSCILLATORTYPE_LSE
+                              |RCC_OSCILLATORTYPE_CSI;
+  RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS_DIG;
+  RCC_OscInitStruct.LSEState = RCC_LSE_ON;
+  RCC_OscInitStruct.HSIState = RCC_HSI_ON;
+  RCC_OscInitStruct.HSICalibrationValue = 0x0; /* Default reset value */
+  RCC_OscInitStruct.HSIDivValue = RCC_HSI_DIV1;
+  RCC_OscInitStruct.LSIState = RCC_LSI_ON;
+  RCC_OscInitStruct.CSIState = RCC_CSI_ON;
+  RCC_OscInitStruct.CSICalibrationValue = 0x10; /* Default reset value */
     
     /**PLL1 Config
     */
@@ -166,7 +170,7 @@ void rt_hw_board_init()
 #if defined(RT_USING_HEAP)
     rt_system_heap_init((void *)HEAP_BEGIN, (void *)HEAP_END);
 #endif
-    
+     
     /* Pin driver initialization is open by default */
 #ifdef RT_USING_PIN
     rt_hw_pin_init();

+ 15 - 13
bsp/stm32/stm32mp157a-st-discovery/board/board.h

@@ -22,23 +22,25 @@
 extern "C" {
 #endif
 
-#define STM32_FLASH_START_ADRESS     ((uint32_t)0x10000000)
-#define STM32_FLASH_SIZE             (256 * 1024)
+#define STM32_FLASH_START_ADRESS     ((uint32_t)0x10000000)  
+#if defined(BSP_USING_OPENAMP)
+#define STM32_FLASH_SIZE             (64 * 1024)
+#else
+#define STM32_FLASH_SIZE             (256 * 1024)    
+#endif
 #define STM32_FLASH_END_ADDRESS      ((uint32_t)(STM32_FLASH_START_ADRESS + STM32_FLASH_SIZE))
 
-#define STM32_SRAM_SIZE           (128)
-#define STM32_SRAM_END            ((uint32_t)0x10040000 + (STM32_SRAM_SIZE * 1024))
-
-#if defined(__CC_ARM) || defined(__CLANG_ARM)
-extern int Image$$RW_IRAM1$$ZI$$Limit;
-#define HEAP_BEGIN      (&Image$$RW_IRAM1$$ZI$$Limit)
-#elif __ICCARM__
-#pragma section="CSTACK"
-#define HEAP_BEGIN      (__segment_end("CSTACK"))
+    
+#if defined(BSP_USING_OPENAMP)    
+#define STM32_SRAM_BEGIN             (uint32_t)0x10020000 
 #else
-extern int __bss_end__;
-#define HEAP_BEGIN       (0x10040000 + 64 * 1024)
+#define STM32_SRAM_BEGIN             (uint32_t)0x2FFF0000     
 #endif
+#define STM32_SRAM_SIZE              (64)    
+#define STM32_SRAM_END               (STM32_SRAM_BEGIN + (STM32_SRAM_SIZE * 1024))
+
+#define HEAP_BEGIN                    STM32_SRAM_BEGIN
+#define HEAP_END                      STM32_SRAM_END
 
 #define HEAP_END        STM32_SRAM_END
 

+ 27 - 11
bsp/stm32/stm32mp157a-st-discovery/board/linker_scripts/link.icf

@@ -1,28 +1,44 @@
 /*###ICF### Section handled by ICF editor, don't touch! ****/
 /*-Editor annotation file-*/
-/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */
+/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\a_v1_0.xml" */
 /*-Specials-*/
 define symbol __ICFEDIT_intvec_start__ = 0x00000000;
 /*-Memory Regions-*/
-define symbol __ICFEDIT_region_ROM_start__ = 0x10000000;
-define symbol __ICFEDIT_region_ROM_end__   = 0x1003FFFF;
-define symbol __ICFEDIT_region_RAM_start__ = 0x10040000;
-define symbol __ICFEDIT_region_RAM_end__   = 0x1005FFFF;
+define symbol __ICFEDIT_region_text_start__ = 0x10000000;
+define symbol __ICFEDIT_region_text_end__   = 0x1001FFFF;
+define symbol __ICFEDIT_region_data_start__ = 0x10030000;
+define symbol __ICFEDIT_region_data_end__   = 0x1003FFFF;
 /*-Sizes-*/
 define symbol __ICFEDIT_size_cstack__ = 0x400;
 define symbol __ICFEDIT_size_heap__   = 0x000;
 /**** End of ICF editor section. ###ICF###*/
 
 define memory mem with size = 4G;
-define region ROM_region   = mem:[from __ICFEDIT_region_ROM_start__   to __ICFEDIT_region_ROM_end__];
-define region RAM_region   = mem:[from __ICFEDIT_region_RAM_start__   to __ICFEDIT_region_RAM_end__];
+define region text_region   = mem:[from __ICFEDIT_region_text_start__   to __ICFEDIT_region_text_end__];
+define region data_region   = mem:[from __ICFEDIT_region_data_start__   to __ICFEDIT_region_data_end__];
+
+keep { section .resource_table };
+".resource_table" :  place in data_region {section .resource_table};
+
+/* Create region for OPENAMP */
+/* !!! These 4 lines can be commented if OPENAMP is not used !!!*/
+define symbol __OPENAMP_region_start__ = 0x10040000;
+define symbol __OPENAMP_region_size__   = 0x8000;
+export symbol __OPENAMP_region_start__;
+export symbol __OPENAMP_region_size__;
+
+define symbol __SDMMC_region_start__   = 0x10048000;
+define symbol __SDMMC_region_size__    = 0x1FFFF;
+export symbol __SDMMC_region_start__;
+export symbol __SDMMC_region_size__;
 
 define block CSTACK    with alignment = 8, size = __ICFEDIT_size_cstack__   { };
+define block HEAP      with alignment = 8, size = __ICFEDIT_size_heap__     { };
 
 initialize by copy { readwrite };
-do not initialize  { section .noinit };
+do not initialize  { section .noinit};
 
 place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec };
-
-place in ROM_region   { readonly };
-place in RAM_region   { readwrite, last block CSTACK};
+place in text_region   { readonly };
+place in data_region   { readwrite,
+                         block CSTACK, block HEAP};

+ 292 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/drv_openamp.c

@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-06-24     thread-liu   first version
+ */
+
+#include <board.h>
+
+#ifdef BSP_USING_OPENAMP
+
+#include <drv_openamp.h>
+#include <openamp.h>
+#include <virt_uart.h>
+#include <openamp/rpmsg_virtio.h>
+
+//#define DRV_DEBUG
+#define LOG_TAG             "drv.openamp"
+#include <drv_log.h>
+
+IPCC_HandleTypeDef hipcc;
+static VIRT_UART_HandleTypeDef huart0;
+
+static rt_uint8_t rx_buffer[MAX_BUFFER_SIZE];
+static rt_uint8_t tx_buffer[MAX_BUFFER_SIZE];
+  
+struct rthw_openamp
+{
+    struct rt_device  parent;
+    struct rt_openamp serial;
+    struct rt_semaphore sema;
+};
+static struct rthw_openamp  dev_openamp;
+
+void IPCC_RX1_IRQHandler(void) 
+{
+    rt_interrupt_enter();
+    
+    HAL_IPCC_RX_IRQHandler(&hipcc);
+    
+    rt_interrupt_leave();
+}
+
+void IPCC_TX1_IRQHandler(void)
+{
+    rt_interrupt_enter();
+        
+    HAL_IPCC_TX_IRQHandler(&hipcc);
+    
+    rt_interrupt_leave();
+}
+
+void VIRT_UART0_RxCpltCallback(VIRT_UART_HandleTypeDef *huart) 
+{  
+    rt_uint16_t rx_size = 0, i = 0;
+    rt_size_t count, size, offset;
+    rt_uint8_t *buf = RT_NULL;
+    
+    struct rthw_openamp  *device;
+    device = (struct rthw_openamp *)rt_device_find("openamp");
+    RT_ASSERT(device != RT_NULL);
+   
+    buf    = device->serial.rbuf; 
+    count  = device->serial.rbuf_count;
+    size   = device->serial.rbuf_size;
+    offset = device->serial.rbuf_start + count;
+   
+    rt_sem_take(&device->sema, RT_WAITING_FOREVER);
+        
+    rx_size = (huart->RxXferSize < MAX_BUFFER_SIZE) ? huart->RxXferSize : MAX_BUFFER_SIZE - 1;
+
+    if (count < size)
+    {
+        if (offset >= size)
+        {
+            offset -= size;
+        }
+        
+        for (i = 0; i < rx_size; i++)
+        {
+           buf[offset++] = huart->pRxBuffPtr[i];
+           count++;
+        }
+    }
+
+    device->serial.rbuf_count = count;
+    
+    rt_sem_release(&device->sema);
+}
+ 
+static rt_err_t _init(struct rt_device *dev)
+{
+    struct rthw_openamp  *device;
+    device = (struct rthw_openamp *)dev;
+    RT_ASSERT(device != RT_NULL);
+    
+    device->serial.rbuf_start  = 0;
+    device->serial.rbuf_count  = 0;
+    device->serial.tbuf_start  = 0;
+    device->serial.tbuf_count  = 0;
+    device->serial.rbuf_size   = MAX_BUFFER_SIZE;
+    device->serial.tbuf_size   = MAX_BUFFER_SIZE;
+    device->serial.rbuf        = rx_buffer;
+    device->serial.tbuf        = tx_buffer;
+  
+    if (rt_sem_init(&device->sema, "openamplock", 1, RT_IPC_FLAG_FIFO) != RT_EOK)
+    {
+        return RT_ERROR;
+    }
+    
+    return RT_EOK;
+}
+
+static rt_size_t _read(struct rt_device *dev, rt_off_t pos, void *buffer, rt_size_t size)
+{
+    rt_size_t count, rbsize, offset;
+    rt_uint8_t *buf     = RT_NULL; 
+    rt_uint8_t *pBuffer = RT_NULL;
+    rt_uint16_t i = 0;
+    
+    struct rthw_openamp  *device;
+    device = (struct rthw_openamp *)dev;
+    RT_ASSERT(device != RT_NULL);
+    
+    pBuffer = (unsigned char*)buffer;
+    count   = device->serial.rbuf_count;
+    buf     = device->serial.rbuf;
+    
+    if (count == 0)
+    {
+        return -RT_ERROR;
+    }
+    
+    rt_sem_take(&device->sema, RT_WAITING_FOREVER);
+    
+    if (count >= size)
+    {
+        count = size;
+    } 
+
+    offset = device->serial.rbuf_start;
+    rbsize = device->serial.rbuf_size;
+ 
+    for (i = 0; i < count; i++)
+    {
+        *pBuffer++ = buf[offset++];
+        if (offset > rbsize)
+        {
+           offset = 0;  
+        }
+    }
+
+    device->serial.rbuf_start  = offset;
+    device->serial.rbuf_count -= count;
+    
+    rt_sem_release(&device->sema);
+    
+    return count;
+}
+ 
+static rt_size_t _write(struct rt_device *dev, rt_off_t pos, const void *buffer, rt_size_t size)
+{
+    rt_err_t result = VIRT_UART_OK;
+    
+    struct rthw_openamp  *device;
+    device = (struct rthw_openamp *)dev;
+    RT_ASSERT(device != RT_NULL);
+    
+    rt_sem_take(&device->sema, RT_WAITING_FOREVER);
+    result = VIRT_UART_Transmit(&huart0, (uint8_t *)buffer, size); 
+    rt_sem_release(&device->sema);
+        
+    if (result != VIRT_UART_OK)
+    {
+        return -RT_ERROR;
+    }
+    
+    return size;
+}
+
+static rt_err_t rt_hw_openamp_register(struct rthw_openamp  *openamp, const char *name, rt_uint32_t flag, void *data)
+{
+    struct rt_device *device;
+    RT_ASSERT(openamp != RT_NULL);
+
+    device = &(openamp->parent);
+
+    device->type        = RT_Device_Class_Char;
+    device->rx_indicate = RT_NULL;
+    device->tx_complete = RT_NULL;
+
+    device->init        = _init;
+    device->open        = RT_NULL;
+    device->close       = RT_NULL;
+    device->read        = _read;
+    device->write       = _write;
+    device->control     = RT_NULL;
+    device->user_data   = data;
+
+    /* register a character device */
+    return rt_device_register(device, name, flag);
+}
+
+static int openamp_init(void)
+{  
+    extern int MX_OPENAMP_Init(int RPMsgRole, rpmsg_ns_bind_cb ns_bind_cb);
+
+    /* IPCC init */
+    hipcc.Instance = IPCC;
+    if (HAL_IPCC_Init(&hipcc) != HAL_OK)
+    {
+        return RT_ERROR;
+    }
+    /* openamp slave device */
+    MX_OPENAMP_Init(RPMSG_REMOTE, NULL);
+    
+    if (VIRT_UART_Init(&huart0) != VIRT_UART_OK) 
+    {
+        return RT_ERROR;
+    }
+    if (VIRT_UART_RegisterCallback(&huart0, VIRT_UART_RXCPLT_CB_ID, VIRT_UART0_RxCpltCallback) != VIRT_UART_OK) 
+    {
+        return RT_ERROR;
+    }
+    
+    return RT_EOK;    
+}
+
+int rt_hw_openamp_init(void)
+{
+    openamp_init();
+    
+    rt_hw_openamp_register(&dev_openamp, "openamp", 0, NULL);
+    
+    rt_console_set_device("openamp");
+
+    return RT_EOK;
+}
+INIT_PREV_EXPORT(rt_hw_openamp_init);
+
+static void openamp_thread_entry(void *parameter) 
+{
+    rt_size_t size = 0;
+    struct rthw_openamp  *device = RT_NULL;
+    
+    device = (struct rthw_openamp *)rt_device_find("openamp");
+    RT_ASSERT(device != RT_NULL);
+    
+    for (;;) 
+    {
+        OPENAMP_check_for_message();
+
+        size = device->serial.rbuf_count;
+        if (size > 0)
+        {
+            if (device->parent.rx_indicate != RT_NULL) 
+            {
+                device->parent.rx_indicate(&device->parent, size);
+            }
+        }
+        
+        rt_thread_mdelay(1);
+    }
+}
+
+static int creat_openamp_thread(void)
+{
+    rt_thread_t tid = RT_NULL;
+    
+    tid = rt_thread_create("OpenAMP", 
+                        openamp_thread_entry, 
+                        RT_NULL, 
+                        OPENAMP_THREAD_STACK_SIZE, 
+                        OPENAMP_THREAD_PRIORITY, 
+                        OPENAMP_THREAD_TIMESLICE);
+    
+    if (tid == RT_NULL) 
+    {
+        LOG_E("openamp thread create failed!");
+        return RT_ERROR;
+    } 
+    
+    rt_thread_startup(tid);
+    
+    return RT_EOK;
+}
+INIT_APP_EXPORT(creat_openamp_thread);
+
+#endif

+ 41 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/drv_openamp.h

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2006-2022, RT-Thread Development Team
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Change Logs:
+ * Date           Author       Notes
+ * 2020-06-24     thread-liu   first version
+ */
+
+#ifndef __DRV_OPENAMP_H__
+#define __DRV_OPENAMP_H__
+
+#include "board.h"
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct rt_openamp
+{
+    rt_uint8_t   *rbuf; 
+    rt_uint8_t   *tbuf;          
+    volatile rt_uint16_t  rbuf_size;      
+    volatile rt_uint16_t  tbuf_size;
+    volatile rt_uint16_t  rbuf_start;
+    volatile rt_uint16_t  rbuf_count;
+    volatile rt_uint16_t  tbuf_start;
+    volatile rt_uint16_t  tbuf_count;
+};
+    
+#define OPENAMP_THREAD_STACK_SIZE   512
+#define OPENAMP_THREAD_PRIORITY     5
+#define OPENAMP_THREAD_TIMESLICE    10
+
+#define MAX_BUFFER_SIZE             256
+  
+#ifdef __cplusplus
+}
+#endif
+
+#endif

+ 58 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/dma.c

@@ -0,0 +1,58 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <metal/errno.h>
+#include <string.h>
+#include <metal/device.h>
+#include <metal/log.h>
+#include <metal/dma.h>
+#include <metal/atomic.h>
+
+int metal_dma_map(struct metal_device *dev,
+		  uint32_t dir,
+		  struct metal_sg *sg_in,
+		  int nents_in,
+		  struct metal_sg *sg_out)
+{
+	int nents_out;
+
+	if (!dev || !sg_in || !sg_out)
+		return -EINVAL;
+	if (!dev->bus->ops.dev_dma_map)
+		return -ENODEV;
+
+	/* memory barrier */
+	if (dir == METAL_DMA_DEV_R)
+		/* If it is device read, apply memory write fence. */
+		atomic_thread_fence(memory_order_release);
+	else
+		/* If it is device write or device r/w,
+		   apply memory r/w fence. */
+		atomic_thread_fence(memory_order_acq_rel);
+	nents_out = dev->bus->ops.dev_dma_map(dev->bus,
+			dev, dir, sg_in, nents_in, sg_out);
+	return nents_out;
+}
+
+void metal_dma_unmap(struct metal_device *dev,
+		  uint32_t dir,
+		  struct metal_sg *sg,
+		  int nents)
+{
+	/* memory barrier */
+	if (dir == METAL_DMA_DEV_R)
+		/* If it is device read, apply memory write fence. */
+		atomic_thread_fence(memory_order_release);
+	else
+		/* If it is device write or device r/w,
+		   apply memory r/w fence. */
+		atomic_thread_fence(memory_order_acq_rel);
+
+	if (!dev || !dev->bus->ops.dev_dma_unmap || !sg)
+		return;
+	dev->bus->ops.dev_dma_unmap(dev->bus,
+			dev, dir, sg, nents);
+}

+ 46 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/alloc.h

@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	alloc.h
+ * @brief	Memory allocation handling primitives for libmetal.
+ */
+
+#ifndef __METAL_ALLOC__H__
+#define __METAL_ALLOC__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup Memory Allocation Interfaces
+ *  @{ */
+
+/**
+ * @brief      allocate requested memory size
+ *             return a pointer to the allocated memory
+ *
+ * @param[in]  size        size in byte of requested memory
+ * @return     memory pointer, or 0 if it failed to allocate
+ */
+static inline void *metal_allocate_memory(unsigned int size);
+
+/**
+ * @brief      free the memory previously allocated
+ *
+ * @param[in]  ptr       pointer to memory
+ */
+static inline void metal_free_memory(void *ptr);
+
+#include <metal/system/generic/alloc.h>
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_ALLOC__H__ */

+ 24 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/assert.h

@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	assert.h
+ * @brief	Assertion support.
+ */
+
+#ifndef __METAL_ASSERT__H__
+#define __METAL_ASSERT__H__
+
+#include <metal/system/generic/assert.h>
+
+/**
+ * @brief Assertion macro.
+ * @param cond Condition to test.
+ */
+#define metal_assert(cond) metal_sys_assert(cond)
+
+#endif /* __METAL_ASSERT_H__ */
+

+ 32 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/atomic.h

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	atomic.h
+ * @brief	Atomic primitives for libmetal.
+ */
+
+#ifndef __METAL_ATOMIC__H__
+#define __METAL_ATOMIC__H__
+
+#include <metal/config.h>
+
+#if defined(HAVE_STDATOMIC_H) && !defined (__CC_ARM) && \
+    !defined(__STDC_NO_ATOMICS__) && !defined(__cplusplus)
+
+# include <stdatomic.h>
+
+#ifndef atomic_thread_fence
+#define atomic_thread_fence(order)
+#endif
+
+#elif defined(__GNUC__)
+# include <metal/compiler/gcc/atomic.h>
+#else
+# include <metal/processor/arm/atomic.h>
+#endif
+
+#endif /* __METAL_ATOMIC__H__ */

+ 57 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/cache.h

@@ -0,0 +1,57 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	cache.h
+ * @brief	CACHE operation primitives for libmetal.
+ */
+
+#ifndef __METAL_CACHE__H__
+#define __METAL_CACHE__H__
+
+#include <metal/system/generic/cache.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** \defgroup cache CACHE Interfaces
+ *  @{ */
+
+/**
+ * @brief flush specified data cache
+ *
+ * @param[in] addr start memory logical address
+ * @param[in] len  length of memory
+ *                 If addr is NULL, and len is 0,
+ *                 It will flush the whole data cache.
+ */
+static inline void metal_cache_flush(void *addr, unsigned int len)
+{
+	__metal_cache_flush(addr, len);
+}
+
+/**
+ * @brief invalidate specified data cache
+ *
+ * @param[in] addr start memory logical address
+ * @param[in] len  length of memory
+ *                 If addr is NULL, and len is 0,
+ *                 It will invalidate the whole data cache.
+ */
+static inline void metal_cache_invalidate(void *addr, unsigned int len)
+{
+	__metal_cache_invalidate(addr, len);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_CACHE__H__ */

+ 25 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler.h

@@ -0,0 +1,25 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	compiler.h
+ * @brief	Compiler specific primitives for libmetal.
+ */
+
+#ifndef __METAL_COMPILER__H__
+#define __METAL_COMPILER__H__
+
+#if defined(__GNUC__)
+# include <metal/compiler/gcc/compiler.h>
+#elif defined(__ICCARM__)
+# include <metal/compiler/iar/compiler.h>
+#elif defined (__CC_ARM)
+# error "MDK-ARM ARMCC compiler requires the GNU extentions to work correctly"
+#else
+# error "Missing compiler support"
+#endif
+
+#endif /* __METAL_COMPILER__H__ */

+ 123 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/gcc/atomic.h

@@ -0,0 +1,123 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	gcc/atomic.h
+ * @brief	GCC specific atomic primitives for libmetal.
+ */
+
+#ifndef __METAL_GCC_ATOMIC__H__
+#define __METAL_GCC_ATOMIC__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef int atomic_flag;
+typedef char atomic_char;
+typedef unsigned char atomic_uchar;
+typedef short atomic_short;
+typedef unsigned short atomic_ushort;
+typedef int atomic_int;
+typedef unsigned int atomic_uint;
+typedef long atomic_long;
+typedef unsigned long atomic_ulong;
+typedef long long atomic_llong;
+typedef unsigned long long atomic_ullong;
+
+#define ATOMIC_FLAG_INIT	0
+#define ATOMIC_VAR_INIT(VAL)	(VAL)
+
+typedef enum {
+	memory_order_relaxed,
+	memory_order_consume,
+	memory_order_acquire,
+	memory_order_release,
+	memory_order_acq_rel,
+	memory_order_seq_cst,
+} memory_order;
+
+#define atomic_flag_test_and_set(FLAG)					\
+	__sync_lock_test_and_set((FLAG), 1)
+#define atomic_flag_test_and_set_explicit(FLAG, MO)			\
+	atomic_flag_test_and_set(FLAG)
+#define atomic_flag_clear(FLAG)						\
+	__sync_lock_release((FLAG))
+#define atomic_flag_clear_explicit(FLAG, MO)				\
+	atomic_flag_clear(FLAG)
+#define atomic_init(OBJ, VAL)						\
+	do { *(OBJ) = (VAL); } while (0)
+#define atomic_is_lock_free(OBJ)					\
+	(sizeof(*(OBJ)) <= sizeof(long))
+#define atomic_store(OBJ, VAL)						\
+	do { *(OBJ) = (VAL); __sync_synchronize(); } while (0)
+#define atomic_store_explicit(OBJ, VAL, MO)				\
+	atomic_store((OBJ), (VAL))
+#define atomic_load(OBJ)						\
+	({ __sync_synchronize(); *(OBJ); })
+#define atomic_load_explicit(OBJ, MO)					\
+	atomic_load(OBJ)
+#define atomic_exchange(OBJ, DES)					\
+	({								\
+		typeof(OBJ) obj = (OBJ);				\
+		typeof(*obj) des = (DES);				\
+		typeof(*obj) expval;					\
+		typeof(*obj) oldval = atomic_load(obj);			\
+		do {							\
+			expval = oldval;				\
+			oldval = __sync_val_compare_and_swap(		\
+				obj, expval, des);			\
+		} while (oldval != expval);				\
+		oldval;							\
+	})
+#define atomic_exchange_explicit(OBJ, DES, MO)				\
+	atomic_exchange((OBJ), (DES))
+#define atomic_compare_exchange_strong(OBJ, EXP, DES)			\
+	({								\
+		typeof(OBJ) obj = (OBJ);				\
+		typeof(EXP) exp = (EXP);				\
+		typeof(*obj) expval = *exp;				\
+		typeof(*obj) oldval = __sync_val_compare_and_swap(	\
+			obj, expval, (DES));				\
+		*exp = oldval;						\
+		oldval == expval;					\
+	})
+#define atomic_compare_exchange_strong_explicit(OBJ, EXP, DES, MO)	\
+	atomic_compare_exchange_strong((OBJ), (EXP), (DES))
+#define atomic_compare_exchange_weak(OBJ, EXP, DES)			\
+	atomic_compare_exchange_strong((OBJ), (EXP), (DES))
+#define atomic_compare_exchange_weak_explicit(OBJ, EXP, DES, MO)	\
+	atomic_compare_exchange_weak((OBJ), (EXP), (DES))
+#define atomic_fetch_add(OBJ, VAL)					\
+	__sync_fetch_and_add((OBJ), (VAL))
+#define atomic_fetch_add_explicit(OBJ, VAL, MO)				\
+	atomic_fetch_add((OBJ), (VAL))
+#define atomic_fetch_sub(OBJ, VAL)					\
+	__sync_fetch_and_sub((OBJ), (VAL))
+#define atomic_fetch_sub_explicit(OBJ, VAL, MO)				\
+	atomic_fetch_sub((OBJ), (VAL))
+#define atomic_fetch_or(OBJ, VAL)					\
+	__sync_fetch_and_or((OBJ), (VAL))
+#define atomic_fetch_or_explicit(OBJ, VAL, MO)				\
+	atomic_fetch_or((OBJ), (VAL))
+#define atomic_fetch_xor(OBJ, VAL)					\
+	__sync_fetch_and_xor((OBJ), (VAL))
+#define atomic_fetch_xor_explicit(OBJ, VAL, MO)				\
+	atomic_fetch_xor((OBJ), (VAL))
+#define atomic_fetch_and(OBJ, VAL)					\
+	__sync_fetch_and_and((OBJ), (VAL))
+#define atomic_fetch_and_explicit(OBJ, VAL, MO)				\
+	atomic_fetch_and((OBJ), (VAL))
+#define atomic_thread_fence(MO)						\
+	__sync_synchronize()
+#define atomic_signal_fence(MO)						\
+	__sync_synchronize()
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GCC_ATOMIC__H__ */

+ 27 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/gcc/compiler.h

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	gcc/compiler.h
+ * @brief	GCC specific primitives for libmetal.
+ */
+
+#ifndef __METAL_GCC_COMPILER__H__
+#define __METAL_GCC_COMPILER__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define restrict __restrict__
+#define metal_align(n) __attribute__((aligned(n)))
+#define metal_weak __attribute__((weak))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GCC_COMPILER__H__ */

+ 27 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/iar/compiler.h

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2018, ST Microelectronics. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	iar/compiler.h
+ * @brief	IAR specific primitives for libmetal.
+ */
+
+#ifndef __METAL_IAR_COMPILER__H__
+#define __METAL_IAR_COMPILER__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#define restrict __restrict__
+#define metal_align(n) __attribute__((aligned(n)))
+#define metal_weak __attribute__((weak))
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_IAR_COMPILER__H__ */

+ 289 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/iar/errno.h

@@ -0,0 +1,289 @@
+/*
+ * * Copyright (c) 2019 STMicroelectronics. All rights reserved.
+ * *
+ * * Copyright (c) 1982, 1986, 1989, 1993
+ * *	The Regents of the University of California.  All rights reserved.
+ * * Copyright (c) 1982, 1986, 1989, 1993
+ * *	The Regents of the University of California.  All rights reserved.
+ * * (c) UNIX System Laboratories, Inc.
+ * * All or some portions of this file are derived from material licensed
+ * * to the University of California by American Telephone and Telegraph
+ * * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * * the permission of UNIX System Laboratories, Inc.
+ *
+ * * SPDX-License-Identifier: BSD-3-Clause
+ * */
+
+#ifndef __METAL_ERRNO__H__
+#error "Include metal/errno.h instead of metal/iar/errno.h"
+#endif
+
+#ifndef _ERRNO_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define _ERRNO_H_
+
+
+#ifndef EPERM
+#define	EPERM 1		/* Not owner */
+#endif
+#ifndef ENOENT
+#define	ENOENT 2	/* No such file or directory */    
+#endif
+#ifndef ESRCH
+#define	ESRCH 3		/* No such process */
+#endif
+#ifndef EINTR
+#define	EINTR 4		/* Interrupted system call */
+#endif
+#ifndef EIO
+#define	EIO 5		/* I/O error */
+#endif
+#ifndef ENXIO
+#define	ENXIO 6		/* No such device or address */
+#endif
+#ifndef E2BIG
+#define	E2BIG 7		/* Arg list too long */
+#endif
+#ifndef ENOEXEC
+#define	ENOEXEC 8	/* Exec format error */
+#endif
+#ifndef EBADF
+#define	EBADF 9		/* Bad file number */
+#endif
+#ifndef ECHILD
+#define	ECHILD 10	/* No children */
+#endif
+#ifndef EAGAIN
+#define	EAGAIN 11	/* No more processes */
+#endif
+#ifndef ENOMEM
+#define	ENOMEM 12	/* Not enough space */
+#endif
+#ifndef EACCES
+#define	EACCES 13	/* Permission denied */
+#endif
+#ifndef EFAULT
+#define	EFAULT 14	/* Bad address */
+#endif
+#ifndef EBUSY
+#define	EBUSY 16	/* Device or resource busy */
+#endif
+#ifndef EEXIST
+#define	EEXIST 17	/* File exists */
+#endif
+#ifndef EXDEV
+#define	EXDEV 18	/* Cross-device link */
+#endif
+#ifndef ENODEV
+#define	ENODEV 19	/* No such device */
+#endif
+#ifndef ENOTDIR
+#define	ENOTDIR 20	/* Not a directory */
+#endif
+#ifndef EISDIR
+#define	EISDIR 21	/* Is a directory */
+#endif
+#ifndef EINVAL
+#define	EINVAL 22	/* Invalid argument */
+#endif
+#ifndef ENFILE
+#define	ENFILE 23	/* Too many open files in system */
+#endif
+#ifndef EMFILE
+#define	EMFILE 24	/* File descriptor value too large */
+#endif
+#ifndef ENOTTY
+#define	ENOTTY 25	/* Not a character device */
+#endif
+#ifndef ETXTBSY
+#define	ETXTBSY 26	/* Text file busy */
+#endif
+#ifndef EFBIG
+#define	EFBIG 27	/* File too large */
+#endif
+#ifndef ENOSPC
+#define	ENOSPC 28	/* No space left on device */
+#endif
+#ifndef ESPIPE
+#define	ESPIPE 29	/* Illegal seek */
+#endif
+#ifndef EROFS
+#define	EROFS 30	/* Read-only file system */
+#endif
+#ifndef EMLINK 
+#define	EMLINK 31	/* Too many links */
+#endif
+#ifndef EPIPE
+#define	EPIPE 32	/* Broken pipe */
+#endif
+#ifndef EDOM
+#define	EDOM 33		/* Mathematics argument out of domain of function */
+#endif
+#ifndef ERANGE
+#define	ERANGE 34	/* Result too large */
+#endif
+#ifndef ENOMSG
+#define	ENOMSG 35	/* No message of desired type */
+#endif
+#ifndef EIDRM
+#define	EIDRM 36	/* Identifier removed */
+#endif
+#ifndef EDEADLK
+#define	EDEADLK 45	/* Deadlock */
+#endif
+#ifndef ENOLCK
+#define	ENOLCK 46	/* No lock */
+#endif
+#ifndef ENOSTR
+#define ENOSTR 60	/* Not a stream */
+#endif
+#ifndef ENODATA
+#define ENODATA 61	/* No data (for no delay io) */
+#endif
+#ifndef ETIME
+#define ETIME 62	/* Stream ioctl timeout */
+#endif
+#ifndef ENOSR
+#define ENOSR 63	/* No stream resources */
+#endif
+#ifndef ENOLINK
+#define ENOLINK 67	/* Virtual circuit is gone */
+#endif
+#ifndef EPROTO
+#define EPROTO 71	/* Protocol error */
+#endif
+#ifndef EMULTIHOP
+#define	EMULTIHOP 74	/* Multihop attempted */
+#endif
+#ifndef EBADMSG
+#define EBADMSG 77	/* Bad message */
+#endif
+#ifndef EFTYPE
+#define EFTYPE 79	/* Inappropriate file type or format */
+#endif
+#ifndef ENOSYS
+#define ENOSYS 88	/* Function not implemented */
+#endif
+#ifndef ENOTEMPTY
+#define ENOTEMPTY 90	/* Directory not empty */
+#endif
+#ifndef ENAMETOOLONG
+#define ENAMETOOLONG 91	/* File or path name too long */
+#endif
+#ifndef ELOOP
+#define ELOOP 92	/* Too many symbolic links */
+#endif
+#ifndef EOPNOTSUPP
+#define EOPNOTSUPP 95	/* Operation not supported on socket */
+#endif
+#ifndef EPFNOSUPPORT
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#endif
+#ifndef ECONNRESET
+#define ECONNRESET 104  /* Connection reset by peer */
+#endif
+#ifndef ENOBUFS
+#define ENOBUFS 105	/* No buffer space available */
+#endif
+#ifndef EAFNOSUPPORT
+#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
+#endif
+#ifndef EPROTOTYPE
+#define EPROTOTYPE 107	/* Protocol wrong type for socket */
+#endif
+#ifndef ENOTSOCK
+#define ENOTSOCK 108	/* Socket operation on non-socket */
+#endif
+#ifndef ENOPROTOOPT
+#define ENOPROTOOPT 109	/* Protocol not available */
+#endif 
+#ifndef ECONNREFUSED
+#define ECONNREFUSED 111	/* Connection refused */
+#endif
+#ifndef EADDRINUSE
+#define EADDRINUSE 112		/* Address already in use */
+#endif
+#ifndef ECONNABORTED
+#define ECONNABORTED 113	/* Software caused connection abort */
+#endif
+#ifndef ENETUNREACH
+#define ENETUNREACH 114		/* Network is unreachable */
+#endif
+#ifndef ENETDOWN
+#define ENETDOWN 115		/* Network interface is not configured */
+#endif
+#ifndef ETIMEDOUT
+#define ETIMEDOUT 116		/* Connection timed out */
+#endif
+#ifndef EHOSTDOWN
+#define EHOSTDOWN 117		/* Host is down */
+#endif
+#ifndef EHOSTUNREACH
+#define EHOSTUNREACH 118	/* Host is unreachable */
+#endif
+#ifndef EINPROGRESS
+#define EINPROGRESS 119		/* Connection already in progress */
+#endif
+#ifndef EALREADY
+#define EALREADY 120		/* Socket already connected */
+#endif
+#ifndef EDESTADDRREQ
+#define EDESTADDRREQ 121	/* Destination address required */
+#endif
+#ifndef EMSGSIZE
+#define EMSGSIZE 122		/* Message too long */
+#endif
+#ifndef EPROTONOSUPPORT
+#define EPROTONOSUPPORT 123	/* Unknown protocol */
+#endif
+#ifndef EADDRNOTAVAIL
+#define EADDRNOTAVAIL 125	/* Address not available */
+#endif
+#ifndef ENETRESET
+#define ENETRESET 126		/* Connection aborted by network */
+#endif
+#ifndef EISCONN
+#define EISCONN 127		/* Socket is already connected */
+#endif
+#ifndef ENOTCONN
+#define ENOTCONN 128		/* Socket is not connected */
+#endif
+#ifndef ETOOMANYREFS
+#define ETOOMANYREFS 129
+#endif
+#ifndef EDQUOT
+#define EDQUOT 132
+#endif
+#ifndef ESTALE
+#define ESTALE 133
+#endif
+#ifndef ENOTSUP
+#define ENOTSUP 134		/* Not supported */
+#endif
+#ifndef EILSEQ
+#define EILSEQ 138		/* Illegal byte sequence */
+#endif
+#ifndef EOVERFLOW
+#define EOVERFLOW 139	/* Value too large for defined data type */
+#endif
+#ifndef ECANCELED
+#define ECANCELED 140	/* Operation canceled */
+#endif
+#ifndef ENOTRECOVERABLE
+#define ENOTRECOVERABLE 141	/* State not recoverable */
+#endif
+#ifndef EOWNERDEAD
+#define EOWNERDEAD 142	/* Previous owner died */
+#endif
+#ifndef EWOULDBLOCK
+#define EWOULDBLOCK EAGAIN	/* Operation would block */
+#endif
+
+#define __ELASTERROR 2000	/* Users can add values starting here */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ERRNO_H */

+ 137 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/compiler/mdk-arm/errno.h

@@ -0,0 +1,137 @@
+/*
+ * * Copyright (c) 2019 STMicroelectronics. All rights reserved.
+ * *
+ * * Copyright (c) 1982, 1986, 1989, 1993
+ * *	The Regents of the University of California.  All rights reserved.
+ * * Copyright (c) 1982, 1986, 1989, 1993
+ * *	The Regents of the University of California.  All rights reserved.
+ * * (c) UNIX System Laboratories, Inc.
+ * * All or some portions of this file are derived from material licensed
+ * * to the University of California by American Telephone and Telegraph
+ * * Co. or Unix System Laboratories, Inc. and are reproduced herein with
+ * * the permission of UNIX System Laboratories, Inc.
+ *
+ * * SPDX-License-Identifier: BSD-3-Clause
+ * */
+
+
+#ifndef __METAL_ERRNO__H__
+#error "Include metal/errno.h instead of metal/mdk-arm/errno.h"
+#endif
+
+#ifndef _ERRNO_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+#define _ERRNO_H_
+
+#define	EPERM 1		/* Not owner */
+#define	ENOENT 2	/* No such file or directory */
+#define	ESRCH 3		/* No such process */
+#define	EINTR 4		/* Interrupted system call */
+#define	EIO 5		/* I/O error */
+#define	ENXIO 6		/* No such device or address */
+#define	E2BIG 7		/* Arg list too long */
+#define	ENOEXEC 8	/* Exec format error */
+#define	EBADF 9		/* Bad file number */
+#define	ECHILD 10	/* No children */
+#define	EAGAIN 11	/* No more processes */
+#ifdef ENOMEM
+#undef ENOMEM
+#endif
+#define	ENOMEM 12	/* Not enough space */
+
+#define	EACCES 13	/* Permission denied */
+#define	EFAULT 14	/* Bad address */
+#define	EBUSY 16	/* Device or resource busy */
+#define	EEXIST 17	/* File exists */
+#define	EXDEV 18	/* Cross-device link */
+#define	ENODEV 19	/* No such device */
+#define	ENOTDIR 20	/* Not a directory */
+#define	EISDIR 21	/* Is a directory */
+#ifdef EINVAL
+#undef EINVAL
+#endif
+#define	EINVAL 22	/* Invalid argument */
+#define	ENFILE 23	/* Too many open files in system */
+#define	EMFILE 24	/* File descriptor value too large */
+#define	ENOTTY 25	/* Not a character device */
+#define	ETXTBSY 26	/* Text file busy */
+#define	EFBIG 27	/* File too large */
+#define	ENOSPC 28	/* No space left on device */
+#define	ESPIPE 29	/* Illegal seek */
+#define	EROFS 30	/* Read-only file system */
+#define	EMLINK 31	/* Too many links */
+#define	EPIPE 32	/* Broken pipe */
+#ifdef EDOM
+#undef EDOM
+#endif
+#define	EDOM 33		/* Mathematics argument out of domain of function */
+
+#ifdef ERANGE
+#undef ERANGE
+#endif
+#define	ERANGE 34	/* Result too large */
+
+#define	ENOMSG 35	/* No message of desired type */
+#define	EIDRM 36	/* Identifier removed */
+#define	EDEADLK 45	/* Deadlock */
+#define	ENOLCK 46	/* No lock */
+#define ENOSTR 60	/* Not a stream */
+#define ENODATA 61	/* No data (for no delay io) */
+#define ETIME 62	/* Stream ioctl timeout */
+#define ENOSR 63	/* No stream resources */
+#define ENOLINK 67	/* Virtual circuit is gone */
+#define EPROTO 71	/* Protocol error */
+#define	EMULTIHOP 74	/* Multihop attempted */
+#define EBADMSG 77	/* Bad message */
+#define EFTYPE 79	/* Inappropriate file type or format */
+#define ENOSYS 88	/* Function not implemented */
+#define ENOTEMPTY 90	/* Directory not empty */
+#define ENAMETOOLONG 91	/* File or path name too long */
+#define ELOOP 92	/* Too many symbolic links */
+#define EOPNOTSUPP 95	/* Operation not supported on socket */
+#define EPFNOSUPPORT 96 /* Protocol family not supported */
+#define ECONNRESET 104  /* Connection reset by peer */
+#define ENOBUFS 105	/* No buffer space available */
+#define EAFNOSUPPORT 106 /* Address family not supported by protocol family */
+#define EPROTOTYPE 107	/* Protocol wrong type for socket */
+#define ENOTSOCK 108	/* Socket operation on non-socket */
+#define ENOPROTOOPT 109	/* Protocol not available */
+#define ECONNREFUSED 111	/* Connection refused */
+#define EADDRINUSE 112		/* Address already in use */
+#define ECONNABORTED 113	/* Software caused connection abort */
+#define ENETUNREACH 114		/* Network is unreachable */
+#define ENETDOWN 115		/* Network interface is not configured */
+#define ETIMEDOUT 116		/* Connection timed out */
+#define EHOSTDOWN 117		/* Host is down */
+#define EHOSTUNREACH 118	/* Host is unreachable */
+#define EINPROGRESS 119		/* Connection already in progress */
+#define EALREADY 120		/* Socket already connected */
+#define EDESTADDRREQ 121	/* Destination address required */
+#define EMSGSIZE 122		/* Message too long */
+#define EPROTONOSUPPORT 123	/* Unknown protocol */
+#define EADDRNOTAVAIL 125	/* Address not available */
+#define ENETRESET 126		/* Connection aborted by network */
+#define EISCONN 127		/* Socket is already connected */
+#define ENOTCONN 128		/* Socket is not connected */
+#define ETOOMANYREFS 129
+#define EDQUOT 132
+#define ESTALE 133
+#define ENOTSUP 134		/* Not supported */
+#ifdef EILSEQ
+#undef EILSEQ
+#endif
+#define EILSEQ 138		/* Illegal byte sequence */
+#define EOVERFLOW 139	/* Value too large for defined data type */
+#define ECANCELED 140	/* Operation canceled */
+#define ENOTRECOVERABLE 141	/* State not recoverable */
+#define EOWNERDEAD 142	/* Previous owner died */
+#define EWOULDBLOCK EAGAIN	/* Operation would block */
+
+#define __ELASTERROR 2000	/* Users can add values starting here */
+
+#ifdef __cplusplus
+}
+#endif
+#endif /* _ERRNO_H */

+ 73 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/condition.h

@@ -0,0 +1,73 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	condition.h
+ * @brief	Condition variable for libmetal.
+ */
+
+#ifndef __METAL_CONDITION__H__
+#define __METAL_CONDITION__H__
+
+#include <metal/mutex.h>
+#include <metal/utilities.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup condition Condition Variable Interfaces
+ *  @{ */
+
+/** Opaque libmetal condition variable data structure. */
+struct metal_condition;
+
+/**
+ * @brief        Initialize a libmetal condition variable.
+ * @param[in]	 cv	condition variable to initialize.
+ */
+static inline void metal_condition_init(struct metal_condition *cv);
+
+/**
+ * @brief        Notify one waiter.
+ *               Before calling this function, the caller
+ *               should have acquired the mutex.
+ * @param[in]    cv    condition variable
+ * @return       zero on no errors, non-zero on errors
+ * @see metal_condition_wait, metal_condition_broadcast
+ */
+static inline int metal_condition_signal(struct metal_condition *cv);
+
+/**
+ * @brief        Notify all waiters.
+ *               Before calling this function, the caller
+ *               should have acquired the mutex.
+ * @param[in]    cv    condition variable
+ * @return       zero on no errors, non-zero on errors
+ * @see metal_condition_wait, metal_condition_signal
+ */
+static inline int metal_condition_broadcast(struct metal_condition *cv);
+
+/**
+ * @brief        Block until the condition variable is notified.
+ *               Before calling this function, the caller should
+ *               have acquired the mutex.
+ * @param[in]    cv    condition variable
+ * @param[in]    m     mutex
+ * @return	 0 on success, non-zero on failure.
+ * @see metal_condition_signal
+ */
+int metal_condition_wait(struct metal_condition *cv, metal_mutex_t *m);
+
+#include <metal/system/generic/condition.h>
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_CONDITION__H__ */

+ 50 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/config.h

@@ -0,0 +1,50 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	config.h
+ * @brief	Generated configuration settings for libmetal.
+ */
+
+#ifndef __METAL_CONFIG__H__
+#define __METAL_CONFIG__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** Library major version number. */
+#define METAL_VER_MAJOR		0
+
+/** Library minor version number. */
+#define METAL_VER_MINOR		1
+
+/** Library patch level. */
+#define METAL_VER_PATCH		0
+
+/** Library version string. */
+#define METAL_VER		"0.1.0"
+
+/** System type (linux, generic, ...). */
+#define METAL_SYSTEM		"generic"
+#define METAL_SYSTEM_GENERIC
+
+/** Processor type (arm, x86_64, ...). */
+#define METAL_PROCESSOR		"arm"
+#define METAL_PROCESSOR_ARM
+
+/** Machine type (zynq, zynqmp, ...). */
+#define METAL_MACHINE		"cortexm"
+#define METAL_MACHINE_CORTEXM
+
+#define HAVE_STDATOMIC_H
+/* #undef HAVE_FUTEX_H */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_CONFIG__H__ */

+ 17 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/cpu.h

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	cpu.h
+ * @brief	CPU primitives for libmetal.
+ */
+
+#ifndef __METAL_CPU__H__
+#define __METAL_CPU__H__
+
+# include <metal/processor/arm/cpu.h>
+
+#endif /* __METAL_CPU__H__ */

+ 176 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/device.h

@@ -0,0 +1,176 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	device.h
+ * @brief	Bus abstraction for libmetal.
+ */
+
+#ifndef __METAL_BUS__H__
+#define __METAL_BUS__H__
+
+#include <stdint.h>
+#include <metal/io.h>
+#include <metal/list.h>
+#include <metal/dma.h>
+#include <metal/sys.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup device Bus Abstraction
+ *  @{ */
+
+#ifndef METAL_MAX_DEVICE_REGIONS
+#define METAL_MAX_DEVICE_REGIONS	32
+#endif
+
+struct metal_bus;
+struct metal_device;
+
+/** Bus operations. */
+struct metal_bus_ops {
+	void		(*bus_close)(struct metal_bus *bus);
+	int		(*dev_open)(struct metal_bus *bus,
+				    const char *dev_name,
+				    struct metal_device **device);
+	void		(*dev_close)(struct metal_bus *bus,
+				     struct metal_device *device);
+	void		(*dev_irq_ack)(struct metal_bus *bus,
+				     struct metal_device *device,
+				     int irq);
+	int		(*dev_dma_map)(struct metal_bus *bus,
+				       struct metal_device *device,
+				       uint32_t dir,
+				       struct metal_sg *sg_in,
+				       int nents_in,
+				       struct metal_sg *sg_out);
+	void		(*dev_dma_unmap)(struct metal_bus *bus,
+				       struct metal_device *device,
+				       uint32_t dir,
+				       struct metal_sg *sg,
+				       int nents);
+};
+
+/** Libmetal bus structure. */
+struct metal_bus {
+	const char		*name;
+	struct metal_bus_ops	ops;
+	struct metal_list	devices;
+	struct metal_list	node;
+};
+
+/** Libmetal generic bus. */
+extern struct metal_bus metal_generic_bus;
+
+/** Libmetal device structure. */
+struct metal_device {
+	const char             *name;       /**< Device name */
+	struct metal_bus       *bus;        /**< Bus that contains device */
+	unsigned               num_regions; /**< Number of I/O regions in
+					      device */
+	struct metal_io_region regions[METAL_MAX_DEVICE_REGIONS]; /**< Array of
+                                                        I/O regions in device*/
+	struct metal_list      node;       /**< Node on bus' list of devices */
+	int                    irq_num;    /**< Number of IRQs per device */
+	void                   *irq_info;  /**< IRQ ID */
+};
+
+/**
+ * @brief	Register a libmetal bus.
+ * @param[in]	bus	Pre-initialized bus structure.
+ * @return 0 on success, or -errno on failure.
+ */
+extern int metal_bus_register(struct metal_bus *bus);
+
+/**
+ * @brief	Unregister a libmetal bus.
+ * @param[in]	bus	Pre-registered bus structure.
+ * @return 0 on success, or -errno on failure.
+ */
+extern int metal_bus_unregister(struct metal_bus *bus);
+
+/**
+ * @brief	Find a libmetal bus by name.
+ * @param[in]	name	Bus name.
+ * @param[out]	bus	Returned bus handle.
+ * @return 0 on success, or -errno on failure.
+ */
+extern int metal_bus_find(const char *name, struct metal_bus **bus);
+
+/**
+ * @brief	Statically register a generic libmetal device.
+ *
+ * In non-Linux systems, devices are always required to be statically
+ * registered at application initialization.
+ * In Linux system, devices can be dynamically opened via sysfs or libfdt based
+ * enumeration at runtime.
+ * This interface is used for static registration of devices. Subsequent calls
+ * to metal_device_open() look up in this list of pre-registered devices on the
+ * "generic" bus.
+ * "generic" bus is used on non-Linux system to group the memory mapped devices.
+ *
+ * @param[in]	device	Generic device.
+ * @return 0 on success, or -errno on failure.
+ */
+extern int metal_register_generic_device(struct metal_device *device);
+
+/**
+ * @brief	Open a libmetal device by name.
+ * @param[in]	bus_name	Bus name.
+ * @param[in]	dev_name	Device name.
+ * @param[out]	device		Returned device handle.
+ * @return 0 on success, or -errno on failure.
+ */
+extern int metal_device_open(const char *bus_name, const char *dev_name,
+			     struct metal_device **device);
+
+/**
+ * @brief	Close a libmetal device.
+ * @param[in]	device		Device handle.
+ */
+extern void metal_device_close(struct metal_device *device);
+
+/**
+ * @brief	Get an I/O region accessor for a device region.
+ *
+ * @param[in]	device		Device handle.
+ * @param[in]	index		Region index.
+ * @return I/O accessor handle, or NULL on failure.
+ */
+static inline struct metal_io_region *
+metal_device_io_region(struct metal_device *device, unsigned index)
+{
+	return (index < device->num_regions
+		? &device->regions[index]
+		: NULL);
+}
+
+/** @} */
+
+#ifdef METAL_INTERNAL
+extern int metal_generic_dev_sys_open(struct metal_device *dev);
+extern int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name,
+				  struct metal_device **device);
+extern int metal_generic_dev_dma_map(struct metal_bus *bus,
+				     struct metal_device *device,
+				     uint32_t dir,
+				     struct metal_sg *sg_in,
+				     int nents_in,
+				     struct metal_sg *sg_out);
+extern void metal_generic_dev_dma_unmap(struct metal_bus *bus,
+					struct metal_device *device,
+					uint32_t dir,
+					struct metal_sg *sg,
+					int nents);
+#endif /* METAL_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_BUS__H__ */

+ 79 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/dma.h

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	dma.h
+ * @brief	DMA primitives for libmetal.
+ */
+
+#ifndef __METAL_DMA__H__
+#define __METAL_DMA__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup dma DMA Interfaces
+ *  @{ */
+
+#include <stdint.h>
+#include <metal/sys.h>
+
+#define METAL_DMA_DEV_R  1 /**< DMA direction, device read */
+#define METAL_DMA_DEV_W  2 /**< DMA direction, device write */
+#define METAL_DMA_DEV_WR 3 /**< DMA direction, device read/write */
+
+/**
+ * @brief scatter/gather list element structure
+ */
+struct metal_sg {
+	void *virt; /**< CPU virtual address */
+	struct metal_io_region *io; /**< IO region */
+	int len; /**< length */
+};
+
+struct metal_device;
+
+/**
+ * @brief      Map memory for DMA transaction.
+ *             After the memory is DMA mapped, the memory should be
+ *             accessed by the DMA device but not the CPU.
+ *
+ * @param[in]  dev       DMA device
+ * @param[in]  dir       DMA direction
+ * @param[in]  sg_in     sg list of memory to map
+ * @param[in]  nents_in  number of sg list entries of memory to map
+ * @param[out] sg_out    sg list of mapped memory
+ * @return     number of mapped sg entries, -error on failure.
+ */
+int metal_dma_map(struct metal_device *dev,
+		  uint32_t dir,
+		  struct metal_sg *sg_in,
+		  int nents_in,
+		  struct metal_sg *sg_out);
+
+/**
+ * @brief      Unmap DMA memory
+ *             After the memory is DMA unmapped, the memory should
+ *             be accessed by the CPU but not the DMA device.
+ *
+ * @param[in]  dev       DMA device
+ * @param[in]  dir       DMA direction
+ * @param[in]  sg        sg list of mapped DMA memory
+ * @param[in]  nents     number of sg list entries of DMA memory
+ */
+void metal_dma_unmap(struct metal_device *dev,
+		  uint32_t dir,
+		  struct metal_sg *sg,
+		  int nents);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_DMA__H__ */

+ 24 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/errno.h

@@ -0,0 +1,24 @@
+/*
+ * * Copyright (c) 2019 STMicrolectonics , Xilinx Inc. and Contributors. All rights reserved.
+ * *
+ * * SPDX-License-Identifier: BSD-3-Clause
+ * */
+
+/*
+ * * @file      metal/errno.h
+ * * @brief     error specific primitives for libmetal.
+ * */
+
+#ifndef __METAL_ERRNO__H__
+#define __METAL_ERRNO__H__
+
+#if defined (__CC_ARM)
+# include <metal/compiler/mdk-arm/errno.h>
+#elif defined (__ICCARM__)
+# include <metal/compiler/iar/errno.h>
+#else
+#include <errno.h>
+#endif
+
+#endif /* __METAL_ERRNO__H__ */
+

+ 354 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/io.h

@@ -0,0 +1,354 @@
+/*
+ * Copyright (c) 2015 - 2017, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	io.h
+ * @brief	I/O access primitives for libmetal.
+ */
+
+#ifndef __METAL_IO__H__
+#define __METAL_IO__H__
+
+#include <limits.h>
+#include <stdint.h>
+#include <string.h>
+#include <stdlib.h>
+#include <metal/assert.h>
+#include <metal/compiler.h>
+#include <metal/atomic.h>
+#include <metal/sys.h>
+#include <metal/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup io IO Interfaces
+ *  @{ */
+
+#ifdef __MICROBLAZE__
+#define NO_ATOMIC_64_SUPPORT
+#endif
+
+struct metal_io_region;
+
+/** Generic I/O operations. */
+struct metal_io_ops {
+	uint64_t	(*read)(struct metal_io_region *io,
+				unsigned long offset,
+				memory_order order,
+				int width);
+	void		(*write)(struct metal_io_region *io,
+				 unsigned long offset,
+				 uint64_t value,
+				 memory_order order,
+				 int width);
+	int		(*block_read)(struct metal_io_region *io,
+				unsigned long offset,
+				void *restrict dst,
+				memory_order order,
+				int len);
+	int		(*block_write)(struct metal_io_region *io,
+				 unsigned long offset,
+				 const void *restrict src,
+				 memory_order order,
+				 int len);
+	void		(*block_set)(struct metal_io_region *io,
+				 unsigned long offset,
+				 unsigned char value,
+				 memory_order order,
+				 int len);
+	void		(*close)(struct metal_io_region *io);
+};
+
+/** Libmetal I/O region structure. */
+struct metal_io_region {
+	void			*virt;      /**< base virtual address */
+	const metal_phys_addr_t	*physmap;   /**< table of base physical address
+                                                 of each of the pages in the I/O
+                                                 region */
+	size_t			size;       /**< size of the I/O region */
+	unsigned long		page_shift; /**< page shift of I/O region */
+	metal_phys_addr_t	page_mask;  /**< page mask of I/O region */
+	unsigned int		mem_flags;  /**< memory attribute of the
+						 I/O region */
+	struct metal_io_ops	ops;        /**< I/O region operations */
+};
+
+/**
+ * @brief	Open a libmetal I/O region.
+ *
+ * @param[in, out]	io		I/O region handle.
+ * @param[in]		virt		Virtual address of region.
+ * @param[in]		physmap		Array of physical addresses per page.
+ * @param[in]		size		Size of region.
+ * @param[in]		page_shift	Log2 of page size (-1 for single page).
+ * @param[in]		mem_flags	Memory flags
+ * @param[in]		ops			ops
+ */
+void
+metal_io_init(struct metal_io_region *io, void *virt,
+	      const metal_phys_addr_t *physmap, size_t size,
+	      unsigned page_shift, unsigned int mem_flags,
+	      const struct metal_io_ops *ops);
+
+/**
+ * @brief	Close a libmetal shared memory segment.
+ * @param[in]	io	I/O region handle.
+ */
+static inline void metal_io_finish(struct metal_io_region *io)
+{
+	if (io->ops.close)
+		(*io->ops.close)(io);
+	memset(io, 0, sizeof(*io));
+}
+
+/**
+ * @brief	Get size of I/O region.
+ *
+ * @param[in]	io	I/O region handle.
+ * @return	Size of I/O region.
+ */
+static inline size_t metal_io_region_size(struct metal_io_region *io)
+{
+	return io->size;
+}
+
+/**
+ * @brief	Get virtual address for a given offset into the I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	offset	Offset into shared memory segment.
+ * @return	NULL if offset is out of range, or pointer to offset.
+ */
+static inline void *
+metal_io_virt(struct metal_io_region *io, unsigned long offset)
+{
+	return (io->virt != METAL_BAD_VA && offset <= io->size
+		? (uint8_t *)io->virt + offset
+		: NULL);
+}
+
+/**
+ * @brief	Convert a virtual address to offset within I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	virt	Virtual address within segment.
+ * @return	METAL_BAD_OFFSET if out of range, or offset.
+ */
+static inline unsigned long
+metal_io_virt_to_offset(struct metal_io_region *io, void *virt)
+{
+	size_t offset = (uint8_t *)virt - (uint8_t *)io->virt;
+	return (offset < io->size ? offset : METAL_BAD_OFFSET);
+}
+
+/**
+ * @brief	Get physical address for a given offset into the I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	offset	Offset into shared memory segment.
+ * @return	METAL_BAD_PHYS if offset is out of range, or physical address
+ *		of offset.
+ */
+static inline metal_phys_addr_t
+metal_io_phys(struct metal_io_region *io, unsigned long offset)
+{
+	unsigned long page = (io->page_shift >=
+			     sizeof(offset) * CHAR_BIT ?
+			     0 : offset >> io->page_shift);
+	return (io->physmap != NULL && offset <= io->size
+		? io->physmap[page] + (offset & io->page_mask)
+		: METAL_BAD_PHYS);
+}
+
+/**
+ * @brief	Convert a physical address to offset within I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	phys	Physical address within segment.
+ * @return	METAL_BAD_OFFSET if out of range, or offset.
+ */
+static inline unsigned long
+metal_io_phys_to_offset(struct metal_io_region *io, metal_phys_addr_t phys)
+{
+	unsigned long offset =
+		(io->page_mask == (metal_phys_addr_t)(-1) ?
+		phys - io->physmap[0] :  phys & io->page_mask);
+	do {
+		if (metal_io_phys(io, offset) == phys)
+			return offset;
+		offset += io->page_mask + 1;
+	} while (offset < io->size);
+	return METAL_BAD_OFFSET;
+}
+
+/**
+ * @brief	Convert a physical address to virtual address.
+ * @param[in]	io	Shared memory segment handle.
+ * @param[in]	phys	Physical address within segment.
+ * @return	NULL if out of range, or corresponding virtual address.
+ */
+static inline void *
+metal_io_phys_to_virt(struct metal_io_region *io, metal_phys_addr_t phys)
+{
+	return metal_io_virt(io, metal_io_phys_to_offset(io, phys));
+}
+
+/**
+ * @brief	Convert a virtual address to physical address.
+ * @param[in]	io	Shared memory segment handle.
+ * @param[in]	virt	Virtual address within segment.
+ * @return	METAL_BAD_PHYS if out of range, or corresponding
+ *		physical address.
+ */
+static inline metal_phys_addr_t
+metal_io_virt_to_phys(struct metal_io_region *io, void *virt)
+{
+	return metal_io_phys(io, metal_io_virt_to_offset(io, virt));
+}
+
+/**
+ * @brief	Read a value from an I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	offset	Offset into I/O region.
+ * @param[in]	order	Memory ordering.
+ * @param[in]	width	Width in bytes of datatype to read.  This must be 1, 2,
+ *			4, or 8, and a compile time constant for this function
+ *			to inline cleanly.
+ * @return	Value.
+ */
+static inline uint64_t
+metal_io_read(struct metal_io_region *io, unsigned long offset,
+	      memory_order order, int width)
+{
+	void *ptr = metal_io_virt(io, offset);
+
+	if (io->ops.read)
+		return (*io->ops.read)(io, offset, order, width);
+	else if (ptr && sizeof(atomic_uchar) == width)
+		return atomic_load_explicit((atomic_uchar *)ptr, order);
+	else if (ptr && sizeof(atomic_ushort) == width)
+		return atomic_load_explicit((atomic_ushort *)ptr, order);
+	else if (ptr && sizeof(atomic_uint) == width)
+		return atomic_load_explicit((atomic_uint *)ptr, order);
+	else if (ptr && sizeof(atomic_ulong) == width)
+		return atomic_load_explicit((atomic_ulong *)ptr, order);
+#ifndef NO_ATOMIC_64_SUPPORT
+	else if (ptr && sizeof(atomic_ullong) == width)
+		return atomic_load_explicit((atomic_ullong *)ptr, order);
+#endif
+	metal_assert(0);
+	return 0; /* quiet compiler */
+}
+
+/**
+ * @brief	Write a value into an I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	offset	Offset into I/O region.
+ * @param[in]	value	Value to write.
+ * @param[in]	order	Memory ordering.
+ * @param[in]	width	Width in bytes of datatype to read.  This must be 1, 2,
+ *			4, or 8, and a compile time constant for this function
+ *			to inline cleanly.
+ */
+static inline void
+metal_io_write(struct metal_io_region *io, unsigned long offset,
+	       uint64_t value, memory_order order, int width)
+{
+	void *ptr = metal_io_virt(io, offset);
+	if (io->ops.write)
+		(*io->ops.write)(io, offset, value, order, width);
+	else if (ptr && sizeof(atomic_uchar) == width)
+		atomic_store_explicit((atomic_uchar *)ptr, value, order);
+	else if (ptr && sizeof(atomic_ushort) == width)
+		atomic_store_explicit((atomic_ushort *)ptr, value, order);
+	else if (ptr && sizeof(atomic_uint) == width)
+		atomic_store_explicit((atomic_uint *)ptr, value, order);
+	else if (ptr && sizeof(atomic_ulong) == width)
+		atomic_store_explicit((atomic_ulong *)ptr, value, order);
+#ifndef NO_ATOMIC_64_SUPPORT
+	else if (ptr && sizeof(atomic_ullong) == width)
+		atomic_store_explicit((atomic_ullong *)ptr, value, order);
+#endif
+	else
+		metal_assert (0);
+}
+
+#define metal_io_read8_explicit(_io, _ofs, _order)			\
+	metal_io_read((_io), (_ofs), (_order), 1)
+#define metal_io_read8(_io, _ofs)					\
+	metal_io_read((_io), (_ofs), memory_order_seq_cst, 1)
+#define metal_io_write8_explicit(_io, _ofs, _val, _order)		\
+	metal_io_write((_io), (_ofs), (_val), (_order), 1)
+#define metal_io_write8(_io, _ofs, _val)				\
+	metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 1)
+
+#define metal_io_read16_explicit(_io, _ofs, _order)			\
+	metal_io_read((_io), (_ofs), (_order), 2)
+#define metal_io_read16(_io, _ofs)					\
+	metal_io_read((_io), (_ofs), memory_order_seq_cst, 2)
+#define metal_io_write16_explicit(_io, _ofs, _val, _order)		\
+	metal_io_write((_io), (_ofs), (_val), (_order), 2)
+#define metal_io_write16(_io, _ofs, _val)				\
+	metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 2)
+
+#define metal_io_read32_explicit(_io, _ofs, _order)			\
+	metal_io_read((_io), (_ofs), (_order), 4)
+#define metal_io_read32(_io, _ofs)					\
+	metal_io_read((_io), (_ofs), memory_order_seq_cst, 4)
+#define metal_io_write32_explicit(_io, _ofs, _val, _order)		\
+	metal_io_write((_io), (_ofs), (_val), (_order), 4)
+#define metal_io_write32(_io, _ofs, _val)				\
+	metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 4)
+
+#define metal_io_read64_explicit(_io, _ofs, _order)			\
+	metal_io_read((_io), (_ofs), (_order), 8)
+#define metal_io_read64(_io, _ofs)					\
+	metal_io_read((_io), (_ofs), memory_order_seq_cst, 8)
+#define metal_io_write64_explicit(_io, _ofs, _val, _order)		\
+	metal_io_write((_io), (_ofs), (_val), (_order), 8)
+#define metal_io_write64(_io, _ofs, _val)				\
+	metal_io_write((_io), (_ofs), (_val), memory_order_seq_cst, 8)
+
+/**
+ * @brief	Read a block from an I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	offset	Offset into I/O region.
+ * @param[in]	dst	destination to store the read data.
+ * @param[in]	len	length in bytes to read.
+ * @return      On success, number of bytes read. On failure, negative value
+ */
+int metal_io_block_read(struct metal_io_region *io, unsigned long offset,
+	       void *restrict dst, int len);
+
+/**
+ * @brief	Write a block into an I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	offset	Offset into I/O region.
+ * @param[in]	src	source to write.
+ * @param[in]	len	length in bytes to write.
+ * @return      On success, number of bytes written. On failure, negative value
+ */
+int metal_io_block_write(struct metal_io_region *io, unsigned long offset,
+	       const void *restrict src, int len);
+
+/**
+ * @brief	fill a block of an I/O region.
+ * @param[in]	io	I/O region handle.
+ * @param[in]	offset	Offset into I/O region.
+ * @param[in]	value	value to fill into the block
+ * @param[in]	len	length in bytes to fill.
+ * @return      On success, number of bytes filled. On failure, negative value
+ */
+int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
+	       unsigned char value, int len);
+
+#include <metal/system/generic/io.h>
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_IO__H__ */

+ 116 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/irq.h

@@ -0,0 +1,116 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	irq.h
+ * @brief	Interrupt handling primitives for libmetal.
+ */
+
+#ifndef __METAL_IRQ__H__
+#define __METAL_IRQ__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup irq Interrupt Handling Interfaces
+ *  @{ */
+
+#include <stdlib.h>
+
+/** IRQ handled status */
+#define METAL_IRQ_NOT_HANDLED 0
+#define METAL_IRQ_HANDLED     1
+
+/**
+ * @brief	type of interrupt handler
+ * @param[in]   irq interrupt id
+ * @param[in]	priv private data
+ * @return      irq handled status
+ */
+typedef int (*metal_irq_handler) (int irq, void *priv);
+
+struct metal_device;
+
+/**
+ * @brief      Register interrupt handler for driver ID/device.
+ *
+ * @param[in]  irq         interrupt id
+ * @param[in]  irq_handler interrupt handler
+ * @param[in]  dev         metal device this irq belongs to (can be NULL).
+ * @param[in]  drv_id      driver id is a unique interrupt handler identifier.
+ *                         It can also be used for driver data.
+ * @return     0 for success, non-zero on failure
+ */
+int metal_irq_register(int irq,
+		       metal_irq_handler irq_handler,
+		       struct metal_device *dev,
+		       void *drv_id);
+
+/**
+ * @brief      Unregister interrupt handler for driver ID and/or device.
+ *
+ *             If interrupt handler (hd), driver ID (drv_id) and device (dev)
+ *             are NULL, unregister all handlers for this interrupt.
+ *
+ *             If interrupt handler (hd), device (dev) or driver ID (drv_id),
+ *             are not NULL, unregister handlers matching non NULL criterias.
+ *             e.g: when call is made with drv_id and dev non NULL,
+ *             all handlers matching both are unregistered.
+ *
+ *             If interrupt is not found, or other criterias not matching,
+ *             return -ENOENT
+ *
+ * @param[in]  irq         interrupt id
+ * @param[in]  irq_handler interrupt handler
+ * @param[in]  dev         metal device this irq belongs to
+ * @param[in]  drv_id      driver id. It can be used for driver data.
+ * @return     0 for success, non-zero on failure
+ */
+int metal_irq_unregister(int irq,
+			metal_irq_handler irq_handler,
+			struct metal_device *dev,
+			void *drv_id);
+
+/**
+ * @brief      disable interrupts
+ * @return     interrupts state
+ */
+unsigned int metal_irq_save_disable(void);
+
+/**
+ * @brief      restore interrupts to their previous state
+ * @param[in]  flags previous interrupts state
+ */
+void metal_irq_restore_enable(unsigned int flags);
+
+/**
+ * @brief	metal_irq_enable
+ *
+ * Enables the given interrupt
+ *
+ * @param vector   - interrupt vector number
+ */
+void metal_irq_enable(unsigned int vector);
+
+/**
+ * @brief	metal_irq_disable
+ *
+ * Disables the given interrupt
+ *
+ * @param vector   - interrupt vector number
+ */
+void metal_irq_disable(unsigned int vector);
+
+#include <metal/system/generic/irq.h>
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_IRQ__H__ */

+ 102 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/list.h

@@ -0,0 +1,102 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	list.h
+ * @brief	List primitives for libmetal.
+ */
+
+#ifndef __METAL_LIST__H__
+#define __METAL_LIST__H__
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup list List Primitives
+ *  @{ */
+
+struct metal_list {
+	struct metal_list *next, *prev;
+};
+
+/*
+ * METAL_INIT_LIST - used for initializing an list elmenet in a static struct
+ * or global
+ */
+#define METAL_INIT_LIST(name) { .next = &name, .prev = &name }
+/*
+ * METAL_DECLARE_LIST - used for defining and initializing a global or
+ * static singleton list
+ */
+#define METAL_DECLARE_LIST(name)			\
+	struct metal_list name = METAL_INIT_LIST(name)
+
+static inline void metal_list_init(struct metal_list *list)
+{
+	list->next = list->prev = list;
+}
+
+static inline void metal_list_add_before(struct metal_list *node,
+					 struct metal_list *new_node)
+{
+	new_node->prev = node->prev;
+	new_node->next = node;
+	new_node->next->prev = new_node;
+	new_node->prev->next = new_node;
+}
+
+static inline void metal_list_add_after(struct metal_list *node,
+					struct metal_list *new_node)
+{
+	new_node->prev = node;
+	new_node->next = node->next;
+	new_node->next->prev = new_node;
+	new_node->prev->next = new_node;
+}
+
+static inline void metal_list_add_head(struct metal_list *list,
+				       struct metal_list *node)
+{
+	metal_list_add_after(list, node);
+}
+
+static inline void metal_list_add_tail(struct metal_list *list,
+				       struct metal_list *node)
+{
+	metal_list_add_before(list, node);
+}
+
+static inline int metal_list_is_empty(struct metal_list *list)
+{
+	return list->next == list;
+}
+
+static inline void metal_list_del(struct metal_list *node)
+{
+	node->next->prev = node->prev;
+	node->prev->next = node->next;
+	node->next = node->prev = node;
+}
+
+static inline struct metal_list *metal_list_first(struct metal_list *list)
+{
+	return metal_list_is_empty(list) ? NULL : list->next;
+}
+
+#define metal_list_for_each(list, node)		\
+	for ((node) = (list)->next;		\
+	     (node) != (list);			\
+	     (node) = (node)->next)
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_LIST__H__ */

+ 93 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/log.h

@@ -0,0 +1,93 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	log.h
+ * @brief	Logging support for libmetal.
+ */
+
+#ifndef __METAL_METAL_LOG__H__
+#define __METAL_METAL_LOG__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup logging Library Logging Interfaces
+ *  @{ */
+
+/** Log message priority levels for libmetal. */
+enum metal_log_level {
+	METAL_LOG_EMERGENCY,	/**< system is unusable.               */
+	METAL_LOG_ALERT,	/**< action must be taken immediately. */
+	METAL_LOG_CRITICAL,	/**< critical conditions.              */
+	METAL_LOG_ERROR,	/**< error conditions.                 */
+	METAL_LOG_WARNING,	/**< warning conditions.               */
+	METAL_LOG_NOTICE,	/**< normal but significant condition. */
+	METAL_LOG_INFO,		/**< informational messages.           */
+	METAL_LOG_DEBUG,	/**< debug-level messages.             */
+};
+
+/** Log message handler type. */
+typedef void (*metal_log_handler)(enum metal_log_level level,
+				  const char *format, ...);
+
+/**
+ * @brief	Set libmetal log handler.
+ * @param[in]	handler	log message handler.
+ * @return	0 on success, or -errno on failure.
+ */
+extern void metal_set_log_handler(metal_log_handler handler);
+
+/**
+ * @brief	Get the current libmetal log handler.
+ * @return	Current log handler.
+ */
+extern metal_log_handler metal_get_log_handler(void);
+
+/**
+ * @brief	Set the level for libmetal logging.
+ * @param[in]	level	log message level.
+ */
+extern void metal_set_log_level(enum metal_log_level level);
+
+/**
+ * @brief	Get the current level for libmetal logging.
+ * @return	Current log level.
+ */
+extern enum metal_log_level metal_get_log_level(void);
+
+/**
+ * @brief	Default libmetal log handler.  This handler prints libmetal log
+ *		mesages to stderr.
+ * @param[in]	level	log message level.
+ * @param[in]	format	log message format string.
+ * @return	0 on success, or -errno on failure.
+ */
+extern void metal_default_log_handler(enum metal_log_level level,
+				      const char *format, ...);
+
+
+/**
+ * Emit a log message if the log level permits.
+ *
+ * @param	level	Log level.
+ * @param	...	Format string and arguments.
+ */
+#define metal_log(level, ...)						       \
+	((level <= _metal.common.log_level && _metal.common.log_handler) \
+	       ? (void)_metal.common.log_handler(level, __VA_ARGS__)	       \
+	       : (void)0)
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#include <metal/system/generic/log.h>
+
+#endif /* __METAL_METAL_LOG__H__ */

+ 87 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/mutex.h

@@ -0,0 +1,87 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	mutex.h
+ * @brief	Mutex primitives for libmetal.
+ */
+
+#ifndef __METAL_MUTEX__H__
+#define __METAL_MUTEX__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup mutex Mutex Interfaces
+ *  @{ */
+
+#include <metal/system/generic/mutex.h>
+
+/**
+ * @brief	Initialize a libmetal mutex.
+ * @param[in]	mutex	Mutex to initialize.
+ */
+static inline void metal_mutex_init(metal_mutex_t *mutex)
+{
+	__metal_mutex_init(mutex);
+}
+
+/**
+ * @brief	Deinitialize a libmetal mutex.
+ * @param[in]	mutex	Mutex to deinitialize.
+ */
+static inline void metal_mutex_deinit(metal_mutex_t *mutex)
+{
+	__metal_mutex_deinit(mutex);
+}
+
+/**
+ * @brief	Try to acquire a mutex
+ * @param[in]	mutex	Mutex to mutex.
+ * @return	0 on failure to acquire, non-zero on success.
+ */
+static inline int metal_mutex_try_acquire(metal_mutex_t *mutex)
+{
+	return __metal_mutex_try_acquire(mutex);
+}
+
+/**
+ * @brief	Acquire a mutex
+ * @param[in]	mutex	Mutex to mutex.
+ */
+static inline void metal_mutex_acquire(metal_mutex_t *mutex)
+{
+	__metal_mutex_acquire(mutex);
+}
+
+/**
+ * @brief	Release a previously acquired mutex.
+ * @param[in]	mutex	Mutex to mutex.
+ * @see metal_mutex_try_acquire, metal_mutex_acquire
+ */
+static inline void metal_mutex_release(metal_mutex_t *mutex)
+{
+	__metal_mutex_release(mutex);
+}
+
+/**
+ * @brief	Checked if a mutex has been acquired.
+ * @param[in]	mutex	mutex to check.
+ * @see metal_mutex_try_acquire, metal_mutex_acquire
+ */
+static inline int metal_mutex_is_acquired(metal_mutex_t *mutex)
+{
+	return __metal_mutex_is_acquired(mutex);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_MUTEX__H__ */

+ 15 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/processor/arm/atomic.h

@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	arm/atomic.h
+ * @brief   ARM specific atomic primitives for libmetal.
+ */
+
+#ifndef __METAL_ARM_ATOMIC__H__
+#define __METAL_ARM_ATOMIC__H__
+
+#endif /* __METAL_ARM_ATOMIC__H__ */

+ 17 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/processor/arm/cpu.h

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	cpu.h
+ * @brief	CPU specific primatives
+ */
+
+#ifndef __METAL_ARM_CPU__H__
+#define __METAL_ARM_CPU__H__
+
+#define metal_cpu_yield()
+
+#endif /* __METAL_ARM_CPU__H__ */

+ 83 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/shmem.h

@@ -0,0 +1,83 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	shmem.h
+ * @brief	Shared memory primitives for libmetal.
+ */
+
+#ifndef __METAL_SHMEM__H__
+#define __METAL_SHMEM__H__
+
+#include <metal/io.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup shmem Shared Memory Interfaces
+ *  @{ */
+
+/** Generic shared memory data structure. */
+struct metal_generic_shmem {
+	const char		*name;
+	struct metal_io_region	io;
+	struct metal_list	node;
+};
+
+/**
+ * @brief	Open a libmetal shared memory segment.
+ *
+ * Open a shared memory segment.
+ *
+ * @param[in]		name	Name of segment to open.
+ * @param[in]		size	Size of segment.
+ * @param[out]		io	I/O region handle, if successful.
+ * @return	0 on success, or -errno on failure.
+ *
+ * @see metal_shmem_create
+ */
+extern int metal_shmem_open(const char *name, size_t size,
+			    struct metal_io_region **io);
+
+/**
+ * @brief	Statically register a generic shared memory region.
+ *
+ * Shared memory regions may be statically registered at application
+ * initialization, or may be dynamically opened.  This interface is used for
+ * static registration of regions.  Subsequent calls to metal_shmem_open() look
+ * up in this list of pre-registered regions.
+ *
+ * @param[in]	shmem	Generic shmem structure.
+ * @return 0 on success, or -errno on failure.
+ */
+extern int metal_shmem_register_generic(struct metal_generic_shmem *shmem);
+
+#ifdef METAL_INTERNAL
+
+/**
+ * @brief	Open a statically registered shmem segment.
+ *
+ * This interface is meant for internal libmetal use within system specific
+ * shmem implementations.
+ *
+ * @param[in]		name	Name of segment to open.
+ * @param[in]		size	Size of segment.
+ * @param[out]		io	I/O region handle, if successful.
+ * @return	0 on success, or -errno on failure.
+ */
+int metal_shmem_open_generic(const char *name, size_t size,
+			     struct metal_io_region **result);
+
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_SHMEM__H__ */

+ 44 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/sleep.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	sleep.h
+ * @brief	Sleep primitives for libmetal.
+ */
+
+#ifndef __METAL_SLEEP__H__
+#define __METAL_SLEEP__H__
+
+#include <metal/system/generic/sleep.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup sleep Sleep Interfaces
+ *  @{ */
+
+/**
+ * @brief      delay in microseconds
+ *             delay the next execution in the calling thread
+ *             fo usec microseconds.
+ *
+ * @param[in]  usec      microsecond intervals
+ * @return     0 on success, non-zero for failures
+ */
+static inline int metal_sleep_usec(unsigned int usec)
+{
+	return __metal_sleep_usec(usec);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_SLEEP__H__ */
+

+ 71 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/spinlock.h

@@ -0,0 +1,71 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	spinlock.h
+ * @brief	Spinlock primitives for libmetal.
+ */
+
+#ifndef __METAL_SPINLOCK__H__
+#define __METAL_SPINLOCK__H__
+
+#include <metal/atomic.h>
+#include <metal/cpu.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup spinlock Spinlock Interfaces
+ *  @{ */
+struct metal_spinlock {
+	union{
+		atomic_int v;
+		atomic_flag w;
+	};
+};
+
+/** Static metal spinlock initialization. */
+#define METAL_SPINLOCK_INIT		{ATOMIC_VAR_INIT(0)}
+
+/**
+ * @brief	Initialize a libmetal spinlock.
+ * @param[in]	slock	Spinlock to initialize.
+ */
+static inline void metal_spinlock_init(struct metal_spinlock *slock)
+{
+	atomic_store(&slock->v, 0);
+}
+
+/**
+ * @brief	Acquire a spinlock.
+ * @param[in]	slock   Spinlock to acquire.
+ * @see metal_spinlock_release
+ */
+static inline void metal_spinlock_acquire(struct metal_spinlock *slock)
+{
+	while (atomic_flag_test_and_set(&slock->w)) {
+		metal_cpu_yield();
+	}
+}
+
+/**
+ * @brief	Release a previously acquired spinlock.
+ * @param[in]	slock	Spinlock to release.
+ * @see metal_spinlock_acquire
+ */
+static inline void metal_spinlock_release(struct metal_spinlock *slock)
+{
+	atomic_flag_clear(&slock->w);
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_SPINLOCK__H__ */

+ 148 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/sys.h

@@ -0,0 +1,148 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	sys.h
+ * @brief	System primitives for libmetal.
+ * @brief	Top level include internal to libmetal library code.
+ */
+
+#ifndef __METAL_SYS__H__
+#define __METAL_SYS__H__
+
+#include <stdlib.h>
+
+#include <metal/log.h>
+#include <metal/list.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup system Top Level Interfaces
+ *  @{ */
+
+/** Physical address type. */
+typedef unsigned long metal_phys_addr_t;
+
+/** Interrupt request number. */
+typedef int metal_irq_t;
+
+/** Bad offset into shared memory or I/O region. */
+#define METAL_BAD_OFFSET	((unsigned long)-1)
+
+/** Bad physical address value. */
+#define METAL_BAD_PHYS		((metal_phys_addr_t)-1)
+
+/** Bad virtual address value. */
+#define METAL_BAD_VA		((void *)-1)
+
+/** Bad IRQ. */
+#define METAL_BAD_IRQ		((metal_irq_t)-1)
+
+/**
+ * Initialization configuration for libmetal.
+ */
+struct metal_init_params {
+
+	/** log message handler (defaults to stderr). */
+	metal_log_handler		log_handler;
+
+	/** default log message level (defaults to emergency). */
+	enum metal_log_level		log_level;
+};
+
+/**
+ * System independent runtime state for libmetal.  This is part of a system
+ * specific singleton data structure (@see _metal).
+ */
+struct metal_common_state {
+	/** Current log level. */
+	enum metal_log_level		log_level;
+
+	/** Current log handler (null for none). */
+	metal_log_handler		log_handler;
+
+	/** List of registered buses. */
+	struct metal_list		bus_list;
+
+	/** Generic statically defined shared memory segments. */
+	struct metal_list		generic_shmem_list;
+
+	/** Generic statically defined devices. */
+	struct metal_list		generic_device_list;
+};
+
+struct metal_state;
+
+#include <metal/system/generic/sys.h>
+
+#ifndef METAL_INIT_DEFAULTS
+#define METAL_INIT_DEFAULTS				\
+{							\
+	.log_handler	= metal_default_log_handler,	\
+	.log_level	= METAL_LOG_INFO,		\
+}
+#endif
+
+/** System specific runtime data. */
+extern struct metal_state _metal;
+
+/**
+ * @brief	Initialize libmetal.
+ *
+ * Initialize the libmetal library.
+ *
+ * @param[in]	params	Initialization params (@see metal_init_params).
+ *
+ * @return	0 on success, or -errno on failure.
+ *
+ * @see metal_finish
+ */
+extern int metal_init(const struct metal_init_params *params);
+
+/**
+ * @brief	Shutdown libmetal.
+ *
+ * Shutdown the libmetal library, and release all reserved resources.
+ *
+ * @see metal_init
+ */
+extern void metal_finish(void);
+
+#ifdef METAL_INTERNAL
+
+/**
+ * @brief	libmetal system initialization.
+ *
+ * This function initializes libmetal on Linux or Generic platforms.  This
+ * involves obtaining necessary pieces of system information (sysfs mount path,
+ * page size, etc.).
+ *
+ * @param[in]	params	Initialization parameters (@see metal_init_params).
+ * @return	0 on success, or -errno on failure.
+ */
+extern int metal_sys_init(const struct metal_init_params *params);
+
+/**
+ * @brief	libmetal system shutdown.
+ *
+ * This function shuts down and releases resources held by libmetal Linux or
+ * Generic platform layers.
+ *
+ * @see metal_sys_init
+ */
+extern void metal_sys_finish(void);
+
+#endif
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_SYS__H__ */

+ 39 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/alloc.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/alloc.c
+ * @brief	generic libmetal memory allocattion definitions.
+ */
+
+#ifndef __METAL_ALLOC__H__
+#error "Include metal/alloc.h instead of metal/generic/alloc.h"
+#endif
+
+#ifndef __METAL_GENERIC_ALLOC__H__
+#define __METAL_GENERIC_ALLOC__H__
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline void *metal_allocate_memory(unsigned int size)
+{
+	return (malloc(size));
+}
+
+static inline void metal_free_memory(void *ptr)
+{
+	free(ptr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_ALLOC__H__ */

+ 28 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/assert.h

@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	assert.h
+ * @brief	Generic assertion support.
+ */
+
+#ifndef __METAL_ASSERT__H__
+#error "Include metal/assert.h instead of metal/generic/assert.h"
+#endif
+
+#ifndef __METAL_GENERIC_ASSERT__H__
+#define __METAL_GENERIC_ASSERT__H__
+
+#include <assert.h>
+
+/**
+ * @brief Assertion macro for bare-metal applications.
+ * @param cond Condition to evaluate.
+ */
+#define metal_sys_assert(cond) assert(cond)
+
+#endif /* __METAL_GENERIC_ASSERT__H__ */
+

+ 40 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/cache.h

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Linaro Limited. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/cache.h
+ * @brief	generic cache operation primitives for libmetal.
+ */
+
+#ifndef __METAL_CACHE__H__
+#error "Include metal/cache.h instead of metal/generic/cache.h"
+#endif
+
+#ifndef __METAL_GENERIC_CACHE__H__
+#define __METAL_GENERIC_CACHE__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void metal_machine_cache_flush(void *addr, unsigned int len);
+extern void metal_machine_cache_invalidate(void *addr, unsigned int len);
+
+static inline void __metal_cache_flush(void *addr, unsigned int len)
+{
+	metal_machine_cache_flush(addr, len);
+}
+
+static inline void __metal_cache_invalidate(void *addr, unsigned int len)
+{
+	metal_machine_cache_invalidate(addr, len);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_CACHE__H__ */

+ 72 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/condition.h

@@ -0,0 +1,72 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/condition.h
+ * @brief	Generic condition variable primitives for libmetal.
+ */
+
+#ifndef __METAL_CONDITION__H__
+#error "Include metal/condition.h instead of metal/generic/condition.h"
+#endif
+
+#ifndef __METAL_GENERIC_CONDITION__H__
+#define __METAL_GENERIC_CONDITION__H__
+
+#if defined (__CC_ARM)
+#include <stdio.h>
+#endif
+#include <metal/atomic.h>
+#include <stdint.h>
+#include <limits.h>
+#include <metal/errno.h>
+
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct metal_condition {
+	metal_mutex_t *m; /**< mutex.
+	                       The condition variable is attached to
+	                       this mutex when it is waiting.
+	                       It is also used to check correctness
+	                       in case there are multiple waiters. */
+
+	atomic_int v; /**< condition variable value. */
+};
+
+/** Static metal condition variable initialization. */
+#define METAL_CONDITION_INIT		{ NULL, ATOMIC_VAR_INIT(0) }
+
+static inline void metal_condition_init(struct metal_condition *cv)
+{
+	cv->m = NULL;
+	atomic_init(&cv->v, 0);
+}
+
+static inline int metal_condition_signal(struct metal_condition *cv)
+{
+	if (!cv)
+		return -EINVAL;
+
+	/** wake up waiters if there are any. */
+	atomic_fetch_add(&cv->v, 1);
+	return 0;
+}
+
+static inline int metal_condition_broadcast(struct metal_condition *cv)
+{
+	return metal_condition_signal(cv);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_CONDITION__H__ */

+ 65 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/cortexm/sys.h

@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Xilinx nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @file	generic/mp1_m4/sys.h
+ * @brief	generic mp1_m4 system primitives for libmetal.
+ */
+
+#ifndef __METAL_GENERIC_SYS__H__
+#error "Include metal/sys.h instead of metal/generic/cortexm/sys.h"
+#endif
+
+#ifndef __METAL_GENERIC_MP1_M4_SYS__H__
+#define __METAL_GENERIC_MP1_M4_SYS__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MAX_IRQS)
+#define MAX_IRQS	8          /**< maximum number of irqs */
+#endif
+
+static inline void sys_irq_enable(unsigned int vector)
+{
+	(void)vector;
+}
+
+static inline void sys_irq_disable(unsigned int vector)
+{
+	(void)vector;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_MP1_M4_SYS__H__ */

+ 44 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/io.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/io.h
+ * @brief	Generic specific io definitions.
+ */
+
+#ifndef __METAL_IO__H__
+#error "Include metal/io.h instead of metal/generic/io.h"
+#endif
+
+#ifndef __METAL_GENERIC_IO__H__
+#define __METAL_GENERIC_IO__H__
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef METAL_INTERNAL
+
+/**
+ * @brief memory mapping for an I/O region
+ */
+void metal_sys_io_mem_map(struct metal_io_region *io);
+
+/**
+ * @brief memory mapping
+ */
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
+			       size_t size, unsigned int flags);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_IO__H__ */

+ 34 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/irq.h

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/irq.c
+ * @brief	Generic libmetal irq definitions.
+ */
+
+#ifndef __METAL_IRQ__H__
+#error "Include metal/irq.h instead of metal/generic/irq.h"
+#endif
+
+#ifndef __METAL_GENERIC_IRQ__H__
+#define __METAL_GENERIC_IRQ__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief      default interrupt handler
+ * @param[in]  vector interrupt vector
+ */
+void metal_irq_isr(unsigned int vector);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_IRQ__H__ */

+ 52 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/log.h

@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018, Linaro Limited. and Contributors. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Linaro nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @file	generic/log.h
+ * @brief	Generic libmetal log handler definition.
+ */
+
+#ifndef __METAL_METAL_LOG__H__
+#error "Include metal/log.h instead of metal/generic/log.h"
+#endif
+
+#ifndef __METAL_GENERIC_LOG__H__
+#define __METAL_GENERIC_LOG__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_LOG__H__ */

+ 79 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/mutex.h

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/mutex.h
+ * @brief	Generic mutex primitives for libmetal.
+ */
+
+#ifndef __METAL_MUTEX__H__
+#error "Include metal/mutex.h instead of metal/generic/mutex.h"
+#endif
+
+#ifndef __METAL_GENERIC_MUTEX__H__
+#define __METAL_GENERIC_MUTEX__H__
+
+#include <metal/atomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+	union{
+		atomic_int v;
+		atomic_flag w;
+	};
+} metal_mutex_t;
+
+/*
+ * METAL_MUTEX_INIT - used for initializing an mutex elmenet in a static struct
+ * or global
+ */
+#define METAL_MUTEX_INIT(m) { ATOMIC_VAR_INIT(0) }
+/*
+ * METAL_MUTEX_DEFINE - used for defining and initializing a global or
+ * static singleton mutex
+ */
+#define METAL_MUTEX_DEFINE(m) metal_mutex_t m = METAL_MUTEX_INIT(m)
+
+static inline void __metal_mutex_init(metal_mutex_t *mutex)
+{
+	atomic_store(&mutex->v, 0);
+}
+
+static inline void __metal_mutex_deinit(metal_mutex_t *mutex)
+{
+	(void)mutex;
+}
+
+static inline int __metal_mutex_try_acquire(metal_mutex_t *mutex)
+{
+	return 1 - atomic_flag_test_and_set(&mutex->w);
+}
+
+static inline void __metal_mutex_acquire(metal_mutex_t *mutex)
+{
+	while (atomic_flag_test_and_set(&mutex->w)) {
+		;
+	}
+}
+
+static inline void __metal_mutex_release(metal_mutex_t *mutex)
+{
+	atomic_flag_clear(&mutex->w);
+}
+
+static inline int __metal_mutex_is_acquired(metal_mutex_t *mutex)
+{
+	return atomic_load(&mutex->v);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_MUTEX__H__ */

+ 38 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/sleep.h

@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018, Linaro Limited. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/sleep.h
+ * @brief	Generic sleep primitives for libmetal.
+ */
+
+#ifndef __METAL_SLEEP__H__
+#error "Include metal/sleep.h instead of metal/generic/sleep.h"
+#endif
+
+#ifndef __METAL_GENERIC_SLEEP__H__
+#define __METAL_GENERIC_SLEEP__H__
+
+#include <metal/utilities.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline int __metal_sleep_usec(unsigned int usec)
+{
+	metal_unused(usec);
+	/* Fix me */
+	return 0;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_SLEEP__H__ */

+ 61 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/system/generic/sys.h

@@ -0,0 +1,61 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/sys.h
+ * @brief	Generic system primitives for libmetal.
+ */
+
+#ifndef __METAL_SYS__H__
+#error "Include metal/sys.h instead of metal/generic/sys.h"
+#endif
+
+#ifndef __METAL_GENERIC_SYS__H__
+#define __METAL_GENERIC_SYS__H__
+
+#include <metal/errno.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "./cortexm/sys.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef METAL_MAX_DEVICE_REGIONS
+#define METAL_MAX_DEVICE_REGIONS 1
+#endif
+
+/** Structure of generic libmetal runtime state. */
+struct metal_state {
+
+	/** Common (system independent) data. */
+	struct metal_common_state common;
+};
+
+#ifdef METAL_INTERNAL
+
+/**
+ * @brief restore interrupts to state before disable_global_interrupt()
+ */
+void sys_irq_restore_enable(unsigned int flags);
+
+/**
+ * @brief disable all interrupts
+ */
+unsigned int sys_irq_save_disable(void);
+
+#endif /* METAL_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_SYS__H__ */

+ 41 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/time.h

@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	time.h
+ * @brief	Time primitives for libmetal.
+ */
+
+#ifndef __METAL_TIME__H__
+#define __METAL_TIME__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup time TIME Interfaces
+ *  @{ */
+
+#include <stdint.h>
+#include <metal/sys.h>
+
+/**
+ * @brief      get timestamp
+ *             This function returns the timestampe as unsigned long long
+ *             value.
+ *
+ * @return     timestamp
+ */
+unsigned long long metal_get_timestamp(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_TIME__H__ */
+

+ 152 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/utilities.h

@@ -0,0 +1,152 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	utilities.h
+ * @brief	Utility routines for libmetal.
+ */
+
+#ifndef __METAL_UTILITIES__H__
+#define __METAL_UTILITIES__H__
+
+#include <stdint.h>
+#include <metal/assert.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup utilities Simple Utilities
+ *  @{ */
+
+/** Marker for unused function arguments/variables. */
+#define metal_unused(x)	do { (x) = (x); } while (0)
+
+/** Figure out number of elements in an array. */
+#define metal_dim(x)	(sizeof(x) / sizeof(x[0]))
+
+/** Minimum of two numbers (warning: multiple evaluation!).  */
+#define metal_min(x, y)	((x) < (y) ? (x) : (y))
+
+/** Maximum of two numbers (warning: multiple evaluation!).  */
+#define metal_max(x, y)	((x) > (y) ? (x) : (y))
+
+/** Sign of a number [-1, 0, or 1] (warning: multiple evaluation!).  */
+#define metal_sign(x)	((x) < 0 ? -1 : ((x) > 0 ? 1 : 0))
+
+/** Align 'size' down to a multiple of 'align' (must be a power of two). */
+#define metal_align_down(size, align)			\
+	((size) & ~((align) - 1))
+
+/** Align 'size' up to a multiple of 'align' (must be a power of two). */
+#define metal_align_up(size, align)			\
+	metal_align_down((size) + (align) - 1, align)
+
+/** Divide (and round down). */
+#define metal_div_round_down(num, den)			\
+	((num) / (den))
+
+/** Divide (and round up). */
+#define metal_div_round_up(num, den)			\
+	metal_div_round_down((num) + (den) - 1, (den))
+
+/** Align 'ptr' down to a multiple of 'align' (must be a power of two). */
+#define metal_ptr_align_down(ptr, align)		\
+	(void *)(metal_align_down((uintptr_t)(ptr), (uintptr_t)(align)))
+
+/** Align 'ptr' up to a multiple of 'align' (must be a power of two). */
+#define metal_ptr_align_up(ptr, align)			\
+	(void *)(metal_align_up((uintptr_t)(ptr), (uintptr_t)(align)))
+
+/** Compute offset of a field within a structure. */
+#define metal_offset_of(structure, member)		\
+	((uintptr_t) &(((structure *) 0)->member))
+
+/** Compute pointer to a structure given a pointer to one of its fields. */
+#define metal_container_of(ptr, structure, member)	\
+	(void *)((uintptr_t)(ptr) - metal_offset_of(structure, member))
+
+#define METAL_BITS_PER_ULONG	(8 * sizeof(unsigned long))
+
+#define metal_bit(bit)		(1UL << (bit))
+
+#define metal_bitmap_longs(x)	metal_div_round_up((x), METAL_BITS_PER_ULONG)
+
+static inline void metal_bitmap_set_bit(unsigned long *bitmap, int bit)
+{
+	bitmap[bit / METAL_BITS_PER_ULONG] |=
+		metal_bit(bit & (METAL_BITS_PER_ULONG - 1));
+}
+
+static inline int metal_bitmap_is_bit_set(unsigned long *bitmap, int bit)
+{
+	return bitmap[bit / METAL_BITS_PER_ULONG] &
+		metal_bit(bit & (METAL_BITS_PER_ULONG - 1));
+}
+
+static inline void metal_bitmap_clear_bit(unsigned long *bitmap, int bit)
+{
+	bitmap[bit / METAL_BITS_PER_ULONG] &=
+		~metal_bit(bit & (METAL_BITS_PER_ULONG - 1));
+}
+
+static inline int metal_bitmap_is_bit_clear(unsigned long *bitmap, int bit)
+{
+	return !metal_bitmap_is_bit_set(bitmap, bit);
+}
+
+static inline unsigned int
+metal_bitmap_next_set_bit(unsigned long *bitmap, unsigned int start,
+			  unsigned int max)
+{
+	unsigned int bit;
+	for (bit = start;
+	     bit < max && !metal_bitmap_is_bit_set(bitmap, bit);
+	     bit ++)
+		;
+	return bit;
+}
+
+#define metal_bitmap_for_each_set_bit(bitmap, bit, max)			\
+	for ((bit) = metal_bitmap_next_set_bit((bitmap), 0, (max));	\
+	     (bit) < (max);						\
+	     (bit) = metal_bitmap_next_set_bit((bitmap), (bit), (max)))
+
+static inline unsigned int
+metal_bitmap_next_clear_bit(unsigned long *bitmap, unsigned int start,
+			    unsigned int max)
+{
+	unsigned int bit;
+	for (bit = start;
+	     bit < max && !metal_bitmap_is_bit_clear(bitmap, bit);
+	     bit ++)
+		;
+	return bit;
+}
+
+#define metal_bitmap_for_each_clear_bit(bitmap, bit, max)		\
+	for ((bit) = metal_bitmap_next_clear_bit((bitmap), 0, (max));	\
+	     (bit) < (max);						\
+	     (bit) = metal_bitmap_next_clear_bit((bitmap), (bit), (max)))
+
+static inline unsigned long metal_log2(unsigned long in)
+{
+	unsigned long result;
+
+	metal_assert((in & (in - 1)) == 0);
+
+	for (result = 0; (1UL << result) < in; result ++)
+		;
+	return result;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_UTILITIES__H__ */

+ 76 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/include/metal/version.h

@@ -0,0 +1,76 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	version.h
+ * @brief	Library version information for libmetal.
+ */
+
+#ifndef __METAL_VERSION__H__
+#define __METAL_VERSION__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/** \defgroup versions Library Version Interfaces
+ *  @{ */
+
+/**
+ *  @brief	Library major version number.
+ *
+ *  Return the major version number of the library linked into the application.
+ *  This is required to match the value of METAL_VER_MAJOR, which is the major
+ *  version of the library that the application was compiled against.
+ *
+ *  @return	Library major version number.
+ *  @see	METAL_VER_MAJOR
+ */
+extern int metal_ver_major(void);
+
+/**
+ *  @brief	Library minor version number.
+ *
+ *  Return the minor version number of the library linked into the application.
+ *  This could differ from the value of METAL_VER_MINOR, which is the minor
+ *  version of the library that the application was compiled against.
+ *
+ *  @return	Library minor version number.
+ *  @see	METAL_VER_MINOR
+ */
+extern int metal_ver_minor(void);
+
+/**
+ *  @brief	Library patch level.
+ *
+ *  Return the patch level of the library linked into the application.  This
+ *  could differ from the value of METAL_VER_PATCH, which is the patch level of
+ *  the library that the application was compiled against.
+ *
+ *  @return	Library patch level.
+ *  @see	METAL_VER_PATCH
+ */
+extern int metal_ver_patch(void);
+
+/**
+ *  @brief	Library version string.
+ *
+ *  Return the version string of the library linked into the application.  This
+ *  could differ from the value of METAL_VER, which is the version string of
+ *  the library that the application was compiled against.
+ *
+ *  @return	Library version string.
+ *  @see	METAL_VER
+ */
+extern const char *metal_ver(void);
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_VERSION__H__ */

+ 34 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/init.c

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <metal/sys.h>
+
+int metal_init(const struct metal_init_params *params)
+{
+	int error = 0;
+
+	memset(&_metal, 0, sizeof(_metal));
+
+	_metal.common.log_handler   = params->log_handler;
+	_metal.common.log_level     = params->log_level;
+
+	metal_list_init(&_metal.common.bus_list);
+	metal_list_init(&_metal.common.generic_shmem_list);
+	metal_list_init(&_metal.common.generic_device_list);
+
+	error = metal_sys_init(params);
+	if (error)
+		return error;
+
+	return error;
+}
+
+void metal_finish(void)
+{
+	metal_sys_finish();
+	memset(&_metal, 0, sizeof(_metal));
+}

+ 139 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/io.c

@@ -0,0 +1,139 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <metal/errno.h>
+#include <limits.h>
+#include <metal/io.h>
+#include <metal/sys.h>
+
+void metal_io_init(struct metal_io_region *io, void *virt,
+	      const metal_phys_addr_t *physmap, size_t size,
+	      unsigned page_shift, unsigned int mem_flags,
+	      const struct metal_io_ops *ops)
+{
+	const struct metal_io_ops nops = {NULL, NULL, NULL, NULL, NULL, NULL};
+
+	io->virt = virt;
+	io->physmap = physmap;
+	io->size = size;
+	io->page_shift = page_shift;
+	if (page_shift >= sizeof(io->page_mask) * CHAR_BIT)
+		/* avoid overflow */
+		io->page_mask = -1UL;
+	else
+		io->page_mask = (1UL << page_shift) - 1UL;
+	io->mem_flags = mem_flags;
+	io->ops = ops ? *ops : nops;
+	metal_sys_io_mem_map(io);
+}
+
+int metal_io_block_read(struct metal_io_region *io, unsigned long offset,
+	       void *restrict dst, int len)
+{
+	unsigned char *ptr = metal_io_virt(io, offset);
+	unsigned char *dest = dst;
+	int retlen;
+
+	if (offset > io->size)
+		return -ERANGE;
+	if ((offset + len) > io->size)
+		len = io->size - offset;
+	retlen = len;
+	if (io->ops.block_read) {
+		retlen = (*io->ops.block_read)(
+			io, offset, dst, memory_order_seq_cst, len);
+	} else {
+		atomic_thread_fence(memory_order_seq_cst);
+		while ( len && (
+			((uintptr_t)dest % sizeof(int)) ||
+			((uintptr_t)ptr % sizeof(int)))) {
+			*(unsigned char *)dest =
+				*(const unsigned char *)ptr;
+			dest++;
+			ptr++;
+			len--;
+		}
+		for (; len >= (int)sizeof(int); dest += sizeof(int),
+					ptr += sizeof(int),
+					len -= sizeof(int))
+			*(unsigned int *)dest = *(const unsigned int *)ptr;
+		for (; len != 0; dest++, ptr++, len--)
+			*(unsigned char *)dest =
+				*(const unsigned char *)ptr;
+	}
+	return retlen;
+}
+
+int metal_io_block_write(struct metal_io_region *io, unsigned long offset,
+	       const void *restrict src, int len)
+{
+	unsigned char *ptr = metal_io_virt(io, offset);
+	const unsigned char *source = src;
+	int retlen;
+
+	if (offset > io->size)
+		return -ERANGE;
+	if ((offset + len) > io->size)
+		len = io->size - offset;
+	retlen = len;
+	if (io->ops.block_write) {
+		retlen = (*io->ops.block_write)(
+			io, offset, src, memory_order_seq_cst, len);
+	} else {
+		while ( len && (
+			((uintptr_t)ptr % sizeof(int)) ||
+			((uintptr_t)source % sizeof(int)))) {
+			*(unsigned char *)ptr =
+				*(const unsigned char *)source;
+			ptr++;
+			source++;
+			len--;
+		}
+		for (; len >= (int)sizeof(int); ptr += sizeof(int),
+					source += sizeof(int),
+					len -= sizeof(int))
+			*(unsigned int *)ptr = *(const unsigned int *)source;
+		for (; len != 0; ptr++, source++, len--)
+			*(unsigned char *)ptr =
+				*(const unsigned char *)source;
+		atomic_thread_fence(memory_order_seq_cst);
+	}
+	return retlen;
+}
+
+int metal_io_block_set(struct metal_io_region *io, unsigned long offset,
+	       unsigned char value, int len)
+{
+	unsigned char *ptr = metal_io_virt(io, offset);
+	int retlen = len;
+
+	if (offset > io->size)
+		return -ERANGE;
+	if ((offset + len) > io->size)
+		len = io->size - offset;
+	retlen = len;
+	if (io->ops.block_set) {
+		(*io->ops.block_set)(
+			io, offset, value, memory_order_seq_cst, len);
+	} else {
+		unsigned int cint = value;
+		unsigned int i;
+
+		for (i = 1; i < sizeof(int); i++)
+			cint |= ((unsigned int)value << (8 * i));
+
+		for (; len && ((uintptr_t)ptr % sizeof(int)); ptr++, len--)
+			*(unsigned char *)ptr = (unsigned char) value;
+		for (; len >= (int)sizeof(int); ptr += sizeof(int),
+						len -= sizeof(int))
+			*(unsigned int *)ptr = cint;
+		for (; len != 0; ptr++, len--)
+			*(unsigned char *)ptr = (unsigned char) value;
+		atomic_thread_fence(memory_order_seq_cst);
+	}
+	return retlen;
+}
+

+ 62 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/log.c

@@ -0,0 +1,62 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <stdarg.h>
+#include <stdio.h>
+
+#include <metal/log.h>
+#include <metal/sys.h>
+
+void metal_default_log_handler(enum metal_log_level level,
+			       const char *format, ...)
+{
+#ifdef DEFAULT_LOGGER_ON
+	char msg[1024];
+	va_list args;
+	static const char *level_strs[] = {
+		"metal: emergency: ",
+		"metal: alert:     ",
+		"metal: critical:  ",
+		"metal: error:     ",
+		"metal: warning:   ",
+		"metal: notice:    ",
+		"metal: info:      ",
+		"metal: debug:     ",
+	};
+
+	va_start(args, format);
+	vsnprintf(msg, sizeof(msg), format, args);
+	va_end(args);
+
+	if (level <= METAL_LOG_EMERGENCY || level > METAL_LOG_DEBUG)
+		level = METAL_LOG_EMERGENCY;
+
+	fprintf(stderr, "%s%s", level_strs[level], msg);
+#else
+	(void)level;
+	(void)format;
+#endif
+}
+
+void metal_set_log_handler(metal_log_handler handler)
+{
+	_metal.common.log_handler = handler;
+}
+
+metal_log_handler metal_get_log_handler(void)
+{
+	return _metal.common.log_handler;
+}
+
+void metal_set_log_level(enum metal_log_level level)
+{
+	_metal.common.log_level = level;
+}
+
+enum metal_log_level metal_get_log_level(void)
+{
+	return _metal.common.log_level;
+}

+ 48 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/shmem.c

@@ -0,0 +1,48 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/shmem.c
+ * @brief	Generic libmetal shared memory handling.
+ */
+
+#include <metal/errno.h>
+#include <metal/assert.h>
+#include <metal/shmem.h>
+#include <metal/sys.h>
+#include <metal/utilities.h>
+
+int metal_shmem_register_generic(struct metal_generic_shmem *shmem)
+{
+	/* Make sure that we can be found. */
+	metal_assert(shmem->name && strlen(shmem->name) != 0);
+
+	/* Statically registered shmem regions cannot have a destructor. */
+	metal_assert(!shmem->io.ops.close);
+
+	metal_list_add_tail(&_metal.common.generic_shmem_list,
+			    &shmem->node);
+	return 0;
+}
+
+int metal_shmem_open_generic(const char *name, size_t size,
+			     struct metal_io_region **result)
+{
+	struct metal_generic_shmem *shmem;
+	struct metal_list *node;
+
+	metal_list_for_each(&_metal.common.generic_shmem_list, node) {
+		shmem = metal_container_of(node, struct metal_generic_shmem, node);
+		if (strcmp(shmem->name, name) != 0)
+			continue;
+		if (size > metal_io_region_size(&shmem->io))
+			continue;
+		*result = &shmem->io;
+		return 0;
+	}
+
+	return -ENOENT;
+}

+ 167 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/st_device.c

@@ -0,0 +1,167 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <string.h>
+#include <metal/errno.h>
+#include <metal/assert.h>
+#include <metal/device.h>
+#include <metal/list.h>
+#include <metal/log.h>
+#include <metal/sys.h>
+#include <metal/utilities.h>
+#include <metal/dma.h>
+#include <metal/cache.h>
+
+int metal_bus_register(struct metal_bus *bus)
+{
+	if (!bus || !bus->name || !strlen(bus->name))
+		return -EINVAL;
+	if (metal_bus_find(bus->name, NULL) == 0)
+		return -EEXIST;
+	metal_list_init(&bus->devices);
+	metal_list_add_tail(&_metal.common.bus_list, &bus->node);
+	metal_log(METAL_LOG_DEBUG, "registered %s bus\n", bus->name);
+	return 0;
+}
+
+int metal_bus_unregister(struct metal_bus *bus)
+{
+	metal_list_del(&bus->node);
+	if (bus->ops.bus_close)
+		bus->ops.bus_close(bus);
+	metal_log(METAL_LOG_DEBUG, "unregistered %s bus\n", bus->name);
+	return 0;
+}
+
+int metal_bus_find(const char *name, struct metal_bus **result)
+{
+	struct metal_list *node;
+	struct metal_bus *bus;
+
+	metal_list_for_each(&_metal.common.bus_list, node) {
+		bus = metal_container_of(node, struct metal_bus, node);
+		if (strcmp(bus->name, name) != 0)
+			continue;
+		if (result)
+			*result = bus;
+		return 0;
+	}
+	return -ENOENT;
+}
+
+int metal_device_open(const char *bus_name, const char *dev_name,
+		      struct metal_device **device)
+{
+	struct metal_bus *bus;
+	int error;
+
+	if (!bus_name || !strlen(bus_name) ||
+	    !dev_name || !strlen(dev_name) ||
+	    !device)
+		return -EINVAL;
+
+	error = metal_bus_find(bus_name, &bus);
+	if (error)
+		return error;
+
+	if (!bus->ops.dev_open)
+		return -ENODEV;
+
+	error = (*bus->ops.dev_open)(bus, dev_name, device);
+	if (error)
+		return error;
+
+	return 0;
+}
+
+void metal_device_close(struct metal_device *device)
+{
+	metal_assert(device && device->bus);
+	if (device->bus->ops.dev_close)
+		device->bus->ops.dev_close(device->bus, device);
+}
+
+int metal_register_generic_device(struct metal_device *device)
+{
+	if (!device->name || !strlen(device->name) ||
+	    device->num_regions > METAL_MAX_DEVICE_REGIONS)
+		return -EINVAL;
+
+	device->bus = &metal_generic_bus;
+	metal_list_add_tail(&_metal.common.generic_device_list,
+			    &device->node);
+	return 0;
+}
+
+int metal_generic_dev_open(struct metal_bus *bus, const char *dev_name,
+			   struct metal_device **device)
+{
+	struct metal_list *node;
+	struct metal_device *dev;
+
+	(void)bus;
+
+	metal_list_for_each(&_metal.common.generic_device_list, node) {
+		dev = metal_container_of(node, struct metal_device, node);
+		if (strcmp(dev->name, dev_name) != 0)
+			continue;
+		*device = dev;
+		return metal_generic_dev_sys_open(dev);
+	}
+
+	return -ENODEV;
+}
+
+int metal_generic_dev_dma_map(struct metal_bus *bus,
+			     struct metal_device *device,
+			     uint32_t dir,
+			     struct metal_sg *sg_in,
+			     int nents_in,
+			     struct metal_sg *sg_out)
+{
+	(void)bus;
+	(void)device;
+	int i;
+
+	if (sg_out != sg_in)
+		memcpy(sg_out, sg_in, nents_in*(sizeof(struct metal_sg)));
+	for (i = 0; i < nents_in; i++) {
+		if (dir == METAL_DMA_DEV_W) {
+			metal_cache_flush(sg_out[i].virt, sg_out[i].len);
+		}
+		metal_cache_invalidate(sg_out[i].virt, sg_out[i].len);
+	}
+
+	return nents_in;
+}
+
+void metal_generic_dev_dma_unmap(struct metal_bus *bus,
+				 struct metal_device *device,
+				 uint32_t dir,
+				 struct metal_sg *sg,
+				 int nents)
+{
+	(void)bus;
+	(void)device;
+	(void)dir;
+	int i;
+
+	for (i = 0; i < nents; i++) {
+		metal_cache_invalidate(sg[i].virt, sg[i].len);
+	}
+}
+
+struct metal_bus metal_weak metal_generic_bus = {
+	.name = "generic",
+	.ops  = {
+		.bus_close = NULL,
+		.dev_open  = metal_generic_dev_open,
+		.dev_close = NULL,
+		.dev_irq_ack = NULL,
+		.dev_dma_map = metal_generic_dev_dma_map,
+		.dev_dma_unmap = metal_generic_dev_dma_unmap,
+	},
+};

+ 39 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/alloc.h

@@ -0,0 +1,39 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/alloc.c
+ * @brief	generic libmetal memory allocattion definitions.
+ */
+
+#ifndef __METAL_ALLOC__H__
+#error "Include metal/alloc.h instead of metal/generic/alloc.h"
+#endif
+
+#ifndef __METAL_GENERIC_ALLOC__H__
+#define __METAL_GENERIC_ALLOC__H__
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline void *metal_allocate_memory(unsigned int size)
+{
+	return (malloc(size));
+}
+
+static inline void metal_free_memory(void *ptr)
+{
+	free(ptr);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_ALLOC__H__ */

+ 28 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/assert.h

@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2018, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	assert.h
+ * @brief	Generic assertion support.
+ */
+
+#ifndef __METAL_ASSERT__H__
+#error "Include metal/assert.h instead of metal/generic/assert.h"
+#endif
+
+#ifndef __METAL_GENERIC_ASSERT__H__
+#define __METAL_GENERIC_ASSERT__H__
+
+#include <assert.h>
+
+/**
+ * @brief Assertion macro for bare-metal applications.
+ * @param cond Condition to evaluate.
+ */
+#define metal_sys_assert(cond) assert(cond)
+
+#endif /* __METAL_GENERIC_ASSERT__H__ */
+

+ 40 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/cache.h

@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2018, Linaro Limited. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/cache.h
+ * @brief	generic cache operation primitives for libmetal.
+ */
+
+#ifndef __METAL_CACHE__H__
+#error "Include metal/cache.h instead of metal/generic/cache.h"
+#endif
+
+#ifndef __METAL_GENERIC_CACHE__H__
+#define __METAL_GENERIC_CACHE__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+extern void metal_machine_cache_flush(void *addr, unsigned int len);
+extern void metal_machine_cache_invalidate(void *addr, unsigned int len);
+
+static inline void __metal_cache_flush(void *addr, unsigned int len)
+{
+	metal_machine_cache_flush(addr, len);
+}
+
+static inline void __metal_cache_invalidate(void *addr, unsigned int len)
+{
+	metal_machine_cache_invalidate(addr, len);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_CACHE__H__ */

+ 49 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/condition.c

@@ -0,0 +1,49 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/condition.c
+ * @brief	Generic libmetal condition variable handling.
+ */
+
+#include <metal/condition.h>
+#include <metal/irq.h>
+
+extern void metal_generic_default_poll(void);
+
+int metal_condition_wait(struct metal_condition *cv,
+			 metal_mutex_t *m)
+{
+	metal_mutex_t *tmpm = 0;
+	int v;
+	unsigned int flags;
+
+	/* Check if the mutex has been acquired */
+	if (!cv || !m || !metal_mutex_is_acquired(m))
+		return -EINVAL;
+
+	if (!atomic_compare_exchange_strong(&cv->m->v, &tmpm->v, m->v)) {
+		if (m != tmpm)
+			return -EINVAL;
+	}
+
+	v = atomic_load(&cv->v);
+
+	/* Release the mutex first. */
+	metal_mutex_release(m);
+	do {
+		flags = metal_irq_save_disable();
+		if (atomic_load(&cv->v) != v) {
+			metal_irq_restore_enable(flags);
+			break;
+		}
+		metal_generic_default_poll();
+		metal_irq_restore_enable(flags);
+	} while(1);
+	/* Acquire the mutex again. */
+	metal_mutex_acquire(m);
+	return 0;
+}

+ 68 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/condition.h

@@ -0,0 +1,68 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/condition.h
+ * @brief	Generic condition variable primitives for libmetal.
+ */
+
+#ifndef __METAL_CONDITION__H__
+#error "Include metal/condition.h instead of metal/generic/condition.h"
+#endif
+
+#ifndef __METAL_GENERIC_CONDITION__H__
+#define __METAL_GENERIC_CONDITION__H__
+
+#include <unistd.h>
+#include <metal/atomic.h>
+#include <stdint.h>
+#include <limits.h>
+#include <metal/errno.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+struct metal_condition {
+	metal_mutex_t *m; /**< mutex.
+	                       The condition variable is attached to
+	                       this mutex when it is waiting.
+	                       It is also used to check correctness
+	                       in case there are multiple waiters. */
+
+	atomic_int v; /**< condition variable value. */
+};
+
+/** Static metal condition variable initialization. */
+#define METAL_CONDITION_INIT		{ NULL, ATOMIC_VAR_INIT(0) }
+
+static inline void metal_condition_init(struct metal_condition *cv)
+{
+	cv->m = NULL;
+	atomic_init(&cv->v, 0);
+}
+
+static inline int metal_condition_signal(struct metal_condition *cv)
+{
+	if (!cv)
+		return -EINVAL;
+
+	/** wake up waiters if there are any. */
+	atomic_fetch_add(&cv->v, 1);
+	return 0;
+}
+
+static inline int metal_condition_broadcast(struct metal_condition *cv)
+{
+	return metal_condition_signal(cv);
+}
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_CONDITION__H__ */

+ 77 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/cortexm/sys.c

@@ -0,0 +1,77 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Xilinx nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @file	generic/sys.c
+ * @brief	machine specific system primitives implementation.
+ */
+
+
+#include "metal/io.h"
+#include "metal/sys.h"
+
+void sys_irq_restore_enable(unsigned int flags)
+{
+}
+
+unsigned int sys_irq_save_disable(void)
+{
+  return 0;
+}
+
+void metal_machine_cache_flush(void *addr, unsigned int len)
+{
+	(void)addr;
+	(void)len;
+}
+
+void metal_machine_cache_invalidate(void *addr, unsigned int len)
+{
+	(void)addr;
+	(void)len;
+}
+
+/**
+ * @brief poll function until some event happens
+ */
+void __attribute__((weak)) metal_generic_default_poll(void)
+{
+}
+
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
+			       size_t size, unsigned int flags)
+{
+	(void)va;
+	(void)pa;
+	(void)size;
+	(void)flags;
+
+	return va;
+}

+ 65 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/cortexm/sys.h

@@ -0,0 +1,65 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Xilinx nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @file	generic/mp1_m4/sys.h
+ * @brief	generic mp1_m4 system primitives for libmetal.
+ */
+
+#ifndef __METAL_GENERIC_SYS__H__
+#error "Include metal/sys.h instead of metal/generic/@PROJECT_MACHINE@/sys.h"
+#endif
+
+#ifndef __METAL_GENERIC_MP1_M4_SYS__H__
+#define __METAL_GENERIC_MP1_M4_SYS__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#if !defined(MAX_IRQS)
+#define MAX_IRQS	8          /**< maximum number of irqs */
+#endif
+
+static inline void sys_irq_enable(unsigned int vector)
+{
+	(void)vector;
+}
+
+static inline void sys_irq_disable(unsigned int vector)
+{
+	(void)vector;
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_MP1_M4_SYS__H__ */

+ 32 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_device.c

@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/device.c
+ * @brief	Generic libmetal device operations.
+ */
+
+#include <metal/device.h>
+#include <metal/io.h>
+#include <metal/sys.h>
+#include <metal/utilities.h>
+
+int metal_generic_dev_sys_open(struct metal_device *dev)
+{
+	struct metal_io_region *io;
+	unsigned i;
+
+	/* map I/O memory regions */
+	for (i = 0; i < dev->num_regions; i++) {
+		io = &dev->regions[i];
+		if (!io->size)
+			break;
+		metal_sys_io_mem_map(io);
+	}
+
+	return 0;
+}
+

+ 28 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_init.c

@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/init.c
+ * @brief	Generic libmetal initialization.
+ */
+
+#include <metal/sys.h>
+#include <metal/utilities.h>
+#include <metal/device.h>
+
+struct metal_state _metal;
+
+int metal_sys_init(const struct metal_init_params *params)
+{
+	metal_unused(params);
+	metal_bus_register(&metal_generic_bus);
+	return 0;
+}
+
+void metal_sys_finish(void)
+{
+	metal_bus_unregister(&metal_generic_bus);
+}

+ 31 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_io.c

@@ -0,0 +1,31 @@
+/*
+ * Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/io.c
+ * @brief	Generic libmetal io operations
+ */
+
+#include <metal/io.h>
+
+void metal_sys_io_mem_map(struct metal_io_region *io)
+{
+	unsigned long p;
+	size_t psize;
+	size_t *va;
+
+	va = (size_t *)io->virt;
+	psize = io->size;
+	if (psize) {
+		if (psize >> io->page_shift)
+			psize = (size_t)1 << io->page_shift;
+		for (p = 0; p <= (io->size >> io->page_shift); p++) {
+			metal_machine_io_mem_map(va, io->physmap[p],
+						 psize, io->mem_flags);
+			va += psize;
+		}
+	}
+}

+ 279 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_irq.c

@@ -0,0 +1,279 @@
+/*
+ * Copyright (c) 2016 - 2017, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/irq.c
+ * @brief	generic libmetal irq definitions.
+ */
+
+#include <metal/errno.h>
+#include <metal/irq.h>
+#include <metal/sys.h>
+#include <metal/log.h>
+#include <metal/mutex.h>
+#include <metal/list.h>
+#include <metal/utilities.h>
+#include <metal/alloc.h>
+
+/** IRQ handlers descriptor structure */
+struct metal_irq_hddesc {
+	metal_irq_handler hd;     /**< irq handler */
+	void *drv_id;             /**< id to identify the driver
+	                               of the irq handler */
+	struct metal_device *dev; /**< device identifier */
+	struct metal_list node;   /**< node on irq handlers list */
+};
+
+/** IRQ descriptor structure */
+struct metal_irq_desc {
+	int irq;                  /**< interrupt number */
+	struct metal_list hdls;   /**< interrupt handlers */
+	struct metal_list node;   /**< node on irqs list */
+};
+
+/** IRQ state structure */
+struct metal_irqs_state {
+	struct metal_list irqs;   /**< interrupt descriptors */
+	metal_mutex_t irq_lock;   /**< access lock */
+};
+
+static struct metal_irqs_state _irqs = {
+	.irqs = METAL_INIT_LIST(_irqs.irqs),
+	.irq_lock = METAL_MUTEX_INIT(_irqs.irq_lock),
+};
+
+int metal_irq_register(int irq,
+                       metal_irq_handler hd,
+                       struct metal_device *dev,
+                       void *drv_id)
+{
+	struct metal_irq_desc *irq_p = NULL;
+	struct metal_irq_hddesc *hdl_p;
+	struct metal_list *node;
+	unsigned int irq_flags_save;
+
+	if (irq < 0) {
+		metal_log(METAL_LOG_ERROR,
+			  "%s: irq %d need to be a positive number\n",
+		          __func__, irq);
+		return -EINVAL;
+	}
+
+	if ((drv_id == NULL) || (hd == NULL)) {
+		metal_log(METAL_LOG_ERROR, "%s: irq %d need drv_id and hd.\n",
+		          __func__, irq);
+		return -EINVAL;
+	}
+
+	/* Search for irq in list */
+	metal_mutex_acquire(&_irqs.irq_lock);
+	metal_list_for_each(&_irqs.irqs, node) {
+		irq_p = metal_container_of(node, struct metal_irq_desc, node);
+
+		if (irq_p->irq == irq) {
+			struct metal_list *h_node;
+
+			/* Check if drv_id already exist */
+			metal_list_for_each(&irq_p->hdls, h_node) {
+				hdl_p = metal_container_of(h_node,
+							   struct metal_irq_hddesc,
+							   node);
+
+				/* if drv_id already exist reject */
+				if ((hdl_p->drv_id == drv_id) &&
+					((dev == NULL) || (hdl_p->dev == dev))) {
+					metal_log(METAL_LOG_ERROR,
+						  "%s: irq %d already registered."
+						  "Will not register again.\n",
+						  __func__, irq);
+					metal_mutex_release(&_irqs.irq_lock);
+					return -EINVAL;
+				}
+			}
+			/* irq found and drv_id not used, get out of metal_list_for_each */
+			break;
+		}
+	}
+
+	/* Either need to add handler to an existing list or to a new one */
+	hdl_p = metal_allocate_memory(sizeof(struct metal_irq_hddesc));
+	if (hdl_p == NULL) {
+		metal_log(METAL_LOG_ERROR,
+		          "%s: irq %d cannot allocate mem for drv_id %d.\n",
+		          __func__, irq, drv_id);
+		metal_mutex_release(&_irqs.irq_lock);
+		return -ENOMEM;
+	}
+	hdl_p->hd = hd;
+	hdl_p->drv_id = drv_id;
+	hdl_p->dev = dev;
+
+	/* interrupt already registered, add handler to existing list*/
+	if ((irq_p != NULL) && (irq_p->irq == irq)) {
+		irq_flags_save = metal_irq_save_disable();
+		metal_list_add_tail(&irq_p->hdls, &hdl_p->node);
+		metal_irq_restore_enable(irq_flags_save);
+
+		metal_log(METAL_LOG_DEBUG, "%s: success, irq %d add drv_id %p \n",
+		          __func__, irq, drv_id);
+		metal_mutex_release(&_irqs.irq_lock);
+		return 0;
+	}
+
+	/* interrupt was not already registered, add */
+	irq_p = metal_allocate_memory(sizeof(struct metal_irq_desc));
+	if (irq_p == NULL) {
+		metal_log(METAL_LOG_ERROR, "%s: irq %d cannot allocate mem.\n",
+		          __func__, irq);
+		metal_mutex_release(&_irqs.irq_lock);
+		return -ENOMEM;
+	}
+	irq_p->irq = irq;
+	metal_list_init(&irq_p->hdls);
+	metal_list_add_tail(&irq_p->hdls, &hdl_p->node);
+
+	irq_flags_save = metal_irq_save_disable();
+	metal_list_add_tail(&_irqs.irqs, &irq_p->node);
+	metal_irq_restore_enable(irq_flags_save);
+
+	metal_log(METAL_LOG_DEBUG, "%s: success, added irq %d\n", __func__, irq);
+	metal_mutex_release(&_irqs.irq_lock);
+	return 0;
+}
+
+/* helper function for metal_irq_unregister() */
+static void metal_irq_delete_node(struct metal_list *node, void *p_to_free)
+{
+	unsigned int irq_flags_save;
+
+	irq_flags_save=metal_irq_save_disable();
+	metal_list_del(node);
+	metal_irq_restore_enable(irq_flags_save);
+	metal_free_memory(p_to_free);
+}
+
+int metal_irq_unregister(int irq,
+                         metal_irq_handler hd,
+                         struct metal_device *dev,
+                         void *drv_id)
+{
+	struct metal_irq_desc *irq_p;
+	struct metal_list *node;
+
+	if (irq < 0) {
+		metal_log(METAL_LOG_ERROR, "%s: irq %d need to be a positive number\n",
+		          __func__, irq);
+		return -EINVAL;
+	}
+
+	/* Search for irq in list */
+	metal_mutex_acquire(&_irqs.irq_lock);
+	metal_list_for_each(&_irqs.irqs, node) {
+
+		irq_p = metal_container_of(node, struct metal_irq_desc, node);
+
+		if (irq_p->irq == irq) {
+			struct metal_list *h_node, *h_prenode;
+			struct metal_irq_hddesc *hdl_p;
+			unsigned int delete_count = 0;
+
+			metal_log(METAL_LOG_DEBUG, "%s: found irq %d\n",
+				  __func__, irq);
+
+			/* Search through handlers */
+			metal_list_for_each(&irq_p->hdls, h_node) {
+				hdl_p = metal_container_of(h_node,
+							   struct metal_irq_hddesc,
+							   node);
+
+				if (((hd == NULL) || (hdl_p->hd == hd)) &&
+				    ((drv_id == NULL) || (hdl_p->drv_id == drv_id)) &&
+				    ((dev == NULL) || (hdl_p->dev == dev))) {
+					metal_log(METAL_LOG_DEBUG,
+					          "%s: unregister hd=%p drv_id=%p dev=%p\n",
+						  __func__, hdl_p->hd, hdl_p->drv_id, hdl_p->dev);
+					h_prenode = h_node->prev;
+					metal_irq_delete_node(h_node, hdl_p);
+					h_node = h_prenode;
+					delete_count++;
+				}
+			}
+
+			/* we did not find any handler to delete */
+			if (!delete_count) {
+				metal_log(METAL_LOG_DEBUG, "%s: No matching entry\n",
+				          __func__);
+				metal_mutex_release(&_irqs.irq_lock);
+				return -ENOENT;
+
+			}
+
+			/* if interrupt handlers list is empty, unregister interrupt */
+			if (metal_list_is_empty(&irq_p->hdls)) {
+				metal_log(METAL_LOG_DEBUG,
+				          "%s: handlers list empty, unregister interrupt\n",
+					  __func__);
+				metal_irq_delete_node(node, irq_p);
+			}
+
+			metal_log(METAL_LOG_DEBUG, "%s: success\n", __func__);
+
+			metal_mutex_release(&_irqs.irq_lock);
+			return 0;
+		}
+	}
+
+	metal_log(METAL_LOG_DEBUG, "%s: No matching IRQ entry\n", __func__);
+
+	metal_mutex_release(&_irqs.irq_lock);
+	return -ENOENT;
+}
+
+unsigned int metal_irq_save_disable(void)
+{
+	return sys_irq_save_disable();
+}
+
+void metal_irq_restore_enable(unsigned int flags)
+{
+	sys_irq_restore_enable(flags);
+}
+
+void metal_irq_enable(unsigned int vector)
+{
+	sys_irq_enable(vector);
+}
+
+void metal_irq_disable(unsigned int vector)
+{
+	sys_irq_disable(vector);
+}
+
+/**
+ * @brief default handler
+ */
+void metal_irq_isr(unsigned int vector)
+{
+	struct metal_list *node;
+	struct metal_irq_desc *irq_p;
+
+	metal_list_for_each(&_irqs.irqs, node) {
+		irq_p = metal_container_of(node, struct metal_irq_desc, node);
+
+		if ((unsigned int)irq_p->irq == vector) {
+			struct metal_list *h_node;
+			struct metal_irq_hddesc *hdl_p;
+
+			metal_list_for_each(&irq_p->hdls, h_node) {
+				hdl_p = metal_container_of(h_node,
+							   struct metal_irq_hddesc,
+							   node);
+
+				(hdl_p->hd)(vector, hdl_p->drv_id);
+			}
+		}
+	}
+}

+ 34 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_irq.h

@@ -0,0 +1,34 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/irq.c
+ * @brief	Generic libmetal irq definitions.
+ */
+
+#ifndef __METAL_IRQ__H__
+#error "Include metal/irq.h instead of metal/generic/irq.h"
+#endif
+
+#ifndef __METAL_GENERIC_IRQ__H__
+#define __METAL_GENERIC_IRQ__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @brief      default interrupt handler 
+ * @param[in]  vector interrupt vector
+ */
+void metal_irq_isr(unsigned int vector);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_IRQ__H__ */

+ 18 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_shmem.c

@@ -0,0 +1,18 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/shmem.c
+ * @brief	Generic libmetal shared memory handling.
+ */
+
+#include <metal/shmem.h>
+
+int metal_shmem_open(const char *name, size_t size,
+		     struct metal_io_region **io)
+{
+	return metal_shmem_open_generic(name, size, io);
+}

+ 19 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/generic_time.c

@@ -0,0 +1,19 @@
+/*
+ * Copyright (c) 2016, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/time.c
+ * @brief	Generic libmetal time handling.
+ */
+
+#include <metal/time.h>
+
+unsigned long long metal_get_timestamp(void)
+{
+	/* TODO: Implement timestamp for generic system */
+	return 0;
+}
+

+ 44 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/io.h

@@ -0,0 +1,44 @@
+/*
+ * Copyright (c) 2017, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/io.h
+ * @brief	Generic specific io definitions.
+ */
+
+#ifndef __METAL_IO__H__
+#error "Include metal/io.h instead of metal/generic/io.h"
+#endif
+
+#ifndef __METAL_GENERIC_IO__H__
+#define __METAL_GENERIC_IO__H__
+
+#include <stdlib.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef METAL_INTERNAL
+
+/**
+ * @brief memory mapping for an I/O region
+ */
+void metal_sys_io_mem_map(struct metal_io_region *io);
+
+/**
+ * @brief memory mapping
+ */
+void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
+			       size_t size, unsigned int flags);
+
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_IO__H__ */

+ 52 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/log.h

@@ -0,0 +1,52 @@
+/*
+ * Copyright (c) 2018, Linaro Limited. and Contributors. All rights reserved.
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ * 1. Redistributions of source code must retain the above copyright notice,
+ *    this list of conditions and the following disclaimer.
+ *
+ * 2. Redistributions in binary form must reproduce the above copyright notice,
+ *    this list of conditions and the following disclaimer in the documentation
+ *    and/or other materials provided with the distribution.
+ *
+ * 3. Neither the name of Linaro nor the names of its contributors may be used
+ *    to endorse or promote products derived from this software without
+ *    specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
+ * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+ * POSSIBILITY OF SUCH DAMAGE.
+ */
+
+/*
+ * @file	generic/log.h
+ * @brief	Generic libmetal log handler definition.
+ */
+
+#ifndef __METAL_METAL_LOG__H__
+#error "Include metal/log.h instead of metal/generic/log.h"
+#endif
+
+#ifndef __METAL_GENERIC_LOG__H__
+#define __METAL_GENERIC_LOG__H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_LOG__H__ */

+ 79 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/mutex.h

@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/mutex.h
+ * @brief	Generic mutex primitives for libmetal.
+ */
+
+#ifndef __METAL_MUTEX__H__
+#error "Include metal/mutex.h instead of metal/generic/mutex.h"
+#endif
+
+#ifndef __METAL_GENERIC_MUTEX__H__
+#define __METAL_GENERIC_MUTEX__H__
+
+#include <metal/atomic.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+typedef struct {
+	union{
+		atomic_int v;
+		atomic_flag w;
+	};
+} metal_mutex_t;
+
+/*
+ * METAL_MUTEX_INIT - used for initializing an mutex elmenet in a static struct
+ * or global
+ */
+#define METAL_MUTEX_INIT(m) { ATOMIC_VAR_INIT(0) }
+/*
+ * METAL_MUTEX_DEFINE - used for defining and initializing a global or
+ * static singleton mutex
+ */
+#define METAL_MUTEX_DEFINE(m) metal_mutex_t m = METAL_MUTEX_INIT(m)
+
+static inline void __metal_mutex_init(metal_mutex_t *mutex)
+{
+	atomic_store(&mutex->v, 0);
+}
+
+static inline void __metal_mutex_deinit(metal_mutex_t *mutex)
+{
+	(void)mutex;
+}
+
+static inline int __metal_mutex_try_acquire(metal_mutex_t *mutex)
+{
+	return 1 - atomic_flag_test_and_set(&mutex->w);
+}
+
+static inline void __metal_mutex_acquire(metal_mutex_t *mutex)
+{
+	while (atomic_flag_test_and_set(&mutex->w)) {
+		;
+	}
+}
+
+static inline void __metal_mutex_release(metal_mutex_t *mutex)
+{
+	atomic_flag_clear(&mutex->w);
+}
+
+static inline int __metal_mutex_is_acquired(metal_mutex_t *mutex)
+{
+	return atomic_load(&mutex->v);
+}
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_MUTEX__H__ */

+ 38 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/sleep.h

@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2018, Linaro Limited. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/sleep.h
+ * @brief	Generic sleep primitives for libmetal.
+ */
+
+#ifndef __METAL_SLEEP__H__
+#error "Include metal/sleep.h instead of metal/generic/sleep.h"
+#endif
+
+#ifndef __METAL_GENERIC_SLEEP__H__
+#define __METAL_GENERIC_SLEEP__H__
+
+#include <metal/utilities.h>
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+static inline int __metal_sleep_usec(unsigned int usec)
+{
+	metal_unused(usec);
+	/* Fix me */
+	return 0;
+}
+
+/** @} */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_SLEEP__H__ */

+ 63 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/system/generic/sys.h

@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/*
+ * @file	generic/sys.h
+ * @brief	Generic system primitives for libmetal.
+ */
+
+#ifndef __METAL_SYS__H__
+#error "Include metal/sys.h instead of metal/generic/sys.h"
+#endif
+
+#ifndef __METAL_GENERIC_SYS__H__
+#define __METAL_GENERIC_SYS__H__
+
+#include <metal/errno.h>
+#include <fcntl.h>
+#include <libgen.h>
+#include <limits.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+
+#include "./@PROJECT_MACHINE@/sys.h"
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#ifndef METAL_MAX_DEVICE_REGIONS
+#define METAL_MAX_DEVICE_REGIONS 1
+#endif
+
+/** Structure of generic libmetal runtime state. */
+struct metal_state {
+
+	/** Common (system independent) data. */
+	struct metal_common_state common;
+};
+
+#ifdef METAL_INTERNAL
+
+/**
+ * @brief restore interrupts to state before disable_global_interrupt()
+ */
+void sys_irq_restore_enable(unsigned int flags);
+
+/**
+ * @brief disable all interrupts
+ */
+unsigned int sys_irq_save_disable(void);
+
+#endif /* METAL_INTERNAL */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __METAL_GENERIC_SYS__H__ */

+ 27 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/libmetal/lib/version.c

@@ -0,0 +1,27 @@
+/*
+ * Copyright (c) 2015, Xilinx Inc. and Contributors. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#include <metal/config.h>
+
+int metal_ver_major(void)
+{
+	return METAL_VER_MAJOR;
+}
+
+int metal_ver_minor(void)
+{
+       return METAL_VER_MINOR;
+}
+
+int metal_ver_patch(void)
+{
+       return METAL_VER_PATCH;
+}
+
+const char *metal_ver(void)
+{
+       return METAL_VER;
+}

+ 71 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/open-amp/lib/include/openamp/compiler.h

@@ -0,0 +1,71 @@
+#ifndef _COMPILER_H_
+#define _COMPILER_H_
+
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ * Copyright (c) 2016 Freescale Semiconductor, Inc. All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+/**************************************************************************
+ * FILE NAME
+ *
+ *       compiler.h
+ *
+ * DESCRIPTION
+ *
+ *       This file defines compiler-specific macros.
+ *
+ ***************************************************************************/
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/* IAR ARM build tools */
+#if defined(__ICCARM__)
+
+#ifndef OPENAMP_PACKED_BEGIN
+#define OPENAMP_PACKED_BEGIN __packed
+#endif
+
+#ifndef OPENAMP_PACKED_END
+#define OPENAMP_PACKED_END
+#endif
+
+/* GNUC */
+#elif defined(__GNUC__)
+
+#ifndef OPENAMP_PACKED_BEGIN
+#define OPENAMP_PACKED_BEGIN
+#endif
+
+#ifndef OPENAMP_PACKED_END
+#define OPENAMP_PACKED_END __attribute__((__packed__))
+#endif
+
+/* ARM GCC */
+#elif defined(__CC_ARM)
+
+#ifndef OPENAMP_PACKED_BEGIN
+#define OPENAMP_PACKED_BEGIN _Pragma("pack(1U)")
+#endif
+
+#ifndef OPENAMP_PACKED_END
+#define OPENAMP_PACKED_END _Pragma("pack()")
+#endif
+
+#else
+/*
+ * There is no default definition here to avoid wrong structures packing in case
+ * of not supported compiler
+ */
+#error Please implement the structure packing macros for your compiler here!
+#endif
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* _COMPILER_H_ */

+ 428 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/open-amp/lib/include/openamp/elf_loader.h

@@ -0,0 +1,428 @@
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef ELF_LOADER_H_
+#define ELF_LOADER_H_
+
+#include <openamp/remoteproc.h>
+#include <openamp/remoteproc_loader.h>
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+/* ELF32 base types - 32-bit. */
+typedef uint32_t Elf32_Addr;
+typedef uint16_t Elf32_Half;
+typedef uint32_t Elf32_Off;
+typedef int32_t Elf32_Sword;
+typedef uint32_t Elf32_Word;
+
+/* ELF64 base types - 64-bit. */
+typedef uint64_t Elf64_Addr;
+typedef uint16_t Elf64_Half;
+typedef uint64_t Elf64_Off;
+typedef int32_t Elf64_Sword;
+typedef uint32_t Elf64_Word;
+typedef uint64_t Elf64_Xword;
+typedef int64_t Elf64_Sxword;
+
+/* Size of ELF identifier field in the ELF file header. */
+#define     EI_NIDENT       16
+
+/* ELF32 file header */
+typedef struct {
+	unsigned char e_ident[EI_NIDENT];
+	Elf32_Half e_type;
+	Elf32_Half e_machine;
+	Elf32_Word e_version;
+	Elf32_Addr e_entry;
+	Elf32_Off e_phoff;
+	Elf32_Off e_shoff;
+	Elf32_Word e_flags;
+	Elf32_Half e_ehsize;
+	Elf32_Half e_phentsize;
+	Elf32_Half e_phnum;
+	Elf32_Half e_shentsize;
+	Elf32_Half e_shnum;
+	Elf32_Half e_shstrndx;
+} Elf32_Ehdr;
+
+/* ELF64 file header */
+typedef struct {
+	unsigned char e_ident[EI_NIDENT];
+	Elf64_Half e_type;
+	Elf64_Half e_machine;
+	Elf64_Word e_version;
+	Elf64_Addr e_entry;
+	Elf64_Off e_phoff;
+	Elf64_Off e_shoff;
+	Elf64_Word e_flags;
+	Elf64_Half e_ehsize;
+	Elf64_Half e_phentsize;
+	Elf64_Half e_phnum;
+	Elf64_Half e_shentsize;
+	Elf64_Half e_shnum;
+	Elf64_Half e_shstrndx;
+} Elf64_Ehdr;
+
+/* e_ident */
+#define     ET_NONE         0
+#define     ET_REL          1	/* Re-locatable file         */
+#define     ET_EXEC         2	/* Executable file           */
+#define     ET_DYN          3	/* Shared object file        */
+#define     ET_CORE         4	/* Core file                 */
+#define     ET_LOOS         0xfe00	/* Operating system-specific */
+#define     ET_HIOS         0xfeff	/* Operating system-specific */
+#define     ET_LOPROC       0xff00	/* remote_proc-specific        */
+#define     ET_HIPROC       0xffff	/* remote_proc-specific        */
+
+/* e_machine */
+#define     EM_ARM          40	/* ARM/Thumb Architecture    */
+
+/* e_version */
+#define     EV_CURRENT      1	/* Current version           */
+
+/* e_ident[] Identification Indexes */
+#define     EI_MAG0         0	/* File identification       */
+#define     EI_MAG1         1	/* File identification       */
+#define     EI_MAG2         2	/* File identification       */
+#define     EI_MAG3         3	/* File identification       */
+#define     EI_CLASS        4	/* File class                */
+#define     EI_DATA         5	/* Data encoding             */
+#define     EI_VERSION      6	/* File version              */
+#define     EI_OSABI        7	/* Operating system/ABI identification */
+#define     EI_ABIVERSION   8	/* ABI version               */
+#define     EI_PAD          9	/* Start of padding bytes    */
+#define     EI_NIDENT       16	/* Size of e_ident[]         */
+
+/*
+ * EI_MAG0 to EI_MAG3 - A file's first 4 bytes hold amagic number, identifying
+ * the file as an ELF object file
+ */
+#define     ELFMAG0         0x7f /* e_ident[EI_MAG0]          */
+#define     ELFMAG1         'E'	/* e_ident[EI_MAG1]          */
+#define     ELFMAG2         'L'	/* e_ident[EI_MAG2]          */
+#define     ELFMAG3         'F'	/* e_ident[EI_MAG3]          */
+#define     ELFMAG          "\177ELF"
+#define     SELFMAG         4
+
+/*
+ * EI_CLASS - The next byte, e_ident[EI_CLASS], identifies the file's class, or
+ * capacity.
+ */
+#define     ELFCLASSNONE    0	/* Invalid class             */
+#define     ELFCLASS32      1	/* 32-bit objects            */
+#define     ELFCLASS64      2	/* 64-bit objects            */
+
+/*
+ * EI_DATA - Byte e_ident[EI_DATA] specifies the data encoding of the
+ * remote_proc-specific data in the object file. The following encodings are
+ * currently defined.
+ */
+#define     ELFDATANONE     0	/* Invalid data encoding     */
+#define     ELFDATA2LSB     1	/* See Data encodings, below */
+#define     ELFDATA2MSB     2	/* See Data encodings, below */
+
+/* EI_OSABI - We do not define an OS specific ABI */
+#define     ELFOSABI_NONE   0
+
+/* ELF32 program header */
+typedef struct elf32_phdr{
+	Elf32_Word p_type;
+	Elf32_Off p_offset;
+	Elf32_Addr p_vaddr;
+	Elf32_Addr p_paddr;
+	Elf32_Word p_filesz;
+	Elf32_Word p_memsz;
+	Elf32_Word p_flags;
+	Elf32_Word p_align;
+} Elf32_Phdr;
+
+/* ELF64 program header */
+typedef struct elf64_phdr {
+	Elf64_Word p_type;
+	Elf64_Word p_flags;
+	Elf64_Off p_offset;
+	Elf64_Addr p_vaddr;
+	Elf64_Addr p_paddr;
+	Elf64_Xword p_filesz;
+	Elf64_Xword p_memsz;
+	Elf64_Xword p_align;
+} Elf64_Phdr;
+
+/* segment types */
+#define PT_NULL    0
+#define PT_LOAD    1
+#define PT_DYNAMIC 2
+#define PT_INTERP  3
+#define PT_NOTE    4
+#define PT_SHLIB   5
+#define PT_PHDR    6
+#define PT_TLS     7               /* Thread local storage segment */
+#define PT_LOOS    0x60000000      /* OS-specific */
+#define PT_HIOS    0x6fffffff      /* OS-specific */
+#define PT_LOPROC  0x70000000
+#define PT_HIPROC  0x7fffffff
+
+/* ELF32 section header. */
+typedef struct {
+	Elf32_Word sh_name;
+	Elf32_Word sh_type;
+	Elf32_Word sh_flags;
+	Elf32_Addr sh_addr;
+	Elf32_Off sh_offset;
+	Elf32_Word sh_size;
+	Elf32_Word sh_link;
+	Elf32_Word sh_info;
+	Elf32_Word sh_addralign;
+	Elf32_Word sh_entsize;
+} Elf32_Shdr;
+
+/* ELF64 section header. */
+typedef struct {
+	Elf64_Word sh_name;
+	Elf64_Word sh_type;
+	Elf64_Xword sh_flags;
+	Elf64_Addr sh_addr;
+	Elf64_Off sh_offset;
+	Elf64_Xword sh_size;
+	Elf64_Word sh_link;
+	Elf64_Word sh_info;
+	Elf64_Xword sh_addralign;
+	Elf64_Xword sh_entsize;
+} Elf64_Shdr;
+
+/* sh_type */
+#define     SHT_NULL                0
+#define     SHT_PROGBITS            1
+#define     SHT_SYMTAB              2
+#define     SHT_STRTAB              3
+#define     SHT_RELA                4
+#define     SHT_HASH                5
+#define     SHT_DYNAMIC             6
+#define     SHT_NOTE                7
+#define     SHT_NOBITS              8
+#define     SHT_REL                 9
+#define     SHT_SHLIB               10
+#define     SHT_DYNSYM              11
+#define     SHT_INIT_ARRAY          14
+#define     SHT_FINI_ARRAY          15
+#define     SHT_PREINIT_ARRAY       16
+#define     SHT_GROUP               17
+#define     SHT_SYMTAB_SHNDX        18
+#define     SHT_LOOS                0x60000000
+#define     SHT_HIOS                0x6fffffff
+#define     SHT_LOPROC              0x70000000
+#define     SHT_HIPROC              0x7fffffff
+#define     SHT_LOUSER              0x80000000
+#define     SHT_HIUSER              0xffffffff
+
+/* sh_flags */
+#define     SHF_WRITE       0x1
+#define     SHF_ALLOC       0x2
+#define     SHF_EXECINSTR   0x4
+#define     SHF_MASKPROC    0xf0000000
+
+/* Relocation entry (without addend) */
+typedef struct {
+	Elf32_Addr r_offset;
+	Elf32_Word r_info;
+
+} Elf32_Rel;
+
+typedef struct {
+	Elf64_Addr r_offset;
+	Elf64_Xword r_info;
+
+} Elf64_Rel;
+
+/* Relocation entry with addend */
+typedef struct {
+	Elf32_Addr r_offset;
+	Elf32_Word r_info;
+	Elf32_Sword r_addend;
+
+} Elf32_Rela;
+
+typedef struct elf64_rela {
+	Elf64_Addr r_offset;
+	Elf64_Xword r_info;
+	Elf64_Sxword r_addend;
+} Elf64_Rela;
+
+/* Macros to extract information from 'r_info' field of relocation entries */
+#define ELF32_R_SYM(i)  ((i) >> 8)
+#define ELF32_R_TYPE(i) ((unsigned char)(i))
+#define ELF64_R_SYM(i)  ((i) >> 32)
+#define ELF64_R_TYPE(i) ((i) & 0xffffffff)
+
+/* Symbol table entry */
+typedef struct {
+	Elf32_Word st_name;
+	Elf32_Addr st_value;
+	Elf32_Word st_size;
+	unsigned char st_info;
+	unsigned char st_other;
+	Elf32_Half st_shndx;
+
+} Elf32_Sym;
+
+typedef struct elf64_sym {
+	Elf64_Word st_name;
+	unsigned char	st_info;
+	unsigned char	st_other;
+	Elf64_Half st_shndx;
+	Elf64_Addr st_value;
+	Elf64_Xword st_size;
+} Elf64_Sym;
+
+/* ARM specific dynamic relocation codes */
+#define     R_ARM_GLOB_DAT	21	/* 0x15 */
+#define     R_ARM_JUMP_SLOT	22	/* 0x16 */
+#define     R_ARM_RELATIVE	23	/* 0x17 */
+#define     R_ARM_ABS32		2	/* 0x02 */
+
+/* ELF decoding information */
+struct elf32_info {
+	Elf32_Ehdr ehdr;
+	unsigned int load_state;
+	Elf32_Phdr *phdrs;
+	Elf32_Shdr *shdrs;
+	void *shstrtab;
+};
+
+struct elf64_info {
+	Elf64_Ehdr ehdr;
+	unsigned int load_state;
+	Elf64_Phdr *phdrs;
+	Elf64_Shdr *shdrs;
+	void *shstrtab;
+};
+
+#define ELF_STATE_INIT              0x0UL
+#define ELF_STATE_WAIT_FOR_PHDRS    0x100UL
+#define ELF_STATE_WAIT_FOR_SHDRS    0x200UL
+#define ELF_STATE_WAIT_FOR_SHSTRTAB 0x400UL
+#define ELF_STATE_HDRS_COMPLETE     0x800UL
+#define ELF_STATE_MASK              0xFF00UL
+#define ELF_NEXT_SEGMENT_MASK       0x00FFUL
+
+extern struct loader_ops elf_ops;
+
+/**
+ * elf_identify - check if it is an ELF file
+ *
+ * It will check if the input image header is an ELF header.
+ *
+ * @img_data: firmware private data which will be passed to user defined loader
+ *            operations
+ * @len: firmware header length
+ *
+ * return 0 for success or negative value for failure.
+ */
+int elf_identify(const void *img_data, size_t len);
+
+/**
+ * elf_load_header - Load ELF headers
+ *
+ * It will get the ELF header, the program header, and the section header.
+ *
+ * @img_data: image data
+ * @offset: input image data offset to the start of image file
+ * @len: input image data length
+ * @img_info: pointer to store image information data
+ * @last_load_state: last state return by this function
+ * @noffset: pointer to next offset required by loading ELF header
+ * @nlen: pointer to next data length required by loading ELF header
+ *
+ * return ELF loading header state, or negative value for failure
+ */
+int elf_load_header(const void *img_data, size_t offset, size_t len,
+		    void **img_info, int last_load_state,
+		    size_t *noffset, size_t *nlen);
+
+/**
+ * elf_load - load ELF data
+ *
+ * It will parse the ELF image and return the target device address,
+ * offset to the start of the ELF image of the data to load and the
+ * length of the data to load.
+ *
+ * @rproc: pointer to remoteproc instance
+ * @img_data: image data which will passed to the function.
+ *            it can be NULL, if image data doesn't need to be handled
+ *            by the load function. E.g. binary data which was
+ *            loaded to the target memory.
+ * @offset: last loaded image data offset to the start of image file
+ * @len: last loaded image data length
+ * @img_info: pointer to store image information data
+ * @last_load_state: the returned state of the last function call.
+ * @da: target device address, if the data to load is not for target memory
+ *      the da will be set to ANY.
+ * @noffset: pointer to next offset required by loading ELF header
+ * @nlen: pointer to next data length required by loading ELF header
+ * @padding: value to pad it is possible that a size of a segment in memory
+ *           is larger than what it is in the ELF image. e.g. a segment
+ *           can have stack section .bss. It doesn't need to copy image file
+ *           space, in this case, it will be packed with 0.
+ * @nmemsize: pointer to next data target memory size. The size of a segment
+ *            in the target memory can be larger than the its size in the
+ *            image file.
+ *
+ * return 0 for success, otherwise negative value for failure
+ */
+int elf_load(struct remoteproc *rproc, const void *img_data,
+	     size_t offset, size_t len,
+	     void **img_info, int last_load_state,
+	     metal_phys_addr_t *da,
+	     size_t *noffset, size_t *nlen,
+	     unsigned char *padding, size_t *nmemsize);
+
+/**
+ * elf_release - Release ELF image information
+ *
+ * It will release ELF image information data.
+ *
+ * @img_info: pointer to ELF image information
+ */
+void elf_release(void *img_info);
+
+/**
+ * elf_get_entry - Get entry point
+ *
+ * It will return entry point specified in the ELF file.
+ *
+ * @img_info: pointer to ELF image information
+ *
+ * return entry address
+ */
+metal_phys_addr_t elf_get_entry(void *img_info);
+
+/**
+ * elf_locate_rsc_table - locate the resource table information
+ *
+ * It will return the length of the resource table, and the device address of
+ * the resource table.
+ *
+ * @img_info: pointer to ELF image information
+ * @da: pointer to the device address
+ * @offset: pointer to the offset to in the ELF image of the resource
+ *          table section.
+ * @size: pointer to the size of the resource table section.
+ *
+ * return 0 if successfully locate the resource table, negative value for
+ * failure.
+ */
+int elf_locate_rsc_table(void *img_info, metal_phys_addr_t *da,
+			 size_t *offset, size_t *size);
+
+#if defined __cplusplus
+}
+#endif
+
+#endif /* ELF_LOADER_H_ */

+ 17 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/open-amp/lib/include/openamp/open_amp.h

@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2014, Mentor Graphics Corporation
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef OPEN_AMP_H_
+#define OPEN_AMP_H_
+
+#include <openamp/rpmsg.h>
+#include <openamp/rpmsg_virtio.h>
+#include <openamp/remoteproc.h>
+#include <openamp/remoteproc_virtio.h>
+
+
+#endif				/* OPEN_AMP_H_ */

+ 871 - 0
bsp/stm32/stm32mp157a-st-discovery/board/ports/OpenAMP/open-amp/lib/include/openamp/remoteproc.h

@@ -0,0 +1,871 @@
+/*
+ * Remoteproc Framework
+ *
+ * Copyright(c) 2018 Xilinx Ltd.
+ * Copyright(c) 2011 Texas Instruments, Inc.
+ * Copyright(c) 2011 Google, Inc.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: BSD-3-Clause
+ */
+
+#ifndef REMOTEPROC_H
+#define REMOTEPROC_H
+
+#include <metal/io.h>
+#include <metal/mutex.h>
+#include <openamp/compiler.h>
+
+#if defined __cplusplus
+extern "C" {
+#endif
+
+#define RSC_NOTIFY_ID_ANY 0xFFFFFFFFUL
+
+/**
+ * struct resource_table - firmware resource table header
+ * @ver: version number
+ * @num: number of resource entries
+ * @reserved: reserved (must be zero)
+ * @offset: array of offsets pointing at the various resource entries
+ *
+ * A resource table is essentially a list of system resources required
+ * by the remote remote_proc. It may also include configuration entries.
+ * If needed, the remote remote_proc firmware should contain this table
+ * as a dedicated ".resource_table" ELF section.
+ *
+ * Some resources entries are mere announcements, where the host is informed
+ * of specific remoteproc configuration. Other entries require the host to
+ * do something (e.g. allocate a system resource). Sometimes a negotiation
+ * is expected, where the firmware requests a resource, and once allocated,
+ * the host should provide back its details (e.g. address of an allocated
+ * memory region).
+ *
+ * The header of the resource table, as expressed by this structure,
+ * contains a version number (should we need to change this format in the
+ * future), the number of available resource entries, and their offsets
+ * in the table.
+ *
+ * Immediately following this header are the resource entries themselves,
+ * each of which begins with a resource entry header (as described below).
+ */
+OPENAMP_PACKED_BEGIN
+struct resource_table {
+	uint32_t ver;
+	uint32_t num;
+	uint32_t reserved[2];
+	uint32_t offset[0];
+} OPENAMP_PACKED_END;
+
+/**
+ * struct fw_rsc_hdr - firmware resource entry header
+ * @type: resource type
+ * @data: resource data
+ *
+ * Every resource entry begins with a 'struct fw_rsc_hdr' header providing
+ * its @type. The content of the entry itself will immediately follow
+ * this header, and it should be parsed according to the resource type.
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_hdr {
+	uint32_t type;
+	uint8_t data[0];
+} OPENAMP_PACKED_END;
+
+/**
+ * enum fw_resource_type - types of resource entries
+ *
+ * @RSC_CARVEOUT:   request for allocation of a physically contiguous
+ *          memory region.
+ * @RSC_DEVMEM:     request to iommu_map a memory-based peripheral.
+ * @RSC_TRACE:      announces the availability of a trace buffer into which
+ *          the remote remote_proc will be writing logs.
+ * @RSC_VDEV:       declare support for a virtio device, and serve as its
+ *          virtio header.
+ * @RSC_VENDOR_START: start of the vendor specific resource types range
+ * @RSC_VENDOR_END  : end of the vendor specific resource types range
+ * @RSC_LAST:       just keep this one at the end
+ *
+ * For more details regarding a specific resource type, please see its
+ * dedicated structure below.
+ *
+ * Please note that these values are used as indices to the rproc_handle_rsc
+ * lookup table, so please keep them sane. Moreover, @RSC_LAST is used to
+ * check the validity of an index before the lookup table is accessed, so
+ * please update it as needed.
+ */
+enum fw_resource_type {
+	RSC_CARVEOUT = 0,
+	RSC_DEVMEM = 1,
+	RSC_TRACE = 2,
+	RSC_VDEV = 3,
+	RSC_RPROC_MEM = 4,
+	RSC_FW_CHKSUM = 5,
+	RSC_LAST = 6,
+	RSC_VENDOR_START = 128,
+	RSC_VENDOR_END = 512,
+};
+
+#define FW_RSC_ADDR_ANY (0xFFFFFFFFFFFFFFFF)
+#define FW_RSC_U32_ADDR_ANY (0xFFFFFFFF)
+
+/**
+ * struct fw_rsc_carveout - physically contiguous memory request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested memory region
+ *
+ * This resource entry requests the host to allocate a physically contiguous
+ * memory region.
+ *
+ * These request entries should precede other firmware resource entries,
+ * as other entries might request placing other data objects inside
+ * these memory regions (e.g. data/code segments, trace resource entries, ...).
+ *
+ * Allocating memory this way helps utilizing the reserved physical memory
+ * (e.g. CMA) more efficiently, and also minimizes the number of TLB entries
+ * needed to map it (in case @rproc is using an IOMMU). Reducing the TLB
+ * pressure is important; it may have a substantial impact on performance.
+ *
+ * If the firmware is compiled with static addresses, then @da should specify
+ * the expected device address of this memory region. If @da is set to
+ * FW_RSC_ADDR_ANY, then the host will dynamically allocate it, and then
+ * overwrite @da with the dynamically allocated address.
+ *
+ * We will always use @da to negotiate the device addresses, even if it
+ * isn't using an iommu. In that case, though, it will obviously contain
+ * physical addresses.
+ *
+ * Some remote remote_procs needs to know the allocated physical address
+ * even if they do use an iommu. This is needed, e.g., if they control
+ * hardware accelerators which access the physical memory directly (this
+ * is the case with OMAP4 for instance). In that case, the host will
+ * overwrite @pa with the dynamically allocated physical address.
+ * Generally we don't want to expose physical addresses if we don't have to
+ * (remote remote_procs are generally _not_ trusted), so we might want to
+ * change this to happen _only_ when explicitly required by the hardware.
+ *
+ * @flags is used to provide IOMMU protection flags, and @name should
+ * (optionally) contain a human readable name of this carveout region
+ * (mainly for debugging purposes).
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_carveout {
+	uint32_t type;
+	uint32_t da;
+	uint32_t pa;
+	uint32_t len;
+	uint32_t flags;
+	uint32_t reserved;
+	uint8_t name[32];
+} OPENAMP_PACKED_END;
+
+/**
+ * struct fw_rsc_devmem - iommu mapping request
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @flags: iommu protection flags
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the requested region to be mapped
+ *
+ * This resource entry requests the host to iommu map a physically contiguous
+ * memory region. This is needed in case the remote remote_proc requires
+ * access to certain memory-based peripherals; _never_ use it to access
+ * regular memory.
+ *
+ * This is obviously only needed if the remote remote_proc is accessing memory
+ * via an iommu.
+ *
+ * @da should specify the required device address, @pa should specify
+ * the physical address we want to map, @len should specify the size of
+ * the mapping and @flags is the IOMMU protection flags. As always, @name may
+ * (optionally) contain a human readable name of this mapping (mainly for
+ * debugging purposes).
+ *
+ * Note: at this point we just "trust" those devmem entries to contain valid
+ * physical addresses, but this isn't safe and will be changed: eventually we
+ * want remoteproc implementations to provide us ranges of physical addresses
+ * the firmware is allowed to request, and not allow firmwares to request
+ * access to physical addresses that are outside those ranges.
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_devmem {
+	uint32_t type;
+	uint32_t da;
+	uint32_t pa;
+	uint32_t len;
+	uint32_t flags;
+	uint32_t reserved;
+	uint8_t name[32];
+} OPENAMP_PACKED_END;
+
+/**
+ * struct fw_rsc_trace - trace buffer declaration
+ * @da: device address
+ * @len: length (in bytes)
+ * @reserved: reserved (must be zero)
+ * @name: human-readable name of the trace buffer
+ *
+ * This resource entry provides the host information about a trace buffer
+ * into which the remote remote_proc will write log messages.
+ *
+ * @da specifies the device address of the buffer, @len specifies
+ * its size, and @name may contain a human readable name of the trace buffer.
+ *
+ * After booting the remote remote_proc, the trace buffers are exposed to the
+ * user via debugfs entries (called trace0, trace1, etc..).
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_trace {
+	uint32_t type;
+	uint32_t da;
+	uint32_t len;
+	uint32_t reserved;
+	uint8_t name[32];
+} OPENAMP_PACKED_END;
+
+/**
+ * struct fw_rsc_vdev_vring - vring descriptor entry
+ * @da: device address
+ * @align: the alignment between the consumer and producer parts of the vring
+ * @num: num of buffers supported by this vring (must be power of two)
+ * @notifyid is a unique rproc-wide notify index for this vring. This notify
+ * index is used when kicking a remote remote_proc, to let it know that this
+ * vring is triggered.
+ * @reserved: reserved (must be zero)
+ *
+ * This descriptor is not a resource entry by itself; it is part of the
+ * vdev resource type (see below).
+ *
+ * Note that @da should either contain the device address where
+ * the remote remote_proc is expecting the vring, or indicate that
+ * dynamically allocation of the vring's device address is supported.
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_vdev_vring {
+	uint32_t da;
+	uint32_t align;
+	uint32_t num;
+	uint32_t notifyid;
+	uint32_t reserved;
+} OPENAMP_PACKED_END;
+
+/**
+ * struct fw_rsc_vdev - virtio device header
+ * @id: virtio device id (as in virtio_ids.h)
+ * @notifyid is a unique rproc-wide notify index for this vdev. This notify
+ * index is used when kicking a remote remote_proc, to let it know that the
+ * status/features of this vdev have changes.
+ * @dfeatures specifies the virtio device features supported by the firmware
+ * @gfeatures is a place holder used by the host to write back the
+ * negotiated features that are supported by both sides.
+ * @config_len is the size of the virtio config space of this vdev. The config
+ * space lies in the resource table immediate after this vdev header.
+ * @status is a place holder where the host will indicate its virtio progress.
+ * @num_of_vrings indicates how many vrings are described in this vdev header
+ * @reserved: reserved (must be zero)
+ * @vring is an array of @num_of_vrings entries of 'struct fw_rsc_vdev_vring'.
+ *
+ * This resource is a virtio device header: it provides information about
+ * the vdev, and is then used by the host and its peer remote remote_procs
+ * to negotiate and share certain virtio properties.
+ *
+ * By providing this resource entry, the firmware essentially asks remoteproc
+ * to statically allocate a vdev upon registration of the rproc (dynamic vdev
+ * allocation is not yet supported).
+ *
+ * Note: unlike virtualization systems, the term 'host' here means
+ * the Linux side which is running remoteproc to control the remote
+ * remote_procs. We use the name 'gfeatures' to comply with virtio's terms,
+ * though there isn't really any virtualized guest OS here: it's the host
+ * which is responsible for negotiating the final features.
+ * Yeah, it's a bit confusing.
+ *
+ * Note: immediately following this structure is the virtio config space for
+ * this vdev (which is specific to the vdev; for more info, read the virtio
+ * spec). the size of the config space is specified by @config_len.
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_vdev {
+	uint32_t type;
+	uint32_t id;
+	uint32_t notifyid;
+	uint32_t dfeatures;
+	uint32_t gfeatures;
+	uint32_t config_len;
+	uint8_t status;
+	uint8_t num_of_vrings;
+	uint8_t reserved[2];
+	struct fw_rsc_vdev_vring vring[0];
+} OPENAMP_PACKED_END;
+
+/**
+ * struct fw_rsc_vendor - remote processor vendor specific resource
+ * @len: length of the resource
+ *
+ * This resource entry tells the host the vendor specific resource
+ * required by the remote.
+ *
+ * These request entries should precede other shared resource entries
+ * such as vdevs, vrings.
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_vendor {
+	uint32_t type;
+	uint32_t len;
+} OPENAMP_PACKED_END;
+
+/**
+ * struct fw_rsc_rproc_mem - remote processor memory
+ * @da: device address
+ * @pa: physical address
+ * @len: length (in bytes)
+ * @reserved: reserved (must be zero)
+ *
+ * This resource entry tells the host to the remote processor
+ * memory that the host can be used as shared memory.
+ *
+ * These request entries should precede other shared resource entries
+ * such as vdevs, vrings.
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_rproc_mem {
+	uint32_t type;
+	uint32_t da;
+	uint32_t pa;
+	uint32_t len;
+	uint32_t reserved;
+} OPENAMP_PACKED_END;
+
+/*
+ * struct fw_rsc_fw_chksum - firmware checksum
+ * @algo: algorithm to generate the cheksum
+ * @chksum: checksum of the firmware loadable sections.
+ *
+ * This resource entry provides checksum for the firmware loadable sections.
+ * It is used to check if the remote already runs with the expected firmware to
+ * decide if it needs to start the remote if the remote is already running.
+ */
+OPENAMP_PACKED_BEGIN
+struct fw_rsc_fw_chksum {
+	uint32_t type;
+	uint8_t algo[16];
+	uint8_t chksum[64];
+} OPENAMP_PACKED_END;
+
+struct loader_ops;
+struct image_store_ops;
+struct remoteproc_ops;
+
+/**
+ * struct remoteproc_mem
+ *
+ * This structure presents the memory used by the remote processor
+ *
+ * @da: device memory
+ * @pa: physical memory
+ * @size: size of the memory
+ * @io: pointer to the I/O region
+ * @node: list node
+ */
+struct remoteproc_mem {
+	metal_phys_addr_t da;
+	metal_phys_addr_t pa;
+	size_t size;
+	char name[32];
+	struct metal_io_region *io;
+	struct metal_list node;
+};
+
+/**
+ * struct remoteproc
+ *
+ * This structure is maintained by the remoteproc to represent the remote
+ * processor instance. This structure acts as a prime parameter to use
+ * the remoteproc APIs.
+ *
+ * @bootadd: boot address
+ * @loader: executable loader
+ * @lock: mutext lock
+ * @ops: remoteproc operations
+ * @rsc_table: pointer to resource table
+ * @rsc_len: length of resource table
+ * @rsc_io: metal I/O region of resource table
+ * @mems: remoteproc memories
+ * @vdevs: remoteproc virtio devices
+ * @bitmap: bitmap for notify IDs for remoteproc subdevices
+ * @state: remote processor state
+ * @priv: private data
+ */
+struct remoteproc {
+	metal_mutex_t lock;
+	void *rsc_table;
+	size_t rsc_len;
+	struct metal_io_region *rsc_io;
+	struct metal_list mems;
+	struct metal_list vdevs;
+	unsigned long bitmap;
+	struct remoteproc_ops *ops;
+	metal_phys_addr_t bootaddr;
+	struct loader_ops *loader;
+	unsigned int state;
+	void *priv;
+};
+
+/**
+ * struct remoteproc_ops
+ *
+ * remoteproc operations needs to be implemented by each remoteproc driver
+ *
+ * @init: initialize the remoteproc instance
+ * @remove: remove the remoteproc instance
+ * @mmap: memory mapped the mempory with physical address or destination
+ *        address as input.
+ * @handle_rsc: handle the vendor specific resource
+ * @config: configure the remoteproc to make it ready to load and run
+ *          executable
+ * @start: kick the remoteproc to run application
+ * @stop: stop the remoteproc from running application, the resource such as
+ *        memory may not be off.
+ * @shutdown: shutdown the remoteproc and release its resources.
+ * @notify: notify the remote
+ */
+struct remoteproc_ops {
+	struct remoteproc *(*init)(struct remoteproc *rproc,
+				   struct remoteproc_ops *ops, void *arg);
+	void (*remove)(struct remoteproc *rproc);
+	void *(*mmap)(struct remoteproc *rproc,
+		      metal_phys_addr_t *pa, metal_phys_addr_t *da,
+		      size_t size, unsigned int attribute,
+		      struct metal_io_region **io);
+	int (*handle_rsc)(struct remoteproc *rproc, void *rsc, size_t len);
+	int (*config)(struct remoteproc *rproc, void *data);
+	int (*start)(struct remoteproc *rproc);
+	int (*stop)(struct remoteproc *rproc);
+	int (*shutdown)(struct remoteproc *rproc);
+	int (*notify)(struct remoteproc *rproc, uint32_t id);
+};
+
+/* Remoteproc error codes */
+#define RPROC_EBASE	0
+#define RPROC_ENOMEM	(RPROC_EBASE + 1)
+#define RPROC_EINVAL	(RPROC_EBASE + 2)
+#define RPROC_ENODEV	(RPROC_EBASE + 3)
+#define RPROC_EAGAIN	(RPROC_EBASE + 4)
+#define RPROC_ERR_RSC_TAB_TRUNC (RPROC_EBASE + 5)
+#define RPROC_ERR_RSC_TAB_VER   (RPROC_EBASE + 6)
+#define RPROC_ERR_RSC_TAB_RSVD  (RPROC_EBASE + 7)
+#define RPROC_ERR_RSC_TAB_VDEV_NRINGS (RPROC_EBASE + 9)
+#define RPROC_ERR_RSC_TAB_NP          (RPROC_EBASE + 10)
+#define RPROC_ERR_RSC_TAB_NS          (RPROC_EBASE + 11)
+#define RPROC_ERR_LOADER_STATE (RPROC_EBASE + 12)
+#define RPROC_EMAX	(RPROC_EBASE + 16)
+#define RPROC_EPTR	(void *)(-1)
+#define RPROC_EOF	(void *)(-1)
+
+static inline long RPROC_PTR_ERR(const void *ptr)
+{
+	return (long)ptr;
+}
+
+static inline int RPROC_IS_ERR(const void *ptr)
+{
+	if ((unsigned long)ptr >= (unsigned long)(-RPROC_EMAX))
+		return 1;
+	else
+		return 0;
+}
+
+static inline void *RPROC_ERR_PTR(long error)
+{
+	return (void *)error;
+}
+
+/**
+ * enum rproc_state - remote processor states
+ * @RPROC_OFFLINE:	remote is offline
+ * @RPROC_READY:	remote is ready to start
+ * @RPROC_RUNNING:	remote is up and running
+ * @RPROC_SUSPENDED:	remote is suspended
+ * @RPROC_ERROR:	remote has error; need to recover
+ * @RPROC_STOPPED:	remote is stopped
+ * @RPROC_LAST:		just keep this one at the end
+ */
+enum remoteproc_state {
+	RPROC_OFFLINE		= 0,
+	RPROC_CONFIGURED	= 1,
+	RPROC_READY		= 2,
+	RPROC_RUNNING		= 3,
+	RPROC_SUSPENDED		= 4,
+	RPROC_ERROR		= 5,
+	RPROC_STOPPED		= 6,
+	RPROC_LAST		= 7,
+};
+
+/**
+ * remoteproc_init
+ *
+ * Initializes remoteproc resource.
+ *
+ * @rproc - pointer to remoteproc instance
+ * @ops - pointer to remoteproc operations
+ * @priv - pointer to private data
+ *
+ * @returns created remoteproc pointer
+ */
+struct remoteproc *remoteproc_init(struct remoteproc *rproc,
+				   struct remoteproc_ops *ops, void *priv);
+
+/**
+ * remoteproc_remove
+ *
+ * Remove remoteproc resource
+ *
+ * @rproc - pointer to remoteproc instance
+ *
+ * returns 0 for success, negative value for failure
+ */
+int remoteproc_remove(struct remoteproc *rproc);
+
+/**
+ * remoteproc_init_mem
+ *
+ * Initialize remoteproc memory
+ *
+ * @mem - pointer to remoteproc memory
+ * @char - memory name
+ * @pa - physcial address
+ * @da - device address
+ * @size - memory size
+ * @io - pointer to the I/O region
+ */
+static inline void
+remoteproc_init_mem(struct remoteproc_mem *mem, const char *name,
+		    metal_phys_addr_t pa, metal_phys_addr_t da,
+		    size_t size, struct metal_io_region *io)
+{
+	if (!mem)
+		return;
+	if (name)
+		strncpy(mem->name, name, sizeof(mem->name));
+	else
+		mem->name[0] = 0;
+	mem->pa = pa;
+	mem->da = da;
+	mem->io = io;
+	mem->size = size;
+}
+
+/**
+ * remoteproc_add_mem
+ *
+ * Add remoteproc memory
+ *
+ * @rproc - pointer to remoteproc
+ * @mem - pointer to remoteproc memory
+ */
+static inline void
+remoteproc_add_mem(struct remoteproc *rproc, struct remoteproc_mem *mem)
+{
+	if (!rproc || !mem)
+		return;
+	metal_list_add_tail(&rproc->mems, &mem->node);
+}
+
+/**
+ * remoteproc_get_io_with_name
+ *
+ * get remoteproc memory I/O region with name
+ *
+ * @rproc - pointer to the remote processor
+ * @name - name of the shared memory
+ * @io - pointer to the pointer of the I/O region
+ *
+ * returns metal I/O region pointer, NULL for failure
+ */
+struct metal_io_region *
+remoteproc_get_io_with_name(struct remoteproc *rproc,
+			    const char *name);
+
+/**
+ * remoteproc_get_io_with_pa
+ *
+ * get remoteproc memory I/O region with physical address
+ *
+ * @rproc - pointer to the remote processor
+ * @pa - physical address
+ *
+ * returns metal I/O region pointer, NULL for failure
+ */
+struct metal_io_region *
+remoteproc_get_io_with_pa(struct remoteproc *rproc,
+			  metal_phys_addr_t pa);
+
+/**
+ * remoteproc_get_io_with_da
+ *
+ * get remoteproc memory I/O region with device address
+ *
+ * @rproc - pointer to the remote processor
+ * @da - device address
+ * @offset - I/O region offset of the device address
+ *
+ * returns metal I/O region pointer, NULL for failure
+ */
+struct metal_io_region *
+remoteproc_get_io_with_da(struct remoteproc *rproc,
+			  metal_phys_addr_t da,
+			  unsigned long *offset);
+
+/**
+ * remoteproc_get_io_with_va
+ *
+ * get remoteproc memory I/O region with virtual address
+ *
+ * @rproc - pointer to the remote processor
+ * @va - virtual address
+ *
+ * returns metal I/O region pointer, NULL for failure
+ */
+struct metal_io_region *
+remoteproc_get_io_with_va(struct remoteproc *rproc,
+			  void *va);
+
+/**
+ * remoteproc_mmap
+ *
+ * remoteproc mmap memory
+ *
+ * @rproc - pointer to the remote processor
+ * @pa - physical address pointer
+ * @da - device address pointer
+ * @size - size of the memory
+ * @attribute - memory attribute
+ * @io - pointer to the I/O region
+ *
+ * returns pointer to the memory
+ */
+void *remoteproc_mmap(struct remoteproc *rproc,
+		      metal_phys_addr_t *pa, metal_phys_addr_t *da,
+		      size_t size, unsigned int attribute,
+		      struct metal_io_region **io);
+
+/**
+ * remoteproc_parse_rsc_table
+ *
+ * Parse resource table of remoteproc
+ *
+ * @rproc - pointer to remoteproc instance
+ * @rsc_table - pointer to resource table
+ * @rsc_size - resource table size
+ *
+ * returns 0 for success and negative value for errors
+ */
+int remoteproc_parse_rsc_table(struct remoteproc *rproc,
+			       struct resource_table *rsc_table,
+			       size_t rsc_size);
+
+/**
+ * remoteproc_set_rsc_table
+ *
+ * Parse and set resource table of remoteproc
+ *
+ * @rproc - pointer to remoteproc instance
+ * @rsc_table - pointer to resource table
+ * @rsc_size - resource table size
+ *
+ * returns 0 for success and negative value for errors
+ */
+int remoteproc_set_rsc_table(struct remoteproc *rproc,
+			     struct resource_table *rsc_table,
+			     size_t rsc_size);
+
+/**
+ * remoteproc_config
+ *
+ * This function configures the remote processor to get it
+ * ready to load and run executable.
+ *
+ * @rproc - pointer to remoteproc instance to start
+ * @data - configuration data
+ *
+ * returns 0 for success and negative value for errors
+ */
+int remoteproc_config(struct remoteproc *rproc, void *data);
+
+/**
+ * remoteproc_start
+ *
+ * This function starts the remote processor.
+ * It assumes the firmware is already loaded,
+ *
+ * @rproc - pointer to remoteproc instance to start
+ *
+ * returns 0 for success and negative value for errors
+ */
+int remoteproc_start(struct remoteproc *rproc);
+
+/**
+ * remoteproc_stop
+ *
+ * This function stops the remote processor but it
+ * will not release its resource.
+ *
+ * @rproc - pointer to remoteproc instance
+ *
+ * returns 0 for success and negative value for errors
+ */
+int remoteproc_stop(struct remoteproc *rproc);
+
+/**
+ * remoteproc_shutdown
+ *
+ * This function shutdown the remote processor and
+ * release its resources.
+ *
+ * @rproc - pointer to remoteproc instance
+ *
+ * returns 0 for success and negative value for errors
+ */
+int remoteproc_shutdown(struct remoteproc *rproc);
+
+/**
+ * remoteproc_load
+ *
+ * load executable, it expects the user application defines how to
+ * open the executable file and how to get data from the executable file
+ * and how to load data to the target memory.
+ *
+ * @rproc: pointer to the remoteproc instance
+ * @path: optional path to the image file
+ * @store: pointer to user defined image store argument
+ * @store_ops: pointer to image store operations
+ * @image_info: pointer to memory which stores image information used
+ *              by remoteproc loader
+ *
+ * return 0 for success and negative value for failure
+ */
+int remoteproc_load(struct remoteproc *rproc, const char *path,
+		    void *store, struct image_store_ops *store_ops,
+		    void **img_info);
+
+/**
+ * remoteproc_load_noblock
+ *
+ * load executable, it expects the caller has loaded image data to local
+ * memory and passed to the this function. If the function needs more
+ * image data it will return the next expected image data offset and
+ * the next expected image data length. If the function requires the
+ * caller to download image data to the target memory, it will also
+ * return the target physical address besides the offset and length.
+ * This function can be used to load firmware in stream mode. In this
+ * mode, you cannot do seek to the executable file. If the executable
+ * is ELF, it cannot get the resource table section before it loads
+ * the full ELF file. Furthermore, application usually don't store
+ * the data which is loaded to local memory in streaming mode, and
+ * thus, in this mode, it will load the binrary to the target memory
+ * before it gets the resource table. And thus, when calling this funciton
+ * don't put the target exectuable memory in the resource table, as
+ * this function will parse the resource table after it loads the binary
+ * to target memory.
+ *
+ * @rproc: pointer to the remoteproc instance
+ * @img_data: pointer to image data for remoteproc loader to parse
+ * @offset: image data offset to the beginning of the image file
+ * @len: image data length
+ * @image_info: pointer to memory which stores image information used
+ *              by remoteproc loader
+ * @pa: pointer to the target memory physical address. If the next expected
+ *      data doesn't need to load to the target memory, the function will
+ *      set it to ANY.
+ * @io: pointer to the target memory physical address. If the next expected
+ *      data doesn't need to load to the target memory, the function will
+ *      set it to ANY.
+ * @noffset: pointer to the next image data offset to the beginning of
+ *           the image file needs to load to local or to the target
+ *           memory.
+ * @nlen: pointer to the next image data length needs to load to local
+ *        or to the target memory.
+ * @nmlen: pointer to the memory size. It is only used when the next
+ *         expected data is going to be loaded to the target memory. E.g.
+ *         in ELF, it is possible that loadable segment in memory is
+ *         larger that the segment data in the ELF file. In this case,
+ *         application will need to pad the rest of the memory with
+ *         padding.
+ * @padding: pointer to the padding value. It is only used when the next
+ *           expected data is going to be loaded to the target memory.
+ *           and the target memory size is larger than the segment data in
+ *           the executable file.
+ *
+ * return 0 for success and negative value for failure
+ */
+int remoteproc_load_noblock(struct remoteproc *rproc,
+			    const void *img_data, size_t offset, size_t len,
+			    void **img_info,
+			    metal_phys_addr_t *pa, struct metal_io_region **io,
+			    size_t *noffset, size_t *nlen,
+			    size_t *nmlen, unsigned char *padding);
+
+/**
+ * remoteproc_allocate_id
+ *
+ * allocate notifyid for resource
+ *
+ * @rproc - pointer to the remoteproc instance
+ * @start - start of the id range
+ * @end - end of the id range
+ *
+ * return allocated notify id
+ */
+unsigned int remoteproc_allocate_id(struct remoteproc *rproc,
+				    unsigned int start,
+				    unsigned int end);
+
+/* remoteproc_create_virtio
+ *
+ * create virtio device, it returns pointer to the created virtio device.
+ *
+ * @rproc: pointer to the remoteproc instance
+ * @vdev_id: virtio device ID
+ * @role: virtio device role
+ * @rst_cb: virtio device reset callback
+ *
+ * return pointer to the created virtio device, NULL for failure.
+ */
+struct virtio_device *
+remoteproc_create_virtio(struct remoteproc *rproc,
+			 int vdev_id, unsigned int role,
+			 void (*rst_cb)(struct virtio_device *vdev));
+
+/* remoteproc_remove_virtio
+ *
+ * Remove virtio device
+ *
+ * @rproc: pointer to the remoteproc instance
+ * @vdev: pointer to the virtio device
+ *
+ */
+void remoteproc_remove_virtio(struct remoteproc *rproc,
+			      struct virtio_device *vdev);
+
+/* remoteproc_get_notification
+ *
+ * remoteproc is got notified, it will check its subdevices
+ * for the notification
+ *
+ * @rproc -  pointer to the remoteproc instance
+ * @notifyid - notificatin id
+ *
+ * return 0 for succeed, negative value for failure
+ */
+int remoteproc_get_notification(struct remoteproc *rproc,
+				uint32_t notifyid);
+#if defined __cplusplus
+}
+#endif
+
+#endif /* REMOTEPROC_H_ */

Some files were not shown because too many files changed in this diff