Add board module (import from RPI4)
authorMateusz Moscicki <m.moscicki2@partner.samsung.com>
Wed, 12 Jun 2024 09:37:21 +0000 (11:37 +0200)
committerMateusz Moscicki <m.moscicki2@partner.samsung.com>
Fri, 14 Jun 2024 08:55:26 +0000 (10:55 +0200)
Change-Id: I815053a2c8250aba8efef32fd0ff0401edd33198

CMakeLists.txt [new file with mode: 0644]
hw/board/CMakeLists.txt [new file with mode: 0644]
hw/board/board.c [new file with mode: 0644]
packaging/hal-backend-device-vf2.spec

diff --git a/CMakeLists.txt b/CMakeLists.txt
new file mode 100644 (file)
index 0000000..d5d985e
--- /dev/null
@@ -0,0 +1,14 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(hal-backend-device-vf2 C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS} -Wall -Werror")
+
+IF(ENABLE_DLOG STREQUAL on)
+       ADD_DEFINITIONS("-DFEATURE_DLOG")
+ENDIF()
+
+INSTALL(FILES ${CMAKE_CURRENT_SOURCE_DIR}/LICENSE.Apache-2.0 DESTINATION ${HAL_LICENSE_DIR}/${PROJECT_NAME})
+
+ADD_SUBDIRECTORY(hw/board)
diff --git a/hw/board/CMakeLists.txt b/hw/board/CMakeLists.txt
new file mode 100644 (file)
index 0000000..5234091
--- /dev/null
@@ -0,0 +1,21 @@
+CMAKE_MINIMUM_REQUIRED(VERSION 2.6)
+PROJECT(hal-backend-device-board C)
+
+SET(PREFIX ${CMAKE_INSTALL_PREFIX})
+
+INCLUDE(FindPkgConfig)
+pkg_check_modules(hal-backend-device-board_pkgs REQUIRED
+       hal-backend-device-common
+       libsyscommon
+       )
+
+FOREACH(flag ${hal-backend-device-board_pkgs_CFLAGS})
+       SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} ${flag}")
+ENDFOREACH(flag)
+
+SET(EXTRA_CFLAGS "${EXTRA_CFLAGS} -fvisibility=hidden")
+SET(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${EXTRA_CFLAGS}")
+
+ADD_LIBRARY(${PROJECT_NAME} MODULE board.c)
+TARGET_LINK_LIBRARIES(${PROJECT_NAME} ${hal-backend-device-board_pkgs_LDFLAGS})
+INSTALL(TARGETS ${PROJECT_NAME} DESTINATION ${HAL_LIB_DIR} COMPONENT RuntimeLibraries)
diff --git a/hw/board/board.c b/hw/board/board.c
new file mode 100644 (file)
index 0000000..2767d6a
--- /dev/null
@@ -0,0 +1,358 @@
+/*
+ * Copyright (c) 2016 Samsung Electronics Co., Ltd.
+ *
+ * Licensed under the Apache License, Version 2.0 (the License);
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#define _GNU_SOURCE
+#include <hal/hal-device-board-interface.h>
+#include <hal/hal-common-interface.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include </hal/include/device/hal-backend-common.h>
+#include <libsyscommon/file.h>
+
+#define INFORM_MNT_PATH                        "/mnt/inform"
+#define PARTITION_AB_PATH              INFORM_MNT_PATH"/partition-ab.info"
+#define PARTITION_AB_CLONED_PATH       INFORM_MNT_PATH"/partition-ab-cloned.info"
+#define UPGRADE_PROGRESS_STATUS_PATH   INFORM_MNT_PATH"/upgrade-progress-status.info"
+#define PARTITION_A_STATUS_PATH                INFORM_MNT_PATH"/partition-a-status.info"
+#define PARTITION_B_STATUS_PATH                INFORM_MNT_PATH"/partition-b-status.info"
+#define REBOOT_PARAM_PATH              INFORM_MNT_PATH"/reboot-param.bin"
+#define UPGRADE_STATE_PATH             INFORM_MNT_PATH"/upgrade-state.info"
+#define SERIAL_FILE_PATH               "/sys/firmware/devicetree/base/serial-number"
+
+#define PARTITION_STATUS_OK        "ok"
+#define PARTITION_STATUS_CORRUPTED "corrupted"
+#define PARTITION_STATUS_FAILED    "failed"
+#define BOOT_MODE_NORMAL           "norm"
+
+static int get_device_serial_number(char *buffer, int len)
+{
+       FILE *fp;
+       char *retval;
+
+       fp = fopen(SERIAL_FILE_PATH, "r");
+       if (!fp)
+               return -errno;
+
+       retval = fgets(buffer, len, fp);
+       if (retval == NULL) {
+               fclose(fp);
+               return -errno;
+       }
+
+       fclose(fp);
+
+       return 0;
+}
+
+static int clear_boot_mode(void)
+{
+       /* clear contents of the file first */
+       if (truncate(REBOOT_PARAM_PATH, 0) == -1) {
+               int ferror = errno;
+               errno = 0;
+               return -ferror;
+       }
+
+       return sys_set_str(REBOOT_PARAM_PATH, BOOT_MODE_NORMAL);
+}
+
+static int get_boot_mode(char *buffer, const int max_len)
+{
+       char scan_format[32] = { 0, };
+       int ret = 0;
+
+       snprintf(scan_format, sizeof(scan_format), "bootmode=%%%ds", max_len - 1);
+
+       ret = syscommon_parse_cmdline_scanf(scan_format, buffer);
+
+       if (ret <= 0) {
+               return -ENOENT;
+       }
+
+       if (!strncmp(buffer, "ramdisk", max_len)) {
+               snprintf(buffer, max_len, "normal");
+       }
+
+       return 0;
+}
+
+
+static int get_current_partition(char *partition_ab)
+{
+       int ret_parse = syscommon_parse_cmdline_scanf("partition_ab=%c", partition_ab);
+
+       if (ret_parse <= 0) {
+               return -ENOENT;
+       }
+
+       return 0;
+
+}
+
+static int switch_partition(char partition_ab)
+{
+       char cur_partition_ab;
+       char next_partition_ab[2];
+
+       next_partition_ab[0] = partition_ab;
+       next_partition_ab[1] = '\0';
+
+       if (partition_ab == '\0') {
+               /* Toggle partition a/b */
+               int ret_cur_part = get_current_partition(&cur_partition_ab);
+
+               if (ret_cur_part < 0) {
+                       return ret_cur_part;
+               }
+
+               if (cur_partition_ab == 'a') {
+                       next_partition_ab[0] = 'b';
+               } else if(cur_partition_ab == 'b') {
+                       next_partition_ab[0] = 'a';
+               } else {
+                       return -ENOENT;
+               }
+       } else if(partition_ab != 'a' && partition_ab != 'b') {
+               return -EINVAL;
+       }
+
+       return sys_write_buf(PARTITION_AB_PATH, next_partition_ab);
+}
+
+static int set_partition_ab_cloned(void)
+{
+       return sys_write_buf(PARTITION_AB_CLONED_PATH, "1");
+}
+
+static int clear_partition_ab_cloned(void)
+{
+       return sys_write_buf(PARTITION_AB_CLONED_PATH, "0");
+}
+
+static int get_partition_ab_cloned(int *cloned)
+{
+       int ret_get_int = sys_get_int(PARTITION_AB_CLONED_PATH, cloned);
+
+       if (ret_get_int < 0) {
+               return ret_get_int;
+       }
+
+       return 0;
+}
+
+static int set_partition_status(char partition_ab, const char *status)
+{
+       char *path;
+       char target_partition_ab = partition_ab;
+
+       if (target_partition_ab == '\0') {
+               int ret_cur_part = get_current_partition(&target_partition_ab);
+
+               if (ret_cur_part < 0) {
+                       return ret_cur_part;
+               }
+
+               if (target_partition_ab != 'a' && target_partition_ab != 'b') {
+                       return -ENOENT;
+               }
+       }
+
+       if (target_partition_ab == 'a') {
+               path = PARTITION_A_STATUS_PATH;
+       } else if (target_partition_ab == 'b') {
+               path = PARTITION_B_STATUS_PATH;
+       } else {
+               return -EINVAL;
+       }
+
+       if (status == NULL || (strcmp(status, PARTITION_STATUS_OK) != 0 &&
+                               strcmp(status, PARTITION_STATUS_CORRUPTED) != 0 &&
+                               strcmp(status, PARTITION_STATUS_FAILED) != 0)) {
+               return -EINVAL;
+       }
+
+       /* clear contents of the file first */
+       if (truncate(path, 0) == -1) {
+               int ferror = errno;
+               errno = 0;
+               return -ferror;
+       }
+
+       return sys_set_str(path, (char *)status);
+}
+
+static int get_partition_status(char partition_ab, char *buffer, const int max_len)
+{
+       char *dummy;
+       char *path;
+       char target_partition_ab = partition_ab;
+
+       if (target_partition_ab == '\0') {
+               int ret_cur_part = get_current_partition(&target_partition_ab);
+
+               if (ret_cur_part < 0) {
+                       return ret_cur_part;
+               }
+
+               if (target_partition_ab != 'a' && target_partition_ab != 'b') {
+                       return -ENOENT;
+               }
+       }
+
+       if (target_partition_ab == 'a') {
+               path = PARTITION_A_STATUS_PATH;
+       } else if (target_partition_ab == 'b') {
+               path = PARTITION_B_STATUS_PATH;
+       } else {
+               return -EINVAL;
+       }
+
+       int res_get_str = sys_get_str(path, buffer, max_len);
+       if (res_get_str < 0) {
+               return res_get_str;
+       }
+
+       /* remove potential newline | tokenizer will place '\0' in a place of '\n' */
+       strtok_r(buffer, "\n", &dummy);
+
+       if (strcmp(buffer, PARTITION_STATUS_OK) != 0 &&
+                       strcmp(buffer, PARTITION_STATUS_CORRUPTED) != 0 &&
+                       strcmp(buffer, PARTITION_STATUS_FAILED) != 0) {
+               return -ENOENT;
+       }
+
+       return 0;
+}
+
+static int set_upgrade_progress_status(int status)
+{
+       /* status: -1 if upgrade fail, otherwise 0~100 */
+       if (status < -1 || status > 100) {
+               return -EINVAL;
+       }
+
+       /* clear contents of the file first */
+       if (truncate(UPGRADE_PROGRESS_STATUS_PATH, 0) == -1) {
+               int ferror = errno;
+               errno = 0;
+               return -ferror;
+       }
+
+       return sys_set_int(UPGRADE_PROGRESS_STATUS_PATH, status);
+}
+
+static int get_upgrade_progress_status(int *status)
+{
+       int ret_get_int = sys_get_int(UPGRADE_PROGRESS_STATUS_PATH, status);
+
+       if (ret_get_int < 0) {
+               return ret_get_int;
+       }
+
+       /* status: -1 if upgrade fail, otherwise 0~100 */
+       if (*status < -1 || *status > 100) {
+               return -EINVAL;
+       }
+
+       return 0;
+}
+
+static int set_upgrade_state(char *state)
+{
+       if (state == NULL)
+               return -EINVAL;
+
+       /* clear contents of the file first */
+       if (truncate(UPGRADE_STATE_PATH, 0) == -1) {
+               int ferror = errno;
+               errno = 0;
+               return -ferror;
+       }
+
+       return sys_set_str(UPGRADE_STATE_PATH, state);
+}
+
+static int get_upgrade_state(char *buffer, const int max_len)
+{
+       int ret = 0;
+
+       if (buffer == NULL)
+               return -EINVAL;
+
+       if (max_len < 1)
+               return -EINVAL;
+
+       ret = sys_get_str(UPGRADE_STATE_PATH, buffer, max_len - 1);
+       if (ret < 0)
+               return ret;
+
+       return 0;
+}
+
+static int board_init(void **data)
+{
+       hal_backend_device_board_funcs *device_board_funcs;
+
+       if (!data) {
+               _E("Invalid parameter");
+               return -EINVAL;
+       }
+
+       device_board_funcs = *(hal_backend_device_board_funcs **) data;
+       if (!device_board_funcs)
+               return -EINVAL;
+
+       device_board_funcs->get_device_serial_number  = get_device_serial_number;
+
+       device_board_funcs->clear_boot_mode           = clear_boot_mode;
+       device_board_funcs->get_boot_mode             = get_boot_mode;
+
+       device_board_funcs->get_current_partition     = get_current_partition;
+       device_board_funcs->switch_partition          = switch_partition;
+       device_board_funcs->set_partition_ab_cloned   = set_partition_ab_cloned;
+       device_board_funcs->clear_partition_ab_cloned = clear_partition_ab_cloned;
+       device_board_funcs->get_partition_ab_cloned   = get_partition_ab_cloned;
+       device_board_funcs->set_partition_status      = set_partition_status;
+       device_board_funcs->get_partition_status      = get_partition_status;
+
+       device_board_funcs->set_upgrade_progress_status = set_upgrade_progress_status;
+       device_board_funcs->get_upgrade_progress_status = get_upgrade_progress_status;
+
+       device_board_funcs->set_upgrade_state = set_upgrade_state;
+       device_board_funcs->get_upgrade_state = get_upgrade_state;
+
+       return 0;
+}
+
+static int board_exit(void *data)
+{
+       return 0;
+}
+
+hal_backend EXPORT hal_backend_device_board_data = {
+       .name = "board",
+       .vendor = "VF2",
+       .init = board_init,
+       .exit = board_exit,
+       .major_version = 1,
+       .minor_version = 0,
+};
index d4452ed1698385a031494a995aa324b0a6410afa..32e04efb6f77557786790dcc0eb55ad852c89d0d 100644 (file)
@@ -6,6 +6,13 @@ Group:      System/Hardware Adaptation
 License:    Apache-2.0
 Source0:    %{name}-%{version}.tar.gz
 Source1:    %{name}.manifest
+Requires(post): /sbin/ldconfig
+Requires(postun): /sbin/ldconfig
+BuildRequires:  cmake
+BuildRequires:  pkgconfig(hal-api-common)
+BuildRequires:  pkgconfig(hal-api-device)
+BuildRequires:  pkgconfig(libsyscommon)
+BuildRequires:  pkgconfig(hal-backend-device-common)
 
 %description
 Device HAL backend drivers for VisionFive2 targets
@@ -14,13 +21,28 @@ Device HAL backend drivers for VisionFive2 targets
 %setup -q
 cp %{SOURCE1} .
 
+%build
+%cmake . -DENABLE_DLOG=on \
+       -DHAL_LICENSE_DIR=%{_hal_licensedir} \
+       -DHAL_LIB_DIR=%{_hal_libdir}
+
+make %{?jobs:-j%jobs}
+
+%install
 %make_install
 
 # background_copy.list
 mkdir -p %{buildroot}%{_hal_sysconfdir}/upgrade
 install -m 644 hw/upgrade/* %{buildroot}%{_hal_sysconfdir}/upgrade
 
+
+%post
+/sbin/ldconfig
+
+%postun
+/sbin/ldconfig
 %files
+%{_hal_libdir}/libhal-backend-device-board.so
 %manifest %{name}.manifest
 %{_hal_licensedir}/%{name}/LICENSE.Apache-2.0
 %{_hal_sysconfdir}/upgrade/*