1 // SPDX-License-Identifier: Apache-2.0
2 // Copyright (C) 2018 IBM Corp.
3 
4 #include <assert.h>
5 #include <sys/mman.h>
6 
7 #include "mboxd.h"
8 #include "mtd/backend.h"
9 #include "transport_mbox.h"
10 
11 #include "test/mbox.h"
12 #include "test/system.h"
13 
14 static const uint8_t get_info[] = {
15 	0x02, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
16 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
17 };
18 
19 static const uint8_t create_write_window[] = {
20 	0x06, 0x01, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00,
21 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
22 };
23 
24 static const uint8_t mark_write_dirty_left[] = {
25 	0x07, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
26 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
27 };
28 
29 static const uint8_t mark_write_dirty_right[] = {
30 	0x07, 0x03, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
31 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
32 };
33 
34 static const uint8_t mark_write_erase_middle[] = {
35 	0x0a, 0x04, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
36 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
37 };
38 
39 static const uint8_t mark_write_erase_left[] = {
40 	0x0a, 0x05, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
41 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
42 };
43 
44 static const uint8_t mark_write_erase_right[] = {
45 	0x0a, 0x06, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00,
46 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
47 };
48 
49 static const uint8_t mark_write_dirty_middle[] = {
50 	0x07, 0x07, 0x01, 0x00, 0x01, 0x00, 0x00, 0x00,
51 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
52 };
53 
54 static const uint8_t write_flush[] = {
55 	0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
56 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00
57 };
58 
59 static const uint8_t flush_response[] = {
60 	0x08, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
61 	0x00, 0x00, 0x00, 0x00, 0x00, 0x01
62 };
63 
64 const uint8_t start_data[] = { 0xaa, 0x55, 0xaa };
65 const uint8_t flush_dirty_erased_dirty_data[] = { 0x55, 0xff, 0x55 };
66 const uint8_t flush_erased_dirty_erased_data[] = { 0xff, 0x55, 0xff };
67 
68 #define MEM_SIZE	sizeof(start_data)
69 #define ERASE_SIZE	1
70 #define N_WINDOWS	1
71 #define WINDOW_SIZE	sizeof(start_data)
72 
main(void)73 int main(void)
74 {
75 	struct mbox_context *ctx;
76 	uint8_t *map;
77 	int rc;
78 
79 	system_set_reserved_size(MEM_SIZE);
80 	system_set_mtd_sizes(MEM_SIZE, ERASE_SIZE);
81 
82 	ctx = mbox_create_test_context(N_WINDOWS, WINDOW_SIZE);
83 	rc = mbox_set_mtd_data(ctx, start_data, sizeof(start_data));
84 	assert(rc == 0);
85 
86 	rc = mbox_command_dispatch(ctx, get_info, sizeof(get_info));
87 	assert(rc == 1);
88 
89 	rc = mbox_command_dispatch(ctx, create_write_window,
90 			sizeof(create_write_window));
91 	assert(rc == 1);
92 
93 	/* { dirty, erased, dirty } */
94 
95 	((uint8_t *)ctx->mem)[0] = 0x55;
96 
97 	rc = mbox_command_dispatch(ctx, mark_write_dirty_left,
98 			sizeof(mark_write_dirty_left));
99 	assert(rc == 1);
100 
101 	((uint8_t *)ctx->mem)[2] = 0x55;
102 
103 	rc = mbox_command_dispatch(ctx, mark_write_dirty_right,
104 			sizeof(mark_write_dirty_right));
105 	assert(rc == 1);
106 
107 	rc = mbox_command_dispatch(ctx, mark_write_erase_middle,
108 			sizeof(mark_write_erase_middle));
109 	assert(rc == 1);
110 
111 	rc = mbox_command_dispatch(ctx, write_flush, sizeof(write_flush));
112 	assert(rc == 1);
113 
114 	rc = mbox_cmp(ctx, flush_response, sizeof(flush_response));
115 	assert(rc == 0);
116 
117 	map = mmap(NULL, MEM_SIZE, PROT_READ, MAP_PRIVATE,
118 			((struct mtd_data *)ctx->backend.priv)->fd, 0);
119 	assert(map != MAP_FAILED);
120 
121 	rc = memcmp(flush_dirty_erased_dirty_data, map,
122 			sizeof(flush_dirty_erased_dirty_data));
123 	assert(rc == 0);
124 
125 	/* { erased, dirty, erased } */
126 
127 	((uint8_t *)ctx->mem)[1] = 0x55;
128 
129 	rc = mbox_command_dispatch(ctx, mark_write_dirty_middle,
130 			sizeof(mark_write_dirty_middle));
131 	assert(rc == 1);
132 
133 	rc = mbox_command_dispatch(ctx, mark_write_erase_left,
134 			sizeof(mark_write_erase_left));
135 	assert(rc == 1);
136 
137 	rc = mbox_command_dispatch(ctx, mark_write_erase_right,
138 			sizeof(mark_write_erase_right));
139 	assert(rc == 1);
140 
141 	rc = mbox_command_dispatch(ctx, write_flush, sizeof(write_flush));
142 	assert(rc == 1);
143 
144 	rc = mbox_cmp(ctx, flush_response, sizeof(flush_response));
145 	assert(rc == 0);
146 
147 	rc = memcmp(flush_erased_dirty_erased_data, map,
148 			sizeof(flush_erased_dirty_erased_data));
149 	assert(rc == 0);
150 
151 	return rc;
152 }
153