1 /*
2  * Copyright (c) 2015 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <zephyr/kernel.h>
8 #include <zephyr/drivers/ipm.h>
9 #include <zephyr/drivers/console/ipm_console.h>
10 #include <zephyr/device.h>
11 #include <zephyr/misc/lorem_ipsum.h>
12 #include <zephyr/init.h>
13 #include <stdio.h>
14 
15 #include <zephyr/tc_util.h>
16 #include "ipm_dummy.h"
17 
18 #define PRINTK_OUT      1
19 
20 #if PRINTK_OUT
21 #define SOURCE  IPM_CONSOLE_STDOUT
22 #define DEST    IPM_CONSOLE_PRINTK
23 #else
24 #define SOURCE  IPM_CONSOLE_PRINTK
25 #define DEST    IPM_CONSOLE_STDOUT
26 #endif
27 
28 #define INIT_PRIO_IPM_SEND 40
29 #define INIT_PRIO_IPM_RECV 50
30 
31 extern struct ipm_driver_api ipm_dummy_api;
32 
33 /* Set up the dummy IPM driver */
34 struct ipm_dummy_driver_data ipm_dummy0_driver_data;
35 DEVICE_DEFINE(ipm_dummy0, "ipm_dummy0", NULL,
36 		NULL, &ipm_dummy0_driver_data, NULL,
37 		POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
38 		&ipm_dummy_api);
39 
40 /* Sending side of the console IPM driver, will forward anything sent
41  * to printf() since we selected IPM_CONSOLE_STDOUT
42  */
43 static struct ipm_console_sender_config_info sender_config = {
44 	.bind_to = "ipm_dummy0",
45 	.flags = SOURCE
46 };
47 DEVICE_DEFINE(ipm_console_send0, "ipm_send0", ipm_console_sender_init,
48 	      NULL, NULL, &sender_config,
49 	      POST_KERNEL, INIT_PRIO_IPM_SEND, NULL);
50 
51 /* Receiving side of the console IPM driver. These numbers are
52  * more or less arbitrary
53  */
54 #define LINE_BUF_SIZE           80
55 #define RING_BUF_SIZE32         8
56 
57 static uint32_t ring_buf_data[RING_BUF_SIZE32];
58 static K_THREAD_STACK_DEFINE(thread_stack, IPM_CONSOLE_STACK_SIZE);
59 static char line_buf[LINE_BUF_SIZE];
60 
61 /* Dump incoming messages to printk() */
62 static struct ipm_console_receiver_config_info receiver_config = {
63 	.bind_to = "ipm_dummy0",
64 	.thread_stack = thread_stack,
65 	.ring_buf_data = ring_buf_data,
66 	.rb_size32 = RING_BUF_SIZE32,
67 	.line_buf = line_buf,
68 	.lb_size = LINE_BUF_SIZE,
69 	.flags = DEST
70 };
71 
72 struct ipm_console_receiver_runtime_data receiver_data;
73 DEVICE_DEFINE(ipm_console_recv0, "ipm_recv0", ipm_console_receiver_init,
74 	      NULL, &receiver_data, &receiver_config,
75 	      POST_KERNEL, INIT_PRIO_IPM_RECV, NULL);
76 
77 static const char thestr[] = "everything is awesome\n";
78 
main(void)79 int main(void)
80 {
81 	int rv, i;
82 	const struct device *ipm;
83 
84 	TC_SUITE_START("test_ipm");
85 	ipm = device_get_binding("ipm_dummy0");
86 
87 	/* Try sending a raw string to the IPM device to show that the
88 	 * receiver works
89 	 */
90 	for (i = 0; i < strlen(thestr); i++) {
91 		ipm_send(ipm, 1, thestr[i], NULL, 0);
92 	}
93 
94 	/* Now do this through printf() to exercise the sender */
95 	printf(LOREM_IPSUM_SHORT "\n");
96 
97 	/* XXX how to tell if something was actually printed out for
98 	 * automation purposes?
99 	 */
100 
101 	rv = TC_PASS;
102 	TC_END_RESULT(rv);
103 	TC_SUITE_END("test_ipm", rv);
104 	TC_END_REPORT(rv);
105 	return 0;
106 }
107