1 /*
2 * Copyright (c) 2025 Silicon Laboratories Inc.
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 /**
8 * @file
9 * @brief Test for driver relocation to RAM for ISRs
10 *
11 * This test demonstrates how to use the fake_driver and verify
12 * that the callback are properly relocated to RAM.
13 */
14
15 #if !defined(CONFIG_CPU_CORTEX_M)
16 #error project can only run on Cortex-M for now
17 #endif
18
19 #include <zephyr/ztest.h>
20 #include "fake_driver.h"
21
22 static volatile bool test_flag;
23
test_irq_callback(const struct device * dev,void * user_data)24 static void test_irq_callback(const struct device *dev, void *user_data)
25 {
26 uintptr_t func_addr = (uintptr_t)test_irq_callback;
27 uintptr_t driver_isr_addr, arch_isr_wrapper_addr;
28
29 test_flag = true;
30
31 /* Retrieve the caller address (the arch specific isr wrapper since driver isr will be
32 * optimized by the compiler)
33 */
34 __asm__ volatile("mov %0, lr" : "=r"(arch_isr_wrapper_addr));
35
36 /* retrieve the fake_driver_isr function address that was stored in user_data */
37 driver_isr_addr = (uintptr_t)user_data;
38
39 /* Check that the function and its call stack are in RAM */
40 zassert_true(func_addr >= CONFIG_SRAM_BASE_ADDRESS &&
41 func_addr <= CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE * 1024,
42 "%s is not in RAM! Address: 0x%lx", __func__, func_addr);
43
44 zassert_true(driver_isr_addr >= CONFIG_SRAM_BASE_ADDRESS &&
45 driver_isr_addr <= CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE * 1024,
46 "fake_driver_isr is not in RAM! Address: 0x%lx", driver_isr_addr);
47
48 zassert_true(arch_isr_wrapper_addr >= CONFIG_SRAM_BASE_ADDRESS &&
49 arch_isr_wrapper_addr <=
50 CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE * 1024,
51 "arch_isr_wrapper_addr is not in RAM! Address: 0x%lx", arch_isr_wrapper_addr);
52
53 TC_PRINT("Callback function address: 0x%lx\n", func_addr);
54 TC_PRINT("Driver ISR address: 0x%lx\n", driver_isr_addr);
55 TC_PRINT("Arch ISR wrapper address: 0x%lx\n", arch_isr_wrapper_addr);
56 }
57
ZTEST(ram_context_for_isr,test_fake_driver_in_ram)58 ZTEST(ram_context_for_isr, test_fake_driver_in_ram)
59 {
60 const struct device *dev = DEVICE_DT_GET(DT_NODELABEL(fakedriver));
61 const struct fake_driver_api *api = DEVICE_API_GET(fake, dev);
62 uintptr_t dev_addr = (uintptr_t)dev;
63
64 zassert_true(dev_addr >= CONFIG_SRAM_BASE_ADDRESS &&
65 dev_addr <= CONFIG_SRAM_BASE_ADDRESS + CONFIG_SRAM_SIZE * 1024,
66 "fake driver device is not in RAM! Address: 0x%lx", dev_addr);
67
68 TC_PRINT("Fake driver device address: 0x%lx\n", dev_addr);
69
70 zassert_not_null(api, "Failed to get fake driver API");
71
72 api->register_irq_callback(dev, test_irq_callback, NULL);
73 test_flag = false;
74
75 NVIC_SetPendingIRQ(TEST_IRQ_NUM);
76
77 k_busy_wait(1000);
78
79 zassert_true(test_flag, "ISR callback was not called");
80 }
81
82 ZTEST_SUITE(ram_context_for_isr, NULL, NULL, NULL, NULL, NULL);
83