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/init.h>
12 #include <stdio.h>
13 
14 #include <zephyr/tc_util.h>
15 #include "ipm_dummy.h"
16 
17 #define PRINTK_OUT      1
18 
19 #if PRINTK_OUT
20 #define SOURCE  IPM_CONSOLE_STDOUT
21 #define DEST    IPM_CONSOLE_PRINTK
22 #else
23 #define SOURCE  IPM_CONSOLE_PRINTK
24 #define DEST    IPM_CONSOLE_STDOUT
25 #endif
26 
27 #define INIT_PRIO_IPM_SEND 40
28 #define INIT_PRIO_IPM_RECV 50
29 
30 extern struct ipm_driver_api ipm_dummy_api;
31 
32 /* Set up the dummy IPM driver */
33 struct ipm_dummy_driver_data ipm_dummy0_driver_data;
34 DEVICE_DEFINE(ipm_dummy0, "ipm_dummy0", NULL,
35 		NULL, &ipm_dummy0_driver_data, NULL,
36 		POST_KERNEL, CONFIG_KERNEL_INIT_PRIORITY_DEFAULT,
37 		&ipm_dummy_api);
38 
39 /* Sending side of the console IPM driver, will forward anything sent
40  * to printf() since we selected IPM_CONSOLE_STDOUT
41  */
42 static struct ipm_console_sender_config_info sender_config = {
43 	.bind_to = "ipm_dummy0",
44 	.flags = SOURCE
45 };
46 DEVICE_DEFINE(ipm_console_send0, "ipm_send0", ipm_console_sender_init,
47 	      NULL, NULL, &sender_config,
48 	      POST_KERNEL, INIT_PRIO_IPM_SEND, NULL);
49 
50 /* Receiving side of the console IPM driver. These numbers are
51  * more or less arbitrary
52  */
53 #define LINE_BUF_SIZE           80
54 #define RING_BUF_SIZE32         8
55 
56 static uint32_t ring_buf_data[RING_BUF_SIZE32];
57 static K_THREAD_STACK_DEFINE(thread_stack, IPM_CONSOLE_STACK_SIZE);
58 static char line_buf[LINE_BUF_SIZE];
59 
60 /* Dump incoming messages to printk() */
61 static struct ipm_console_receiver_config_info receiver_config = {
62 	.bind_to = "ipm_dummy0",
63 	.thread_stack = thread_stack,
64 	.ring_buf_data = ring_buf_data,
65 	.rb_size32 = RING_BUF_SIZE32,
66 	.line_buf = line_buf,
67 	.lb_size = LINE_BUF_SIZE,
68 	.flags = DEST
69 };
70 
71 struct ipm_console_receiver_runtime_data receiver_data;
72 DEVICE_DEFINE(ipm_console_recv0, "ipm_recv0", ipm_console_receiver_init,
73 	      NULL, &receiver_data, &receiver_config,
74 	      POST_KERNEL, INIT_PRIO_IPM_RECV, NULL);
75 
76 static const char thestr[] = "everything is awesome\n";
77 
main(void)78 int main(void)
79 {
80 	int rv, i;
81 	const struct device *ipm;
82 
83 	TC_SUITE_START("test_ipm");
84 	ipm = device_get_binding("ipm_dummy0");
85 
86 	/* Try sending a raw string to the IPM device to show that the
87 	 * receiver works
88 	 */
89 	for (i = 0; i < strlen(thestr); i++) {
90 		ipm_send(ipm, 1, thestr[i], NULL, 0);
91 	}
92 
93 	/* Now do this through printf() to exercise the sender */
94 	printf("Lorem ipsum dolor sit amet, consectetur adipiscing elit, "
95 	       "sed do eiusmod tempor incididunt ut labore et dolore magna "
96 	       "aliqua. Ut enim ad minim veniam, quis nostrud exercitation "
97 	       "ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis "
98 	       "aute irure dolor in reprehenderit in voluptate velit esse "
99 	       "cillum dolore eu fugiat nulla pariatur. Excepteur sint "
100 	       "occaecat cupidatat non proident, sunt in culpa qui officia "
101 	       "deserunt mollit anim id est laborum.\n");
102 
103 	/* XXX how to tell if something was actually printed out for
104 	 * automation purposes?
105 	 */
106 
107 	rv = TC_PASS;
108 	TC_END_RESULT(rv);
109 	TC_SUITE_END("test_ipm", rv);
110 	TC_END_REPORT(rv);
111 	return 0;
112 }
113