Skip to content

Commit 4f6f283

Browse files
iabdalkaderdpgeorge
authored andcommitted
alif: Implement Open-AMP port backend.
Signed-off-by: iabdalkader <i.abdalkader@gmail.com>
1 parent 6b4d465 commit 4f6f283

8 files changed

Lines changed: 403 additions & 2 deletions

File tree

ports/alif/Makefile

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -76,10 +76,10 @@ $(BUILD):
7676
$(MKDIR) -p $@
7777

7878
$(BUILD)/M55_HP/firmware.bin:
79-
make -f alif.mk MCU_CORE=M55_HP
79+
make -f alif.mk MCU_CORE=M55_HP MICROPY_PY_OPENAMP_MODE=0
8080

8181
$(BUILD)/M55_HE/firmware.bin:
82-
make -f alif.mk MCU_CORE=M55_HE
82+
make -f alif.mk MCU_CORE=M55_HE MICROPY_PY_OPENAMP_MODE=1
8383

8484
$(BUILD)/firmware.toc.bin: $(ALIF_TOC_APPS)
8585
$(Q)python $(ALIF_TOOLS)/app-gen-toc.py \

ports/alif/alif.mk

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -203,6 +203,17 @@ $(BUILD)/tinyusb_port/tusb_alif_dcd.o: CFLAGS += -Wno-unused-variable -DTUSB_ALI
203203
$(BUILD)/$(ALIF_DFP_REL_TOP)/se_services/source/services_host_boot.o: CFLAGS += -Wno-stringop-truncation
204204
$(BUILD)/$(ALIF_DFP_REL_TOP)/se_services/source/services_host_system.o: CFLAGS += -Wno-maybe-uninitialized
205205

206+
# Add Alif-specific implementation of libmetal (and optionally OpenAMP's rproc).
207+
# Note: libmetal code is generated via a pre-processor so ensure that runs first.
208+
ifeq ($(MICROPY_PY_OPENAMP),1)
209+
SRC_C += mpmetalport.c
210+
$(BUILD)/mpmetalport.o: $(BUILD)/openamp/metal/config.h
211+
ifeq ($(MICROPY_PY_OPENAMP_REMOTEPROC),1)
212+
SRC_C += mpremoteprocport.c
213+
$(BUILD)/mpremoteprocport.o: $(BUILD)/openamp/metal/config.h
214+
endif
215+
endif
216+
206217
# List of sources for qstr extraction
207218
SRC_QSTR += $(SRC_C) $(SHARED_SRC_C) $(GEN_PINS_SRC)
208219

ports/alif/irq.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@
4545
#define IRQ_PRI_UART_REPL NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 1, 0)
4646
#define IRQ_PRI_ADC NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 3, 0)
4747
#define IRQ_PRI_USB NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 5, 0)
48+
#define IRQ_PRI_HWSEM NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 8, 0)
4849
#define IRQ_PRI_PENDSV NVIC_EncodePriority(NVIC_PRIORITYGROUP_7, 127, 0)
4950

5051
// these states correspond to values from query_irq, enable_irq and disable_irq

ports/alif/mcu/ensemble.ld.S

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,14 @@ SECTIONS
114114
* (.bss.sram0*)
115115
} > SRAM0
116116

117+
/* Open-AMP Shared Memory Region */
118+
.openamp_memory (NOLOAD) : ALIGN(32)
119+
{
120+
_openamp_shm_region_start = .;
121+
. = . + 64K;
122+
_openamp_shm_region_end = .;
123+
} >SRAM6_A
124+
117125
.bss : ALIGN(4)
118126
{
119127
__bss_start__ = .;

ports/alif/mpconfigport.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#define MICROPY_SCHEDULER_DEPTH (8)
9292
#define MICROPY_SCHEDULER_STATIC_NODES (1)
9393
#define MICROPY_USE_INTERNAL_ERRNO (1)
94+
#define MICROPY_TRACKED_ALLOC (MICROPY_PY_OPENAMP)
9495

9596
// Fine control over Python builtins, classes, modules, etc
9697
#define MICROPY_PY_SYS_PLATFORM "alif"

ports/alif/mpmetalport.c

Lines changed: 119 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2024 OpenMV LLC.
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*
26+
* libmetal Alif port.
27+
*/
28+
29+
#include ALIF_CMSIS_H
30+
#include "hwsem.h"
31+
32+
#include "py/mperrno.h"
33+
#include "py/mphal.h"
34+
35+
#include "metal/sys.h"
36+
#include "metal/utilities.h"
37+
#include "metal/device.h"
38+
39+
struct metal_state _metal;
40+
static mp_sched_node_t rproc_notify_node;
41+
42+
int metal_sys_init(const struct metal_init_params *params) {
43+
metal_unused(params);
44+
45+
// Reset the hardware semaphore.
46+
hwsem_reset(METAL_HSEM_DEVICE);
47+
#if MICROPY_PY_OPENAMP_HOST
48+
hwsem_reset(METAL_HSEM_REMOTE);
49+
#endif
50+
51+
// Enable the hardware semaphore IRQ.
52+
NVIC_ClearPendingIRQ(METAL_HSEM_IRQn);
53+
NVIC_SetPriority(METAL_HSEM_IRQn, IRQ_PRI_HWSEM);
54+
NVIC_EnableIRQ(METAL_HSEM_IRQn);
55+
56+
// If cache management is not enabled, configure the MPU to disable
57+
// caching for the entire Open-AMP shared memory region.
58+
#ifndef VIRTIO_USE_DCACHE
59+
ARM_MPU_Disable();
60+
// NOTE: The startup code uses the first 4 attributes.
61+
#define MEMATTR_IDX_NORMAL_NON_CACHEABLE 4
62+
ARM_MPU_SetMemAttr(MEMATTR_IDX_NORMAL_NON_CACHEABLE, ARM_MPU_ATTR(
63+
ARM_MPU_ATTR_NON_CACHEABLE,
64+
ARM_MPU_ATTR_NON_CACHEABLE));
65+
MPU->RNR = METAL_MPU_REGION_ID;
66+
MPU->RBAR = ARM_MPU_RBAR(METAL_MPU_REGION_BASE, ARM_MPU_SH_NON, 0, 1, 0); // RO-0, NP-1, XN-0
67+
MPU->RLAR = ARM_MPU_RLAR(METAL_MPU_REGION_BASE + METAL_MPU_REGION_SIZE - 1, MEMATTR_IDX_NORMAL_NON_CACHEABLE);
68+
ARM_MPU_Enable(MPU_CTRL_PRIVDEFENA_Msk | MPU_CTRL_HFNMIENA_Msk);
69+
#endif
70+
71+
metal_bus_register(&metal_generic_bus);
72+
73+
return 0;
74+
}
75+
76+
void metal_sys_finish(void) {
77+
NVIC_DisableIRQ(METAL_HSEM_IRQn);
78+
NVIC_ClearPendingIRQ(METAL_HSEM_IRQn);
79+
hwsem_reset(METAL_HSEM_DEVICE);
80+
metal_bus_unregister(&metal_generic_bus);
81+
}
82+
83+
unsigned int sys_irq_save_disable(void) {
84+
return disable_irq();
85+
}
86+
87+
void sys_irq_restore_enable(unsigned int state) {
88+
enable_irq(state);
89+
}
90+
91+
void *metal_machine_io_mem_map(void *va, metal_phys_addr_t pa,
92+
size_t size, unsigned int flags) {
93+
metal_unused(pa);
94+
metal_unused(size);
95+
metal_unused(flags);
96+
return va;
97+
}
98+
99+
void metal_machine_cache_flush(void *addr, unsigned int len) {
100+
SCB_CleanDCache_by_Addr(addr, len);
101+
}
102+
103+
void metal_machine_cache_invalidate(void *addr, unsigned int len) {
104+
SCB_InvalidateDCache_by_Addr(addr, len);
105+
}
106+
107+
int metal_rproc_notify(void *priv, uint32_t id) {
108+
// Release the HW semaphore to notify the other core.
109+
hwsem_release(METAL_HSEM_REMOTE, HWSEM_MASTERID);
110+
return 0;
111+
}
112+
113+
void METAL_HSEM_IRQ_HANDLER(void) {
114+
// Schedule the node only if the other core released the Semaphore.
115+
if (METAL_HSEM_DEVICE->HWSEM_REL_REG == 0) {
116+
mp_sched_schedule_node(&rproc_notify_node, openamp_remoteproc_notified);
117+
}
118+
hwsem_request(METAL_HSEM_DEVICE, METAL_HSEM_REMOTE_ID);
119+
}

ports/alif/mpmetalport.h

Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*
2+
* This file is part of the MicroPython project, http://micropython.org/
3+
*
4+
* The MIT License (MIT)
5+
*
6+
* Copyright (c) 2024 OpenMV LLC.
7+
*
8+
* Permission is hereby granted, free of charge, to any person obtaining a copy
9+
* of this software and associated documentation files (the "Software"), to deal
10+
* in the Software without restriction, including without limitation the rights
11+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
12+
* copies of the Software, and to permit persons to whom the Software is
13+
* furnished to do so, subject to the following conditions:
14+
*
15+
* The above copyright notice and this permission notice shall be included in
16+
* all copies or substantial portions of the Software.
17+
*
18+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
19+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
20+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
21+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
22+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
23+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24+
* THE SOFTWARE.
25+
*
26+
* libmetal alif port.
27+
*/
28+
#ifndef MICROPY_INCLUDED_ALIF_MPMETALPORT_H
29+
#define MICROPY_INCLUDED_ALIF_MPMETALPORT_H
30+
31+
#include <stdlib.h>
32+
#include "py/mphal.h"
33+
#include "py/runtime.h"
34+
35+
#define METAL_HAVE_STDATOMIC_H 0
36+
#define METAL_HAVE_FUTEX_H 0
37+
38+
#define METAL_MAX_DEVICE_REGIONS 2
39+
40+
#if MICROPY_PY_OPENAMP_HOST
41+
#define METAL_HSEM_DEVICE ((HWSEM_Type *)HWSEM14_BASE)
42+
#define METAL_HSEM_REMOTE ((HWSEM_Type *)HWSEM15_BASE)
43+
#define METAL_HSEM_REMOTE_ID (0x410FD222U)
44+
#define METAL_HSEM_IRQn HWSEM_IRQ14_IRQn
45+
#define METAL_HSEM_IRQ_HANDLER HWSEM_IRQ14Handler
46+
#else
47+
#define METAL_HSEM_DEVICE ((HWSEM_Type *)HWSEM15_BASE)
48+
#define METAL_HSEM_REMOTE ((HWSEM_Type *)HWSEM14_BASE)
49+
#define METAL_HSEM_REMOTE_ID (0x410FD221U)
50+
#define METAL_HSEM_IRQn HWSEM_IRQ15_IRQn
51+
#define METAL_HSEM_IRQ_HANDLER HWSEM_IRQ15Handler
52+
#endif
53+
54+
// Set to 1 to enable log output.
55+
#define METAL_LOG_HANDLER_ENABLE 0
56+
57+
#define metal_cpu_yield()
58+
59+
// Shared memory config
60+
#define METAL_SHM_NAME "OPENAMP_SHM"
61+
// Note 1K must be reserved at the start of the openamp
62+
// shared memory region, for the shared resource table.
63+
#define METAL_RSC_ADDR ((void *)_openamp_shm_region_start)
64+
#define METAL_RSC_SIZE (1024)
65+
66+
#define METAL_SHM_ADDR ((metal_phys_addr_t)(_openamp_shm_region_start + METAL_RSC_SIZE))
67+
#define METAL_SHM_SIZE ((size_t)(_openamp_shm_region_end - _openamp_shm_region_start - METAL_RSC_SIZE))
68+
69+
#define METAL_MPU_REGION_ID (9) // NOTE: The startup code uses the first 9 regions.
70+
#define METAL_MPU_REGION_BASE ((uint32_t)_openamp_shm_region_start)
71+
#define METAL_MPU_REGION_SIZE (0x00010000U)
72+
73+
extern const char _openamp_shm_region_start[];
74+
extern const char _openamp_shm_region_end[];
75+
76+
int metal_rproc_notify(void *priv, uint32_t id);
77+
extern void openamp_remoteproc_notified(mp_sched_node_t *node);
78+
79+
static inline int __metal_sleep_usec(unsigned int usec) {
80+
mp_hal_delay_us(usec);
81+
return 0;
82+
}
83+
84+
static inline void metal_generic_default_poll(void) {
85+
mp_event_handle_nowait();
86+
__WFI();
87+
}
88+
89+
#endif // MICROPY_INCLUDED_ALIF_METAL_PORT_H

0 commit comments

Comments
 (0)