common_library: gettid is multiple declaration in cl_error
[staging/basesystem.git] / video_in_hal / boot_hal / src / boot_hal.cpp
1 /*
2  * @copyright Copyright (c) 2018-2020 TOYOTA MOTOR CORPORATION.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 #include <boot_hal.h>
18
19 #include <unistd.h>
20 #include <fcntl.h>
21 #include <stdlib.h>
22 #include <string.h>
23 #include <sys/types.h>
24 #include <sys/mman.h>
25 #include <sys/vfs.h>
26
27 #include <cstdio>
28 #include <cerrno>
29 #include <cstring>
30
31 #include "boot_hal_boothallog.h"
32
33 #define BOOT_PARTATION "/dev/mmcblk0boot1"
34 #define BOOTINFO_FILEA "/repro/mmcblk0boot1-launch_a.bin"
35 #define BOOTINFO_FILEB "/repro/mmcblk0boot1-launch_b.bin"
36
37 #define MMCBLK0BOOT1_FORCE_RO "/sys/class/block/mmcblk0boot1/force_ro"
38 #define MMCBLK0BOOT1_SIZE_PATH "/sys/class/block/mmcblk0boot1/size"
39 #define MMCBLK0BOOT1_SIZE_DEF (0x1000000)
40 #define BOOTINFO_SIZE (0x20000)
41 #define SECTOR_SIZE (512)
42 #define FILEPATH_MAX (256)
43
44 #define BOOT_CMDLINE "/proc/cmdline"
45 #define CMDLINE_MAX_SIZE (256)
46 #define BOOT_ROOTFS_A "/dev/mmcblk0p1"
47 #define BOOT_ROOTFS_B "/dev/mmcblk0p2"
48 #define BOOTARGS_LST_ROOT "root="
49
50
51 #define BOOT_COPYBUF_SIZE (64 * 1024)
52
53 static int EnableMmcBlk(const char *path) {
54   int fd;
55   char enable[] = "0";
56
57   if ((fd = open(path, O_RDWR)) < 0) {
58     return -1;
59   }
60
61   if (write(fd, enable, sizeof(enable)) < 0) {
62     close(fd);
63     return -1;
64   }
65
66   close(fd);
67   return 0;
68 }
69
70 static int GetMmcBlkCount(const char *path) {
71   int fd;
72   char block_size[16] = {0};
73
74   if ((fd = open(path, O_RDONLY)) < 0) {
75     return -1;
76   }
77
78   if (read(fd, block_size, sizeof(block_size)) < 0) {
79     close(fd);
80     return -1;
81   }
82
83   close(fd);
84   return strtol(block_size, NULL, 10);
85 }
86
87 static ssize_t BootReadN(int fd, void *buffer, size_t n) {
88   size_t tot_read;
89   char *buf;
90
91   buf = reinterpret_cast<char *>(buffer);
92   for (tot_read = 0; tot_read < n;) {
93     ssize_t num_read;
94     num_read = read(fd, buf, n - tot_read);
95
96     if (num_read == 0) {
97       return tot_read;
98     }
99     if (num_read == -1) {
100       if (errno == EINTR) {
101         continue;
102       } else {
103         return -1;
104       }
105     }
106     tot_read += num_read;
107     buf += num_read;
108   }
109   return tot_read;
110 }
111
112 static ssize_t BootWriteN(int fd, const void *buffer, size_t n) {
113   size_t tot_written;
114   const char *buf;
115
116   buf = (const char *)buffer;
117   for (tot_written = 0; tot_written < n;) {
118     ssize_t num_written;
119     num_written = write(fd, buf, n - tot_written);
120
121     if (num_written <= 0) {
122       if (num_written == -1 && errno == EINTR) {
123         continue;
124       } else {
125         return -1;
126       }
127     }
128     tot_written += num_written;
129     buf += num_written;
130   }
131   return tot_written;
132 }
133
134 BootHalStatus setSide(unsigned int upTableID[]) {
135   BootHalStatus ret = BOOTHAL_RET_ERR_FAIL;
136   int binfo_fd = -1;
137   int mmc_fd = -1;
138   int sector_count = 0;
139   char *buf = NULL;
140   char binfo_file[FILEPATH_MAX] = {0};
141   off_t mmc_offset;
142
143   if (NULL == upTableID) {
144     return BOOTHAL_RET_ERR_PARAM;
145   }
146
147   if (upTableID[BOOTHAL_SIDE_IDX_MAINSOFT] == BOOTHAL_SIDE_A) {
148     snprintf(binfo_file, FILEPATH_MAX, "%s", BOOTINFO_FILEA);
149   } else if (upTableID[BOOTHAL_SIDE_IDX_MAINSOFT] == BOOTHAL_SIDE_B) {
150     snprintf(binfo_file, FILEPATH_MAX, "%s", BOOTINFO_FILEB);
151   } else {
152     ret = BOOTHAL_RET_ERR_PARAM;
153     goto exit;
154   }
155
156   binfo_fd = open(binfo_file, O_RDONLY);
157   if (binfo_fd < 0) {
158     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "open %s:%s", binfo_file, strerror(errno));
159     ret = BOOTHAL_RET_ERR_FAIL;
160     goto exit;
161   }
162
163   mmc_fd = open(BOOT_PARTATION, O_WRONLY);
164   if (mmc_fd < 0) {
165     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "open %s:%s", BOOT_PARTATION, strerror(errno));
166     ret = BOOTHAL_RET_ERR_FAIL;
167     goto exit;
168   }
169
170   /*
171    * enable mmcblk0boot1 for write
172    */
173   if (EnableMmcBlk(MMCBLK0BOOT1_FORCE_RO) < 0) {
174     ret = BOOTHAL_RET_ERR_FAIL;
175     goto exit;
176   }
177
178   /*
179    * Get sector count of mmcblk0boot1 block from sys-file, every sector size is 512byte.
180    * The mmcblk0boot1 block default size is 16M.
181    */
182   if ((sector_count = GetMmcBlkCount(MMCBLK0BOOT1_SIZE_PATH)) < 0) {
183     mmc_offset = MMCBLK0BOOT1_SIZE_DEF - BOOTINFO_SIZE;
184   } else {
185     mmc_offset = sector_count * SECTOR_SIZE - BOOTINFO_SIZE;
186   }
187
188   /*
189    * The environment should be write to the latest 128K of mmcblk0boot1.
190    */
191   if (lseek(mmc_fd, mmc_offset, SEEK_SET) < 0) {
192     ret = BOOTHAL_RET_ERR_FAIL;
193     goto exit;
194   }
195
196   buf = reinterpret_cast<char *>(mmap(NULL, BOOT_COPYBUF_SIZE, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANON, -1, 0));
197   if (buf == MAP_FAILED) {
198     ret = BOOTHAL_RET_ERR_FAIL;
199     goto exit;
200   }
201
202   while (1) {
203     ssize_t rd, wr;
204
205     rd = BootReadN(binfo_fd, buf, BOOT_COPYBUF_SIZE);
206     if (!rd) {
207       // EOF
208       break;
209     }
210     if (rd < 0) {
211       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "read:%s", strerror(errno));
212       ret = BOOTHAL_RET_ERR_FAIL;
213       goto exit;
214     }
215
216     wr = BootWriteN(mmc_fd, buf, rd);
217     if (wr < rd) {
218       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "write(%s):%s", BOOT_PARTATION, strerror(errno));
219       ret = BOOTHAL_RET_ERR_WRITE;
220       goto exit;
221     }
222   }
223
224   if (fsync(mmc_fd) < 0) {
225     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "fsync:%s", strerror(errno));
226   }
227   ret = BOOTHAL_RET_SUCCESS;
228
229 exit:
230   if (binfo_fd >= 0) {
231     if (close(binfo_fd) < 0) {
232       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "close:%s", strerror(errno));
233     }
234   }
235
236   if (mmc_fd >= 0) {
237     if (close(mmc_fd) < 0) {
238       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "close:%s", strerror(errno));
239     }
240   }
241
242   if (buf) {
243     munmap(buf, BOOT_COPYBUF_SIZE);
244   }
245
246   return ret;
247 }
248
249 BootHalStatus getSide(unsigned int upTableID[]) {
250   BootHalStatus ret = BOOTHAL_RET_SUCCESS;
251   int fd;
252   int rd_size;
253   char buf[CMDLINE_MAX_SIZE] = {0};
254   char *rootfs = NULL;
255
256   if (NULL == upTableID) {
257     return BOOTHAL_RET_ERR_PARAM;
258   }
259
260   if ((fd = open(BOOT_CMDLINE, O_RDONLY)) < 0) {
261     ret = BOOTHAL_RET_ERR_FAIL;
262     goto exit;
263   }
264
265   if ((rd_size = BootReadN(fd, buf, CMDLINE_MAX_SIZE)) < 0) {
266     FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "read %s error:%s", BOOT_CMDLINE, strerror(errno));
267     ret = BOOTHAL_RET_ERR_FAIL;
268     goto exit;
269   }
270
271   rootfs = strstr(buf, BOOTARGS_LST_ROOT);
272   if (!rootfs) {
273     ret = BOOTHAL_RET_ERR_FAIL;
274     goto exit;
275   }
276
277   rootfs += strlen(BOOTARGS_LST_ROOT);
278   if (strncmp(rootfs, BOOT_ROOTFS_A, strlen(BOOT_ROOTFS_A)) == 0 &&
279       (rootfs[strlen(BOOT_ROOTFS_A)] == ' ' || rootfs[strlen(BOOT_ROOTFS_A)] == '\0')) {
280     upTableID[BOOTHAL_SIDE_IDX_MAINSOFT] = BOOTHAL_SIDE_A;
281   } else if (strncmp(rootfs, BOOT_ROOTFS_B, strlen(BOOT_ROOTFS_B)) == 0 &&
282       (rootfs[strlen(BOOT_ROOTFS_B)] == ' ' || rootfs[strlen(BOOT_ROOTFS_B)] == '\0')) {
283     upTableID[BOOTHAL_SIDE_IDX_MAINSOFT] = BOOTHAL_SIDE_B;
284   } else {
285     ret = BOOTHAL_RET_ERR_FAIL;
286   }
287
288 exit:
289   if (fd >= 0) {
290     if (close(fd) < 0) {
291       FRAMEWORKUNIFIEDLOG(ZONE_ERR, __func__, "close:%s", strerror(errno));
292     }
293   }
294
295   return ret;
296 }
297
298 BootHalStatus setBootColdStart(void) {
299   /*
300    *  Note.
301    *  This feature needs to be implemented by the vendor.
302    */
303   return BOOTHAL_RET_SUCCESS;
304 }
305
306 BootHalStatus getBootMode(uint32_t *mode) {
307   if (NULL == mode) {
308     return BOOTHAL_RET_ERR_PARAM;
309   }
310
311   *mode = COLD_START;
312   return BOOTHAL_RET_SUCCESS;
313 }