diff --git a/Android.bp b/Android.bp index 872766b..5908f71 100644 --- a/Android.bp +++ b/Android.bp @@ -1,25 +1,6 @@ -// -// Copyright (C) 2022-2024 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - soong_namespace { imports: [ "hardware/google/interfaces", "hardware/google/pixel" ], } - -install_symlink { - name: "firmware_wlan_mac.bin_symlink", - vendor: true, - installed_location: "firmware/wlan/qca_cld/wlan_mac.bin", - symlink_target: "/mnt/vendor/persist/wlan_mac.bin", -} - -install_symlink { - name: "firmware_WCNSS_qcom_cfg.ini_symlink", - vendor: true, - installed_location: "firmware/wlan/qca_cld/WCNSS_qcom_cfg.ini", - symlink_target: "/vendor/etc/wifi/WCNSS_qcom_cfg.ini", -} diff --git a/Android.mk b/Android.mk new file mode 100644 index 0000000..e612a75 --- /dev/null +++ b/Android.mk @@ -0,0 +1,138 @@ +# +# Copyright (C) 2022-2023 The LineageOS Project +# +# SPDX-License-Identifier: Apache-2.0 +# + +LOCAL_PATH := $(call my-dir) + +ifneq ($(filter bangkk fogos,$(TARGET_DEVICE)),) +subdir_makefiles=$(call first-makefiles-under,$(LOCAL_PATH)) +$(foreach mk,$(subdir_makefiles),$(info including $(mk) ...)$(eval include $(mk))) + +include $(CLEAR_VARS) + +# A/B builds require us to create the mount points at compile time. +# Just creating it for all cases since it does not hurt. +FIRMWARE_MOUNT_POINT := $(TARGET_OUT_VENDOR)/firmware_mnt +$(FIRMWARE_MOUNT_POINT): $(LOCAL_INSTALLED_MODULE) + @echo "Creating $(FIRMWARE_MOUNT_POINT)" + @mkdir -p $(TARGET_OUT_VENDOR)/firmware_mnt + +BT_FIRMWARE_MOUNT_POINT := $(TARGET_OUT_VENDOR)/bt_firmware +$(BT_FIRMWARE_MOUNT_POINT): $(LOCAL_INSTALLED_MODULE) + @echo "Creating $(BT_FIRMWARE_MOUNT_POINT)" + @mkdir -p $(TARGET_OUT_VENDOR)/bt_firmware + +DSP_MOUNT_POINT := $(TARGET_OUT_VENDOR)/dsp +$(DSP_MOUNT_POINT): $(LOCAL_INSTALLED_MODULE) + @echo "Creating $(DSP_MOUNT_POINT)" + @mkdir -p $(TARGET_OUT_VENDOR)/dsp + +FSG_MOUNT_POINT := $(TARGET_OUT_VENDOR)/fsg +$(FSG_MOUNT_POINT): $(LOCAL_INSTALLED_MODULE) + @echo "Creating $(FSG_MOUNT_POINT)" + @mkdir -p $(TARGET_OUT_VENDOR)/fsg + +ALL_DEFAULT_INSTALLED_MODULES += $(FIRMWARE_MOUNT_POINT) $(BT_FIRMWARE_MOUNT_POINT) $(DSP_MOUNT_POINT) $(FSG_MOUNT_POINT) + +RFS_MSM_ADSP_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/adsp/ +$(RFS_MSM_ADSP_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "Creating RFS MSM ADSP folder structure: $@" + @rm -rf $@/* + @mkdir -p $(dir $@)/readonly/vendor + $(hide) ln -sf /data/vendor/tombstones/rfs/lpass $@/ramdumps + $(hide) ln -sf /mnt/vendor/persist/rfs/msm/adsp $@/readwrite + $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared + $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos + $(hide) ln -sf /vendor/firmware_mnt $@/readonly/firmware + $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware + +RFS_MSM_CDSP_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/cdsp/ +$(RFS_MSM_CDSP_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "Creating RFS MSM CDSP folder structure: $@" + @rm -rf $@/* + @mkdir -p $(dir $@)/readonly/vendor + $(hide) ln -sf /data/vendor/tombstones/rfs/cdsp $@/ramdumps + $(hide) ln -sf /mnt/vendor/persist/rfs/msm/cdsp $@/readwrite + $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared + $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos + $(hide) ln -sf /vendor/firmware_mnt $@/readonly/firmware + $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware + +RFS_MSM_MPSS_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/mpss/ +$(RFS_MSM_MPSS_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "Creating RFS MSM MPSS folder structure: $@" + @rm -rf $@/* + @mkdir -p $(dir $@)/readonly/fsg + @mkdir -p $(dir $@)/readonly/vendor + $(hide) ln -sf /data/vendor/tombstones/rfs/modem $@/ramdumps + $(hide) ln -sf /mnt/vendor/persist/rfs/msm/mpss $@/readwrite + $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared + $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos + $(hide) ln -sf /vendor/firmware_mnt $@/readonly/firmware + $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware + $(hide) ln -sf /vendor/fsg $@/readonly/vendor/fsg + +RFS_MSM_SLPI_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/slpi/ +$(RFS_MSM_SLPI_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "Creating RFS MSM SLPI folder structure: $@" + @rm -rf $@/* + @mkdir -p $(dir $@)/readonly/vendor + $(hide) ln -sf /data/vendor/tombstones/rfs/slpi $@/ramdumps + $(hide) ln -sf /mnt/vendor/persist/rfs/msm/slpi $@/readwrite + $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared + $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos + $(hide) ln -sf /vendor/firmware_mnt $@/readonly/firmware + $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware + +RFS_MSM_WPSS_SYMLINKS := $(TARGET_OUT_VENDOR)/rfs/msm/wpss/ +$(RFS_MSM_WPSS_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "Creating RFS MSM WPSS folder structure: $@" + @rm -rf $@/* + @mkdir -p $(dir $@)/readonly/vendor + $(hide) ln -sf /data/vendor/tombstones/rfs/wpss $@/ramdumps + $(hide) ln -sf /mnt/vendor/persist/rfs/msm/wpss $@/readwrite + $(hide) ln -sf /mnt/vendor/persist/rfs/shared $@/shared + $(hide) ln -sf /mnt/vendor/persist/hlos_rfs/shared $@/hlos + $(hide) ln -sf /vendor/firmware_mnt $@/readonly/firmware + $(hide) ln -sf /vendor/firmware $@/readonly/vendor/firmware + +WIFI_FIRMWARE_SYMLINKS := $(TARGET_OUT_VENDOR)/firmware/wlan/qca_cld +$(WIFI_FIRMWARE_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "Creating wifi firmware symlinks: $@" + @mkdir -p $@ + $(hide) ln -sf /mnt/vendor/persist/wlan_mac.bin $@/wlan_mac.bin + $(hide) ln -sf /vendor/etc/wifi/WCNSS_qcom_cfg.ini $@/WCNSS_qcom_cfg.ini + +ALL_DEFAULT_INSTALLED_MODULES += $(RFS_MSM_ADSP_SYMLINKS) $(RFS_MSM_CDSP_SYMLINKS) $(RFS_MSM_MPSS_SYMLINKS) \ + $(RFS_MSM_WPSS_SYMLINKS) $(RFS_MSM_SLPI_SYMLINKS) $(WIFI_FIRMWARE_SYMLINKS) + +IMS_LIBS := libimscamera_jni.so libimsmedia_jni.so +IMS_SYMLINKS := $(addprefix $(TARGET_OUT_SYSTEM_EXT_APPS_PRIVILEGED)/ims/lib/arm64/,$(notdir $(IMS_LIBS))) +$(IMS_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "IMS lib link: $@" + @mkdir -p $(dir $@) + @rm -rf $@ + $(hide) ln -sf /system_ext/lib64/$(notdir $@) $@ + +ALL_DEFAULT_INSTALLED_MODULES += $(IMS_SYMLINKS) + +CNE_APP_SYMLINKS := $(TARGET_OUT_VENDOR)/app/CneApp/lib/arm64 +$(CNE_APP_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "Creating CneApp symlinks: $@" + @mkdir -p $@ + $(hide) ln -sf /vendor/lib64/libvndfwk_detect_jni.qti.so $@/libvndfwk_detect_jni.qti.so + +ALL_DEFAULT_INSTALLED_MODULES += $(CNE_APP_SYMLINKS) + +EXPAT_SYMLINKS := $(TARGET_OUT_VENDOR_EXECUTABLES)/expat +$(EXPAT_SYMLINKS): $(LOCAL_INSTALLED_MODULE) + @echo "Expat bin link: $@" + @rm -rf $@ + @mkdir -p $(dir $@) + $(hide) ln -sf motobox $@ + +ALL_DEFAULT_INSTALLED_MODULES += $(EXPAT_SYMLINKS) + +endif diff --git a/BoardConfigCommon.mk b/BoardConfigCommon.mk index add9a4e..9b07b7a 100644 --- a/BoardConfigCommon.mk +++ b/BoardConfigCommon.mk @@ -36,6 +36,11 @@ TARGET_2ND_CPU_VARIANT_RUNTIME := kryo385 # Bootloader TARGET_NO_BOOTLOADER := true +# BUILD_BROKEN_* +BUILD_BROKEN_DUP_RULES := true +BUILD_BROKEN_ELF_PREBUILT_PRODUCT_COPY_FILES := true +BUILD_BROKEN_INCORRECT_PARTITION_IMAGES := true + # Kernel BOARD_BOOT_HEADER_VERSION := 3 BOARD_KERNEL_BASE := 0x00000000 @@ -53,9 +58,7 @@ BOARD_KERNEL_IMAGE_NAME := Image BOARD_KERNEL_PAGESIZE := 4096 BOARD_KERNEL_SEPARATED_DTBO := true BOARD_MKBOOTIMG_ARGS += --header_version $(BOARD_BOOT_HEADER_VERSION) -BOARD_RAMDISK_USE_LZ4 := true TARGET_KERNEL_ADDITIONAL_FLAGS := DTC_EXT=$(shell pwd)/prebuilts/misc/linux-x86/dtc/dtc LLVM=1 -TARGET_KERNEL_CLANG_VERSION := r530567 TARGET_KERNEL_SOURCE := kernel/motorola/sm6375 # Platform @@ -162,6 +165,7 @@ TARGET_NO_RECOVERY := true TARGET_RECOVERY_PIXEL_FORMAT := RGBX_8888 TARGET_USERIMAGES_USE_EXT4 := true TARGET_USERIMAGES_USE_F2FS := true +TARGET_RECOVERY_DEVICE_DIRS += $(COMMON_PATH) TARGET_RECOVERY_FSTAB := $(COMMON_PATH)/rootdir/etc/fstab.qcom TARGET_RECOVERY_WIPE := $(COMMON_PATH)/recovery/recovery.wipe @@ -171,6 +175,7 @@ ENABLE_VENDOR_RIL_SERVICE := true # SELinux include device/lineage/sepolicy/libperfmgr/sepolicy.mk include device/qcom/sepolicy_vndr/SEPolicy.mk +BUILD_BROKEN_VENDOR_PROPERTY_NAMESPACE := true BOARD_VENDOR_SEPOLICY_DIRS += $(COMMON_PATH)/sepolicy/vendor PRODUCT_PRIVATE_SEPOLICY_DIRS += $(COMMON_PATH)/sepolicy/private PRODUCT_PUBLIC_SEPOLICY_DIRS += $(COMMON_PATH)/sepolicy/public diff --git a/bootctrl/1.1/impl/Android.bp b/bootctrl/1.1/impl/Android.bp new file mode 100644 index 0000000..3c8e3a7 --- /dev/null +++ b/bootctrl/1.1/impl/Android.bp @@ -0,0 +1,24 @@ +filegroup { + name: "android.hardware.boot@1.1-impl-qti_src", + srcs: ["BootControl.cpp"], +} + +cc_defaults { + name: "android.hardware.boot@1.1-impl-qti_defaults", + defaults: [ + "hidl_defaults", + "libboot_control_qti_defaults", + ], + relative_install_path: "hw", + vendor: true, + recovery_available: true, + srcs: [":android.hardware.boot@1.1-impl-qti_src"], + shared_libs: [ + "liblog", + "libhidlbase", + "libhardware", + "libutils", + "android.hardware.boot@1.0", + "android.hardware.boot@1.1", + ], +} diff --git a/bootctrl/1.1/impl/BootControl.cpp b/bootctrl/1.1/impl/BootControl.cpp new file mode 100644 index 0000000..4094d25 --- /dev/null +++ b/bootctrl/1.1/impl/BootControl.cpp @@ -0,0 +1,132 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define LOG_TAG "android.hardware.boot@1.1-impl-qti" + +#include + +#include + +#include "BootControl.h" + +namespace android { +namespace hardware { +namespace boot { +namespace V1_1 { +namespace implementation { + +using ::android::hardware::boot::V1_0::CommandResult; + +bool BootControl::Init() { + return bootcontrol_init(); +} + +Return BootControl::getNumberSlots() { + return get_number_slots(); +} + +Return BootControl::getCurrentSlot() { + return get_current_slot(); +} + +Return BootControl::markBootSuccessful(markBootSuccessful_cb _hidl_cb) { + int ret = mark_boot_successful(); + struct CommandResult cr; + cr.success = (ret == 0); + cr.errMsg = strerror(-ret); + _hidl_cb(cr); + return Void(); +} + +Return BootControl::setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) { + int ret = set_active_boot_slot(slot); + struct CommandResult cr; + cr.success = (ret == 0); + cr.errMsg = strerror(-ret); + _hidl_cb(cr); + return Void(); +} + +Return BootControl::setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) { + int ret = set_slot_as_unbootable(slot); + struct CommandResult cr; + cr.success = (ret == 0); + cr.errMsg = strerror(-ret); + _hidl_cb(cr); + return Void(); +} + +Return BootControl::isSlotBootable(uint32_t slot) { + int32_t ret = is_slot_bootable(slot); + if (ret < 0) { + return BoolResult::INVALID_SLOT; + } + return ret ? BoolResult::TRUE : BoolResult::FALSE; +} + +Return BootControl::isSlotMarkedSuccessful(uint32_t slot) { + int32_t ret = is_slot_marked_successful(slot); + if (ret < 0) { + return BoolResult::INVALID_SLOT; + } + return ret ? BoolResult::TRUE : BoolResult::FALSE; +} + +Return BootControl::getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) { + hidl_string ans; + const char* suffix = get_suffix(slot); + if (suffix) { + ans = suffix; + } + _hidl_cb(ans); + return Void(); +} + +Return BootControl::setSnapshotMergeStatus(MergeStatus status) { + return set_snapshot_merge_status(status); +} + +Return BootControl::getSnapshotMergeStatus() { + return get_snapshot_merge_status(); +} + +IBootControl* HIDL_FETCH_IBootControl(const char* /* hal */) { + auto module = std::make_unique(); + if (!module->Init()) { + ALOGE("Could not initialize BootControl module"); + return nullptr; + } + return module.release(); +} + +} // namespace implementation +} // namespace V1_1 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/bootctrl/1.1/impl/BootControl.h b/bootctrl/1.1/impl/BootControl.h new file mode 100644 index 0000000..d33ec0c --- /dev/null +++ b/bootctrl/1.1/impl/BootControl.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include +#include +#include + +namespace android { +namespace hardware { +namespace boot { +namespace V1_1 { +namespace implementation { + +using ::android::hardware::Return; +using ::android::hardware::Void; +using ::android::hardware::boot::V1_0::BoolResult; +using ::android::hardware::boot::V1_1::IBootControl; +using ::android::hardware::boot::V1_1::MergeStatus; + +class BootControl : public IBootControl { + public: + bool Init(); + + // Methods from ::android::hardware::boot::V1_0::IBootControl follow. + Return getNumberSlots() override; + Return getCurrentSlot() override; + Return markBootSuccessful(markBootSuccessful_cb _hidl_cb) override; + Return setActiveBootSlot(uint32_t slot, setActiveBootSlot_cb _hidl_cb) override; + Return setSlotAsUnbootable(uint32_t slot, setSlotAsUnbootable_cb _hidl_cb) override; + Return isSlotBootable(uint32_t slot) override; + Return isSlotMarkedSuccessful(uint32_t slot) override; + Return getSuffix(uint32_t slot, getSuffix_cb _hidl_cb) override; + + // Methods from ::android::hardware::boot::V1_1::IBootControl follow. + Return setSnapshotMergeStatus(MergeStatus status) override; + Return getSnapshotMergeStatus() override; + +}; + +extern "C" IBootControl* HIDL_FETCH_IBootControl(const char* name); + +} // namespace implementation +} // namespace V1_1 +} // namespace boot +} // namespace hardware +} // namespace android diff --git a/bootctrl/1.1/libboot_control_qti/Android.bp b/bootctrl/1.1/libboot_control_qti/Android.bp new file mode 100644 index 0000000..10cef14 --- /dev/null +++ b/bootctrl/1.1/libboot_control_qti/Android.bp @@ -0,0 +1,38 @@ +filegroup { + name: "libboot_control_qti_src", + srcs: ["libboot_control_qti.cpp"], +} + +cc_library_headers { + name: "libboot_control_qti_headers", + vendor: true, + recovery_available: true, + export_include_dirs: ["."], +} + +cc_defaults { + name: "libboot_control_qti_defaults", + vendor: true, + recovery_available: true, + shared_libs: [ + "android.hardware.boot@1.1", + "libbase", + "libcutils", + "liblog", + "libz", + ], + static_libs: [ + "libboot_control", + "libbootloader_message_vendor", + "libfstab", + ], + owner: "qti", + cflags: [ + "-Wall", + "-Werror", + ], + srcs: [ + ":libboot_control_qti_src", + ], + header_libs: ["libboot_control_qti_headers"], +} diff --git a/bootctrl/1.1/libboot_control_qti/libboot_control_qti.cpp b/bootctrl/1.1/libboot_control_qti/libboot_control_qti.cpp new file mode 100644 index 0000000..371be6d --- /dev/null +++ b/bootctrl/1.1/libboot_control_qti/libboot_control_qti.cpp @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2016,2020, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +//#define LOG_NDEBUG 0 +#define LOG_TAG "bootcontrolhal" + +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define BOOTDEV_DIR "/dev/block/bootdevice/by-name" +#define BOOT_IMG_PTN_NAME "boot" +#define LUN_NAME_END_LOC 14 +#define BOOT_SLOT_PROP "ro.boot.slot_suffix" +#define BOARD_PLATFORM_PROP "ro.build.product" +#define GVMQ_PLATFORM "msmnile_gvmq" + +#define SLOT_ACTIVE 1 +#define SLOT_INACTIVE 2 +#define UPDATE_SLOT(pentry, guid, slot_state) ({ \ + memcpy(pentry, guid, TYPE_GUID_SIZE); \ + if (slot_state == SLOT_ACTIVE)\ + *(pentry + AB_FLAG_OFFSET) = AB_SLOT_ACTIVE_VAL; \ + else if (slot_state == SLOT_INACTIVE) \ + *(pentry + AB_FLAG_OFFSET) = (*(pentry + AB_FLAG_OFFSET)& \ + ~AB_PARTITION_ATTR_SLOT_ACTIVE); \ + }) + +using namespace std; +const char *slot_suffix_arr[] = { + AB_SLOT_A_SUFFIX, + AB_SLOT_B_SUFFIX, + NULL}; + +enum part_attr_type { + ATTR_SLOT_ACTIVE = 0, + ATTR_BOOT_SUCCESSFUL, + ATTR_UNBOOTABLE, +}; + +bool mGvmqPlatform = false; + +using ::android::bootable::GetMiscVirtualAbMergeStatus; +using ::android::bootable::InitMiscVirtualAbMessageIfNeeded; +using ::android::bootable::SetMiscVirtualAbMergeStatus; +using ::android::hardware::boot::V1_1::MergeStatus; + +//Get the value of one of the attribute fields for a partition. +static int get_partition_attribute(char *partname, + enum part_attr_type part_attr) +{ + struct gpt_disk *disk = NULL; + uint8_t *pentry = NULL; + int retval = -1; + uint8_t *attr = NULL; + if (!partname) + goto error; + disk = gpt_disk_alloc(); + if (!disk) { + ALOGE("%s: Failed to alloc disk struct", __func__); + goto error; + } + if (gpt_disk_get_disk_info(partname, disk)) { + ALOGE("%s: Failed to get disk info", __func__); + goto error; + } + pentry = gpt_disk_get_pentry(disk, partname, PRIMARY_GPT); + if (!pentry) { + ALOGE("%s: pentry does not exist in disk struct", + __func__); + goto error; + } + attr = pentry + AB_FLAG_OFFSET; + if (part_attr == ATTR_SLOT_ACTIVE) + retval = !!(*attr & AB_PARTITION_ATTR_SLOT_ACTIVE); + else if (part_attr == ATTR_BOOT_SUCCESSFUL) + retval = !!(*attr & AB_PARTITION_ATTR_BOOT_SUCCESSFUL); + else if (part_attr == ATTR_UNBOOTABLE) + retval = !!(*attr & AB_PARTITION_ATTR_UNBOOTABLE); + else + retval = -1; + gpt_disk_free(disk); + return retval; +error: + if (disk) + gpt_disk_free(disk); + return retval; +} + +//Set a particular attribute for all the partitions in a +//slot +static int update_slot_attribute(const char *slot, + enum part_attr_type ab_attr) +{ + unsigned int i = 0; + char buf[PATH_MAX]; + struct stat st; + struct gpt_disk *disk = NULL; + uint8_t *pentry = NULL; + uint8_t *pentry_bak = NULL; + int rc = -1; + uint8_t *attr = NULL; + uint8_t *attr_bak = NULL; + char partName[MAX_GPT_NAME_SIZE + 1] = {0}; + const char ptn_list[][MAX_GPT_NAME_SIZE] = { AB_PTN_LIST }; + int slot_name_valid = 0; + if (!slot) { + ALOGE("%s: Invalid argument", __func__); + goto error; + } + for (i = 0; slot_suffix_arr[i] != NULL; i++) + { + if (!strncmp(slot, slot_suffix_arr[i], + strlen(slot_suffix_arr[i]))) + slot_name_valid = 1; + } + if (!slot_name_valid) { + ALOGE("%s: Invalid slot name", __func__); + goto error; + } + for (i=0; i < ARRAY_SIZE(ptn_list); i++) { + memset(buf, '\0', sizeof(buf)); + //Check if A/B versions of this ptn exist + snprintf(buf, sizeof(buf) - 1, + "%s/%s%s", + BOOT_DEV_DIR, + ptn_list[i], + AB_SLOT_A_SUFFIX + ); + if (stat(buf, &st)) { + //partition does not have _a version + continue; + } + memset(buf, '\0', sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, + "%s/%s%s", + BOOT_DEV_DIR, + ptn_list[i], + AB_SLOT_B_SUFFIX + ); + if (stat(buf, &st)) { + //partition does not have _a version + continue; + } + memset(partName, '\0', sizeof(partName)); + snprintf(partName, + sizeof(partName) - 1, + "%s%s", + ptn_list[i], + slot); + disk = gpt_disk_alloc(); + if (!disk) { + ALOGE("%s: Failed to alloc disk struct", + __func__); + goto error; + } + rc = gpt_disk_get_disk_info(partName, disk); + if (rc != 0) { + ALOGE("%s: Failed to get disk info for %s", + __func__, + partName); + goto error; + } + pentry = gpt_disk_get_pentry(disk, partName, PRIMARY_GPT); + pentry_bak = gpt_disk_get_pentry(disk, partName, SECONDARY_GPT); + if (!pentry || !pentry_bak) { + ALOGE("%s: Failed to get pentry/pentry_bak for %s", + __func__, + partName); + goto error; + } + attr = pentry + AB_FLAG_OFFSET; + attr_bak = pentry_bak + AB_FLAG_OFFSET; + if (ab_attr == ATTR_BOOT_SUCCESSFUL) { + *attr = (*attr) | AB_PARTITION_ATTR_BOOT_SUCCESSFUL; + *attr_bak = (*attr_bak) | + AB_PARTITION_ATTR_BOOT_SUCCESSFUL; + } else if (ab_attr == ATTR_UNBOOTABLE) { + *attr = (*attr) | AB_PARTITION_ATTR_UNBOOTABLE; + *attr_bak = (*attr_bak) | AB_PARTITION_ATTR_UNBOOTABLE; + } else if (ab_attr == ATTR_SLOT_ACTIVE) { + *attr = (*attr) | AB_PARTITION_ATTR_SLOT_ACTIVE; + *attr_bak = (*attr) | AB_PARTITION_ATTR_SLOT_ACTIVE; + } else { + ALOGE("%s: Unrecognized attr", __func__); + goto error; + } + if (gpt_disk_update_crc(disk)) { + ALOGE("%s: Failed to update crc for %s", + __func__, + partName); + goto error; + } + if (gpt_disk_commit(disk)) { + ALOGE("%s: Failed to write back entry for %s", + __func__, + partName); + goto error; + } + gpt_disk_free(disk); + disk = NULL; + } + return 0; +error: + if (disk) + gpt_disk_free(disk); + return -1; +} + +static int boot_control_check_slot_sanity(unsigned slot) +{ + uint32_t num_slots = get_number_slots(); + if ((num_slots < 1) || (slot > num_slots - 1)) { + ALOGE("Invalid slot number"); + return -1; + } + return 0; + +} + +//Return a gpt disk structure representing the disk that holds +//partition. +static struct gpt_disk* boot_ctl_get_disk_info(char *partition) +{ + struct gpt_disk *disk = NULL; + if (!partition) + return NULL; + disk = gpt_disk_alloc(); + if (!disk) { + ALOGE("%s: Failed to alloc disk", + __func__); + goto error; + } + if (gpt_disk_get_disk_info(partition, disk)) { + ALOGE("failed to get disk info for %s", + partition); + goto error; + } + return disk; +error: + if (disk) + gpt_disk_free(disk); + return NULL; +} + +//The argument here is a vector of partition names(including the slot suffix) +//that lie on a single disk +static int boot_ctl_set_active_slot_for_partitions(vector part_list, + unsigned slot) +{ + char buf[PATH_MAX] = {0}; + struct gpt_disk *diskA = NULL; + struct gpt_disk *diskB = NULL; + char slotA[MAX_GPT_NAME_SIZE + 1] = {0}; + char slotB[MAX_GPT_NAME_SIZE + 1] = {0}; + char active_guid[TYPE_GUID_SIZE + 1] = {0}; + char inactive_guid[TYPE_GUID_SIZE + 1] = {0}; + //Pointer to the partition entry of current 'A' partition + uint8_t *pentryA = NULL; + uint8_t *pentryA_bak = NULL; + //Pointer to partition entry of current 'B' partition + uint8_t *pentryB = NULL; + uint8_t *pentryB_bak = NULL; + struct stat st; + vector::iterator partition_iterator; + + for (partition_iterator = part_list.begin(); + partition_iterator != part_list.end(); + partition_iterator++) { + //Chop off the slot suffix from the partition name to + //make the string easier to work with. + string prefix = *partition_iterator; + if (prefix.size() < (strlen(AB_SLOT_A_SUFFIX) + 1)) { + ALOGE("Invalid partition name: %s", prefix.c_str()); + goto error; + } + prefix.resize(prefix.size() - strlen(AB_SLOT_A_SUFFIX)); + //Check if A/B versions of this ptn exist + snprintf(buf, sizeof(buf) - 1, "%s/%s%s", BOOT_DEV_DIR, + prefix.c_str(), + AB_SLOT_A_SUFFIX); + if (stat(buf, &st)) + continue; + memset(buf, '\0', sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "%s/%s%s", BOOT_DEV_DIR, + prefix.c_str(), + AB_SLOT_B_SUFFIX); + if (stat(buf, &st)) + continue; + memset(slotA, 0, sizeof(slotA)); + memset(slotB, 0, sizeof(slotB)); + snprintf(slotA, sizeof(slotA) - 1, "%s%s", prefix.c_str(), + AB_SLOT_A_SUFFIX); + snprintf(slotB, sizeof(slotB) - 1,"%s%s", prefix.c_str(), + AB_SLOT_B_SUFFIX); + //Get the disks containing the partitions that were passed in. + if (!diskA) { + diskA = boot_ctl_get_disk_info(slotA); + if (!diskA) + goto error; + } + if (!diskB) { + diskB = boot_ctl_get_disk_info(slotB); + if (!diskB) + goto error; + } + //Get partition entry for slot A & B from the primary + //and backup tables. + pentryA = gpt_disk_get_pentry(diskA, slotA, PRIMARY_GPT); + pentryA_bak = gpt_disk_get_pentry(diskA, slotA, SECONDARY_GPT); + pentryB = gpt_disk_get_pentry(diskB, slotB, PRIMARY_GPT); + pentryB_bak = gpt_disk_get_pentry(diskB, slotB, SECONDARY_GPT); + if ( !pentryA || !pentryA_bak || !pentryB || !pentryB_bak) { + //None of these should be NULL since we have already + //checked for A & B versions earlier. + ALOGE("Slot pentries for %s not found.", + prefix.c_str()); + goto error; + } + memset(active_guid, '\0', sizeof(active_guid)); + memset(inactive_guid, '\0', sizeof(inactive_guid)); + if (get_partition_attribute(slotA, ATTR_SLOT_ACTIVE) == 1) { + //A is the current active slot + memcpy((void*)active_guid, (const void*)pentryA, + TYPE_GUID_SIZE); + memcpy((void*)inactive_guid,(const void*)pentryB, + TYPE_GUID_SIZE); + } else if (get_partition_attribute(slotB, + ATTR_SLOT_ACTIVE) == 1) { + //B is the current active slot + memcpy((void*)active_guid, (const void*)pentryB, + TYPE_GUID_SIZE); + memcpy((void*)inactive_guid, (const void*)pentryA, + TYPE_GUID_SIZE); + } else { + ALOGE("Both A & B for %s are inactive..Aborting", + prefix.c_str()); + goto error; + } + if (!strncmp(slot_suffix_arr[slot], AB_SLOT_A_SUFFIX, + strlen(AB_SLOT_A_SUFFIX))){ + //Mark A as active in primary table + UPDATE_SLOT(pentryA, active_guid, SLOT_ACTIVE); + //Mark A as active in backup table + UPDATE_SLOT(pentryA_bak, active_guid, SLOT_ACTIVE); + //Mark B as inactive in primary table + UPDATE_SLOT(pentryB, inactive_guid, SLOT_INACTIVE); + //Mark B as inactive in backup table + UPDATE_SLOT(pentryB_bak, inactive_guid, SLOT_INACTIVE); + } else if (!strncmp(slot_suffix_arr[slot], AB_SLOT_B_SUFFIX, + strlen(AB_SLOT_B_SUFFIX))){ + //Mark B as active in primary table + UPDATE_SLOT(pentryB, active_guid, SLOT_ACTIVE); + //Mark B as active in backup table + UPDATE_SLOT(pentryB_bak, active_guid, SLOT_ACTIVE); + //Mark A as inavtive in primary table + UPDATE_SLOT(pentryA, inactive_guid, SLOT_INACTIVE); + //Mark A as inactive in backup table + UPDATE_SLOT(pentryA_bak, inactive_guid, SLOT_INACTIVE); + } else { + //Something has gone terribly terribly wrong + ALOGE("%s: Unknown slot suffix!", __func__); + goto error; + } + + if (diskA) { + if (gpt_disk_update_crc(diskA) != 0) { + ALOGE("%s: Failed to update gpt_disk crc", + __func__); + goto error; + } + } + if (diskB) { + if (gpt_disk_update_crc(diskB) != 0) { + ALOGE("%s: Failed to update gpt_disk crc", + __func__); + goto error; + } + } + } + //write updated content to disk + if (diskA) { + if (gpt_disk_commit(diskA)) { + ALOGE("Failed to commit disk entry"); + goto error; + } + gpt_disk_free(diskA); + } + if (diskB) { + if (gpt_disk_commit(diskB)) { + ALOGE("Failed to commit disk entry"); + goto error; + } + gpt_disk_free(diskB); + } + return 0; + +error: + if (diskA) + gpt_disk_free(diskA); + if (diskB) + gpt_disk_free(diskB); + return -1; +} + +bool bootcontrol_init() +{ + char platform[256]; + property_get(BOARD_PLATFORM_PROP , platform, ""); + if (!strncmp(platform, GVMQ_PLATFORM, strlen(GVMQ_PLATFORM))) + mGvmqPlatform = true; + return InitMiscVirtualAbMessageIfNeeded(); +} + +unsigned get_number_slots() +{ + if (mGvmqPlatform) + return 2; + + struct dirent *de = NULL; + DIR *dir_bootdev = NULL; + unsigned slot_count = 0; + dir_bootdev = opendir(BOOTDEV_DIR); + if (!dir_bootdev) { + ALOGE("%s: Failed to open bootdev dir (%s)", + __func__, + strerror(errno)); + goto error; + } + while ((de = readdir(dir_bootdev))) { + if (de->d_name[0] == '.') + continue; + if (!strncmp(de->d_name, BOOT_IMG_PTN_NAME, + strlen(BOOT_IMG_PTN_NAME))) + slot_count++; + } + closedir(dir_bootdev); + return slot_count; +error: + if (dir_bootdev) + closedir(dir_bootdev); + return 0; +} + +unsigned get_current_slot() +{ + uint32_t num_slots = 0; + char bootSlotProp[PROPERTY_VALUE_MAX] = {'\0'}; + unsigned i = 0; + num_slots = get_number_slots(); + if (num_slots <= 1) { + //Slot 0 is the only slot around. + return 0; + } + property_get(BOOT_SLOT_PROP, bootSlotProp, "N/A"); + if (!strncmp(bootSlotProp, "N/A", strlen("N/A"))) { + ALOGE("%s: Unable to read boot slot property", + __func__); + goto error; + } + //Iterate through a list of partitons named as boot+suffix + //and see which one is currently active. + for (i = 0; slot_suffix_arr[i] != NULL ; i++) { + if (!strncmp(bootSlotProp, + slot_suffix_arr[i], + strlen(slot_suffix_arr[i]))) + return i; + } +error: + //The HAL spec requires that we return a number between + //0 to num_slots - 1. Since something went wrong here we + //are just going to return the default slot. + return 0; +} + +int mark_boot_successful(){ + if (mGvmqPlatform) { + std::string err; + std::string misc_blk_device = get_bootloader_message_blk_device(&err); + if (misc_blk_device.empty()) { + ALOGE("Could not find bootloader message block device: %s", err.c_str()); + return -1; + } + bootloader_message boot; + if (!read_bootloader_message_from(&boot, misc_blk_device, &err)) { + ALOGE(" Failed to read from %s due to %s ", misc_blk_device.c_str(), err.c_str()); + return -1; + } + ALOGV(" bootloader_message is : boot.reserved[0] = %c, boot.reserved[1] = %c", + boot.reserved[0], boot.reserved[1]); + boot.reserved[2] = 'y'; + if (!write_bootloader_message_to(boot, misc_blk_device, &err)) { + ALOGE("Failed to write to %s because : %s", misc_blk_device.c_str(), err.c_str()); + return -1; + } + bootloader_message boot_verify; + if (!read_bootloader_message_from(&boot_verify, misc_blk_device, &err)) { + ALOGE("Failed to read from %s due to %s ", misc_blk_device.c_str(), err.c_str()); + return -1; + } + ALOGV(" bootloader_message : boot_verify.reserved[0] = %c, boot_verify.reserved[1] = %c,boot_verify.reserved[2] = %c", + boot_verify.reserved[0],boot_verify.reserved[1], boot_verify.reserved[2]); + } + + unsigned cur_slot = 0; + cur_slot = get_current_slot(); + if (update_slot_attribute(slot_suffix_arr[cur_slot], + ATTR_BOOT_SUCCESSFUL)) { + goto error; + } + return 0; +error: + ALOGE("%s: Failed to mark boot successful", __func__); + return -1; +} + +int set_active_boot_slot(unsigned slot) +{ + if (mGvmqPlatform) { + std::string err; + std::string misc_blk_device = get_bootloader_message_blk_device(&err); + if (misc_blk_device.empty()) { + ALOGE("Could not find bootloader message block device: %s", err.c_str()); + return -1; + } + unsigned current_slot = get_current_slot(); + uint32_t num_slots = get_number_slots(); + if ((num_slots < 1) || (current_slot > num_slots - 1)) { + ALOGE("Invalid slot number"); + return -1; + } + bootloader_message boot; + if(current_slot == 0) + boot.reserved[0] = 'a'; + else + boot.reserved[0] = 'b'; + if(slot == 0) + boot.reserved[1] = 'a'; + else + boot.reserved[1] = 'b'; + boot.reserved[2] = '\0'; + if (!write_bootloader_message_to(boot, misc_blk_device, &err)) { + ALOGE("Failed to write to %s because : %s", misc_blk_device.c_str(), err.c_str()); + return -1; + } + bootloader_message boot_verify; + if (!read_bootloader_message_from(&boot_verify, misc_blk_device, &err)) { + ALOGE("Failed to read from %s due to %s ", misc_blk_device.c_str(), err.c_str()); + return -1; + } + ALOGV("bootloader_message is : boot_verify.reserved[0] = %c, boot_verify.reserved[1] = %c,boot_verify.reserved[2] = %c", + boot_verify.reserved[0],boot_verify.reserved[1], boot_verify.reserved[2]); + } + map> ptn_map; + vector ptn_vec; + const char ptn_list[][MAX_GPT_NAME_SIZE] = { AB_PTN_LIST }; + uint32_t i; + int rc = -1; + int is_ufs = gpt_utils_is_ufs_device(); + map>::iterator map_iter; + + if (boot_control_check_slot_sanity(slot)) { + ALOGE("%s: Bad arguments", __func__); + goto error; + } + //The partition list just contains prefixes(without the _a/_b) of the + //partitions that support A/B. In order to get the layout we need the + //actual names. To do this we append the slot suffix to every member + //in the list. + for (i = 0; i < ARRAY_SIZE(ptn_list); i++) { + //XBL & XBL_CFG are handled differrently for ufs devices so + //ignore them + if (is_ufs && (!strncmp(ptn_list[i], + PTN_XBL, + strlen(PTN_XBL)) + || !strncmp(ptn_list[i], + PTN_XBL_CFG, + strlen(PTN_XBL_CFG)))) + continue; + //The partition list will be the list of partitions + //corresponding to the slot being set active + string cur_ptn = ptn_list[i]; + cur_ptn.append(slot_suffix_arr[slot]); + ptn_vec.push_back(cur_ptn); + + } + //The partition map gives us info in the following format: + // [path_to_block_device_1]--> + // [path_to_block_device_2]--> + // ... + // ... + // eg: + // [/dev/block/sdb]---> + if (gpt_utils_get_partition_map(ptn_vec, ptn_map)) { + ALOGE("%s: Failed to get partition map", + __func__); + goto error; + } + for (map_iter = ptn_map.begin(); map_iter != ptn_map.end(); map_iter++){ + if (map_iter->second.size() < 1) + continue; + if (boot_ctl_set_active_slot_for_partitions(map_iter->second, + slot)) { + ALOGE("%s: Failed to set active slot", __func__); + goto error; + } + } + if (is_ufs) { + if (!strncmp(slot_suffix_arr[slot], AB_SLOT_A_SUFFIX, + strlen(AB_SLOT_A_SUFFIX))){ + //Set xbl_a as the boot lun + rc = gpt_utils_set_xbl_boot_partition(NORMAL_BOOT); + } else if (!strncmp(slot_suffix_arr[slot], AB_SLOT_B_SUFFIX, + strlen(AB_SLOT_B_SUFFIX))){ + //Set xbl_b as the boot lun + rc = gpt_utils_set_xbl_boot_partition(BACKUP_BOOT); + } else { + //Something has gone terribly terribly wrong + ALOGE("%s: Unknown slot suffix!", __func__); + goto error; + } + if (rc) { + ALOGE("%s: Failed to switch xbl boot partition", + __func__); + goto error; + } + } + return 0; +error: + return -1; +} + +int set_slot_as_unbootable(unsigned slot) +{ + if (boot_control_check_slot_sanity(slot) != 0) { + ALOGE("%s: Argument check failed", __func__); + goto error; + } + if (update_slot_attribute(slot_suffix_arr[slot], + ATTR_UNBOOTABLE)) { + goto error; + } + return 0; +error: + ALOGE("%s: Failed to mark slot unbootable", __func__); + return -1; +} +int is_slot_bootable(unsigned slot) +{ + int attr = 0; + char bootPartition[MAX_GPT_NAME_SIZE + 1] = {0}; + + if (boot_control_check_slot_sanity(slot) != 0) { + ALOGE("%s: Argument check failed", __func__); + goto error; + } + snprintf(bootPartition, + sizeof(bootPartition) - 1, "boot%s", + slot_suffix_arr[slot]); + attr = get_partition_attribute(bootPartition, ATTR_UNBOOTABLE); + if (attr >= 0) + return !attr; +error: + return -1; +} + +int is_slot_marked_successful(unsigned slot) +{ + int attr = 0; + char bootPartition[MAX_GPT_NAME_SIZE + 1] = {0}; + + if (boot_control_check_slot_sanity(slot) != 0) { + ALOGE("%s: Argument check failed", __func__); + goto error; + } + snprintf(bootPartition, + sizeof(bootPartition) - 1, + "boot%s", slot_suffix_arr[slot]); + attr = get_partition_attribute(bootPartition, ATTR_BOOT_SUCCESSFUL); + if (attr >= 0) + return attr; +error: + return -1; +} + +const char* get_suffix(unsigned slot) +{ + if (boot_control_check_slot_sanity(slot) != 0) + return NULL; + else + return slot_suffix_arr[slot]; +} + +bool set_snapshot_merge_status(MergeStatus status) +{ + bool retval = SetMiscVirtualAbMergeStatus(get_current_slot(), status); + ALOGI("%s: MergeStatus = %d, current_slot = %d, returning: %s \n", __func__, + status, get_current_slot(), retval ? "true" : "false"); + return retval; +} + +MergeStatus get_snapshot_merge_status() +{ + MergeStatus status; + if (!GetMiscVirtualAbMergeStatus(get_current_slot(), &status)) { + ALOGI("%s: MergeStatus read from misc failed, returning unknown\n", __func__); + return MergeStatus::UNKNOWN; + } + ALOGI("%s: Returning MergeStatus = %d\n", __func__, status); + return status; +} diff --git a/bootctrl/1.1/libboot_control_qti/libboot_control_qti.h b/bootctrl/1.1/libboot_control_qti/libboot_control_qti.h new file mode 100644 index 0000000..b055a49 --- /dev/null +++ b/bootctrl/1.1/libboot_control_qti/libboot_control_qti.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2020, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#pragma once + +#include +#include + +using MergeStatus = ::android::hardware::boot::V1_1::MergeStatus; + +// IBootControl 1.0 methods +bool bootcontrol_init(); +unsigned get_number_slots(); +unsigned get_current_slot(); +int mark_boot_successful(); +int set_active_boot_slot(unsigned slot); +int set_slot_as_unbootable(unsigned slot); +int is_slot_bootable(unsigned slot); +int is_slot_marked_successful(unsigned slot); +const char* get_suffix(unsigned slot); + +// IBootControl 1.1 methods +bool set_snapshot_merge_status(MergeStatus status); +MergeStatus get_snapshot_merge_status(); diff --git a/bootctrl/Android.bp b/bootctrl/Android.bp new file mode 100644 index 0000000..ea51dc3 --- /dev/null +++ b/bootctrl/Android.bp @@ -0,0 +1,44 @@ +filegroup { + name: "bootctrl_hal_src", + srcs: [ + "boot_control.cpp", + ], +} + +cc_defaults { + name: "bootctrl_hal_defaults", + proprietary: true, + recovery_available: true, + header_libs: [ + "libhardware_headers", + "libsystem_headers", + ], + shared_libs: [ + "libcutils", + "liblog", + "libz", + ], + owner: "qti", + relative_install_path: "hw", + cflags: [ + "-Wall", + "-Werror", + ], + srcs: [ + ":bootctrl_hal_src", + ], + +} + +cc_library { + name: "bootctrl.holi", + defaults: ["bootctrl_hal_defaults"], + static_libs: ["libgptutils.moto_holi"], +} + +cc_library_shared { + name: "android.hardware.boot@1.1-impl-qti", + stem: "android.hardware.boot@1.0-impl-1.1-qti", + defaults: ["android.hardware.boot@1.1-impl-qti_defaults"], + static_libs: ["libgptutils.moto_holi"], +} diff --git a/bootctrl/NOTICE b/bootctrl/NOTICE new file mode 100644 index 0000000..820d40c --- /dev/null +++ b/bootctrl/NOTICE @@ -0,0 +1,26 @@ +Copyright (c) 2016, The Linux Foundation. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions are +met: + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above + copyright notice, this list of conditions and the following + disclaimer in the documentation and/or other materials provided + with the distribution. + * Neither the name of The Linux Foundation nor the names of its + contributors may be used to endorse or promote products derived + from this software without specific prior written permission. + +THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED +WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT +ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS +BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR +CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF +SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR +BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE +OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN +IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/bootctrl/boot_control.cpp b/bootctrl/boot_control.cpp new file mode 100644 index 0000000..726b245 --- /dev/null +++ b/bootctrl/boot_control.cpp @@ -0,0 +1,703 @@ +/* + * Copyright (c) 2016, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +#include +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#define LOG_TAG "bootcontrolhal" +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "gpt-utils.h" + +#define BOOTDEV_DIR "/dev/block/bootdevice/by-name" +#define BOOT_IMG_PTN_NAME "boot" +#define LUN_NAME_END_LOC 14 +#define BOOT_SLOT_PROP "ro.boot.slot_suffix" + +#define SLOT_ACTIVE 1 +#define SLOT_INACTIVE 2 +#define UPDATE_SLOT(pentry, guid, slot_state) ({ \ + memcpy(pentry, guid, TYPE_GUID_SIZE); \ + if (slot_state == SLOT_ACTIVE)\ + *(pentry + AB_FLAG_OFFSET) = AB_SLOT_ACTIVE_VAL; \ + else if (slot_state == SLOT_INACTIVE) \ + *(pentry + AB_FLAG_OFFSET) = (*(pentry + AB_FLAG_OFFSET)& \ + ~AB_PARTITION_ATTR_SLOT_ACTIVE); \ + }) + +using namespace std; +const char *slot_suffix_arr[] = { + AB_SLOT_A_SUFFIX, + AB_SLOT_B_SUFFIX, + NULL}; + +enum part_attr_type { + ATTR_SLOT_ACTIVE = 0, + ATTR_BOOT_SUCCESSFUL, + ATTR_UNBOOTABLE, +}; + +void boot_control_init(struct boot_control_module *module) +{ + if (!module) { + ALOGE("Invalid argument passed to %s", __func__); + return; + } + return; +} + +//Get the value of one of the attribute fields for a partition. +static int get_partition_attribute(char *partname, + enum part_attr_type part_attr) +{ + struct gpt_disk *disk = NULL; + uint8_t *pentry = NULL; + int retval = -1; + uint8_t *attr = NULL; + if (!partname) + goto error; + disk = gpt_disk_alloc(); + if (!disk) { + ALOGE("%s: Failed to alloc disk struct", __func__); + goto error; + } + if (gpt_disk_get_disk_info(partname, disk)) { + ALOGE("%s: Failed to get disk info", __func__); + goto error; + } + pentry = gpt_disk_get_pentry(disk, partname, PRIMARY_GPT); + if (!pentry) { + ALOGE("%s: pentry does not exist in disk struct", + __func__); + goto error; + } + attr = pentry + AB_FLAG_OFFSET; + if (part_attr == ATTR_SLOT_ACTIVE) + retval = !!(*attr & AB_PARTITION_ATTR_SLOT_ACTIVE); + else if (part_attr == ATTR_BOOT_SUCCESSFUL) + retval = !!(*attr & AB_PARTITION_ATTR_BOOT_SUCCESSFUL); + else if (part_attr == ATTR_UNBOOTABLE) + retval = !!(*attr & AB_PARTITION_ATTR_UNBOOTABLE); + else + retval = -1; + gpt_disk_free(disk); + return retval; +error: + if (disk) + gpt_disk_free(disk); + return retval; +} + +//Set a particular attribute for all the partitions in a +//slot +static int update_slot_attribute(const char *slot, + enum part_attr_type ab_attr) +{ + unsigned int i = 0; + char buf[PATH_MAX]; + struct stat st; + struct gpt_disk *disk = NULL; + uint8_t *pentry = NULL; + uint8_t *pentry_bak = NULL; + int rc = -1; + uint8_t *attr = NULL; + uint8_t *attr_bak = NULL; + char partName[MAX_GPT_NAME_SIZE + 1] = {0}; + const char ptn_list[][MAX_GPT_NAME_SIZE] = { AB_PTN_LIST }; + int slot_name_valid = 0; + if (!slot) { + ALOGE("%s: Invalid argument", __func__); + goto error; + } + for (i = 0; slot_suffix_arr[i] != NULL; i++) + { + if (!strncmp(slot, slot_suffix_arr[i], + strlen(slot_suffix_arr[i]))) + slot_name_valid = 1; + } + if (!slot_name_valid) { + ALOGE("%s: Invalid slot name", __func__); + goto error; + } + for (i=0; i < ARRAY_SIZE(ptn_list); i++) { + memset(buf, '\0', sizeof(buf)); + //Check if A/B versions of this ptn exist + snprintf(buf, sizeof(buf) - 1, + "%s/%s%s", + BOOT_DEV_DIR, + ptn_list[i], + AB_SLOT_A_SUFFIX + ); + if (stat(buf, &st)) { + //partition does not have _a version + continue; + } + memset(buf, '\0', sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, + "%s/%s%s", + BOOT_DEV_DIR, + ptn_list[i], + AB_SLOT_B_SUFFIX + ); + if (stat(buf, &st)) { + //partition does not have _a version + continue; + } + memset(partName, '\0', sizeof(partName)); + snprintf(partName, + sizeof(partName) - 1, + "%s%s", + ptn_list[i], + slot); + disk = gpt_disk_alloc(); + if (!disk) { + ALOGE("%s: Failed to alloc disk struct", + __func__); + goto error; + } + rc = gpt_disk_get_disk_info(partName, disk); + if (rc != 0) { + ALOGE("%s: Failed to get disk info for %s", + __func__, + partName); + goto error; + } + pentry = gpt_disk_get_pentry(disk, partName, PRIMARY_GPT); + pentry_bak = gpt_disk_get_pentry(disk, partName, SECONDARY_GPT); + if (!pentry || !pentry_bak) { + ALOGE("%s: Failed to get pentry/pentry_bak for %s", + __func__, + partName); + goto error; + } + attr = pentry + AB_FLAG_OFFSET; + attr_bak = pentry_bak + AB_FLAG_OFFSET; + if (ab_attr == ATTR_BOOT_SUCCESSFUL) { + *attr = (*attr) | AB_PARTITION_ATTR_BOOT_SUCCESSFUL; + *attr_bak = (*attr_bak) | + AB_PARTITION_ATTR_BOOT_SUCCESSFUL; + } else if (ab_attr == ATTR_UNBOOTABLE) { + *attr = (*attr) | AB_PARTITION_ATTR_UNBOOTABLE; + *attr_bak = (*attr_bak) | AB_PARTITION_ATTR_UNBOOTABLE; + } else if (ab_attr == ATTR_SLOT_ACTIVE) { + *attr = (*attr) | AB_PARTITION_ATTR_SLOT_ACTIVE; + *attr_bak = (*attr) | AB_PARTITION_ATTR_SLOT_ACTIVE; + } else { + ALOGE("%s: Unrecognized attr", __func__); + goto error; + } + if (gpt_disk_update_crc(disk)) { + ALOGE("%s: Failed to update crc for %s", + __func__, + partName); + goto error; + } + if (gpt_disk_commit(disk)) { + ALOGE("%s: Failed to write back entry for %s", + __func__, + partName); + goto error; + } + gpt_disk_free(disk); + disk = NULL; + } + return 0; +error: + if (disk) + gpt_disk_free(disk); + return -1; +} + +unsigned get_number_slots(struct boot_control_module *module) +{ + struct dirent *de = NULL; + DIR *dir_bootdev = NULL; + unsigned slot_count = 0; + if (!module) { + ALOGE("%s: Invalid argument", __func__); + goto error; + } + dir_bootdev = opendir(BOOTDEV_DIR); + if (!dir_bootdev) { + ALOGE("%s: Failed to open bootdev dir (%s)", + __func__, + strerror(errno)); + goto error; + } + while ((de = readdir(dir_bootdev))) { + if (de->d_name[0] == '.') + continue; + if (!strncmp(de->d_name, BOOT_IMG_PTN_NAME, + strlen(BOOT_IMG_PTN_NAME))) + slot_count++; + } + closedir(dir_bootdev); + return slot_count; +error: + if (dir_bootdev) + closedir(dir_bootdev); + return 0; +} + +unsigned get_current_slot(struct boot_control_module *module) +{ + uint32_t num_slots = 0; + char bootSlotProp[PROPERTY_VALUE_MAX] = {'\0'}; + unsigned i = 0; + if (!module) { + ALOGE("%s: Invalid argument", __func__); + goto error; + } + num_slots = get_number_slots(module); + if (num_slots <= 1) { + //Slot 0 is the only slot around. + return 0; + } + property_get(BOOT_SLOT_PROP, bootSlotProp, "N/A"); + if (!strncmp(bootSlotProp, "N/A", strlen("N/A"))) { + ALOGE("%s: Unable to read boot slot property", + __func__); + goto error; + } + //Iterate through a list of partitons named as boot+suffix + //and see which one is currently active. + for (i = 0; slot_suffix_arr[i] != NULL ; i++) { + if (!strncmp(bootSlotProp, + slot_suffix_arr[i], + strlen(slot_suffix_arr[i]))) + return i; + } +error: + //The HAL spec requires that we return a number between + //0 to num_slots - 1. Since something went wrong here we + //are just going to return the default slot. + return 0; +} + +static int boot_control_check_slot_sanity(struct boot_control_module *module, + unsigned slot) +{ + if (!module) + return -1; + uint32_t num_slots = get_number_slots(module); + if ((num_slots < 1) || (slot > num_slots - 1)) { + ALOGE("Invalid slot number"); + return -1; + } + return 0; + +} + +int mark_boot_successful(struct boot_control_module *module) +{ + unsigned cur_slot = 0; + if (!module) { + ALOGE("%s: Invalid argument", __func__); + goto error; + } + cur_slot = get_current_slot(module); + if (update_slot_attribute(slot_suffix_arr[cur_slot], + ATTR_BOOT_SUCCESSFUL)) { + goto error; + } + return 0; +error: + ALOGE("%s: Failed to mark boot successful", __func__); + return -1; +} + +const char *get_suffix(struct boot_control_module *module, unsigned slot) +{ + if (boot_control_check_slot_sanity(module, slot) != 0) + return NULL; + else + return slot_suffix_arr[slot]; +} + + +//Return a gpt disk structure representing the disk that holds +//partition. +static struct gpt_disk* boot_ctl_get_disk_info(char *partition) +{ + struct gpt_disk *disk = NULL; + if (!partition) + return NULL; + disk = gpt_disk_alloc(); + if (!disk) { + ALOGE("%s: Failed to alloc disk", + __func__); + goto error; + } + if (gpt_disk_get_disk_info(partition, disk)) { + ALOGE("failed to get disk info for %s", + partition); + goto error; + } + return disk; +error: + if (disk) + gpt_disk_free(disk); + return NULL; +} + +//The argument here is a vector of partition names(including the slot suffix) +//that lie on a single disk +static int boot_ctl_set_active_slot_for_partitions(vector part_list, + unsigned slot) +{ + char buf[PATH_MAX] = {0}; + struct gpt_disk *diskA = NULL; + struct gpt_disk *diskB = NULL; + char slotA[MAX_GPT_NAME_SIZE + 1] = {0}; + char slotB[MAX_GPT_NAME_SIZE + 1] = {0}; + char active_guid[TYPE_GUID_SIZE + 1] = {0}; + char inactive_guid[TYPE_GUID_SIZE + 1] = {0}; + //Pointer to the partition entry of current 'A' partition + uint8_t *pentryA = NULL; + uint8_t *pentryA_bak = NULL; + //Pointer to partition entry of current 'B' partition + uint8_t *pentryB = NULL; + uint8_t *pentryB_bak = NULL; + struct stat st; + vector::iterator partition_iterator; + + for (partition_iterator = part_list.begin(); + partition_iterator != part_list.end(); + partition_iterator++) { + //Chop off the slot suffix from the partition name to + //make the string easier to work with. + string prefix = *partition_iterator; + if (prefix.size() < (strlen(AB_SLOT_A_SUFFIX) + 1)) { + ALOGE("Invalid partition name: %s", prefix.c_str()); + goto error; + } + prefix.resize(prefix.size() - strlen(AB_SLOT_A_SUFFIX)); + //Check if A/B versions of this ptn exist + snprintf(buf, sizeof(buf) - 1, "%s/%s%s", BOOT_DEV_DIR, + prefix.c_str(), + AB_SLOT_A_SUFFIX); + if (stat(buf, &st)) + continue; + memset(buf, '\0', sizeof(buf)); + snprintf(buf, sizeof(buf) - 1, "%s/%s%s", BOOT_DEV_DIR, + prefix.c_str(), + AB_SLOT_B_SUFFIX); + if (stat(buf, &st)) + continue; + memset(slotA, 0, sizeof(slotA)); + memset(slotB, 0, sizeof(slotB)); + snprintf(slotA, sizeof(slotA) - 1, "%s%s", prefix.c_str(), + AB_SLOT_A_SUFFIX); + snprintf(slotB, sizeof(slotB) - 1,"%s%s", prefix.c_str(), + AB_SLOT_B_SUFFIX); + //Get the disks containing the partitions that were passed in. + if (!diskA) { + diskA = boot_ctl_get_disk_info(slotA); + if (!diskA) + goto error; + } + if (!diskB) { + diskB = boot_ctl_get_disk_info(slotB); + if (!diskB) + goto error; + } + //Get partition entry for slot A & B from the primary + //and backup tables. + pentryA = gpt_disk_get_pentry(diskA, slotA, PRIMARY_GPT); + pentryA_bak = gpt_disk_get_pentry(diskA, slotA, SECONDARY_GPT); + pentryB = gpt_disk_get_pentry(diskB, slotB, PRIMARY_GPT); + pentryB_bak = gpt_disk_get_pentry(diskB, slotB, SECONDARY_GPT); + if ( !pentryA || !pentryA_bak || !pentryB || !pentryB_bak) { + //None of these should be NULL since we have already + //checked for A & B versions earlier. + ALOGE("Slot pentries for %s not found.", + prefix.c_str()); + goto error; + } + memset(active_guid, '\0', sizeof(active_guid)); + memset(inactive_guid, '\0', sizeof(inactive_guid)); + if (get_partition_attribute(slotA, ATTR_SLOT_ACTIVE) == 1) { + //A is the current active slot + memcpy((void*)active_guid, (const void*)pentryA, + TYPE_GUID_SIZE); + memcpy((void*)inactive_guid,(const void*)pentryB, + TYPE_GUID_SIZE); + } else if (get_partition_attribute(slotB, + ATTR_SLOT_ACTIVE) == 1) { + //B is the current active slot + memcpy((void*)active_guid, (const void*)pentryB, + TYPE_GUID_SIZE); + memcpy((void*)inactive_guid, (const void*)pentryA, + TYPE_GUID_SIZE); + } else { + ALOGE("Both A & B for %s are inactive..Aborting", + prefix.c_str()); + goto error; + } + if (!strncmp(slot_suffix_arr[slot], AB_SLOT_A_SUFFIX, + strlen(AB_SLOT_A_SUFFIX))){ + //Mark A as active in primary table + UPDATE_SLOT(pentryA, active_guid, SLOT_ACTIVE); + //Mark A as active in backup table + UPDATE_SLOT(pentryA_bak, active_guid, SLOT_ACTIVE); + //Mark B as inactive in primary table + UPDATE_SLOT(pentryB, inactive_guid, SLOT_INACTIVE); + //Mark B as inactive in backup table + UPDATE_SLOT(pentryB_bak, inactive_guid, SLOT_INACTIVE); + } else if (!strncmp(slot_suffix_arr[slot], AB_SLOT_B_SUFFIX, + strlen(AB_SLOT_B_SUFFIX))){ + //Mark B as active in primary table + UPDATE_SLOT(pentryB, active_guid, SLOT_ACTIVE); + //Mark B as active in backup table + UPDATE_SLOT(pentryB_bak, active_guid, SLOT_ACTIVE); + //Mark A as inavtive in primary table + UPDATE_SLOT(pentryA, inactive_guid, SLOT_INACTIVE); + //Mark A as inactive in backup table + UPDATE_SLOT(pentryA_bak, inactive_guid, SLOT_INACTIVE); + } else { + //Something has gone terribly terribly wrong + ALOGE("%s: Unknown slot suffix!", __func__); + goto error; + } + + if (diskA) { + if (gpt_disk_update_crc(diskA) != 0) { + ALOGE("%s: Failed to update gpt_disk crc", + __func__); + goto error; + } + } + if (diskB) { + if (gpt_disk_update_crc(diskB) != 0) { + ALOGE("%s: Failed to update gpt_disk crc", + __func__); + goto error; + } + } + } + //write updated content to disk + if (diskA) { + if (gpt_disk_commit(diskA)) { + ALOGE("Failed to commit disk entry"); + goto error; + } + gpt_disk_free(diskA); + } + if (diskB) { + if (gpt_disk_commit(diskB)) { + ALOGE("Failed to commit disk entry"); + goto error; + } + gpt_disk_free(diskB); + } + return 0; + +error: + if (diskA) + gpt_disk_free(diskA); + if (diskB) + gpt_disk_free(diskB); + return -1; +} + +int set_active_boot_slot(struct boot_control_module *module, unsigned slot) +{ + map> ptn_map; + vector ptn_vec; + const char ptn_list[][MAX_GPT_NAME_SIZE] = { AB_PTN_LIST }; + uint32_t i; + int rc = -1; + int is_ufs = gpt_utils_is_ufs_device(); + map>::iterator map_iter; + + if (boot_control_check_slot_sanity(module, slot)) { + ALOGE("%s: Bad arguments", __func__); + goto error; + } + //The partition list just contains prefixes(without the _a/_b) of the + //partitions that support A/B. In order to get the layout we need the + //actual names. To do this we append the slot suffix to every member + //in the list. + for (i = 0; i < ARRAY_SIZE(ptn_list); i++) { + //XBL & XBL_CFG are handled differrently for ufs devices so + //ignore them + if (is_ufs && (!strncmp(ptn_list[i], + PTN_XBL, + strlen(PTN_XBL)) + || !strncmp(ptn_list[i], + PTN_XBL_CFG, + strlen(PTN_XBL_CFG)))) + continue; + //The partition list will be the list of partitions + //corresponding to the slot being set active + string cur_ptn = ptn_list[i]; + cur_ptn.append(slot_suffix_arr[slot]); + ptn_vec.push_back(cur_ptn); + + } + //The partition map gives us info in the following format: + // [path_to_block_device_1]--> + // [path_to_block_device_2]--> + // ... + // ... + // eg: + // [/dev/block/sdb]---> + if (gpt_utils_get_partition_map(ptn_vec, ptn_map)) { + ALOGE("%s: Failed to get partition map", + __func__); + goto error; + } + for (map_iter = ptn_map.begin(); map_iter != ptn_map.end(); map_iter++){ + if (map_iter->second.size() < 1) + continue; + if (boot_ctl_set_active_slot_for_partitions(map_iter->second, + slot)) { + ALOGE("%s: Failed to set active slot", __func__); + goto error; + } + } + if (is_ufs) { + if (!strncmp(slot_suffix_arr[slot], AB_SLOT_A_SUFFIX, + strlen(AB_SLOT_A_SUFFIX))){ + //Set xbl_a as the boot lun + rc = gpt_utils_set_xbl_boot_partition(NORMAL_BOOT); + } else if (!strncmp(slot_suffix_arr[slot], AB_SLOT_B_SUFFIX, + strlen(AB_SLOT_B_SUFFIX))){ + //Set xbl_b as the boot lun + rc = gpt_utils_set_xbl_boot_partition(BACKUP_BOOT); + } else { + //Something has gone terribly terribly wrong + ALOGE("%s: Unknown slot suffix!", __func__); + goto error; + } + if (rc) { + ALOGE("%s: Failed to switch xbl boot partition", + __func__); + goto error; + } + } + return 0; +error: + return -1; +} + +int set_slot_as_unbootable(struct boot_control_module *module, unsigned slot) +{ + if (boot_control_check_slot_sanity(module, slot) != 0) { + ALOGE("%s: Argument check failed", __func__); + goto error; + } + if (update_slot_attribute(slot_suffix_arr[slot], + ATTR_UNBOOTABLE)) { + goto error; + } + return 0; +error: + ALOGE("%s: Failed to mark slot unbootable", __func__); + return -1; +} + +int is_slot_bootable(struct boot_control_module *module, unsigned slot) +{ + int attr = 0; + char bootPartition[MAX_GPT_NAME_SIZE + 1] = {0}; + + if (boot_control_check_slot_sanity(module, slot) != 0) { + ALOGE("%s: Argument check failed", __func__); + goto error; + } + snprintf(bootPartition, + sizeof(bootPartition) - 1, "boot%s", + slot_suffix_arr[slot]); + attr = get_partition_attribute(bootPartition, ATTR_UNBOOTABLE); + if (attr >= 0) + return !attr; +error: + return -1; +} + +int is_slot_marked_successful(struct boot_control_module *module, unsigned slot) +{ + int attr = 0; + char bootPartition[MAX_GPT_NAME_SIZE + 1] = {0}; + + if (boot_control_check_slot_sanity(module, slot) != 0) { + ALOGE("%s: Argument check failed", __func__); + goto error; + } + snprintf(bootPartition, + sizeof(bootPartition) - 1, + "boot%s", slot_suffix_arr[slot]); + attr = get_partition_attribute(bootPartition, ATTR_BOOT_SUCCESSFUL); + if (attr >= 0) + return attr; +error: + return -1; +} + +static hw_module_methods_t boot_control_module_methods = { + .open = NULL, +}; + +boot_control_module_t HAL_MODULE_INFO_SYM = { + .common = { + .tag = HARDWARE_MODULE_TAG, + .module_api_version = 1, + .hal_api_version = 0, + .id = BOOT_CONTROL_HARDWARE_MODULE_ID, + .name = "Boot control HAL", + .author = "Code Aurora Forum", + .methods = &boot_control_module_methods, + }, + .init = boot_control_init, + .getNumberSlots = get_number_slots, + .getCurrentSlot = get_current_slot, + .markBootSuccessful = mark_boot_successful, + .setActiveBootSlot = set_active_boot_slot, + .setSlotAsUnbootable = set_slot_as_unbootable, + .isSlotBootable = is_slot_bootable, + .getSuffix = get_suffix, + .isSlotMarkedSuccessful = is_slot_marked_successful, +}; +#ifdef __cplusplus +} +#endif diff --git a/common.mk b/common.mk index 63334bc..e43d987 100644 --- a/common.mk +++ b/common.mk @@ -1,5 +1,5 @@ # -# Copyright (C) 2022-2024 The LineageOS Project +# Copyright (C) 2022 The LineageOS Project # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -14,13 +14,6 @@ # limitations under the License. # -# Partitions -PRODUCT_PACKAGES += \ - vendor_bt_firmware_mountpoint \ - vendor_dsp_mountpoint \ - vendor_firmware_mnt_mountpoint \ - vendor_fsg_mountpoint - PRODUCT_BUILD_SUPER_PARTITION := false PRODUCT_USE_DYNAMIC_PARTITIONS := true @@ -30,9 +23,6 @@ $(call inherit-product, $(SRC_TARGET_DIR)/product/emulated_storage.mk) # Installs gsi keys into ramdisk, to boot a GSI with verified boot. $(call inherit-product, $(SRC_TARGET_DIR)/product/developer_gsi_keys.mk) -# Add common definitions for Qualcomm -$(call inherit-product, hardware/qcom-caf/common/common.mk) - # Overlays DEVICE_PACKAGE_OVERLAYS += \ $(LOCAL_PATH)/overlay-lineage @@ -79,12 +69,19 @@ PRODUCT_COPY_FILES += \ # Boot control PRODUCT_PACKAGES += \ - android.hardware.boot-service.qti \ - android.hardware.boot-service.qti.recovery + android.hardware.boot@1.1-impl-qti \ + android.hardware.boot@1.1-impl-qti.recovery \ + android.hardware.boot@1.1-service \ + bootctrl.holi \ + bootctrl.holi.recovery PRODUCT_PACKAGES_DEBUG += \ bootctl +# Ant +PRODUCT_PACKAGES += \ + com.dsi.ant@1.0.vendor + # Atrace PRODUCT_PACKAGES += \ android.hardware.atrace@1.0-service @@ -95,6 +92,7 @@ PRODUCT_PACKAGES += \ android.hardware.audio.effect@6.0-impl \ android.hardware.audio.service \ android.hardware.bluetooth@1.0 \ + android.hardware.bluetooth@1.0.vendor \ android.hardware.bluetooth.audio-impl \ android.hardware.soundtrigger@2.3-impl \ audioadsprpcd \ @@ -136,10 +134,26 @@ PRODUCT_COPY_FILES += \ frameworks/av/services/audiopolicy/config/r_submix_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/r_submix_audio_policy_configuration.xml \ frameworks/av/services/audiopolicy/config/usb_audio_policy_configuration.xml:$(TARGET_COPY_OUT_VENDOR)/etc/usb_audio_policy_configuration.xml +# Authsecret +PRODUCT_PACKAGES += \ + android.hardware.authsecret@1.0.vendor + +# Bluetooth +PRODUCT_PACKAGES += \ + android.hardware.bluetooth@1.0.vendor \ + vendor.qti.hardware.bluetooth_audio@2.1.vendor \ + vendor.qti.hardware.btconfigstore@1.0.vendor \ + vendor.qti.hardware.btconfigstore@2.0.vendor + # Camera PRODUCT_PACKAGES += \ android.hardware.camera.provider@2.4-impl \ - android.hardware.camera.provider@2.4-service_64 + android.hardware.camera.provider@2.4-service_64 \ + libcamera2ndk_vendor \ + libexif.vendor:64 \ + libgui_vendor \ + libyuv.vendor:64 \ + vendor.qti.hardware.camera.postproc@1.0.vendor # Charger WITH_LINEAGE_CHARGER := false @@ -153,13 +167,31 @@ PRODUCT_PACKAGES += \ android.hardware.graphics.mapper@3.0-impl-qti-display \ android.hardware.graphics.mapper@4.0-impl-qti-display \ init.qti.display_boot.sh \ + libdisplayconfig.qti \ + libdisplayconfig.system.qti \ + libmemutils \ + libqdMetaData \ + libsdmcore \ + libsdmutils \ + libtinyxml \ + vendor.display.config@1.15.vendor \ + vendor.display.config@2.0 \ + vendor.display.config@2.0.vendor \ vendor.qti.hardware.display.allocator-service \ vendor.qti.hardware.display.composer-service \ - vendor.qti.hardware.memtrack-service \ - libdisplayconfig.system.qti + vendor.qti.hardware.display.mapper@1.1.vendor \ + vendor.qti.hardware.display.mapper@2.0.vendor \ + vendor.qti.hardware.display.mapper@3.0.vendor \ + vendor.qti.hardware.display.mapper@4.0.vendor \ + vendor.qti.hardware.display.mapperextensions@1.0.vendor \ + vendor.qti.hardware.display.mapperextensions@1.1.vendor \ + vendor.qti.hardware.display.mapperextensions@1.2.vendor \ + vendor.qti.hardware.display.mapperextensions@1.3.vendor \ + vendor.qti.hardware.memtrack-service # DRM PRODUCT_PACKAGES += \ + android.hardware.drm@1.4.vendor \ android.hardware.drm-service.clearkey # fastbootd @@ -167,9 +199,9 @@ PRODUCT_PACKAGES += \ android.hardware.fastboot@1.1-impl.custom \ fastbootd -# Framework detect +# Gatekeeper PRODUCT_PACKAGES += \ - libvndfwk_detect_jni.qti.vendor # Needed by CNE app + android.hardware.gatekeeper@1.0.vendor # GPS PRODUCT_PACKAGES += \ @@ -183,6 +215,11 @@ PRODUCT_PACKAGES += \ android.hardware.health@2.1-impl.recovery \ android.hardware.health@2.1-service +# HIDL +PRODUCT_PACKAGES += \ + libhidltransport.vendor \ + libhwbinder.vendor + # Init PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/rootdir/etc/fstab.qcom:$(TARGET_COPY_OUT_VENDOR_RAMDISK)/first_stage_ramdisk/fstab.qcom @@ -198,9 +235,6 @@ $(foreach f,$(wildcard $(LOCAL_PATH)/rootdir/etc/init/*.rc),\ $(foreach f,$(wildcard $(LOCAL_PATH)/rootdir/bin/*.sh),\ $(eval PRODUCT_COPY_FILES += $(f):$(TARGET_COPY_OUT_VENDOR)/bin/$(notdir $f))) -PRODUCT_COPY_FILES += \ - $(LOCAL_PATH)/recovery/root/init.recovery.qcom.rc:recovery/root/init.recovery.qcom.rc - # IPACM PRODUCT_PACKAGES += \ ipacm \ @@ -213,11 +247,11 @@ PRODUCT_COPY_FILES += \ # Kernel PRODUCT_ENABLE_UFFD_GC := false -# Media +# Keymaster PRODUCT_PACKAGES += \ - libcodec2_hidl@1.0.vendor \ - libcodec2_vndk.vendor + android.hardware.keymaster@4.1.vendor +# Media PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/media/init.qti.media.sh:$(TARGET_COPY_OUT_VENDOR)/bin/init.qti.media.sh \ $(LOCAL_PATH)/media/init.qti.media.rc:$(TARGET_COPY_OUT_VENDOR)/etc/init/init.qti.media.rc @@ -239,11 +273,37 @@ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/media/blair/media_codecs_blair.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_codecs_blair.xml \ $(LOCAL_PATH)/media/blair/media_profiles_blair.xml:$(TARGET_COPY_OUT_VENDOR)/etc/media_profiles_blair.xml +PRODUCT_PACKAGES += \ + android.hardware.media.omx@1.0-service \ + libstagefright_omx.vendor \ + libavservices_minijail \ + libavservices_minijail.vendor \ + libcodec2_hidl@1.0.vendor + # Moto hardware PRODUCT_PACKAGES += \ MotoActions \ MotoCommonOverlay +# Neural Networks +PRODUCT_PACKAGES += \ + android.hardware.neuralnetworks@1.3.vendor + +# OMX +PRODUCT_PACKAGES += \ + libcodec2_hidl@1.0.vendor \ + libcodec2_vndk.vendor \ + libmm-omxcore \ + libOmxAacEnc \ + libOmxAmrEnc \ + libOmxCore \ + libOmxEvrcEnc \ + libOmxG711Enc \ + libOmxQcelp13Enc \ + libstagefrighthw \ + libstagefright_softomx.vendor \ + libstagefright_softomx_plugin.vendor + # Permissions PRODUCT_COPY_FILES += \ frameworks/native/data/etc/android.hardware.audio.pro.xml:$(TARGET_COPY_OUT_VENDOR)/etc/permissions/android.hardware.audio.pro.xml \ @@ -304,17 +364,41 @@ PRODUCT_PACKAGES += \ PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/configs/powerhint.json:$(TARGET_COPY_OUT_VENDOR)/etc/powerhint.json +# QMI +PRODUCT_PACKAGES += \ + libjson \ + libjsoncpp.vendor \ + libcurl.vendor \ + libnetutils.vendor:64 \ + libqti_vndfwk_detect \ + libqti_vndfwk_detect.vendor \ + libsqlite.vendor:64 \ + libvndfwk_detect_jni.qti \ + libvndfwk_detect_jni.qti.vendor + # RenderScript PRODUCT_PACKAGES += \ android.hardware.renderscript@1.0-impl -# RFS MSM MPSS symlinks +# RIL PRODUCT_PACKAGES += \ - rfs_msm_mpss_readonly_vendor_fsg_symlink + android.hardware.radio@1.5.vendor \ + android.hardware.radio.config@1.2.vendor \ + android.hardware.radio.deprecated@1.0.vendor \ + android.system.net.netd@1.1.vendor \ + libion.vendor \ + libprotobuf-cpp-full \ + libprotobuf-cpp-full-3.9.1-vendorcompat \ + libprotobuf-cpp-lite-3.9.1-vendorcompat \ + librmnetctl \ + libsysutils.vendor \ + libxml2 # Sensors PRODUCT_PACKAGES += \ - android.hardware.sensors@2.0-service.multihal + android.frameworks.sensorservice@1.0.vendor \ + android.hardware.sensors@2.0-service.multihal \ + libsensorndkbridge # Soong namespaces PRODUCT_SOONG_NAMESPACES += \ @@ -322,7 +406,6 @@ PRODUCT_SOONG_NAMESPACES += \ hardware/google/interfaces \ hardware/google/pixel \ hardware/lineage/interfaces/power-libperfmgr \ - hardware/motorola \ hardware/qcom-caf/common/libqti-perfd-client # Telephony @@ -352,7 +435,14 @@ PRODUCT_COPY_FILES += \ # Thermal PRODUCT_PACKAGES += \ - android.hardware.thermal-service.qti + android.hardware.thermal@2.0-service.mock \ + android.hardware.thermal@2.0 \ + android.hardware.thermal@2.0.vendor + +# Trusted UI +PRODUCT_PACKAGES += \ + android.hidl.memory.block@1.0.vendor \ + vendor.qti.hardware.systemhelper@1.0.vendor # Update engine PRODUCT_PACKAGES += \ @@ -365,7 +455,7 @@ PRODUCT_PACKAGES_DEBUG += \ # USB PRODUCT_PACKAGES += \ - android.hardware.usb-service.qti \ + android.hardware.usb@1.3-service-qti \ init.qcom.usb.rc \ init.qcom.usb.sh @@ -382,6 +472,9 @@ PRODUCT_PACKAGES += \ PRODUCT_COPY_FILES += \ vendor/qcom/opensource/vibrator/excluded-input-devices.xml:$(TARGET_COPY_OUT_VENDOR)/etc/excluded-input-devices.xml +# VNDK +PRODUCT_ENFORCE_ARTIFACT_PATH_REQUIREMENTS := strict + # WiFi PRODUCT_PACKAGES += \ android.hardware.wifi-service \ @@ -390,14 +483,15 @@ PRODUCT_PACKAGES += \ libwpa_client \ libwifi-hal-ctrl \ libwifi-hal-qcom \ + vendor.qti.hardware.wifi.hostapd@1.0.vendor \ + vendor.qti.hardware.wifi.hostapd@1.1.vendor \ + vendor.qti.hardware.wifi.hostapd@1.2.vendor \ + vendor.qti.hardware.wifi.supplicant@2.0.vendor \ + vendor.qti.hardware.wifi.supplicant@2.1.vendor \ + vendor.qti.hardware.wifi.supplicant@2.2.vendor \ wpa_supplicant \ wpa_supplicant.conf -# WiFi firmware symlinks -PRODUCT_PACKAGES += \ - firmware_wlan_mac.bin_symlink \ - firmware_WCNSS_qcom_cfg.ini_symlink - PRODUCT_COPY_FILES += \ $(LOCAL_PATH)/wifi/WCNSS_qcom_cfg.ini:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/WCNSS_qcom_cfg.ini \ $(LOCAL_PATH)/wifi/p2p_supplicant_overlay.conf:$(TARGET_COPY_OUT_VENDOR)/etc/wifi/p2p_supplicant_overlay.conf \ @@ -407,8 +501,7 @@ PRODUCT_VENDOR_MOVE_ENABLED := true # WiFi Display PRODUCT_PACKAGES += \ - libgui_shim \ - libinput_shim \ + libavservices_minijail \ libnl \ libpng.vendor \ libwfdaac_vendor diff --git a/compatibility_matrix.xml b/compatibility_matrix.xml index 6f5e71f..bffde98 100644 --- a/compatibility_matrix.xml +++ b/compatibility_matrix.xml @@ -26,6 +26,14 @@ OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. --> + + android.frameworks.schedulerservice + 1.0 + + ISchedulingPolicyService + default + + android.frameworks.sensorservice 1.0 diff --git a/configs/powerhint.json b/configs/powerhint.json index 8cdd252..24a59e6 100644 --- a/configs/powerhint.json +++ b/configs/powerhint.json @@ -6,10 +6,10 @@ "Values": [ "9999999", "1708800", - "576000", - "300000" + "1651200", + "1516800" ], - "DefaultIndex": 0, + "DefaultIndex": 3, "ResetOnInit": true }, { @@ -17,14 +17,13 @@ "Path": "/sys/devices/system/cpu/cpu0/cpufreq/scaling_min_freq", "Values": [ "9999999", - "1708800", "1324800", "1113600", "691200", "576000", "300000" ], - "DefaultIndex": 6, + "DefaultIndex": 5, "ResetOnInit": true }, { @@ -54,7 +53,7 @@ "1900800", "1516800" ], - "DefaultIndex": 0, + "DefaultIndex": 3, "ResetOnInit": true }, { @@ -62,13 +61,10 @@ "Path": "/sys/devices/system/cpu/cpu6/cpufreq/scaling_min_freq", "Values": [ "9999999", - "2054400", "1651200", - "1228800", "691200", "0" ], - "DefaultIndex": 5, "ResetOnInit": true }, { @@ -114,20 +110,72 @@ "Path": "/dev/cpuctl/foreground/cpu.uclamp.min", "Values": [ "0", - "50", "100" ], "DefaultIndex": 0, "ResetOnInit": true }, + { + "Name": "SchedPreferSpread", + "Path": "/proc/sys/kernel/sched_prefer_spread", + "Values": [ + "2", + "0" + ], + "ResetOnInit": true + }, + { + "Name": "SchedBusyHystNs", + "Path": "/proc/sys/kernel/sched_busy_hyst_ns", + "Values": [ + "99000000", + "3000000", + "0" + ], + "ResetOnInit": true + }, + { + "Name": "SchedBusyHystEnableCPUs", + "Path": "/proc/sys/kernel/sched_busy_hysteresis_enable_cpus", + "Values": [ + "192", + "15", + "0" + ], + "ResetOnInit": true + }, + { + "Name": "SchedMinTaskUtilForBoost", + "Path": "/proc/sys/kernel/sched_min_task_util_for_boost", + "Values": [ + "0", + "51" + ], + "ResetOnInit": true + }, + { + "Name": "SchedMinTaskUtilForColoc", + "Path": "/proc/sys/kernel/sched_min_task_util_for_colocation", + "Values": [ + "0", + "35" + ], + "ResetOnInit": true + }, { "Name": "GPUMaxFreq", "Path": "/sys/class/kgsl/kgsl-3d0/max_pwrlevel", "Values": [ "0", - "1" + "1", + "2" ], - "DefaultIndex": 0, + "Comments": [ + "0 => 840000000", + "1 => 650000000", + "2 => 266000000" + ], + "DefaultIndex": 2, "ResetOnInit": true }, { @@ -136,8 +184,14 @@ "Values": [ "0", "1", - "3", - "5" + "2", + "3" + ], + "Comments": [ + "0 => 840000000", + "1 => 650000000", + "2 => 490000000", + "3 => 266000000" ], "ResetOnInit": true }, @@ -164,7 +218,7 @@ "Path": "/sys/class/kgsl/kgsl-3d0/idle_timer", "Values": [ "10000", - "80" + "58" ], "ResetOnInit": true }, @@ -209,7 +263,9 @@ "Path": "/sys/class/devfreq/soc:qcom,cpu-cpu-ddr-bw/min_freq", "Values": [ "7980", - "5161", + "6881", + "5931", + "3879", "762" ], "ResetOnInit": true @@ -274,6 +330,14 @@ ], "ResetOnInit": true }, + { + "Name": "DoubleTapToWakeEnable", + "Path": "/sys/class/sensors/dt-gesture/enable", + "Values": [ + "1", + "0" + ], + }, { "Name": "PowerHALMainState", "Path": "vendor.powerhal.state", @@ -310,7 +374,7 @@ "PowerHint": "SUSTAINED_PERFORMANCE", "Node": "CPULittleClusterMaxFreq", "Duration": 0, - "Value": "1708800" + "Value": "1651200" }, { "PowerHint": "SUSTAINED_PERFORMANCE", @@ -321,19 +385,19 @@ { "PowerHint": "INTERACTION", "Node": "CPUBigClusterMinFreq", - "Duration": 1000, + "Duration": 0, "Value": "1651200" }, { "PowerHint": "INTERACTION", "Node": "CPULittleClusterMinFreq", - "Duration": 1000, - "Value": "1708800" + "Duration": 0, + "Value": "1113600" }, { "PowerHint": "INTERACTION", "Node": "UclampTAMin", - "Duration": 1000, + "Duration": 0, "Value": "50" }, { @@ -344,74 +408,92 @@ }, { "PowerHint": "INTERACTION", - "Node": "UclampFgMin", - "Duration": 1000, - "Value": "50" + "Node": "SchedPreferSpread", + "Duration": 0, + "Value": "2" }, { "PowerHint": "INTERACTION", - "Node": "GPUMinFreq", - "Duration": 1000, - "Value": "3" + "Node": "SchedBusyHystNs", + "Duration": 0, + "Value": "99000000" + }, + { + "PowerHint": "INTERACTION", + "Node": "SchedBusyHystEnableCPUs", + "Duration": 0, + "Value": "192" + }, + { + "PowerHint": "INTERACTION", + "Node": "SchedMinTaskUtilForBoost", + "Duration": 0, + "Value": "0" + }, + { + "PowerHint": "INTERACTION", + "Node": "SchedMinTaskUtilForColoc", + "Duration": 0, + "Value": "0" }, { "PowerHint": "INTERACTION", "Node": "CPUBWHystTriggerCount", - "Duration": 1000, + "Duration": 0, "Value": "0" }, { "PowerHint": "INTERACTION", "Node": "CPUBWHystLength", - "Duration": 1000, + "Duration": 0, "Value": "0" }, { "PowerHint": "INTERACTION", "Node": "CPUBWHistMemory", - "Duration": 1000, + "Duration": 0, "Value": "0" }, { "PowerHint": "INTERACTION", "Node": "CPUBWMinFreq", - "Duration": 1000, - "Value": "5161" + "Duration": 0, + "Value": "7980" }, { "PowerHint": "INTERACTION", "Node": "CPUDDRLatLittleMinFreq", - "Duration": 1000, + "Duration": 0, "Value": "7980" }, { "PowerHint": "INTERACTION", "Node": "CPUDDRLatBigMinFreq", - "Duration": 1000, + "Duration": 0, "Value": "7980" }, { "PowerHint": "INTERACTION", "Node": "CPUDDRLatfloorLittleMinFreq", - "Duration": 1000, + "Duration": 0, "Value": "7980" }, { "PowerHint": "INTERACTION", "Node": "CPUDDRLatfloorBigMinFreq", - "Duration": 1000, + "Duration": 0, "Value": "7980" }, { "PowerHint": "INTERACTION", "Node": "L3LittleClusterMinFreq", - "Duration": 1000, + "Duration": 0, "Value": "1171200000" }, { "PowerHint": "INTERACTION", "Node": "L3BigClusterMinFreq", - "Duration": 1000, + "Duration": 0, "Value": "1171200000" }, { @@ -438,29 +520,41 @@ "Duration": 0, "Value": "20000" }, + { + "PowerHint": "INTERACTIVE", + "Node": "SchedBusyHystNs", + "Duration": 0, + "Value": "3000000" + }, + { + "PowerHint": "INTERACTIVE", + "Node": "SchedBusyHystEnableCPUs", + "Duration": 0, + "Value": "15" + }, { "PowerHint": "LAUNCH", "Node": "CPUBigClusterMaxFreq", - "Duration": 3000, + "Duration": 5000, "Value": "9999999" }, { "PowerHint": "LAUNCH", "Node": "CPUBigClusterMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "9999999" }, { "PowerHint": "LAUNCH", "Node": "CPULittleClusterMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "9999999" }, { "PowerHint": "LAUNCH", "Node": "UclampTAMin", "Duration": 3000, - "Value": "100" + "Value": "50" }, { "PowerHint": "LAUNCH", @@ -471,81 +565,87 @@ { "PowerHint": "LAUNCH", "Node": "CPUBWHystTriggerCount", - "Duration": 3000, + "Duration": 5000, "Value": "0" }, { "PowerHint": "LAUNCH", "Node": "CPUBWHystLength", - "Duration": 3000, + "Duration": 5000, "Value": "0" }, { "PowerHint": "LAUNCH", "Node": "CPUBWHistMemory", - "Duration": 3000, + "Duration": 5000, "Value": "0" }, { "PowerHint": "LAUNCH", "Node": "CPUBWMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "7980" }, { "PowerHint": "LAUNCH", "Node": "CPUDDRLatLittleMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "7980" }, { "PowerHint": "LAUNCH", "Node": "CPUDDRLatBigMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "7980" }, { "PowerHint": "LAUNCH", "Node": "CPUDDRLatfloorLittleMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "7980" }, { "PowerHint": "LAUNCH", "Node": "CPUDDRLatfloorBigMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "7980" }, { "PowerHint": "LAUNCH", "Node": "GPUForceClkOn", - "Duration": 3000, + "Duration": 5000, "Value": "1" }, { "PowerHint": "LAUNCH", "Node": "GPUForceRailOn", - "Duration": 3000, + "Duration": 5000, "Value": "1" }, { "PowerHint": "LAUNCH", "Node": "GPUIdleTimer", - "Duration": 3000, + "Duration": 5000, "Value": "10000" }, { "PowerHint": "LAUNCH", "Node": "L3LittleClusterMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "1497600000" }, { "PowerHint": "LAUNCH", "Node": "L3BigClusterMinFreq", - "Duration": 3000, + "Duration": 5000, "Value": "1497600000" }, + { + "PowerHint": "DOUBLE_TAP_TO_WAKE", + "Node": "DoubleTapToWakeEnable", + "Duration": 0, + "Value": "1" + }, { "PowerHint": "FIXED_PERFORMANCE", "Node": "CPUBigClusterMaxFreq", @@ -601,16 +701,22 @@ "Value": "0" }, { - "PowerHint": "EXPENSIVE_RENDERING", - "Node": "CPULittleClusterMinFreq", - "Duration": 0, - "Value": "1708800" - }, - { - "PowerHint": "EXPENSIVE_RENDERING", - "Node": "CPUBigClusterMinFreq", + "PowerHint": "Flipendo", + "Node": "CPULittleClusterMaxFreq", "Duration": 0, "Value": "1651200" + }, + { + "PowerHint": "Flipendo", + "Node": "CPUBigClusterMaxFreq", + "Duration": 0, + "Value": "1516800" + }, + { + "PowerHint": "DISPLAY_INACTIVE", + "Node": "CPULittleClusterMinFreq", + "Duration": 0, + "Value": "300000" } ] } diff --git a/extract-files.py b/extract-files.py deleted file mode 100755 index 79deec9..0000000 --- a/extract-files.py +++ /dev/null @@ -1,90 +0,0 @@ -#!/usr/bin/env -S PYTHONPATH=../../../tools/extract-utils python3 -# -# SPDX-FileCopyrightText: 2024 The LineageOS Project -# SPDX-License-Identifier: Apache-2.0 -# - -from extract_utils.fixups_blob import ( - blob_fixup, - blob_fixups_user_type, -) -from extract_utils.fixups_lib import ( - lib_fixup_remove, - lib_fixups, - lib_fixups_user_type, -) -from extract_utils.main import ( - ExtractUtils, - ExtractUtilsModule, -) - -namespace_imports = [ - 'device/motorola/sm6375-common', - 'hardware/qcom-caf/common/libqti-perfd-client', - 'hardware/qcom-caf/sm8350', - 'hardware/qcom-caf/wlan', - 'hardware/motorola', - 'vendor/qcom/opensource/commonsys/display', - 'vendor/qcom/opensource/commonsys-intf/display', - 'vendor/qcom/opensource/dataservices', - 'vendor/qcom/opensource/display', -] - -def lib_fixup_vendor_suffix(lib: str, partition: str, *args, **kwargs): - return f'{lib}_{partition}' if partition == 'vendor' else None - -lib_fixups: lib_fixups_user_type = { - **lib_fixups, - ( - 'com.qualcomm.qti.dpm.api@1.0', - 'libmmosal', - 'vendor.qti.diaghal@1.0', - 'vendor.qti.hardware.fm@1.0', - 'vendor.qti.hardware.qccsyshal@1.0', - 'vendor.qti.hardware.wifidisplaysession@1.0', - 'vendor.qti.imsrtpservice@3.0', - ): lib_fixup_vendor_suffix, - ( - 'libdiag_system', - 'libqsap_sdk', - 'libthermalclient', - 'libwpa_client', - 'vendor.qti.qspmhal@1.0', - ): lib_fixup_remove, -} - -blob_fixups: blob_fixups_user_type = { - 'system_ext/bin/wfdservice': blob_fixup() - .add_needed('libwfdservice_shim.so'), - 'system_ext/etc/permissions/moto-telephony.xml': blob_fixup() - .regex_replace('/system/', '/system_ext/'), - 'system_ext/priv-app/ims/ims.apk': blob_fixup() - .apktool_patch('ims-patches'), - 'vendor/lib64/libwvhidl.so': blob_fixup() - .add_needed('libcrypto_shim.so'), - ('system_ext/lib/libwfdmmsrc_system.so', 'system_ext/lib64/libwfdmmsrc_system.so'): blob_fixup() - .add_needed('libgui_shim.so'), - 'system_ext/lib64/libwfdnative.so': blob_fixup() - .add_needed('libbinder_shim.so') - .add_needed('libinput_shim.so'), - ('system_ext/lib/libwfdservice.so', 'system_ext/lib64/libwfdservice.so'): blob_fixup() - .replace_needed('android.media.audio.common.types-V2-cpp.so', 'android.media.audio.common.types-V4-cpp.so'), - 'vendor/etc/vintf/manifest/vendor.dolby.media.c2@1.0-service.xml': blob_fixup() - .regex_replace('IComponentStore/default9', 'IComponentStore/default'), - 'vendor/etc/qcril_database/qcrilNr.db': blob_fixup() - .patch_file('qcril-patches/qcrilNr.db.patch'), - 'vendor/etc/qcril_database/upgrade/config/6.0_config.sql': blob_fixup() - .patch_file('qcril-patches/6.0_config.sql.patch'), -} # fmt: skip - -module = ExtractUtilsModule( - 'sm6375-common', - 'motorola', - blob_fixups=blob_fixups, - lib_fixups=lib_fixups, - namespace_imports=namespace_imports, -) - -if __name__ == '__main__': - utils = ExtractUtils.device(module) - utils.run() diff --git a/extract-files.sh b/extract-files.sh new file mode 100755 index 0000000..76b9436 --- /dev/null +++ b/extract-files.sh @@ -0,0 +1,132 @@ +#!/bin/bash +# +# SPDX-FileCopyrightText: 2016 The CyanogenMod Project +# SPDX-FileCopyrightText: 2017-2024 The LineageOS Project +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +# Load extract_utils and do some sanity checks +MY_DIR="${BASH_SOURCE%/*}" +if [[ ! -d "${MY_DIR}" ]]; then MY_DIR="${PWD}"; fi + +ANDROID_ROOT="${MY_DIR}/../../.." + +HELPER="${ANDROID_ROOT}/tools/extract-utils/extract_utils.sh" +if [ ! -f "${HELPER}" ]; then + echo "Unable to find helper script at ${HELPER}" + exit 1 +fi +source "${HELPER}" + +# Default to sanitizing the vendor folder before extraction +CLEAN_VENDOR=true + +ONLY_COMMON= +ONLY_FIRMWARE= +ONLY_TARGET= +KANG= +SECTION= + +while [ "${#}" -gt 0 ]; do + case "${1}" in + --only-common ) + ONLY_COMMON=true + ;; + --only-firmware ) + ONLY_FIRMWARE=true + ;; + --only-target ) + ONLY_TARGET=true + ;; + -n | --no-cleanup ) + CLEAN_VENDOR=false + ;; + -k | --kang ) + KANG="--kang" + ;; + -s | --section ) + SECTION="${2}" + shift + CLEAN_VENDOR=false + ;; + * ) + SRC="${1}" + ;; + esac + shift +done + +if [ -z "${SRC}" ]; then + SRC="adb" +fi + +function blob_fixup() { + case "${1}" in + system_ext/lib64/libwfdnative.so) + [ "$2" = "" ] && return 0 + "${PATCHELF}" --remove-needed "android.hidl.base@1.0.so" "${2}" + ;; + system_ext/etc/permissions/moto-telephony.xml) + [ "$2" = "" ] && return 0 + sed -i "s#/system/#/system_ext/#" "${2}" + ;; + system_ext/priv-app/ims/ims.apk) + apktool_patch "${2}" "$MY_DIR/ims-patches" + ;; + vendor/etc/vintf/manifest/vendor.dolby.media.c2@1.0-service.xml) + [ "$2" = "" ] && return 0 + sed -ni '/default.*fqname/!p' "${2}" + ;; + *) + return 1 + ;; + vendor/etc/qcril_database/qcrilNr.db|\ + vendor/etc/qcril_database/upgrade/config/*) + sed -i '/persist.vendor.radio.poweron_opt/ s/1/0/g' "${2}" + ;; + esac + return 0 +} +function blob_fixup_dry() { + blob_fixup "$1" "" +} + +function prepare_firmware() { + if [ "${SRC}" != "adb" ]; then + local STAR="${ANDROID_ROOT}"/lineage/scripts/motorola/star.sh + for IMAGE in bootloader radio; do + if [ -f "${SRC}/${IMAGE}.img" ]; then + echo "Extracting Motorola star image ${SRC}/${IMAGE}.img" + sh "${STAR}" "${SRC}/${IMAGE}.img" "${SRC}" + fi + done + local INFO="${ANDROID_ROOT}"/lineage/scripts/motorola/info.sh + ./${INFO} "${SRC}" + fi +} + +if [ -z "${ONLY_FIRMWARE}" ] && [ -z "${ONLY_TARGET}" ]; then + # Initialize the helper for common device + setup_vendor "${DEVICE_COMMON}" "${VENDOR_COMMON:-$VENDOR}" "${ANDROID_ROOT}" true "${CLEAN_VENDOR}" + + extract "${MY_DIR}/proprietary-files.txt" "${SRC}" "${KANG}" --section "${SECTION}" +fi + +if [ -z "${ONLY_COMMON}" ] && [ -s "${MY_DIR}/../../${VENDOR}/${DEVICE}/proprietary-files.txt" ]; then + # Reinitialize the helper for device + source "${MY_DIR}/../../${VENDOR}/${DEVICE}/extract-files.sh" + setup_vendor "${DEVICE}" "${VENDOR}" "${ANDROID_ROOT}" false "${CLEAN_VENDOR}" + + if [ -z "${ONLY_FIRMWARE}" ]; then + extract "${MY_DIR}/../../${VENDOR}/${DEVICE}/proprietary-files.txt" "${SRC}" "${KANG}" --section "${SECTION}" + fi + + if [ -z "${SECTION}" ] && [ -f "${MY_DIR}/../../${VENDOR}/${DEVICE}/proprietary-firmware.txt" ]; then + extract_firmware "${MY_DIR}/../../${VENDOR}/${DEVICE}/proprietary-firmware.txt" "${SRC}" + fi +fi + +"${MY_DIR}/setup-makefiles.sh" diff --git a/gpt-utils/Android.bp b/gpt-utils/Android.bp new file mode 100644 index 0000000..fd90b79 --- /dev/null +++ b/gpt-utils/Android.bp @@ -0,0 +1,41 @@ +// +// Copyright (C) 2018 The Android Open Source Project +// +// 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. +// + + +cc_library { + name: "libgptutils.moto_holi", + vendor: true, + recovery_available: true, + shared_libs: [ + "libcutils", + "liblog", + "libz", + ], + cflags: [ + "-Wall", + "-Werror", + "-D_BSG_FRAMEWORK_KERNEL_HEADERS", + ], + srcs: [ + "gpt-utils.cpp", + "recovery-ufs-bsg.cpp", + ], + owner: "qti", + header_libs: [ + "generated_kernel_headers", + ], + export_include_dirs: ["."], +} diff --git a/gpt-utils/gpt-utils.cpp b/gpt-utils/gpt-utils.cpp new file mode 100644 index 0000000..7c3a9bb --- /dev/null +++ b/gpt-utils/gpt-utils.cpp @@ -0,0 +1,1520 @@ +/* + * Copyright (c) 2013,2016,2020 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#define _LARGEFILE64_SOURCE /* enable lseek64() */ + +/****************************************************************************** + * INCLUDE SECTION + ******************************************************************************/ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifndef __STDC_FORMAT_MACROS +#define __STDC_FORMAT_MACROS +#endif +#include + + +#define LOG_TAG "gpt-utils" +#include +#include +#include "gpt-utils.h" +#include +#include + + +/****************************************************************************** + * DEFINE SECTION + ******************************************************************************/ +#define BLK_DEV_FILE "/dev/block/mmcblk0" +/* list the names of the backed-up partitions to be swapped */ +/* extension used for the backup partitions - tzbak, abootbak, etc. */ +#define BAK_PTN_NAME_EXT "bak" +#define XBL_PRIMARY "/dev/block/bootdevice/by-name/xbl" +#define XBL_BACKUP "/dev/block/bootdevice/by-name/xblbak" +#define XBL_AB_PRIMARY "/dev/block/bootdevice/by-name/xbl_a" +#define XBL_AB_SECONDARY "/dev/block/bootdevice/by-name/xbl_b" +/* GPT defines */ +#define MAX_LUNS 26 +//This will allow us to get the root lun path from the path to the partition. +//i.e: from /dev/block/sdaXXX get /dev/block/sda. The assumption here is that +//the boot critical luns lie between sda to sdz which is acceptable because +//only user added external disks,etc would lie beyond that limit which do not +//contain partitions that interest us here. +#define PATH_TRUNCATE_LOC (sizeof("/dev/block/sda") - 1) + +//From /dev/block/sda get just sda +#define LUN_NAME_START_LOC (sizeof("/dev/block/") - 1) +#define BOOT_LUN_A_ID 1 +#define BOOT_LUN_B_ID 2 +/****************************************************************************** + * MACROS + ******************************************************************************/ + + +#define GET_4_BYTES(ptr) ((uint32_t) *((uint8_t *)(ptr)) | \ + ((uint32_t) *((uint8_t *)(ptr) + 1) << 8) | \ + ((uint32_t) *((uint8_t *)(ptr) + 2) << 16) | \ + ((uint32_t) *((uint8_t *)(ptr) + 3) << 24)) + +#define GET_8_BYTES(ptr) ((uint64_t) *((uint8_t *)(ptr)) | \ + ((uint64_t) *((uint8_t *)(ptr) + 1) << 8) | \ + ((uint64_t) *((uint8_t *)(ptr) + 2) << 16) | \ + ((uint64_t) *((uint8_t *)(ptr) + 3) << 24) | \ + ((uint64_t) *((uint8_t *)(ptr) + 4) << 32) | \ + ((uint64_t) *((uint8_t *)(ptr) + 5) << 40) | \ + ((uint64_t) *((uint8_t *)(ptr) + 6) << 48) | \ + ((uint64_t) *((uint8_t *)(ptr) + 7) << 56)) + +#define PUT_4_BYTES(ptr, y) *((uint8_t *)(ptr)) = (y) & 0xff; \ + *((uint8_t *)(ptr) + 1) = ((y) >> 8) & 0xff; \ + *((uint8_t *)(ptr) + 2) = ((y) >> 16) & 0xff; \ + *((uint8_t *)(ptr) + 3) = ((y) >> 24) & 0xff; + +/****************************************************************************** + * TYPES + ******************************************************************************/ +using namespace std; +enum gpt_state { + GPT_OK = 0, + GPT_BAD_SIGNATURE, + GPT_BAD_CRC +}; +//List of LUN's containing boot critical images. +//Required in the case of UFS devices +struct update_data { + char lun_list[MAX_LUNS][PATH_MAX]; + uint32_t num_valid_entries; +}; + +int32_t set_boot_lun(char *sg_dev,uint8_t boot_lun_id); +/****************************************************************************** + * FUNCTIONS + ******************************************************************************/ +/** + * ========================================================================== + * + * \brief Read/Write len bytes from/to block dev + * + * \param [in] fd block dev file descriptor (returned from open) + * \param [in] rw RW flag: 0 - read, != 0 - write + * \param [in] offset block dev offset [bytes] - RW start position + * \param [in] buf Pointer to the buffer containing the data + * \param [in] len RW size in bytes. Buf must be at least that big + * + * \return 0 on success + * + * ========================================================================== + */ +static int blk_rw(int fd, int rw, int64_t offset, uint8_t *buf, unsigned len) +{ + int r; + + if (lseek64(fd, offset, SEEK_SET) < 0) { + fprintf(stderr, "block dev lseek64 %" PRIi64 " failed: %s\n", offset, + strerror(errno)); + return -1; + } + + if (rw) + r = write(fd, buf, len); + else + r = read(fd, buf, len); + + if (r < 0) + fprintf(stderr, "block dev %s failed: %s\n", rw ? "write" : "read", + strerror(errno)); + else + r = 0; + + return r; +} + + + +/** + * ========================================================================== + * + * \brief Search within GPT for partition entry with the given name + * or it's backup twin (name-bak). + * + * \param [in] ptn_name Partition name to seek + * \param [in] pentries_start Partition entries array start pointer + * \param [in] pentries_end Partition entries array end pointer + * \param [in] pentry_size Single partition entry size [bytes] + * + * \return First partition entry pointer that matches the name or NULL + * + * ========================================================================== + */ +static uint8_t *gpt_pentry_seek(const char *ptn_name, + const uint8_t *pentries_start, + const uint8_t *pentries_end, + uint32_t pentry_size) +{ + char *pentry_name; + unsigned len = strlen(ptn_name); + unsigned i; + char name8[MAX_GPT_NAME_SIZE] = {0}; // initialize with null + + for (pentry_name = (char *) (pentries_start + PARTITION_NAME_OFFSET); + pentry_name < (char *) pentries_end; + pentry_name += pentry_size) { + + /* Partition names in GPT are UTF-16 - ignoring UTF-16 2nd byte */ + for (i = 0; i < sizeof(name8) / 2; i++) + name8[i] = pentry_name[i * 2]; + name8[i] = '\0'; + + if (!strncmp(ptn_name, name8, len)) { + if (name8[len] == 0 || !strcmp(&name8[len], BAK_PTN_NAME_EXT)) + return (uint8_t *) (pentry_name - PARTITION_NAME_OFFSET); + } + } + + return NULL; +} + + + +/** + * ========================================================================== + * + * \brief Swaps boot chain in GPT partition entries array + * + * \param [in] pentries_start Partition entries array start + * \param [in] pentries_end Partition entries array end + * \param [in] pentry_size Single partition entry size + * + * \return 0 on success, 1 if no backup partitions found + * + * ========================================================================== + */ +static int gpt_boot_chain_swap(const uint8_t *pentries_start, + const uint8_t *pentries_end, + uint32_t pentry_size) +{ + const char ptn_swap_list[][MAX_GPT_NAME_SIZE] = { PTN_SWAP_LIST }; + + int backup_not_found = 1; + unsigned i; + + for (i = 0; i < ARRAY_SIZE(ptn_swap_list); i++) { + uint8_t *ptn_entry; + uint8_t *ptn_bak_entry; + uint8_t ptn_swap[PTN_ENTRY_SIZE]; + //Skip the xbl partition on UFS devices. That is handled + //seperately. + if (gpt_utils_is_ufs_device() && !strncmp(ptn_swap_list[i], + PTN_XBL, + strlen(PTN_XBL))) + continue; + + ptn_entry = gpt_pentry_seek(ptn_swap_list[i], pentries_start, + pentries_end, pentry_size); + if (ptn_entry == NULL) + continue; + + ptn_bak_entry = gpt_pentry_seek(ptn_swap_list[i], + ptn_entry + pentry_size, pentries_end, pentry_size); + if (ptn_bak_entry == NULL) { + fprintf(stderr, "'%s' partition not backup - skip safe update\n", + ptn_swap_list[i]); + continue; + } + + /* swap primary <-> backup partition entries */ + memcpy(ptn_swap, ptn_entry, PTN_ENTRY_SIZE); + memcpy(ptn_entry, ptn_bak_entry, PTN_ENTRY_SIZE); + memcpy(ptn_bak_entry, ptn_swap, PTN_ENTRY_SIZE); + backup_not_found = 0; + } + + return backup_not_found; +} + + + +/** + * ========================================================================== + * + * \brief Sets secondary GPT boot chain + * + * \param [in] fd block dev file descriptor + * \param [in] boot Boot chain to switch to + * + * \return 0 on success + * + * ========================================================================== + */ +static int gpt2_set_boot_chain(int fd, enum boot_chain boot) +{ + int64_t gpt2_header_offset; + uint64_t pentries_start_offset; + uint32_t gpt_header_size; + uint32_t pentry_size; + uint32_t pentries_array_size; + + uint8_t *gpt_header = NULL; + uint8_t *pentries = NULL; + uint32_t crc; + uint32_t crc_zero; + uint32_t blk_size = 0; + int r; + + + crc_zero = crc32(0L, Z_NULL, 0); + if (ioctl(fd, BLKSSZGET, &blk_size) != 0) { + fprintf(stderr, "Failed to get GPT device block size: %s\n", + strerror(errno)); + r = -1; + goto EXIT; + } + gpt_header = (uint8_t*)malloc(blk_size); + if (!gpt_header) { + fprintf(stderr, "Failed to allocate memory to hold GPT block\n"); + r = -1; + goto EXIT; + } + gpt2_header_offset = lseek64(fd, 0, SEEK_END) - blk_size; + if (gpt2_header_offset < 0) { + fprintf(stderr, "Getting secondary GPT header offset failed: %s\n", + strerror(errno)); + r = -1; + goto EXIT; + } + + /* Read primary GPT header from block dev */ + r = blk_rw(fd, 0, blk_size, gpt_header, blk_size); + + if (r) { + fprintf(stderr, "Failed to read primary GPT header from blk dev\n"); + goto EXIT; + } + pentries_start_offset = + GET_8_BYTES(gpt_header + PENTRIES_OFFSET) * blk_size; + pentry_size = GET_4_BYTES(gpt_header + PENTRY_SIZE_OFFSET); + pentries_array_size = + GET_4_BYTES(gpt_header + PARTITION_COUNT_OFFSET) * pentry_size; + + pentries = (uint8_t *) calloc(1, pentries_array_size); + if (pentries == NULL) { + fprintf(stderr, + "Failed to alloc memory for GPT partition entries array\n"); + r = -1; + goto EXIT; + } + /* Read primary GPT partititon entries array from block dev */ + r = blk_rw(fd, 0, pentries_start_offset, pentries, pentries_array_size); + if (r) + goto EXIT; + + crc = crc32(crc_zero, pentries, pentries_array_size); + if (GET_4_BYTES(gpt_header + PARTITION_CRC_OFFSET) != crc) { + fprintf(stderr, "Primary GPT partition entries array CRC invalid\n"); + r = -1; + goto EXIT; + } + + /* Read secondary GPT header from block dev */ + r = blk_rw(fd, 0, gpt2_header_offset, gpt_header, blk_size); + if (r) + goto EXIT; + + gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET); + pentries_start_offset = + GET_8_BYTES(gpt_header + PENTRIES_OFFSET) * blk_size; + + if (boot == BACKUP_BOOT) { + r = gpt_boot_chain_swap(pentries, pentries + pentries_array_size, + pentry_size); + if (r) + goto EXIT; + } + + crc = crc32(crc_zero, pentries, pentries_array_size); + PUT_4_BYTES(gpt_header + PARTITION_CRC_OFFSET, crc); + + /* header CRC is calculated with this field cleared */ + PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0); + crc = crc32(crc_zero, gpt_header, gpt_header_size); + PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, crc); + + /* Write the modified GPT header back to block dev */ + r = blk_rw(fd, 1, gpt2_header_offset, gpt_header, blk_size); + if (!r) + /* Write the modified GPT partititon entries array back to block dev */ + r = blk_rw(fd, 1, pentries_start_offset, pentries, + pentries_array_size); + +EXIT: + if(gpt_header) + free(gpt_header); + if (pentries) + free(pentries); + return r; +} + +/** + * ========================================================================== + * + * \brief Checks GPT state (header signature and CRC) + * + * \param [in] fd block dev file descriptor + * \param [in] gpt GPT header to be checked + * \param [out] state GPT header state + * + * \return 0 on success + * + * ========================================================================== + */ +static int gpt_get_state(int fd, enum gpt_instance gpt, enum gpt_state *state) +{ + int64_t gpt_header_offset; + uint32_t gpt_header_size; + uint8_t *gpt_header = NULL; + uint32_t crc; + uint32_t crc_zero; + uint32_t blk_size = 0; + + *state = GPT_OK; + + crc_zero = crc32(0L, Z_NULL, 0); + if (ioctl(fd, BLKSSZGET, &blk_size) != 0) { + fprintf(stderr, "Failed to get GPT device block size: %s\n", + strerror(errno)); + goto error; + } + gpt_header = (uint8_t*)malloc(blk_size); + if (!gpt_header) { + fprintf(stderr, "gpt_get_state:Failed to alloc memory for header\n"); + goto error; + } + if (gpt == PRIMARY_GPT) + gpt_header_offset = blk_size; + else { + gpt_header_offset = lseek64(fd, 0, SEEK_END) - blk_size; + if (gpt_header_offset < 0) { + fprintf(stderr, "gpt_get_state:Seek to end of GPT part fail\n"); + goto error; + } + } + + if (blk_rw(fd, 0, gpt_header_offset, gpt_header, blk_size)) { + fprintf(stderr, "gpt_get_state: blk_rw failed\n"); + goto error; + } + if (memcmp(gpt_header, GPT_SIGNATURE, sizeof(GPT_SIGNATURE))) + *state = GPT_BAD_SIGNATURE; + gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET); + + crc = GET_4_BYTES(gpt_header + HEADER_CRC_OFFSET); + /* header CRC is calculated with this field cleared */ + PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0); + if (crc32(crc_zero, gpt_header, gpt_header_size) != crc) + *state = GPT_BAD_CRC; + free(gpt_header); + return 0; +error: + if (gpt_header) + free(gpt_header); + return -1; +} + + + +/** + * ========================================================================== + * + * \brief Sets GPT header state (used to corrupt and fix GPT signature) + * + * \param [in] fd block dev file descriptor + * \param [in] gpt GPT header to be checked + * \param [in] state GPT header state to set (GPT_OK or GPT_BAD_SIGNATURE) + * + * \return 0 on success + * + * ========================================================================== + */ +static int gpt_set_state(int fd, enum gpt_instance gpt, enum gpt_state state) +{ + int64_t gpt_header_offset; + uint32_t gpt_header_size; + uint8_t *gpt_header = NULL; + uint32_t crc; + uint32_t crc_zero; + uint32_t blk_size = 0; + + crc_zero = crc32(0L, Z_NULL, 0); + if (ioctl(fd, BLKSSZGET, &blk_size) != 0) { + fprintf(stderr, "Failed to get GPT device block size: %s\n", + strerror(errno)); + goto error; + } + gpt_header = (uint8_t*)malloc(blk_size); + if (!gpt_header) { + fprintf(stderr, "Failed to alloc memory for gpt header\n"); + goto error; + } + if (gpt == PRIMARY_GPT) + gpt_header_offset = blk_size; + else { + gpt_header_offset = lseek64(fd, 0, SEEK_END) - blk_size; + if (gpt_header_offset < 0) { + fprintf(stderr, "Failed to seek to end of GPT device\n"); + goto error; + } + } + if (blk_rw(fd, 0, gpt_header_offset, gpt_header, blk_size)) { + fprintf(stderr, "Failed to r/w gpt header\n"); + goto error; + } + if (state == GPT_OK) + memcpy(gpt_header, GPT_SIGNATURE, sizeof(GPT_SIGNATURE)); + else if (state == GPT_BAD_SIGNATURE) + *gpt_header = 0; + else { + fprintf(stderr, "gpt_set_state: Invalid state\n"); + goto error; + } + + gpt_header_size = GET_4_BYTES(gpt_header + HEADER_SIZE_OFFSET); + + /* header CRC is calculated with this field cleared */ + PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, 0); + crc = crc32(crc_zero, gpt_header, gpt_header_size); + PUT_4_BYTES(gpt_header + HEADER_CRC_OFFSET, crc); + + if (blk_rw(fd, 1, gpt_header_offset, gpt_header, blk_size)) { + fprintf(stderr, "gpt_set_state: blk write failed\n"); + goto error; + } + return 0; +error: + if(gpt_header) + free(gpt_header); + return -1; +} + +int get_scsi_node_from_bootdevice(const char *bootdev_path, + char *sg_node_path, + size_t buf_size) +{ + char sg_dir_path[PATH_MAX] = {0}; + char real_path[PATH_MAX] = {0}; + DIR *scsi_dir = NULL; + struct dirent *de; + int node_found = 0; + if (!bootdev_path || !sg_node_path) { + fprintf(stderr, "%s : invalid argument\n", + __func__); + goto error; + } + if (readlink(bootdev_path, real_path, sizeof(real_path) - 1) < 0) { + fprintf(stderr, "failed to resolve link for %s(%s)\n", + bootdev_path, + strerror(errno)); + goto error; + } + if(strlen(real_path) < PATH_TRUNCATE_LOC + 1){ + fprintf(stderr, "Unrecognized path :%s:\n", + real_path); + goto error; + } + //For the safe side in case there are additional partitions on + //the XBL lun we truncate the name. + real_path[PATH_TRUNCATE_LOC] = '\0'; + if(strlen(real_path) < LUN_NAME_START_LOC + 1){ + fprintf(stderr, "Unrecognized truncated path :%s:\n", + real_path); + goto error; + } + //This will give us /dev/block/sdb/device/scsi_generic + //which contains a file sgY whose name gives us the path + //to /dev/sgY which we return + snprintf(sg_dir_path, sizeof(sg_dir_path) - 1, + "/sys/block/%s/device/scsi_generic", + &real_path[LUN_NAME_START_LOC]); + scsi_dir = opendir(sg_dir_path); + if (!scsi_dir) { + fprintf(stderr, "%s : Failed to open %s(%s)\n", + __func__, + sg_dir_path, + strerror(errno)); + goto error; + } + while((de = readdir(scsi_dir))) { + if (de->d_name[0] == '.') + continue; + else if (!strncmp(de->d_name, "sg", 2)) { + snprintf(sg_node_path, + buf_size -1, + "/dev/%s", + de->d_name); + fprintf(stderr, "%s:scsi generic node is :%s:\n", + __func__, + sg_node_path); + node_found = 1; + break; + } + } + if(!node_found) { + fprintf(stderr,"%s: Unable to locate scsi generic node\n", + __func__); + goto error; + } + closedir(scsi_dir); + return 0; +error: + if (scsi_dir) + closedir(scsi_dir); + return -1; +} + + + +//Swtich betwieen using either the primary or the backup +//boot LUN for boot. This is required since UFS boot partitions +//cannot have a backup GPT which is what we use for failsafe +//updates of the other 'critical' partitions. This function will +//not be invoked for emmc targets and on UFS targets is only required +//to be invoked for XBL. +// +//The algorithm to do this is as follows: +//- Find the real block device(eg: /dev/block/sdb) that corresponds +// to the /dev/block/bootdevice/by-name/xbl(bak) symlink +// +//- Once we have the block device 'node' name(sdb in the above example) +// use this node to to locate the scsi generic device that represents +// it by checking the file /sys/block/sdb/device/scsi_generic/sgY +// +//- Once we locate sgY we call the query ioctl on /dev/sgy to switch +//the boot lun to either LUNA or LUNB +int gpt_utils_set_xbl_boot_partition(enum boot_chain chain) +{ + struct stat st; + ///sys/block/sdX/device/scsi_generic/ + char sg_dev_node[PATH_MAX] = {0}; + uint8_t boot_lun_id = 0; + const char *boot_dev = NULL; + + if (chain == BACKUP_BOOT) { + boot_lun_id = BOOT_LUN_B_ID; + if (!stat(XBL_BACKUP, &st)) + boot_dev = XBL_BACKUP; + else if (!stat(XBL_AB_SECONDARY, &st)) + boot_dev = XBL_AB_SECONDARY; + else { + fprintf(stderr, "%s: Failed to locate secondary xbl\n", + __func__); + goto error; + } + } else if (chain == NORMAL_BOOT) { + boot_lun_id = BOOT_LUN_A_ID; + if (!stat(XBL_PRIMARY, &st)) + boot_dev = XBL_PRIMARY; + else if (!stat(XBL_AB_PRIMARY, &st)) + boot_dev = XBL_AB_PRIMARY; + else { + fprintf(stderr, "%s: Failed to locate primary xbl\n", + __func__); + goto error; + } + } else { + fprintf(stderr, "%s: Invalid boot chain id\n", __func__); + goto error; + } + //We need either both xbl and xblbak or both xbl_a and xbl_b to exist at + //the same time. If not the current configuration is invalid. + if((stat(XBL_PRIMARY, &st) || + stat(XBL_BACKUP, &st)) && + (stat(XBL_AB_PRIMARY, &st) || + stat(XBL_AB_SECONDARY, &st))) { + fprintf(stderr, "%s:primary/secondary XBL prt not found(%s)\n", + __func__, + strerror(errno)); + goto error; + } + fprintf(stderr, "%s: setting %s lun as boot lun\n", + __func__, + boot_dev); + if (get_scsi_node_from_bootdevice(boot_dev, + sg_dev_node, + sizeof(sg_dev_node))) { + fprintf(stderr, "%s: Failed to get scsi node path for xblbak\n", + __func__); + goto error; + } + /* set boot lun using /dev/sg or /dev/ufs-bsg* */ + if (set_boot_lun(sg_dev_node, boot_lun_id)) { + fprintf(stderr, "%s: Failed to set xblbak as boot partition\n", + __func__); + goto error; + } + return 0; +error: + return -1; +} + +int gpt_utils_is_ufs_device() +{ + char bootdevice[PROPERTY_VALUE_MAX] = {0}; + property_get("ro.boot.bootdevice", bootdevice, "N/A"); + if (strlen(bootdevice) < strlen(".ufshc") + 1) + return 0; + return (!strncmp(&bootdevice[strlen(bootdevice) - strlen(".ufshc")], + ".ufshc", + sizeof(".ufshc"))); +} +//dev_path is the path to the block device that contains the GPT image that +//needs to be updated. This would be the device which holds one or more critical +//boot partitions and their backups. In the case of EMMC this function would +//be invoked only once on /dev/block/mmcblk1 since it holds the GPT image +//containing all the partitions For UFS devices it could potentially be +//invoked multiple times, once for each LUN containing critical image(s) and +//their backups +int prepare_partitions(enum boot_update_stage stage, const char *dev_path) +{ + int r = 0; + int fd = -1; + int is_ufs = gpt_utils_is_ufs_device(); + enum gpt_state gpt_prim, gpt_second; + enum boot_update_stage internal_stage; + struct stat xbl_partition_stat; + + if (!dev_path) { + fprintf(stderr, "%s: Invalid dev_path\n", + __func__); + r = -1; + goto EXIT; + } + fd = open(dev_path, O_RDWR); + if (fd < 0) { + fprintf(stderr, "%s: Opening '%s' failed: %s\n", + __func__, + BLK_DEV_FILE, + strerror(errno)); + r = -1; + goto EXIT; + } + r = gpt_get_state(fd, PRIMARY_GPT, &gpt_prim) || + gpt_get_state(fd, SECONDARY_GPT, &gpt_second); + if (r) { + fprintf(stderr, "%s: Getting GPT headers state failed\n", + __func__); + goto EXIT; + } + + /* These 2 combinations are unexpected and unacceptable */ + if (gpt_prim == GPT_BAD_CRC || gpt_second == GPT_BAD_CRC) { + fprintf(stderr, "%s: GPT headers CRC corruption detected, aborting\n", + __func__); + r = -1; + goto EXIT; + } + if (gpt_prim == GPT_BAD_SIGNATURE && gpt_second == GPT_BAD_SIGNATURE) { + fprintf(stderr, "%s: Both GPT headers corrupted, aborting\n", + __func__); + r = -1; + goto EXIT; + } + + /* Check internal update stage according GPT headers' state */ + if (gpt_prim == GPT_OK && gpt_second == GPT_OK) + internal_stage = UPDATE_MAIN; + else if (gpt_prim == GPT_BAD_SIGNATURE) + internal_stage = UPDATE_BACKUP; + else if (gpt_second == GPT_BAD_SIGNATURE) + internal_stage = UPDATE_FINALIZE; + else { + fprintf(stderr, "%s: Abnormal GPTs state: primary (%d), secondary (%d), " + "aborting\n", __func__, gpt_prim, gpt_second); + r = -1; + goto EXIT; + } + + /* Stage already set - ready for update, exitting */ + if ((int) stage == (int) internal_stage - 1) + goto EXIT; + /* Unexpected stage given */ + if (stage != internal_stage) { + r = -1; + goto EXIT; + } + + switch (stage) { + case UPDATE_MAIN: + if (is_ufs) { + if(stat(XBL_PRIMARY, &xbl_partition_stat)|| + stat(XBL_BACKUP, &xbl_partition_stat)){ + //Non fatal error. Just means this target does not + //use XBL but relies on sbl whose update is handled + //by the normal methods. + fprintf(stderr, "%s: xbl part not found(%s).Assuming sbl in use\n", + __func__, + strerror(errno)); + } else { + //Switch the boot lun so that backup boot LUN is used + r = gpt_utils_set_xbl_boot_partition(BACKUP_BOOT); + if(r){ + fprintf(stderr, "%s: Failed to set xbl backup partition as boot\n", + __func__); + goto EXIT; + } + } + } + //Fix up the backup GPT table so that it actually points to + //the backup copy of the boot critical images + fprintf(stderr, "%s: Preparing for primary partition update\n", + __func__); + r = gpt2_set_boot_chain(fd, BACKUP_BOOT); + if (r) { + if (r < 0) + fprintf(stderr, + "%s: Setting secondary GPT to backup boot failed\n", + __func__); + /* No backup partitions - do not corrupt GPT, do not flag error */ + else + r = 0; + goto EXIT; + } + //corrupt the primary GPT so that the backup(which now points to + //the backup boot partitions is used) + r = gpt_set_state(fd, PRIMARY_GPT, GPT_BAD_SIGNATURE); + if (r) { + fprintf(stderr, "%s: Corrupting primary GPT header failed\n", + __func__); + goto EXIT; + } + break; + case UPDATE_BACKUP: + if (is_ufs) { + if(stat(XBL_PRIMARY, &xbl_partition_stat)|| + stat(XBL_BACKUP, &xbl_partition_stat)){ + //Non fatal error. Just means this target does not + //use XBL but relies on sbl whose update is handled + //by the normal methods. + fprintf(stderr, "%s: xbl part not found(%s).Assuming sbl in use\n", + __func__, + strerror(errno)); + } else { + //Switch the boot lun so that backup boot LUN is used + r = gpt_utils_set_xbl_boot_partition(NORMAL_BOOT); + if(r) { + fprintf(stderr, "%s: Failed to set xbl backup partition as boot\n", + __func__); + goto EXIT; + } + } + } + //Fix the primary GPT header so that is used + fprintf(stderr, "%s: Preparing for backup partition update\n", + __func__); + r = gpt_set_state(fd, PRIMARY_GPT, GPT_OK); + if (r) { + fprintf(stderr, "%s: Fixing primary GPT header failed\n", + __func__); + goto EXIT; + } + //Corrupt the scondary GPT header + r = gpt_set_state(fd, SECONDARY_GPT, GPT_BAD_SIGNATURE); + if (r) { + fprintf(stderr, "%s: Corrupting secondary GPT header failed\n", + __func__); + goto EXIT; + } + break; + case UPDATE_FINALIZE: + //Undo the changes we had made in the UPDATE_MAIN stage so that the + //primary/backup GPT headers once again point to the same set of + //partitions + fprintf(stderr, "%s: Finalizing partitions\n", + __func__); + r = gpt2_set_boot_chain(fd, NORMAL_BOOT); + if (r < 0) { + fprintf(stderr, "%s: Setting secondary GPT to normal boot failed\n", + __func__); + goto EXIT; + } + + r = gpt_set_state(fd, SECONDARY_GPT, GPT_OK); + if (r) { + fprintf(stderr, "%s: Fixing secondary GPT header failed\n", + __func__); + goto EXIT; + } + break; + default:; + } + +EXIT: + if (fd >= 0) { + fsync(fd); + close(fd); + } + return r; +} + +int add_lun_to_update_list(char *lun_path, struct update_data *dat) +{ + uint32_t i = 0; + struct stat st; + if (!lun_path || !dat){ + fprintf(stderr, "%s: Invalid data", + __func__); + return -1; + } + if (stat(lun_path, &st)) { + fprintf(stderr, "%s: Unable to access %s. Skipping adding to list", + __func__, + lun_path); + return -1; + } + if (dat->num_valid_entries == 0) { + fprintf(stderr, "%s: Copying %s into lun_list[%d]\n", + __func__, + lun_path, + i); + strlcpy(dat->lun_list[0], lun_path, + PATH_MAX * sizeof(char)); + dat->num_valid_entries = 1; + } else { + for (i = 0; (i < dat->num_valid_entries) && + (dat->num_valid_entries < MAX_LUNS - 1); i++) { + //Check if the current LUN is not already part + //of the lun list + if (!strncmp(lun_path,dat->lun_list[i], + strlen(dat->lun_list[i]))) { + //LUN already in list..Return + return 0; + } + } + fprintf(stderr, "%s: Copying %s into lun_list[%d]\n", + __func__, + lun_path, + dat->num_valid_entries); + //Add LUN path lun list + strlcpy(dat->lun_list[dat->num_valid_entries], lun_path, + PATH_MAX * sizeof(char)); + dat->num_valid_entries++; + } + return 0; +} + +int prepare_boot_update(enum boot_update_stage stage) +{ + int is_ufs = gpt_utils_is_ufs_device(); + struct stat ufs_dir_stat; + struct update_data data; + int rcode = 0; + uint32_t i = 0; + int is_error = 0; + const char ptn_swap_list[][MAX_GPT_NAME_SIZE] = { PTN_SWAP_LIST }; + //Holds /dev/block/bootdevice/by-name/*bak entry + char buf[PATH_MAX] = {0}; + //Holds the resolved path of the symlink stored in buf + char real_path[PATH_MAX] = {0}; + + if (!is_ufs) { + //emmc device. Just pass in path to mmcblk0 + return prepare_partitions(stage, BLK_DEV_FILE); + } else { + //Now we need to find the list of LUNs over + //which the boot critical images are spread + //and set them up for failsafe updates.To do + //this we find out where the symlinks for the + //each of the paths under + ///dev/block/bootdevice/by-name/PTN_SWAP_LIST + //actually point to. + fprintf(stderr, "%s: Running on a UFS device\n", + __func__); + memset(&data, '\0', sizeof(struct update_data)); + for (i=0; i < ARRAY_SIZE(ptn_swap_list); i++) { + //XBL on UFS does not follow the convention + //of being loaded based on well known GUID'S. + //We take care of switching the UFS boot LUN + //explicitly later on. + if (!strncmp(ptn_swap_list[i], + PTN_XBL, + strlen(PTN_XBL))) + continue; + snprintf(buf, sizeof(buf), + "%s/%sbak", + BOOT_DEV_DIR, + ptn_swap_list[i]); + if (stat(buf, &ufs_dir_stat)) { + continue; + } + if (readlink(buf, real_path, sizeof(real_path) - 1) < 0) + { + fprintf(stderr, "%s: readlink error. Skipping %s", + __func__, + strerror(errno)); + } else { + if(strlen(real_path) < PATH_TRUNCATE_LOC + 1){ + fprintf(stderr, "Unknown path.Skipping :%s:\n", + real_path); + } else { + real_path[PATH_TRUNCATE_LOC] = '\0'; + add_lun_to_update_list(real_path, &data); + } + } + memset(buf, '\0', sizeof(buf)); + memset(real_path, '\0', sizeof(real_path)); + } + for (i=0; i < data.num_valid_entries; i++) { + fprintf(stderr, "%s: Preparing %s for update stage %d\n", + __func__, + data.lun_list[i], + stage); + rcode = prepare_partitions(stage, data.lun_list[i]); + if (rcode != 0) + { + fprintf(stderr, "%s: Failed to prepare %s.Continuing..\n", + __func__, + data.lun_list[i]); + is_error = 1; + } + } + } + if (is_error) + return -1; + return 0; +} + +//Given a parttion name(eg: rpm) get the path to the block device that +//represents the GPT disk the partition resides on. In the case of emmc it +//would be the default emmc dev(/dev/block/mmcblk0). In the case of UFS we look +//through the /dev/block/bootdevice/by-name/ tree for partname, and resolve +//the path to the LUN from there. +static int get_dev_path_from_partition_name(const char *partname, + char *buf, + size_t buflen) +{ + struct stat st; + char path[PATH_MAX] = {0}; + if (!partname || !buf || buflen < ((PATH_TRUNCATE_LOC) + 1)) { + ALOGE("%s: Invalid argument", __func__); + goto error; + } + if (gpt_utils_is_ufs_device()) { + //Need to find the lun that holds partition partname + snprintf(path, sizeof(path), + "%s/%s", + BOOT_DEV_DIR, + partname); + if (stat(path, &st)) { + goto error; + } + if (readlink(path, buf, buflen) < 0) + { + goto error; + } else { + buf[PATH_TRUNCATE_LOC] = '\0'; + } + } else { + snprintf(buf, buflen, BLK_DEV_FILE); + } + return 0; + +error: + return -1; +} + +int gpt_utils_get_partition_map(vector& ptn_list, + map>& partition_map) { + char devpath[PATH_MAX] = {'\0'}; + map>::iterator it; + if (ptn_list.size() < 1) { + fprintf(stderr, "%s: Invalid ptn list\n", __func__); + goto error; + } + //Go through the passed in list + for (uint32_t i = 0; i < ptn_list.size(); i++) + { + //Key in the map is the path to the device that holds the + //partition + if (get_dev_path_from_partition_name(ptn_list[i].c_str(), + devpath, + sizeof(devpath))) { + //Not necessarily an error. The partition may just + //not be present. + continue; + } + string path = devpath; + it = partition_map.find(path); + if (it != partition_map.end()) { + it->second.push_back(ptn_list[i]); + } else { + vector str_vec; + str_vec.push_back( ptn_list[i]); + partition_map.insert(pair> + (path, str_vec)); + } + memset(devpath, '\0', sizeof(devpath)); + } + return 0; +error: + return -1; +} + +//Get the block size of the disk represented by decsriptor fd +static uint32_t gpt_get_block_size(int fd) +{ + uint32_t block_size = 0; + if (fd < 0) { + ALOGE("%s: invalid descriptor", + __func__); + goto error; + } + if (ioctl(fd, BLKSSZGET, &block_size) != 0) { + ALOGE("%s: Failed to get GPT dev block size : %s", + __func__, + strerror(errno)); + goto error; + } + return block_size; +error: + return 0; +} + +//Write the GPT header present in the passed in buffer back to the +//disk represented by fd +static int gpt_set_header(uint8_t *gpt_header, int fd, + enum gpt_instance instance) +{ + uint32_t block_size = 0; + off64_t gpt_header_offset = 0; + if (!gpt_header || fd < 0) { + ALOGE("%s: Invalid arguments", + __func__); + goto error; + } + block_size = gpt_get_block_size(fd); + if (block_size == 0) { + ALOGE("%s: Failed to get block size", __func__); + goto error; + } + if (instance == PRIMARY_GPT) + gpt_header_offset = block_size; + else + gpt_header_offset = lseek64(fd, 0, SEEK_END) - block_size; + if (gpt_header_offset <= 0) { + ALOGE("%s: Failed to get gpt header offset",__func__); + goto error; + } + if (blk_rw(fd, 1, gpt_header_offset, gpt_header, block_size)) { + ALOGE("%s: Failed to write back GPT header", __func__); + goto error; + } + return 0; +error: + return -1; +} + +//Read out the GPT header for the disk that contains the partition partname +static uint8_t* gpt_get_header(const char *partname, enum gpt_instance instance) +{ + uint8_t* hdr = NULL; + char devpath[PATH_MAX] = {0}; + int64_t hdr_offset = 0; + uint32_t block_size = 0; + int fd = -1; + if (!partname) { + ALOGE("%s: Invalid partition name", __func__); + goto error; + } + if (get_dev_path_from_partition_name(partname, devpath, sizeof(devpath)) + != 0) { + ALOGE("%s: Failed to resolve path for %s", + __func__, + partname); + goto error; + } + fd = open(devpath, O_RDWR); + if (fd < 0) { + ALOGE("%s: Failed to open %s : %s", + __func__, + devpath, + strerror(errno)); + goto error; + } + block_size = gpt_get_block_size(fd); + if (block_size == 0) + { + ALOGE("%s: Failed to get gpt block size for %s", + __func__, + partname); + goto error; + } + + hdr = (uint8_t*)malloc(block_size); + if (!hdr) { + ALOGE("%s: Failed to allocate memory for gpt header", + __func__); + } + if (instance == PRIMARY_GPT) + hdr_offset = block_size; + else { + hdr_offset = lseek64(fd, 0, SEEK_END) - block_size; + } + if (hdr_offset < 0) { + ALOGE("%s: Failed to get gpt header offset", + __func__); + goto error; + } + if (blk_rw(fd, 0, hdr_offset, hdr, block_size)) { + ALOGE("%s: Failed to read GPT header from device", + __func__); + goto error; + } + close(fd); + return hdr; +error: + if (fd >= 0) + close(fd); + if (hdr) + free(hdr); + return NULL; +} + +//Returns the partition entry array based on the +//passed in buffer which contains the gpt header. +//The fd here is the descriptor for the 'disk' which +//holds the partition +static uint8_t* gpt_get_pentry_arr(uint8_t *hdr, int fd) +{ + uint64_t pentries_start = 0; + uint32_t pentry_size = 0; + uint32_t block_size = 0; + uint32_t pentries_arr_size = 0; + uint8_t *pentry_arr = NULL; + int rc = 0; + if (!hdr) { + ALOGE("%s: Invalid header", __func__); + goto error; + } + if (fd < 0) { + ALOGE("%s: Invalid fd", __func__); + goto error; + } + block_size = gpt_get_block_size(fd); + if (!block_size) { + ALOGE("%s: Failed to get gpt block size for", + __func__); + goto error; + } + pentries_start = GET_8_BYTES(hdr + PENTRIES_OFFSET) * block_size; + pentry_size = GET_4_BYTES(hdr + PENTRY_SIZE_OFFSET); + pentries_arr_size = + GET_4_BYTES(hdr + PARTITION_COUNT_OFFSET) * pentry_size; + pentry_arr = (uint8_t*)calloc(1, pentries_arr_size); + if (!pentry_arr) { + ALOGE("%s: Failed to allocate memory for partition array", + __func__); + goto error; + } + rc = blk_rw(fd, 0, + pentries_start, + pentry_arr, + pentries_arr_size); + if (rc) { + ALOGE("%s: Failed to read partition entry array", + __func__); + goto error; + } + return pentry_arr; +error: + if (pentry_arr) + free(pentry_arr); + return NULL; +} + +static int gpt_set_pentry_arr(uint8_t *hdr, int fd, uint8_t* arr) +{ + uint32_t block_size = 0; + uint64_t pentries_start = 0; + uint32_t pentry_size = 0; + uint32_t pentries_arr_size = 0; + int rc = 0; + if (!hdr || fd < 0 || !arr) { + ALOGE("%s: Invalid argument", __func__); + goto error; + } + block_size = gpt_get_block_size(fd); + if (!block_size) { + ALOGE("%s: Failed to get gpt block size for", + __func__); + goto error; + } + pentries_start = GET_8_BYTES(hdr + PENTRIES_OFFSET) * block_size; + pentry_size = GET_4_BYTES(hdr + PENTRY_SIZE_OFFSET); + pentries_arr_size = + GET_4_BYTES(hdr + PARTITION_COUNT_OFFSET) * pentry_size; + rc = blk_rw(fd, 1, + pentries_start, + arr, + pentries_arr_size); + if (rc) { + ALOGE("%s: Failed to read partition entry array", + __func__); + goto error; + } + return 0; +error: + return -1; +} + + + +//Allocate a handle used by calls to the "gpt_disk" api's +struct gpt_disk * gpt_disk_alloc() +{ + struct gpt_disk *disk; + disk = (struct gpt_disk *)malloc(sizeof(struct gpt_disk)); + if (!disk) { + ALOGE("%s: Failed to allocate memory", __func__); + goto end; + } + memset(disk, 0, sizeof(struct gpt_disk)); +end: + return disk; +} + +//Free previously allocated/initialized handle +void gpt_disk_free(struct gpt_disk *disk) +{ + if (!disk) + return; + if (disk->hdr) + free(disk->hdr); + if (disk->hdr_bak) + free(disk->hdr_bak); + if (disk->pentry_arr) + free(disk->pentry_arr); + if (disk->pentry_arr_bak) + free(disk->pentry_arr_bak); + free(disk); + return; +} + +//fills up the passed in gpt_disk struct with information about the +//disk represented by path dev. Returns 0 on success and -1 on error. +int gpt_disk_get_disk_info(const char *dev, struct gpt_disk *dsk) +{ + + struct gpt_disk *disk = NULL; + int fd = -1; + uint32_t gpt_header_size = 0; + uint32_t crc_zero; + + crc_zero = crc32(0L, Z_NULL, 0); + if (!dsk || !dev) { + ALOGE("%s: Invalid arguments", __func__); + goto error; + } + disk = dsk; + disk->hdr = gpt_get_header(dev, PRIMARY_GPT); + if (!disk->hdr) { + ALOGE("%s: Failed to get primary header", __func__); + goto error; + } + gpt_header_size = GET_4_BYTES(disk->hdr + HEADER_SIZE_OFFSET); + disk->hdr_crc = crc32(crc_zero, disk->hdr, gpt_header_size); + disk->hdr_bak = gpt_get_header(dev, SECONDARY_GPT); + if (!disk->hdr_bak) { + ALOGE("%s: Failed to get backup header", __func__); + goto error; + } + disk->hdr_bak_crc = crc32(crc_zero, disk->hdr_bak, gpt_header_size); + + //Descriptor for the block device. We will use this for further + //modifications to the partition table + if (get_dev_path_from_partition_name(dev, + disk->devpath, + sizeof(disk->devpath)) != 0) { + ALOGE("%s: Failed to resolve path for %s", + __func__, + dev); + goto error; + } + fd = open(disk->devpath, O_RDWR); + if (fd < 0) { + ALOGE("%s: Failed to open %s: %s", + __func__, + disk->devpath, + strerror(errno)); + goto error; + } + disk->pentry_arr = gpt_get_pentry_arr(disk->hdr, fd); + if (!disk->pentry_arr) { + ALOGE("%s: Failed to obtain partition entry array", + __func__); + goto error; + } + disk->pentry_arr_bak = gpt_get_pentry_arr(disk->hdr_bak, fd); + if (!disk->pentry_arr_bak) { + ALOGE("%s: Failed to obtain backup partition entry array", + __func__); + goto error; + } + disk->pentry_size = GET_4_BYTES(disk->hdr + PENTRY_SIZE_OFFSET); + disk->pentry_arr_size = + GET_4_BYTES(disk->hdr + PARTITION_COUNT_OFFSET) * + disk->pentry_size; + disk->pentry_arr_crc = GET_4_BYTES(disk->hdr + PARTITION_CRC_OFFSET); + disk->pentry_arr_bak_crc = GET_4_BYTES(disk->hdr_bak + + PARTITION_CRC_OFFSET); + disk->block_size = gpt_get_block_size(fd); + close(fd); + disk->is_initialized = GPT_DISK_INIT_MAGIC; + return 0; +error: + if (fd >= 0) + close(fd); + return -1; +} + +//Get pointer to partition entry from a allocated gpt_disk structure +uint8_t* gpt_disk_get_pentry(struct gpt_disk *disk, + const char *partname, + enum gpt_instance instance) +{ + uint8_t *ptn_arr = NULL; + if (!disk || !partname || disk->is_initialized != GPT_DISK_INIT_MAGIC) { + ALOGE("%s: Invalid argument",__func__); + goto error; + } + ptn_arr = (instance == PRIMARY_GPT) ? + disk->pentry_arr : disk->pentry_arr_bak; + return (gpt_pentry_seek(partname, ptn_arr, + ptn_arr + disk->pentry_arr_size , + disk->pentry_size)); +error: + return NULL; +} + +//Update CRC values for the various components of the gpt_disk +//structure. This function should be called after any of the fields +//have been updated before the structure contents are written back to +//disk. +int gpt_disk_update_crc(struct gpt_disk *disk) +{ + uint32_t gpt_header_size = 0; + uint32_t crc_zero; + crc_zero = crc32(0L, Z_NULL, 0); + if (!disk || (disk->is_initialized != GPT_DISK_INIT_MAGIC)) { + ALOGE("%s: invalid argument", __func__); + goto error; + } + //Recalculate the CRC of the primary partiton array + disk->pentry_arr_crc = crc32(crc_zero, + disk->pentry_arr, + disk->pentry_arr_size); + //Recalculate the CRC of the backup partition array + disk->pentry_arr_bak_crc = crc32(crc_zero, + disk->pentry_arr_bak, + disk->pentry_arr_size); + //Update the partition CRC value in the primary GPT header + PUT_4_BYTES(disk->hdr + PARTITION_CRC_OFFSET, disk->pentry_arr_crc); + //Update the partition CRC value in the backup GPT header + PUT_4_BYTES(disk->hdr_bak + PARTITION_CRC_OFFSET, + disk->pentry_arr_bak_crc); + //Update the CRC value of the primary header + gpt_header_size = GET_4_BYTES(disk->hdr + HEADER_SIZE_OFFSET); + //Header CRC is calculated with its own CRC field set to 0 + PUT_4_BYTES(disk->hdr + HEADER_CRC_OFFSET, 0); + PUT_4_BYTES(disk->hdr_bak + HEADER_CRC_OFFSET, 0); + disk->hdr_crc = crc32(crc_zero, disk->hdr, gpt_header_size); + disk->hdr_bak_crc = crc32(crc_zero, disk->hdr_bak, gpt_header_size); + PUT_4_BYTES(disk->hdr + HEADER_CRC_OFFSET, disk->hdr_crc); + PUT_4_BYTES(disk->hdr_bak + HEADER_CRC_OFFSET, disk->hdr_bak_crc); + return 0; +error: + return -1; +} + +//Write the contents of struct gpt_disk back to the actual disk +int gpt_disk_commit(struct gpt_disk *disk) +{ + int fd = -1; + if (!disk || (disk->is_initialized != GPT_DISK_INIT_MAGIC)){ + ALOGE("%s: Invalid args", __func__); + goto error; + } + fd = open(disk->devpath, O_RDWR | O_DSYNC); + if (fd < 0) { + ALOGE("%s: Failed to open %s: %s", + __func__, + disk->devpath, + strerror(errno)); + goto error; + } + //Write the primary header + if(gpt_set_header(disk->hdr, fd, PRIMARY_GPT) != 0) { + ALOGE("%s: Failed to update primary GPT header", + __func__); + goto error; + } + //Write back the primary partition array + if (gpt_set_pentry_arr(disk->hdr, fd, disk->pentry_arr)) { + ALOGE("%s: Failed to write primary GPT partition arr", + __func__); + goto error; + } + //Write back the secondary header + if(gpt_set_header(disk->hdr_bak, fd, SECONDARY_GPT) != 0) { + ALOGE("%s: Failed to update secondary GPT header", + __func__); + goto error; + } + //Write back the secondary partition array + if (gpt_set_pentry_arr(disk->hdr_bak, fd, disk->pentry_arr_bak)) { + ALOGE("%s: Failed to write secondary GPT partition arr", + __func__); + goto error; + } + fsync(fd); + close(fd); + return 0; +error: + if (fd >= 0) + close(fd); + return -1; +} diff --git a/gpt-utils/gpt-utils.h b/gpt-utils/gpt-utils.h new file mode 100644 index 0000000..938587b --- /dev/null +++ b/gpt-utils/gpt-utils.h @@ -0,0 +1,193 @@ +/* + * Copyright (c) 2013,2016, The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#ifndef __GPT_UTILS_H__ +#define __GPT_UTILS_H__ +#include +#include +#include +#ifdef __cplusplus +extern "C" { +#endif +#include +#include +/****************************************************************************** + * GPT HEADER DEFINES + ******************************************************************************/ +#define GPT_SIGNATURE "EFI PART" +#define HEADER_SIZE_OFFSET 12 +#define HEADER_CRC_OFFSET 16 +#define PRIMARY_HEADER_OFFSET 24 +#define BACKUP_HEADER_OFFSET 32 +#define FIRST_USABLE_LBA_OFFSET 40 +#define LAST_USABLE_LBA_OFFSET 48 +#define PENTRIES_OFFSET 72 +#define PARTITION_COUNT_OFFSET 80 +#define PENTRY_SIZE_OFFSET 84 +#define PARTITION_CRC_OFFSET 88 + +#define TYPE_GUID_OFFSET 0 +#define TYPE_GUID_SIZE 16 +#define PTN_ENTRY_SIZE 128 +#define UNIQUE_GUID_OFFSET 16 +#define FIRST_LBA_OFFSET 32 +#define LAST_LBA_OFFSET 40 +#define ATTRIBUTE_FLAG_OFFSET 48 +#define PARTITION_NAME_OFFSET 56 +#define MAX_GPT_NAME_SIZE 72 + +/****************************************************************************** + * AB RELATED DEFINES + ******************************************************************************/ +//Bit 48 onwords in the attribute field are the ones where we are allowed to +//store our AB attributes. +#define AB_FLAG_OFFSET (ATTRIBUTE_FLAG_OFFSET + 6) +#define GPT_DISK_INIT_MAGIC 0xABCD +#define AB_PARTITION_ATTR_SLOT_ACTIVE (0x1<<2) +#define AB_PARTITION_ATTR_BOOT_SUCCESSFUL (0x1<<6) +#define AB_PARTITION_ATTR_UNBOOTABLE (0x1<<7) +#define AB_SLOT_ACTIVE_VAL 0x3F +#define AB_SLOT_INACTIVE_VAL 0x0 +#define AB_SLOT_ACTIVE 1 +#define AB_SLOT_INACTIVE 0 +#define AB_SLOT_A_SUFFIX "_a" +#define AB_SLOT_B_SUFFIX "_b" +#define PTN_XBL "xbl" +#define PTN_XBL_CFG "xbl_config" +#define PTN_SWAP_LIST PTN_XBL, PTN_XBL_CFG, "sbl1", "rpm", "tz", "aboot", "abl", "hyp", "lksecapp", "keymaster", "cmnlib", "cmnlib32", "cmnlib64", "pmic", "apdp", "devcfg", "hosd", "keystore", "msadp", "mdtp", "mdtpsecapp", "dsp", "aop", "qupfw", "vbmeta", "dtbo", "imagefv", "ImageFv", "multiimgoem", "multiimgqti", "uefisecapp", "shrm", "cpucp" +#define AB_PTN_LIST PTN_SWAP_LIST, "boot", "system", "vendor", "odm", "modem", "bluetooth", "fsg", "logo", "mdm1m9kefs3", "prov", "spss", "storsec", "vbmeta_system", "vendor_boot" +#define BOOT_DEV_DIR "/dev/block/bootdevice/by-name" + +/****************************************************************************** + * HELPER MACROS + ******************************************************************************/ +#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) +/****************************************************************************** + * TYPES + ******************************************************************************/ +enum boot_update_stage { + UPDATE_MAIN = 1, + UPDATE_BACKUP, + UPDATE_FINALIZE +}; + +enum gpt_instance { + PRIMARY_GPT = 0, + SECONDARY_GPT +}; + +enum boot_chain { + NORMAL_BOOT = 0, + BACKUP_BOOT +}; + +struct gpt_disk { + //GPT primary header + uint8_t *hdr; + //primary header crc + uint32_t hdr_crc; + //GPT backup header + uint8_t *hdr_bak; + //backup header crc + uint32_t hdr_bak_crc; + //Partition entries array + uint8_t *pentry_arr; + //Partition entries array for backup table + uint8_t *pentry_arr_bak; + //Size of the pentry array + uint32_t pentry_arr_size; + //Size of each element in the pentry array + uint32_t pentry_size; + //CRC of the partition entry array + uint32_t pentry_arr_crc; + //CRC of the backup partition entry array + uint32_t pentry_arr_bak_crc; + //Path to block dev representing the disk + char devpath[PATH_MAX]; + //Block size of disk + uint32_t block_size; + uint32_t is_initialized; +}; + +/****************************************************************************** + * FUNCTION PROTOTYPES + ******************************************************************************/ +int prepare_boot_update(enum boot_update_stage stage); +//GPT disk methods +struct gpt_disk* gpt_disk_alloc(); +//Free previously allocated gpt_disk struct +void gpt_disk_free(struct gpt_disk *disk); +//Get the details of the disk holding the partition whose name +//is passed in via dev +int gpt_disk_get_disk_info(const char *dev, struct gpt_disk *disk); + +//Get pointer to partition entry from a allocated gpt_disk structure +uint8_t* gpt_disk_get_pentry(struct gpt_disk *disk, + const char *partname, + enum gpt_instance instance); + +//Update the crc fields of the modified disk structure +int gpt_disk_update_crc(struct gpt_disk *disk); + +//Write the contents of struct gpt_disk back to the actual disk +int gpt_disk_commit(struct gpt_disk *disk); + +//Return if the current device is UFS based or not +int gpt_utils_is_ufs_device(); + +//Swtich betwieen using either the primary or the backup +//boot LUN for boot. This is required since UFS boot partitions +//cannot have a backup GPT which is what we use for failsafe +//updates of the other 'critical' partitions. This function will +//not be invoked for emmc targets and on UFS targets is only required +//to be invoked for XBL. +// +//The algorithm to do this is as follows: +//- Find the real block device(eg: /dev/block/sdb) that corresponds +// to the /dev/block/bootdevice/by-name/xbl(bak) symlink +// +//- Once we have the block device 'node' name(sdb in the above example) +// use this node to to locate the scsi generic device that represents +// it by checking the file /sys/block/sdb/device/scsi_generic/sgY +// +//- Once we locate sgY we call the query ioctl on /dev/sgy to switch +//the boot lun to either LUNA or LUNB +int gpt_utils_set_xbl_boot_partition(enum boot_chain chain); + +//Given a vector of partition names as a input and a reference to a map, +//populate the map to indicate which physical disk each of the partitions +//sits on. The key in the map is the path to the block device where the +//partiton lies and the value is a vector of strings indicating which of +//the passed in partiton names sits on that device. +int gpt_utils_get_partition_map(std::vector& partition_list, + std::map>& partition_map); +#ifdef __cplusplus +} +#endif +#endif /* __GPT_UTILS_H__ */ diff --git a/gpt-utils/recovery-ufs-bsg.cpp b/gpt-utils/recovery-ufs-bsg.cpp new file mode 100644 index 0000000..4249aa6 --- /dev/null +++ b/gpt-utils/recovery-ufs-bsg.cpp @@ -0,0 +1,255 @@ +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#define LOG_TAG "recovery_ufs" + +#include "recovery-ufs-bsg.h" + +#ifndef _BSG_FRAMEWORK_KERNEL_HEADERS +#ifndef _GENERIC_KERNEL_HEADERS +#include +#include +#endif +#endif + +//Size of the buffer that needs to be passed to the UFS ioctl +#define UFS_ATTR_DATA_SIZE 32 + +#ifdef _BSG_FRAMEWORK_KERNEL_HEADERS +static int get_ufs_bsg_dev(void) +{ + DIR *dir; + struct dirent *ent; + int ret = -ENODEV; + + if ((dir = opendir ("/dev")) != NULL) { + /* read all the files and directories within directory */ + while ((ent = readdir(dir)) != NULL) { + if (!strcmp(ent->d_name, "ufs-bsg") || + !strcmp(ent->d_name, "ufs-bsg0")) { + snprintf(ufs_bsg_dev, FNAME_SZ, "/dev/%s", ent->d_name); + ret = 0; + break; + } + } + if (ret) + ALOGE("could not find the ufs-bsg dev\n"); + closedir (dir); + } else { + /* could not open directory */ + ALOGE("could not open /dev (error no: %d)\n", errno); + ret = -EINVAL; + } + + return ret; +} + +int ufs_bsg_dev_open(void) +{ + int ret; + if (!fd_ufs_bsg) { + fd_ufs_bsg = open(ufs_bsg_dev, O_RDWR); + ret = errno; + if (fd_ufs_bsg < 0) { + ALOGE("Unable to open %s (error no: %d)", + ufs_bsg_dev, errno); + fd_ufs_bsg = 0; + return ret; + } + } + return 0; +} + +void ufs_bsg_dev_close(void) +{ + if (fd_ufs_bsg) { + close(fd_ufs_bsg); + fd_ufs_bsg = 0; + } +} + +static int ufs_bsg_ioctl(int fd, struct ufs_bsg_request *req, + struct ufs_bsg_reply *rsp, __u8 *buf, __u32 buf_len, + enum bsg_ioctl_dir dir) +{ + int ret; + struct sg_io_v4 sg_io{}; + + sg_io.guard = 'Q'; + sg_io.protocol = BSG_PROTOCOL_SCSI; + sg_io.subprotocol = BSG_SUB_PROTOCOL_SCSI_TRANSPORT; + sg_io.request_len = sizeof(*req); + sg_io.request = (__u64)req; + sg_io.response = (__u64)rsp; + sg_io.max_response_len = sizeof(*rsp); + if (dir == BSG_IOCTL_DIR_FROM_DEV) { + sg_io.din_xfer_len = buf_len; + sg_io.din_xferp = (__u64)(buf); + } else { + sg_io.dout_xfer_len = buf_len; + sg_io.dout_xferp = (__u64)(buf); + } + + ret = ioctl(fd, SG_IO, &sg_io); + if (ret) + ALOGE("%s: Error from sg_io ioctl (return value: %d, error no: %d, reply result from LLD: %d\n)", + __func__, ret, errno, rsp->result); + + if (sg_io.info || rsp->result) { + ALOGE("%s: Error from sg_io info (check sg info: device_status: 0x%x, transport_status: 0x%x, driver_status: 0x%x, reply result from LLD: %d\n)", + __func__, sg_io.device_status, sg_io.transport_status, + sg_io.driver_status, rsp->result); + ret = -EAGAIN; + } + + return ret; +} + +static void compose_ufs_bsg_query_req(struct ufs_bsg_request *req, __u8 func, + __u8 opcode, __u8 idn, __u8 index, __u8 sel, + __u16 length) +{ + struct utp_upiu_header *hdr = &req->upiu_req.header; + struct utp_upiu_query *qr = &req->upiu_req.qr; + + req->msgcode = UTP_UPIU_QUERY_REQ; + hdr->dword_0 = DWORD(UTP_UPIU_QUERY_REQ, 0, 0, 0); + hdr->dword_1 = DWORD(0, func, 0, 0); + hdr->dword_2 = DWORD(0, 0, length >> 8, (__u8)length); + qr->opcode = opcode; + qr->idn = idn; + qr->index = index; + qr->selector = sel; + qr->length = htobe16(length); +} + + +static int ufs_query_attr(int fd, __u32 value, + __u8 func, __u8 opcode, __u8 idn, + __u8 index, __u8 sel) +{ + struct ufs_bsg_request req{}; + struct ufs_bsg_reply rsp{}; + enum bsg_ioctl_dir dir = BSG_IOCTL_DIR_FROM_DEV; + int ret = 0; + + if (opcode == QUERY_REQ_OP_WRITE_DESC || opcode == QUERY_REQ_OP_WRITE_ATTR) + dir = BSG_IOCTL_DIR_TO_DEV; + + req.upiu_req.qr.value = htobe32(value); + + compose_ufs_bsg_query_req(&req, func, opcode, idn, index, sel, 0); + + ret = ufs_bsg_ioctl(fd, &req, &rsp, 0, 0, dir); + if (ret) + ALOGE("%s: Error from ufs_bsg_ioctl (return value: %d, error no: %d\n)", + __func__, ret, errno); + + return ret; +} + +int32_t set_boot_lun(char *sg_dev __unused,uint8_t lun_id) +{ + int32_t ret; + __u32 boot_lun_id = lun_id; + + ret = get_ufs_bsg_dev(); + if (ret) + return ret; + ALOGV("Found the ufs bsg dev: %s\n", ufs_bsg_dev); + + ret = ufs_bsg_dev_open(); + if (ret) + return ret; + ALOGV("Opened ufs bsg dev: %s\n", ufs_bsg_dev); + + ret = ufs_query_attr(fd_ufs_bsg, boot_lun_id, QUERY_REQ_FUNC_STD_WRITE, + QUERY_REQ_OP_WRITE_ATTR, QUERY_ATTR_IDN_BOOT_LU_EN, 0, 0); + if (ret) { + ALOGE("Error requesting ufs attr idn %d via query ioctl (return value: %d, error no: %d)", + QUERY_ATTR_IDN_BOOT_LU_EN, ret, errno); + goto out; + } +out: + ufs_bsg_dev_close(); + return ret; +} +#endif + +#ifndef _BSG_FRAMEWORK_KERNEL_HEADERS +int32_t set_boot_lun(char *sg_dev, uint8_t boot_lun_id) +{ +#ifndef _GENERIC_KERNEL_HEADERS + int fd = -1; + int rc; + struct ufs_ioctl_query_data *data = NULL; + size_t ioctl_data_size = sizeof(struct ufs_ioctl_query_data) + UFS_ATTR_DATA_SIZE; + + data = (struct ufs_ioctl_query_data*)malloc(ioctl_data_size); + if (!data) { + fprintf(stderr, "%s: Failed to alloc query data struct\n", + __func__); + goto error; + } + memset(data, 0, ioctl_data_size); + data->opcode = UPIU_QUERY_OPCODE_WRITE_ATTR; + data->idn = QUERY_ATTR_IDN_BOOT_LU_EN; + data->buf_size = UFS_ATTR_DATA_SIZE; + data->buffer[0] = boot_lun_id; + fd = open(sg_dev, O_RDWR); + if (fd < 0) { + fprintf(stderr, "%s: Failed to open %s(%s)\n", + __func__, + sg_dev, + strerror(errno)); + goto error; + } + rc = ioctl(fd, UFS_IOCTL_QUERY, data); + if (rc) { + fprintf(stderr, "%s: UFS query ioctl failed(%s)\n", + __func__, + strerror(errno)); + goto error; + } + close(fd); + free(data); + return 0; +error: + if (fd >= 0) + close(fd); + if (data) + free(data); + return -1; +#else + return 0; +#endif +} +#endif + diff --git a/gpt-utils/recovery-ufs-bsg.h b/gpt-utils/recovery-ufs-bsg.h new file mode 100644 index 0000000..fafea5f --- /dev/null +++ b/gpt-utils/recovery-ufs-bsg.h @@ -0,0 +1,131 @@ +#ifndef __RECOVERY_UFS_BSG_H__ +#define __RECOVERY_UFS_BSG_H__ + +/* + * Copyright (c) 2020 The Linux Foundation. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * * Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * * Redistributions in binary form must reproduce the above + * copyright notice, this list of conditions and the following + * disclaimer in the documentation and/or other materials provided + * with the distribution. + * * Neither the name of The Linux Foundation nor the names of its + * contributors may be used to endorse or promote products derived + * from this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED + * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF + * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS + * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR + * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE + * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN + * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#ifdef ANDROID +#include "cutils/log.h" +#endif + +#ifdef OE +#include +#define LOGI(...) syslog(LOG_NOTICE, "INFO:" __VA_ARGS__) +#define LOGV(...) syslog(LOG_NOTICE,"VERB:" __VA_ARGS__) +#define LOGD(...) syslog(LOG_DEBUG,"DBG:" __VA_ARGS__) +#define LOGE(...) syslog(LOG_ERR,"ERR:" __VA_ARGS__) +#define LOGW(...) syslog(LOG_WARNING,"WRN:" __VA_ARGS__) +#define strlcat(d,s,l) snprintf(d+strlen(d),l,"%s",s) +#endif + + + +#define FNAME_SZ 64 + +#define SG_IO 0x2285 + +#define DWORD(b3, b2, b1, b0) htobe32((b3 << 24) | (b2 << 16) |\ + (b1 << 8) | b0) + +/* UFS BSG device nodes */ +char ufs_bsg_dev[FNAME_SZ] = "/dev/ufs-bsg"; + +int fd_ufs_bsg; + +int32_t set_ufs_lun(uint8_t lun_id); + +#ifdef _BSG_FRAMEWORK_KERNEL_HEADERS +/* UPIU Transaction Codes */ +enum { + UTP_UPIU_NOP_OUT = 0x00, + UTP_UPIU_COMMAND = 0x01, + UTP_UPIU_DATA_OUT = 0x02, + UTP_UPIU_TASK_REQ = 0x04, + UTP_UPIU_QUERY_REQ = 0x16, +}; + +/* UPIU Query Function field */ +enum { + QUERY_REQ_FUNC_STD_READ = 0x01, + QUERY_REQ_FUNC_STD_WRITE = 0x81, +}; + +enum query_req_opcode { + QUERY_REQ_OP_READ_DESC = 0x1, + QUERY_REQ_OP_WRITE_DESC = 0x2, + QUERY_REQ_OP_READ_ATTR = 0x3, + QUERY_REQ_OP_WRITE_ATTR = 0x4, + QUERY_REQ_OP_READ_FLAG = 0x5, + QUERY_REQ_OP_SET_FLAG = 0x6, + QUERY_REQ_OP_CLEAR_FLAG = 0x7, + QUERY_REQ_OP_TOGGLE_FLAG = 0x8, +}; + +enum query_desc_idn { + QUERY_DESC_IDN_DEVICE = 0x0, + QUERY_DESC_IDN_UNIT = 0x2, + QUERY_DESC_IDN_GEOMETRY = 0x7, +}; + +enum query_desc_size { + QUERY_DESC_SIZE_DEVICE = 0x40, + QUERY_DESC_SIZE_GEOMETRY = 0x48, + QUERY_DESC_SIZE_UNIT = 0x23, +}; + +enum bsg_ioctl_dir { + BSG_IOCTL_DIR_TO_DEV, + BSG_IOCTL_DIR_FROM_DEV, +}; + +enum query_attr_idn { + QUERY_ATTR_IDN_BOOT_LU_EN = 0x00, + QUERY_ATTR_IDN_RESERVED = 0x01, + QUERY_ATTR_IDN_POWER_MODE = 0x02, + QUERY_ATTR_IDN_ACTIVE_ICC_LVL = 0x03, +}; +#endif /* _BSG_FRAMEWORK_KERNEL_HEADERS */ + +#endif /* __RECOVERY_UFS_BSG_H__ */ diff --git a/gpt-utils/sparse_crc32.cpp b/gpt-utils/sparse_crc32.cpp new file mode 100644 index 0000000..267322c --- /dev/null +++ b/gpt-utils/sparse_crc32.cpp @@ -0,0 +1,97 @@ +/*- + * COPYRIGHT (C) 1986 Gary S. Brown. You may use this program, or + * code or tables extracted from it, as desired without restriction. + */ + +/* + * First, the polynomial itself and its table of feedback terms. The + * polynomial is + * X^32+X^26+X^23+X^22+X^16+X^12+X^11+X^10+X^8+X^7+X^5+X^4+X^2+X^1+X^0 + * + * Note that we take it "backwards" and put the highest-order term in + * the lowest-order bit. The X^32 term is "implied"; the LSB is the + * X^31 term, etc. The X^0 term (usually shown as "+1") results in + * the MSB being 1 + * + * Note that the usual hardware shift register implementation, which + * is what we're using (we're merely optimizing it by doing eight-bit + * chunks at a time) shifts bits into the lowest-order term. In our + * implementation, that means shifting towards the right. Why do we + * do it this way? Because the calculated CRC must be transmitted in + * order from highest-order term to lowest-order term. UARTs transmit + * characters in order from LSB to MSB. By storing the CRC this way + * we hand it to the UART in the order low-byte to high-byte; the UART + * sends each low-bit to hight-bit; and the result is transmission bit + * by bit from highest- to lowest-order term without requiring any bit + * shuffling on our part. Reception works similarly + * + * The feedback terms table consists of 256, 32-bit entries. Notes + * + * The table can be generated at runtime if desired; code to do so + * is shown later. It might not be obvious, but the feedback + * terms simply represent the results of eight shift/xor opera + * tions for all combinations of data and CRC register values + * + * The values must be right-shifted by eight bits by the "updcrc + * logic; the shift must be unsigned (bring in zeroes). On some + * hardware you could probably optimize the shift in assembler by + * using byte-swap instructions + * polynomial $edb88320 + * + * + * CRC32 code derived from work by Gary S. Brown. + */ + +/* Code taken from FreeBSD 8 */ +#include +#include + +static uint32_t crc32_tab[] = { + 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba, 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3, + 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988, 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91, + 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de, 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7, + 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec, 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5, + 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172, 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b, + 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940, 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59, + 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116, 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f, + 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924, 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d, + 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a, 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433, + 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818, 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01, + 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e, 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457, + 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c, 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65, + 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2, 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb, + 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0, 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9, + 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086, 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f, + 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4, 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad, + 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a, 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683, + 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8, 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1, + 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe, 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7, + 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc, 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5, + 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252, 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b, + 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60, 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79, + 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236, 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f, + 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04, 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d, + 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a, 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713, + 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38, 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21, + 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e, 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777, + 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c, 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45, + 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2, 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db, + 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0, 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9, + 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6, 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf, + 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94, 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d}; + +/* + * A function that calculates the CRC-32 based on the table above is + * given below for documentation purposes. An equivalent implementation + * of this function that's actually used in the kernel can be found + * in sys/libkern.h, where it can be inlined. + */ + +uint32_t sparse_crc32(uint32_t crc_in, const void* buf, size_t size) { + const uint8_t* p = reinterpret_cast(buf); + uint32_t crc; + + crc = crc_in ^ ~0U; + while (size--) crc = crc32_tab[(crc ^ *p++) & 0xFF] ^ (crc >> 8); + return crc ^ ~0U; +} diff --git a/gpt-utils/sparse_crc32.h b/gpt-utils/sparse_crc32.h new file mode 100644 index 0000000..2702c4f --- /dev/null +++ b/gpt-utils/sparse_crc32.h @@ -0,0 +1,24 @@ +/* + * Copyright (C) 2010 The Android Open Source Project + * + * 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. + */ + +#ifndef _LIBSPARSE_SPARSE_CRC32_H_ +#define _LIBSPARSE_SPARSE_CRC32_H_ + +#include + +uint32_t sparse_crc32(uint32_t crc, const void* buf, size_t size); + +#endif diff --git a/ims-patches/0001-ImsConfigImpl-Return-0-in-getWfcMDN-in-any-case.patch b/ims-patches/0001-ImsConfigImpl-Return-0-in-getWfcMDN-in-any-case.patch index 46eecd5..a30b78a 100644 --- a/ims-patches/0001-ImsConfigImpl-Return-0-in-getWfcMDN-in-any-case.patch +++ b/ims-patches/0001-ImsConfigImpl-Return-0-in-getWfcMDN-in-any-case.patch @@ -1,39 +1,35 @@ -From 0f3f402c9718d24a66d3a59b36c167de848fcff9 Mon Sep 17 00:00:00 2001 +From cfd224560c7d76c9bc219eb2c12b099e1537956c Mon Sep 17 00:00:00 2001 From: Erfan Abdi Date: Sun, 26 Jan 2020 20:23:44 +0330 -Subject: [PATCH 1/5] ImsConfigImpl: Return 0 in getWfcMDN in any case +Subject: [PATCH 1/3] ImsConfigImpl: Return 0 in getWfcMDN in any case --- - smali/org/codeaurora/ims/ImsConfigImpl.smali | 13 ------------- - 1 file changed, 13 deletions(-) + smali/org/codeaurora/ims/ImsConfigImpl.smali | 14 -------------- + 1 file changed, 14 deletions(-) diff --git a/smali/org/codeaurora/ims/ImsConfigImpl.smali b/smali/org/codeaurora/ims/ImsConfigImpl.smali -index 644a553..c921038 100644 +index 8daf3342..b2ab6538 100644 --- a/smali/org/codeaurora/ims/ImsConfigImpl.smali +++ b/smali/org/codeaurora/ims/ImsConfigImpl.smali -@@ -1471,22 +1471,9 @@ +@@ -1385,22 +1385,8 @@ .param p1, "subid" # I - - .line 849 -- const-string v0, "wfc_ims_mdn" + + .line 814 +- iget-object v0, p0, Lorg/codeaurora/ims/ImsConfigImpl;->mContext:Landroid/content/Context; - -- iget-object v1, p0, Lorg/codeaurora/ims/ImsConfigImpl;->mContext:Landroid/content/Context; +- const-string v1, "wfc_ims_mdn" - -- invoke-virtual {p0, p1, v0, v1}, Lorg/codeaurora/ims/ImsConfigImpl;->getSubscriptionProperty(ILjava/lang/String;Landroid/content/Context;)Ljava/lang/String; +- invoke-static {p1, v1, v0}, Landroid/telephony/SubscriptionManager;->getSubscriptionProperty(ILjava/lang/String;Landroid/content/Context;)Ljava/lang/String; - - move-result-object v0 - -- .line 851 +- .line 816 - .local v0, "mdn":Ljava/lang/String; - if-nez v0, :cond_0 - +- const-string v0, "0" - -- .line 852 + +- .line 817 - :cond_0 return-object v0 .end method - --- -2.43.0 - diff --git a/ims-patches/0002-ImsConfigImpl-don-t-call-setSubscriptionProperty-for.patch b/ims-patches/0002-ImsConfigImpl-don-t-call-setSubscriptionProperty-for.patch index 4496855..43a706d 100644 --- a/ims-patches/0002-ImsConfigImpl-don-t-call-setSubscriptionProperty-for.patch +++ b/ims-patches/0002-ImsConfigImpl-don-t-call-setSubscriptionProperty-for.patch @@ -1,7 +1,7 @@ -From 9f41786278a80f4e8f8629ae13b1d5cc38c85fde Mon Sep 17 00:00:00 2001 +From ab173b9875550f2462b8ed80ada0dff9bd2804d0 Mon Sep 17 00:00:00 2001 From: Vachounet Date: Wed, 27 Jan 2021 23:28:48 +0100 -Subject: [PATCH 2/5] ImsConfigImpl: don't call setSubscriptionProperty for +Subject: [PATCH 2/3] ImsConfigImpl: don't call setSubscriptionProperty for wfc_ims_mdn --- @@ -9,11 +9,11 @@ Subject: [PATCH 2/5] ImsConfigImpl: don't call setSubscriptionProperty for 1 file changed, 70 deletions(-) diff --git a/smali/org/codeaurora/ims/ImsConfigImpl.smali b/smali/org/codeaurora/ims/ImsConfigImpl.smali -index c921038..c38fe20 100644 +index c921038c..c38fe206 100644 --- a/smali/org/codeaurora/ims/ImsConfigImpl.smali +++ b/smali/org/codeaurora/ims/ImsConfigImpl.smali @@ -3070,76 +3070,6 @@ - + .line 790 :cond_2 - if-ne p1, v2, :cond_3 @@ -87,8 +87,5 @@ index c921038..c38fe20 100644 - :cond_3 - :goto_1 const/16 v3, 0x2c - - const/4 v5, 0x1 --- -2.43.0 + const/4 v5, 0x1 diff --git a/ims-patches/0003-ims-remove-uses-library-for-moto-ims-ext.patch b/ims-patches/0003-ims-remove-uses-library-for-moto-ims-ext.patch index 2111514..64fffe3 100644 --- a/ims-patches/0003-ims-remove-uses-library-for-moto-ims-ext.patch +++ b/ims-patches/0003-ims-remove-uses-library-for-moto-ims-ext.patch @@ -1,7 +1,7 @@ -From 4dd42142e2fbb2afd60ca6d8b4ac497c8d978f74 Mon Sep 17 00:00:00 2001 +From cadd5ec3e6f097bd5619e22bf827fb685e38c1d2 Mon Sep 17 00:00:00 2001 From: Andrew Hexen Date: Thu, 25 May 2023 11:51:44 -0700 -Subject: [PATCH 3/5] ims: remove uses-library for moto-ims-ext +Subject: [PATCH 3/3] ims: remove uses-library for moto-ims-ext * This was added in 13 which breaks ims: 'java.lang.ClassNotFoundException org/codeaurora/ims/utils/QtiCarrierConfigHelper/ImsService.java' @@ -13,7 +13,7 @@ Signed-off-by: Andrew Hexen 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/AndroidManifest.xml b/AndroidManifest.xml -index 3b3dc51..6f4b3de 100644 +index 3b3dc516..6f4b3de4 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -48,9 +48,8 @@ @@ -28,6 +28,3 @@ index 3b3dc51..6f4b3de 100644 - \ No newline at end of file + --- -2.43.0 - diff --git a/ims-patches/0004-ims-globally-set-RECEIVER_EXPORTED-for-registerRecei.patch b/ims-patches/0004-ims-globally-set-RECEIVER_EXPORTED-for-registerReceiver.patch similarity index 94% rename from ims-patches/0004-ims-globally-set-RECEIVER_EXPORTED-for-registerRecei.patch rename to ims-patches/0004-ims-globally-set-RECEIVER_EXPORTED-for-registerReceiver.patch index dfd70cd..6f0ce62 100644 --- a/ims-patches/0004-ims-globally-set-RECEIVER_EXPORTED-for-registerRecei.patch +++ b/ims-patches/0004-ims-globally-set-RECEIVER_EXPORTED-for-registerReceiver.patch @@ -1,7 +1,7 @@ -From 74cc53ffea595daf25e176fb1783641994fb794d Mon Sep 17 00:00:00 2001 +From 789e1c4dace46b872198b5180ea77afb1b1a2c17 Mon Sep 17 00:00:00 2001 From: SGCMarkus Date: Wed, 21 Feb 2024 19:18:49 +0100 -Subject: [PATCH 4/5] ims: globally set RECEIVER_EXPORTED for registerReceiver +Subject: [PATCH] ims: globally set RECEIVER_EXPORTED for registerReceiver E AndroidRuntime: FATAL EXCEPTION: main E AndroidRuntime: Process: org.codeaurora.ims, PID: 3692 @@ -15,7 +15,7 @@ E AndroidRuntime: java.lang.RuntimeException: Unable to create service org.codea 5 files changed, 18 insertions(+), 6 deletions(-) diff --git a/smali/com/qualcomm/ims/vt/LowBatteryHandler.smali b/smali/com/qualcomm/ims/vt/LowBatteryHandler.smali -index d69a656..deff6db 100644 +index d69a656b..deff6dba 100644 --- a/smali/com/qualcomm/ims/vt/LowBatteryHandler.smali +++ b/smali/com/qualcomm/ims/vt/LowBatteryHandler.smali @@ -150,7 +150,9 @@ @@ -30,7 +30,7 @@ index d69a656..deff6db 100644 .line 49 return-void diff --git a/smali/org/codeaurora/ims/ImsCallModification.smali b/smali/org/codeaurora/ims/ImsCallModification.smali -index 3c209df..a18213b 100644 +index 3c209dfd..a18213bf 100644 --- a/smali/org/codeaurora/ims/ImsCallModification.smali +++ b/smali/org/codeaurora/ims/ImsCallModification.smali @@ -300,7 +300,9 @@ @@ -45,7 +45,7 @@ index 3c209df..a18213b 100644 .line 141 const-string v0, "Registering car mode receiver" diff --git a/smali/org/codeaurora/ims/ImsConfigImpl.smali b/smali/org/codeaurora/ims/ImsConfigImpl.smali -index c38fe20..4daeb74 100644 +index c38fe206..4daeb745 100644 --- a/smali/org/codeaurora/ims/ImsConfigImpl.smali +++ b/smali/org/codeaurora/ims/ImsConfigImpl.smali @@ -668,7 +668,9 @@ @@ -60,7 +60,7 @@ index c38fe20..4daeb74 100644 .line 257 new-instance v1, Landroid/os/HandlerThread; diff --git a/smali/org/codeaurora/ims/ImsServiceSub.smali b/smali/org/codeaurora/ims/ImsServiceSub.smali -index 4a4a489..579abd8 100644 +index 4a4a489d..579abd88 100644 --- a/smali/org/codeaurora/ims/ImsServiceSub.smali +++ b/smali/org/codeaurora/ims/ImsServiceSub.smali @@ -1074,7 +1074,9 @@ @@ -75,7 +75,7 @@ index 4a4a489..579abd8 100644 .line 312 iget-object v2, p0, Lorg/codeaurora/ims/ImsServiceSub;->mImsServiceStateReceiver:Lorg/codeaurora/ims/ImsServiceStateReceiver; diff --git a/smali/org/codeaurora/ims/ImsSubController.smali b/smali/org/codeaurora/ims/ImsSubController.smali -index 3f21add..e0f6feb 100644 +index 3f21add4..e0f6feb0 100644 --- a/smali/org/codeaurora/ims/ImsSubController.smali +++ b/smali/org/codeaurora/ims/ImsSubController.smali @@ -416,7 +416,9 @@ @@ -100,6 +100,3 @@ index 3f21add..e0f6feb 100644 .line 752 iput-boolean v3, p0, Lorg/codeaurora/ims/ImsSubController;->mIsReceiverRegistered:Z --- -2.43.0 - diff --git a/ims-patches/0005-PATCH-5-5-fixup-ims-globally-set-RECEIVER_EXPORTED-f.patch b/ims-patches/0005-fixup-ims-globally-set-RECEIVER_EXPORTED-for-registe.patch similarity index 95% rename from ims-patches/0005-PATCH-5-5-fixup-ims-globally-set-RECEIVER_EXPORTED-f.patch rename to ims-patches/0005-fixup-ims-globally-set-RECEIVER_EXPORTED-for-registe.patch index 18a9389..0a62b3a 100644 --- a/ims-patches/0005-PATCH-5-5-fixup-ims-globally-set-RECEIVER_EXPORTED-f.patch +++ b/ims-patches/0005-fixup-ims-globally-set-RECEIVER_EXPORTED-for-registe.patch @@ -1,8 +1,8 @@ -From 799edb94515218e27a8d18e7ae1ce1aef379355a Mon Sep 17 00:00:00 2001 +From 9aa16907f82bd04629f8516b3c2ca082a6d73e67 Mon Sep 17 00:00:00 2001 From: Cosmin Tanislav Date: Fri, 9 Aug 2024 10:47:24 +0300 -Subject: [PATCH 5/5] [PATCH 5/5] fixup! ims: globally set RECEIVER_EXPORTED - for registerReceiver +Subject: [PATCH 5/5] fixup! ims: globally set RECEIVER_EXPORTED for + registerReceiver Use new locals for the RECEIVER_EXPORTED parameter to avoid conflicts. @@ -31,12 +31,12 @@ java.lang.Object (declaration of 'org.codeaurora.ims.ImsCallModification' appear 5 files changed, 16 insertions(+), 16 deletions(-) diff --git a/smali/com/qualcomm/ims/vt/LowBatteryHandler.smali b/smali/com/qualcomm/ims/vt/LowBatteryHandler.smali -index deff6db..6a7e841 100644 +index deff6dba..6a7e841d 100644 --- a/smali/com/qualcomm/ims/vt/LowBatteryHandler.smali +++ b/smali/com/qualcomm/ims/vt/LowBatteryHandler.smali @@ -101,7 +101,7 @@ .end method - + .method private constructor (Ljava/util/List;Landroid/content/Context;)V - .locals 3 + .locals 4 @@ -44,24 +44,24 @@ index deff6db..6a7e841 100644 .annotation system Ldalvik/annotation/Signature; value = { @@ -150,9 +150,9 @@ - + invoke-direct {v1, v2}, Landroid/content/IntentFilter;->(Ljava/lang/String;)V - + - const/4 v2, 0x2 + const/4 v3, 0x2 - + - invoke-virtual {p2, v0, v1, v2}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; + invoke-virtual {p2, v0, v1, v3}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; - + .line 49 return-void diff --git a/smali/org/codeaurora/ims/ImsCallModification.smali b/smali/org/codeaurora/ims/ImsCallModification.smali -index a18213b..cae0c88 100644 +index a18213bf..cae0c88f 100644 --- a/smali/org/codeaurora/ims/ImsCallModification.smali +++ b/smali/org/codeaurora/ims/ImsCallModification.smali @@ -179,7 +179,7 @@ .end method - + .method public constructor (Lorg/codeaurora/ims/ImsCallSessionImpl;Landroid/content/Context;Lorg/codeaurora/ims/ImsSenderRxr;Landroid/os/Looper;)V - .locals 3 + .locals 4 @@ -69,12 +69,12 @@ index a18213b..cae0c88 100644 .param p2, "context" # Landroid/content/Context; .param p3, "senderRxr" # Lorg/codeaurora/ims/ImsSenderRxr; diff --git a/smali/org/codeaurora/ims/ImsConfigImpl.smali b/smali/org/codeaurora/ims/ImsConfigImpl.smali -index 4daeb74..d91ef4f 100644 +index 4daeb745..d91ef4fb 100644 --- a/smali/org/codeaurora/ims/ImsConfigImpl.smali +++ b/smali/org/codeaurora/ims/ImsConfigImpl.smali @@ -414,7 +414,7 @@ .end method - + .method public constructor (Lorg/codeaurora/ims/ImsServiceSub;Lorg/codeaurora/ims/ImsSenderRxr;Landroid/content/Context;)V - .locals 4 + .locals 5 @@ -82,24 +82,24 @@ index 4daeb74..d91ef4f 100644 .param p2, "senderRxr" # Lorg/codeaurora/ims/ImsSenderRxr; .param p3, "context" # Landroid/content/Context; @@ -668,9 +668,9 @@ - + iget-object v2, p0, Lorg/codeaurora/ims/ImsConfigImpl;->mBroadcastReceiver:Landroid/content/BroadcastReceiver; - + - const/4 v3, 0x2 + const/4 v4, 0x2 - + - invoke-virtual {v1, v2, v0, v3}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; + invoke-virtual {v1, v2, v0, v4}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; - + .line 257 new-instance v1, Landroid/os/HandlerThread; diff --git a/smali/org/codeaurora/ims/ImsServiceSub.smali b/smali/org/codeaurora/ims/ImsServiceSub.smali -index 579abd8..839b79d 100644 +index 579abd88..839b79d9 100644 --- a/smali/org/codeaurora/ims/ImsServiceSub.smali +++ b/smali/org/codeaurora/ims/ImsServiceSub.smali @@ -622,7 +622,7 @@ .end method - + .method public constructor (Landroid/content/Context;ILorg/codeaurora/ims/ImsSenderRxr;Lorg/codeaurora/ims/ImsSubController;)V - .locals 5 + .locals 6 @@ -107,24 +107,24 @@ index 579abd8..839b79d 100644 .param p2, "phoneId" # I .param p3, "senderRxr" # Lorg/codeaurora/ims/ImsSenderRxr; @@ -1074,9 +1074,9 @@ - + iget-object v3, p0, Lorg/codeaurora/ims/ImsServiceSub;->mImsServiceStateReceiver:Lorg/codeaurora/ims/ImsServiceStateReceiver; - + - const/4 v4, 0x2 + const/4 v5, 0x2 - + - invoke-virtual {v2, v3, v0, v4}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; + invoke-virtual {v2, v3, v0, v5}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; - + .line 312 iget-object v2, p0, Lorg/codeaurora/ims/ImsServiceSub;->mImsServiceStateReceiver:Lorg/codeaurora/ims/ImsServiceStateReceiver; diff --git a/smali/org/codeaurora/ims/ImsSubController.smali b/smali/org/codeaurora/ims/ImsSubController.smali -index e0f6feb..1cbc3a2 100644 +index e0f6feb0..1cbc3a2f 100644 --- a/smali/org/codeaurora/ims/ImsSubController.smali +++ b/smali/org/codeaurora/ims/ImsSubController.smali @@ -301,7 +301,7 @@ .end method - + .method public constructor (Landroid/content/Context;Ljava/util/List;Ljava/util/List;Landroid/os/Looper;)V - .locals 3 + .locals 4 @@ -132,38 +132,35 @@ index e0f6feb..1cbc3a2 100644 .param p4, "looper" # Landroid/os/Looper; .annotation system Ldalvik/annotation/Signature; @@ -416,9 +416,9 @@ - + invoke-direct {v1, v2}, Landroid/content/IntentFilter;->(Ljava/lang/String;)V - + - const/4 v2, 0x2 + const/4 v3, 0x2 - + - invoke-virtual {p1, v0, v1, v2}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; + invoke-virtual {p1, v0, v1, v3}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; - + .line 217 iput-object p2, p0, Lorg/codeaurora/ims/ImsSubController;->mSenderRxrs:Ljava/util/List; @@ -1037,7 +1037,7 @@ .end method - + .method private handleRafInfo()V - .locals 10 + .locals 11 - + .line 705 iget v0, p0, Lorg/codeaurora/ims/ImsSubController;->mNumMultiModeStacks:I @@ -1269,9 +1269,9 @@ - + invoke-direct {v5, v6}, Landroid/content/IntentFilter;->(Ljava/lang/String;)V - + - const/4 v3, 0x2 + const/4 v10, 0x2 - + - invoke-virtual {v2, v4, v5, v3}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; + invoke-virtual {v2, v4, v5, v10}, Landroid/content/Context;->registerReceiver(Landroid/content/BroadcastReceiver;Landroid/content/IntentFilter;I)Landroid/content/Intent; - + .line 752 iput-boolean v3, p0, Lorg/codeaurora/ims/ImsSubController;->mIsReceiverRegistered:Z --- -2.43.0 - diff --git a/manifest.xml b/manifest.xml index 54da6ca..8be8c05 100644 --- a/manifest.xml +++ b/manifest.xml @@ -1,4 +1,4 @@ - + android.hardware.audio hwbinder @@ -60,6 +60,19 @@ @4.1::IKeymasterDevice/default + + android.hardware.media.omx + hwbinder + 1.0 + + IOmx + default + + + IOmxStore + default + + android.hardware.nfc hwbinder @@ -77,6 +90,15 @@ @1.5::IRadio/slot1 @1.5::IRadio/slot2 + + android.hardware.radio.config + hwbinder + 1.2 + + IRadioConfig + default + + android.hardware.secure_element hwbinder @@ -96,10 +118,19 @@ default + + android.hardware.tetheroffload.config + hwbinder + 1.0 + + IOffloadConfig + default + + android.hardware.tetheroffload.control hwbinder - 1.1 + 1.0 IOffloadControl default @@ -557,4 +588,15 @@ imsrtpservice + + vendor.qti.hardware.qccsyshal + hwbinder + 1.2 + + IQccsyshal + qccsyshal + + @1.2::IQccsyshal/qccsyshal + + diff --git a/proprietary-files.txt b/proprietary-files.txt index 706a82a..96750ec 100644 --- a/proprietary-files.txt +++ b/proprietary-files.txt @@ -1,10 +1,4 @@ -# All unpinned blobs are extracted from fogos_g-user 14 U1UGS34.23-82-2-6 e21904 release-keys - -# Current blobs with ELF checks disabled: -# libcne, libwqe, lowi-server, mutualex depend on libwpa_client, which is a gnu makefile target -# libmdmcutback depends on libqsap_sdk, which is a gnu makefile target -# libmotext_inf, libril-qcril-hook-oem depend on libril, which is a gnu makefile target -# thermal-engine depends on libthermalclient, which is device specific +# All unpinned blobs are extracted from fogos_g-user 14 U1UGS34M.23-82-2-3 da6528 release-keys # ADSP vendor/bin/adsprpcd @@ -40,8 +34,10 @@ vendor/lib/rfsa/adsp/libmctfengine_skel.so vendor/lib/rfsa/adsp/libneat_1_1_skel.so vendor/lib/rfsa/adsp/libscveObjectSegmentation_skel.so vendor/lib/rfsa/adsp/libscveT2T_skel.so -vendor/lib/rfsa/adsp/libsns_device_mode_skel.so;SYMLINK=vendor/lib64/rfsa/adsp/libsns_device_mode_skel.so -vendor/lib/rfsa/adsp/libsns_low_lat_stream_skel.so;SYMLINK=vendor/lib64/rfsa/adsp/libsns_low_lat_stream_skel.so +vendor/lib/rfsa/adsp/libsns_device_mode_skel.so +vendor/lib/rfsa/adsp/libsns_low_lat_stream_skel.so +vendor/lib64/rfsa/adsp/libsns_device_mode_skel.so +vendor/lib64/rfsa/adsp/libsns_low_lat_stream_skel.so # ANT+ system_ext/lib/com.qualcomm.qti.ant@1.0.so @@ -80,9 +76,6 @@ vendor/lib64/soundfx/libshoebox.so # Bluetooth vendor/bin/hw/android.hardware.bluetooth@1.0-service-qti vendor/etc/init/android.hardware.bluetooth@1.0-service-qti.rc -vendor/lib/hw/android.hardware.bluetooth@1.0-impl-qti.so -vendor/lib/libbtnv.so -vendor/lib/libsoc_helper.so vendor/lib64/hw/android.hardware.bluetooth@1.0-impl-qti.so vendor/lib64/libbtnv.so vendor/lib64/libsoc_helper.so @@ -127,7 +120,7 @@ vendor/etc/charger_fstab.qti vendor/etc/init/vendor.qti.hardware.charger_monitor@1.0-service.rc # CNE --vendor/app/CneApp/CneApp.apk;REQUIRED=CneApp.libvndfwk_detect_jni.qti_symlink +-vendor/app/CneApp/CneApp.apk vendor/bin/cnd vendor/etc/cne/mwqem.conf vendor/etc/cne/profileMwqem.xml @@ -160,13 +153,12 @@ vendor/etc/cne/wqeclient/VZW/VZW_profile5.xml vendor/etc/cne/wqeclient/VZW/VZW_profile6.xml vendor/etc/default-permissions/com.qualcomm.qti.cne.xml vendor/etc/init/cnd.rc -vendor/lib/libxml.so -vendor/lib64/libcne.so;DISABLE_CHECKELF +vendor/lib64/libcne.so vendor/lib64/libcneapiclient.so vendor/lib64/libcneoplookup.so vendor/lib64/libcneqmiutils.so vendor/lib64/libwms.so -vendor/lib64/libwqe.so;DISABLE_CHECKELF +vendor/lib64/libwqe.so vendor/lib64/libxml.so vendor/lib64/vendor.qti.data.factory@2.0.so vendor/lib64/vendor.qti.data.factory@2.1.so @@ -197,6 +189,8 @@ vendor/lib64/hw/vendor.qti.hardware.capabilityconfigstore@1.0-impl.so # CVP vendor/lib/libcvp_common.so +vendor/lib/libcvpcpuRev_skel.so +vendor/lib/vendor.qti.hardware.cvp@1.0.so vendor/lib64/libcvp_common.so vendor/lib64/libcvpcpuRev_skel.so vendor/lib64/vendor.qti.hardware.cvp@1.0.so @@ -253,8 +247,8 @@ system_ext/lib64/vendor.qti.diaghal@1.0.so vendor/bin/diag-router vendor/etc/init/vendor.qti.diag.rc -vendor/etc/vintf/manifest/vendor.qti.diag.hal.service.xml -vendor/lib/vendor.qti.diaghal@1.0.so;MODULE_SUFFIX=_vendor -vendor/lib64/vendor.qti.diaghal@1.0.so;MODULE_SUFFIX=_vendor +vendor/lib/vendor.qti.diaghal@1.0.so +vendor/lib64/vendor.qti.diaghal@1.0.so # Display - HDR vendor/lib64/libhdr_stub.so @@ -301,7 +295,7 @@ vendor/lib64/vendor.display.postproc@1.0.so # DPM system/framework/tcmclient.jar -system_ext/bin/dpmd;DISABLE_CHECKELF +system_ext/bin/dpmd system_ext/etc/dpm/dpm.conf system_ext/etc/init/dpmd.rc system_ext/etc/permissions/com.qti.dpmframework.xml @@ -309,20 +303,20 @@ system_ext/etc/permissions/dpmapi.xml system_ext/framework/com.qti.dpmframework.jar system_ext/framework/dpmapi.jar system_ext/lib/com.qualcomm.qti.dpm.api@1.0.so -system_ext/lib/libdpmctmgr.so;DISABLE_CHECKELF -system_ext/lib/libdpmfdmgr.so;DISABLE_CHECKELF -system_ext/lib/libdpmframework.so;DISABLE_CHECKELF -system_ext/lib/libdpmtcm.so;DISABLE_CHECKELF +system_ext/lib/libdpmctmgr.so +system_ext/lib/libdpmfdmgr.so +system_ext/lib/libdpmframework.so +system_ext/lib/libdpmtcm.so system_ext/lib64/com.qualcomm.qti.dpm.api@1.0.so -system_ext/lib64/libdpmctmgr.so;DISABLE_CHECKELF -system_ext/lib64/libdpmfdmgr.so;DISABLE_CHECKELF -system_ext/lib64/libdpmframework.so;DISABLE_CHECKELF -system_ext/lib64/libdpmtcm.so;DISABLE_CHECKELF +system_ext/lib64/libdpmctmgr.so +system_ext/lib64/libdpmfdmgr.so +system_ext/lib64/libdpmframework.so +system_ext/lib64/libdpmtcm.so system_ext/lib64/vendor.qti.hardware.dpmservice@1.0.so -system_ext/priv-app/dpmserviceapp/dpmserviceapp.apk vendor/bin/dpmQmiMgr vendor/etc/init/dpmQmiMgr.rc -vendor/lib64/com.qualcomm.qti.dpm.api@1.0.so;MODULE_SUFFIX=_vendor +vendor/lib64/com.qualcomm.qti.dpm.api@1.0.so vendor/lib64/libdpmqmihal.so # DRM @@ -349,7 +343,7 @@ vendor/lib64/vendor.qti.hardware.eid@1.0.so # FM vendor/lib64/hw/vendor.qti.hardware.fm@1.0-impl.so -vendor/lib64/vendor.qti.hardware.fm@1.0.so;MODULE_SUFFIX=_vendor +vendor/lib64/vendor.qti.hardware.fm@1.0.so # Gatekeeper vendor/bin/hw/android.hardware.gatekeeper@1.0-service-qti @@ -360,7 +354,7 @@ vendor/lib64/hw/android.hardware.gatekeeper@1.0-impl-qti.so -vendor/app/CACertService/CACertService.apk vendor/bin/hw/android.hardware.gnss@2.1-service-qti vendor/bin/loc_launcher -vendor/bin/lowi-server;DISABLE_CHECKELF +vendor/bin/lowi-server vendor/bin/mlid vendor/bin/xtra-daemon vendor/bin/xtwifi-client @@ -426,19 +420,20 @@ vendor/lib64/vendor.qti.gnss@3.0.so vendor/lib64/vendor.qti.gnss@4.0-service.so vendor/lib64/vendor.qti.gnss@4.0.so vendor/lib64/vendor.qti.hardware.cacert@1.0.so +vendor/lib64/vendor.qti.hardware.qccsyshal@1.0.so # Graphics - Adreno vendor/lib/egl/eglSubDriverAndroid.so -vendor/lib/egl/libEGL_adreno.so;SYMLINK=vendor/lib/libEGL_adreno.so +vendor/lib/egl/libEGL_adreno.so vendor/lib/egl/libGLESv1_CM_adreno.so -vendor/lib/egl/libGLESv2_adreno.so;SYMLINK=vendor/lib/libGLESv2_adreno.so -vendor/lib/egl/libq3dtools_adreno.so;SYMLINK=vendor/lib/libq3dtools_adreno.so +vendor/lib/egl/libGLESv2_adreno.so +vendor/lib/egl/libq3dtools_adreno.so vendor/lib/egl/libq3dtools_esx.so vendor/lib/libC2D2.so vendor/lib/libCB.so vendor/lib/libOpenCL.so vendor/lib/libVkLayer_q3dtools.so -vendor/lib/libadreno_app_profiles.so;DISABLE_CHECKELF +vendor/lib/libadreno_app_profiles.so vendor/lib/libadreno_utils.so vendor/lib/libc2d30_bltlib.so vendor/lib/libgpudataproducer.so @@ -448,10 +443,10 @@ vendor/lib/libkernelmanager.so vendor/lib/libllvm-glnext.so vendor/lib/libllvm-qcom.so vendor/lib64/egl/eglSubDriverAndroid.so -vendor/lib64/egl/libEGL_adreno.so;SYMLINK=vendor/lib64/libEGL_adreno.so +vendor/lib64/egl/libEGL_adreno.so vendor/lib64/egl/libGLESv1_CM_adreno.so -vendor/lib64/egl/libGLESv2_adreno.so;SYMLINK=vendor/lib64/libGLESv2_adreno.so -vendor/lib64/egl/libq3dtools_adreno.so;SYMLINK=vendor/lib64/libq3dtools_adreno.so +vendor/lib64/egl/libGLESv2_adreno.so +vendor/lib64/egl/libq3dtools_adreno.so vendor/lib64/egl/libq3dtools_esx.so vendor/lib64/libC2D2.so vendor/lib64/libCB.so @@ -530,7 +525,7 @@ vendor/etc/seccomp_policy/codec2.vendor.base-arm.policy vendor/etc/seccomp_policy/codec2.vendor.ext-arm.policy vendor/etc/video_system_specs.json -vendor/etc/vintf/manifest/vendor.dolby.media.c2@1.0-service.xml -vendor/lib/libmmosal.so;MODULE_SUFFIX=_vendor +vendor/lib/libmmosal.so vendor/lib/libqcodec2_base.so vendor/lib/libqcodec2_basecodec.so vendor/lib/libqcodec2_core.so @@ -538,14 +533,37 @@ vendor/lib/libqcodec2_hooks.so vendor/lib/libqcodec2_platform.so vendor/lib/libqcodec2_utils.so vendor/lib/libqcodec2_v4l2codec.so -vendor/lib64/libmmosal.so;MODULE_SUFFIX=_vendor +vendor/lib64/libmmosal.so # Media configs vendor/etc/media_blair/video_system_specs.json vendor/etc/media_holi/video_system_specs.json # OEM -vendor/bin/motobox;SYMLINK=vendor/bin/expat +vendor/bin/motobox + +# OMX +vendor/lib/libOmxAacDec.so +vendor/lib/libOmxAlacDec.so +vendor/lib/libOmxAmrDec.so +vendor/lib/libOmxAmrwbplusDec.so +vendor/lib/libOmxApeDec.so +vendor/lib/libOmxDsdDec.so +vendor/lib/libOmxEvrcDec.so +vendor/lib/libOmxG711Dec.so +vendor/lib/libOmxQcelp13Dec.so +vendor/lib/libOmxVideoDSMode.so +vendor/lib/libOmxWmaDec.so +vendor/lib/libdsd2pcm.so +vendor/lib64/libOmxAacDec.so +vendor/lib64/libOmxAlacDec.so +vendor/lib64/libOmxAmrDec.so +vendor/lib64/libOmxAmrwbplusDec.so +vendor/lib64/libOmxApeDec.so +vendor/lib64/libOmxEvrcDec.so +vendor/lib64/libOmxG711Dec.so +vendor/lib64/libOmxQcelp13Dec.so +vendor/lib64/libOmxWmaDec.so # Peripheral manager vendor/bin/pm-proxy @@ -574,8 +592,8 @@ system_ext/lib64/vendor.qti.hardware.qccsyshal@1.0.so system_ext/lib64/vendor.qti.hardware.qccsyshal@1.1.so system_ext/lib64/vendor.qti.hardware.qccsyshal@1.2-halimpl.so system_ext/lib64/vendor.qti.hardware.qccsyshal@1.2.so -vendor/lib/vendor.qti.hardware.qccsyshal@1.0.so;MODULE_SUFFIX=_vendor -vendor/lib64/vendor.qti.hardware.qccsyshal@1.0.so;MODULE_SUFFIX=_vendor +vendor/lib/vendor.qti.hardware.qccsyshal@1.0.so +vendor/lib64/vendor.qti.hardware.qccsyshal@1.0.so # QMI system/etc/permissions/privapp-permissions-qti.xml @@ -637,6 +655,7 @@ system_ext/etc/permissions/qti_permissions.xml system_ext/framework/qcrilhook.jar -system_ext/priv-app/qcrilmsgtunnel/qcrilmsgtunnel.apk -vendor/app/IWlanService/IWlanService.apk +vendor/bin/ATFWD-daemon vendor/bin/adpl vendor/bin/hw/qcrilNrd vendor/bin/ks @@ -719,17 +738,15 @@ vendor/etc/qcril_database/upgrade/ecc/9_version_qcrildb.sql vendor/etc/qcril_database/upgrade/other/2_version_add_wps_config_qcrilnr.sql vendor/etc/qcril_database/upgrade/other/3_version_update_wps_config_qcrilnr.sql vendor/etc/qcril_database/upgrade/other/6_version_change_property_table_qcrilnr.sql +vendor/etc/seccomp_policy/atfwd@2.0.policy vendor/etc/seccomp_policy/qcrilnr@2.0.policy vendor/etc/ssg/ta_config.json vendor/etc/ssg/tz_whitelist.json -vendor/lib/libconfigdb.so -vendor/lib/libmdmdetect.so -vendor/lib/libnetmgr.so vendor/lib64/deviceInfoServiceModuleNr.so vendor/lib64/libconfigdb.so vendor/lib64/liblog_vendor.so vendor/lib64/liblqe.so -vendor/lib64/libmdmcutback.so;DISABLE_CHECKELF +vendor/lib64/libmdmcutback.so vendor/lib64/libmdmdetect.so vendor/lib64/libminkdescriptor.so vendor/lib64/libmotext_inf.so @@ -764,6 +781,7 @@ vendor/lib64/qcrild_libqcrilnrutils.so vendor/lib64/qtiril-utils.so vendor/lib64/qtiwakelock.so vendor/lib64/vendor.qti.hardware.radio.am@1.0.so +vendor/lib64/vendor.qti.hardware.radio.atcmdfwd@1.0.so vendor/lib64/vendor.qti.hardware.radio.internal.deviceinfo@1.0.so vendor/lib64/vendor.qti.hardware.radio.lpa@1.0.so vendor/lib64/vendor.qti.hardware.radio.lpa@1.1.so @@ -789,6 +807,7 @@ vendor/lib64/vendor.qti.hardware.radio.uim_remote_server@1.0.so # Ril - IMS (APK) system/etc/permissions/moto-telephony.xml:system_ext/etc/permissions/moto-telephony.xml system/framework/moto-telephony.jar:system_ext/framework/moto-telephony.jar +system_ext/lib64/libimsmedia_jni.so # RIL - IMS -system_ext/app/ImsRcsService/ImsRcsService.apk @@ -806,13 +825,13 @@ system_ext/framework/vendor.qti.ims.rcssip-V1.2-java.jar system_ext/framework/vendor.qti.ims.rcsuce-V1.0-java.jar system_ext/framework/vendor.qti.ims.rcsuce-V1.1-java.jar system_ext/framework/vendor.qti.ims.rcsuce-V1.2-java.jar -system_ext/lib64/lib-imsvideocodec.so;DISABLE_CHECKELF -system_ext/lib64/lib-imsvt.so;DISABLE_CHECKELF -system_ext/lib64/lib-imsvtextutils.so;DISABLE_CHECKELF -system_ext/lib64/lib-imsvtutils.so;DISABLE_CHECKELF -system_ext/lib64/libdiag_system.so;DISABLE_CHECKELF -system_ext/lib64/libimscamera_jni.so;SYMLINK=system_ext/priv-app/ims/lib/arm64/libimscamera_jni.so -system_ext/lib64/libimsmedia_jni.so;SYMLINK=system_ext/priv-app/ims/lib/arm64/libimsmedia_jni.so +system_ext/lib64/lib-imsvideocodec.so +system_ext/lib64/lib-imsvt.so +system_ext/lib64/lib-imsvtextutils.so +system_ext/lib64/lib-imsvtutils.so +system_ext/lib64/libdiag_system.so +system_ext/lib64/libimscamera_jni.so +system_ext/lib64/libimsmedia_jni.so system_ext/lib64/vendor.qti.imsrtpservice@3.0.so system_ext/lib64/vendor.qti.imsrtpservice@3.1.so system_ext/lib64/vendor.qti.ImsRtpService-V1-ndk.so @@ -872,7 +891,7 @@ vendor/lib64/vendor.qti.ims.rcsuce@1.0.so vendor/lib64/vendor.qti.ims.rcsuce@1.1.so vendor/lib64/vendor.qti.ims.rcsuce@1.2.so vendor/lib64/vendor.qti.imsrtpservice@3.0-service-Impl.so -vendor/lib64/vendor.qti.imsrtpservice@3.0.so;MODULE_SUFFIX=_vendor +vendor/lib64/vendor.qti.imsrtpservice@3.0.so # Sensors vendor/bin/hw/vendor.qti.hardware.sensorscalibrate@1.0-service @@ -899,17 +918,19 @@ vendor/lib64/vendor.qti.hardware.sensorscalibrate@1.0.so # Snapdragon Computer Vision Engine vendor/lib/libfastcvdsp_stub.so -vendor/lib/libfastcvopt.so +-vendor/lib/libfastcvopt.so vendor/lib/libscveCommon.so vendor/lib/libscveCommon_stub.so vendor/lib/libscveObjectSegmentation.so vendor/lib/libscveObjectSegmentation_stub.so vendor/lib/libscveObjectTracker.so vendor/lib/libscveObjectTracker_stub.so +vendor/lib/rfsa/adsp/libscveObjectSegmentation_skel.so +vendor/lib/rfsa/adsp/libscveT2T_skel.so vendor/lib/vendor.qti.hardware.scve.objecttracker@1.0.so vendor/lib/vendor.qti.hardware.scve.panorama@1.0.so vendor/lib64/libfastcvdsp_stub.so -vendor/lib64/libfastcvopt.so +-vendor/lib64/libfastcvopt.so vendor/lib64/libscveCommon.so vendor/lib64/libscveCommon_stub.so vendor/lib64/libscveObjectSegmentation.so @@ -927,10 +948,10 @@ vendor/lib64/hw/vendor.qti.hardware.soter@1.0-impl.so vendor/lib64/vendor.qti.hardware.soter@1.0.so # Thermal engine -vendor/bin/thermal-engine;DISABLE_CHECKELF +vendor/bin/thermal-engine vendor/etc/init/init_thermal-engine.rc -vendor/lib/libthermalclient.so -vendor/lib64/libthermalclient.so +-vendor/lib/libthermalclient.so +-vendor/lib64/libthermalclient.so # Time services -vendor/app/TimeService/TimeService.apk @@ -1032,6 +1053,7 @@ vendor/firmware/vpu20_4v_unsigned.mbn vendor/bin/hw/android.hardware.drm@1.3-service.widevine vendor/etc/init/android.hardware.drm@1.3-service.widevine.rc -vendor/etc/vintf/manifest/manifest_android.hardware.drm@1.3-service.widevine.xml +vendor/lib64/libtrustedapploader.so vendor/lib64/libwvhidl.so # WiFi @@ -1085,7 +1107,6 @@ system_ext/lib64/libwfduibcsink.so system_ext/lib64/libwfduibcsinkinterface.so system_ext/lib64/libwfduibcsrc.so system_ext/lib64/libwfduibcsrcinterface.so -system_ext/lib64/vendor.qti.hardware.wifidisplaysession@1.0.so -system_ext/priv-app/WfdService/WfdService.apk vendor/bin/wfdhdcphalservice vendor/bin/wfdvndservice @@ -1123,6 +1144,5 @@ vendor/lib/libwfduibcsinkinterface_proprietary.so vendor/lib/libwfduibcsrc_proprietary.so vendor/lib/libwfduibcsrcinterface_proprietary.so vendor/lib/libwfdutils_proprietary.so -vendor/lib/vendor.qti.hardware.wifidisplaysession@1.0.so;MODULE_SUFFIX=_vendor +vendor/lib/vendor.qti.hardware.wifidisplaysession@1.0.so vendor/lib/vendor.qti.hardware.wifidisplaysessionl@1.0-halimpl.so -vendor/lib64/vendor.qti.hardware.wifidisplaysession@1.0.so;MODULE_SUFFIX=_vendor diff --git a/qcril-patches/6.0_config.sql.patch b/qcril-patches/6.0_config.sql.patch deleted file mode 100644 index 9106044..0000000 --- a/qcril-patches/6.0_config.sql.patch +++ /dev/null @@ -1,30 +0,0 @@ -From 4ed8978b35fd6b6723f995d534b534c4c4071c49 Mon Sep 17 00:00:00 2001 -From: SagarMakhar -Date: Tue, 1 Oct 2024 23:59:30 +0530 -Subject: [PATCH] sm6375-common: Fix persist.vendor.radio.poweron_opt to 0 - -* If this value 1 breaks SMS receiving - -Change-Id: I6f045b67c4a84b246471fa9249fa883fc78c1ee1 ---- - .../vendor/etc/qcril_database/qcrilNr.db | Bin 106496 -> 106496 bytes - .../upgrade/config/6.0_config.sql | 2 +- - 2 files changed, 1 insertion(+), 1 deletion(-) - -diff --git a/6.0_config.sql b/6.0_config.sql -index d178cf1..3a4c811 100644 ---- a/6.0_config.sql -+++ b/6.0_config.sql -@@ -104,7 +104,7 @@ INSERT OR REPLACE INTO qcril_properties_table(property, def_val) VALUES("persist - INSERT OR REPLACE INTO qcril_properties_table(property, def_val) VALUES("persist.vendor.radio.csg_info_avlbl", "0"); - INSERT OR REPLACE INTO qcril_properties_table(property, def_val) VALUES("persist.vendor.radio.cs_srv_type", "0"); - INSERT OR REPLACE INTO qcril_properties_table(property, def_val) VALUES("persist.vendor.radio.limit_rac_change", "0"); --INSERT OR REPLACE INTO qcril_properties_table(property, def_val) VALUES("persist.vendor.radio.poweron_opt", "1"); -+INSERT OR REPLACE INTO qcril_properties_table(property, def_val) VALUES("persist.vendor.radio.poweron_opt", "0"); - INSERT OR REPLACE INTO qcril_properties_table(property) VALUES("persist.vendor.radio.sglte_target"); - INSERT OR REPLACE INTO qcril_properties_table(property) VALUES("persist.vendor.radio.nitz_plmn_0"); - INSERT OR REPLACE INTO qcril_properties_table(property) VALUES("persist.vendor.radio.nitz_plmn_1"); - --- -GitLab - diff --git a/qcril-patches/qcrilNr.db.patch b/qcril-patches/qcrilNr.db.patch deleted file mode 100644 index a1cce6e..0000000 --- a/qcril-patches/qcrilNr.db.patch +++ /dev/null @@ -1,41 +0,0 @@ -From 4ed8978b35fd6b6723f995d534b534c4c4071c49 Mon Sep 17 00:00:00 2001 -From: SagarMakhar -Date: Tue, 1 Oct 2024 23:59:30 +0530 -Subject: [PATCH] sm6375-common: Fix persist.vendor.radio.poweron_opt to 0 - -* If this value 1 breaks SMS receiving - -Change-Id: I6f045b67c4a84b246471fa9249fa883fc78c1ee1 ---- - .../vendor/etc/qcril_database/qcrilNr.db | Bin 106496 -> 106496 bytes - .../upgrade/config/6.0_config.sql | 2 +- - 2 files changed, 1 insertion(+), 1 deletion(-) - -diff --git a/qcrilNr.db b/qcrilNr.db -index da4cbc60ddfefce5e42ca2b2512db4354c6dec0e..5e2ff97d7bafc4db15b9166b1be284e61508dac8 100644 -GIT binary patch -delta 528 -zcmYL^&r4KM9K}6zXB-H`B-X1h?7x#0{x!>Msl3zVs -zV!?xJF%jXRhapZEk${N=duLY>jt$|z<{EJ-meRaX)x@VFhE*!Jqzxb0giMR$w=@Xv -z`54lm*AltwBd5-HeUKD+H96@n@`n$HnGyyd;ms2Ipn;h(s_i1~)A$rmOX%U1O{CZr -zU@$I{De&|WdYKE*!TSL&8_CS^L7){60^Bw-Jj;_=4b*Em%S^=vvJZLjrAmjZIKzbs -zYP#%C1?RhsjHmc}OD$>Os*$!8UTnwpBUORL(X3xyum+P3z`I -zO@VtWILD(VZWu9-BT8=|$?bXl%IG@wb??u0OxThG#7<0}^X{5%zf;!0FT#zXg4{ -C_@I;k - -delta 540 -zcmYL^%}Z2a6vpS7cRnCRoPxf@sqi{8&XC-LQCpR87e%yj)o2rqB^II4bv~Z4|$OKH<0xC^0=eGvTtfwOBBxNp&U8!&hm=lq`MJ?A|2FR{A5j~MqNl6n^BR}TXm -z^$_Kphm>W}4%_!I6qDNu%s&8O&mywc0ShuLEFxtjRkK}^=NdZWgE|yd{-gC0GEqCG -zbj0GksZed+5sGrBgkfFrU6r`FPbVgFPxzyR9EZy2*1R4xvW7j~{&NlEHtKm|J1h@* -z@T7#`1Vc*{RQMJrl$Y^ - --- -GitLab - diff --git a/resource-overlay/Android.mk b/resource-overlay/Android.mk new file mode 100644 index 0000000..5053e7d --- /dev/null +++ b/resource-overlay/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/resource-overlay/common/Android.mk b/resource-overlay/common/Android.mk new file mode 100644 index 0000000..5053e7d --- /dev/null +++ b/resource-overlay/common/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/resource-overlay/common/CarrierConfig/Android.bp b/resource-overlay/common/CarrierConfig/Android.bp deleted file mode 100644 index df1a2c2..0000000 --- a/resource-overlay/common/CarrierConfig/Android.bp +++ /dev/null @@ -1,10 +0,0 @@ -// -// SPDX-FileCopyrightText: 2024-2025 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - -runtime_resource_overlay { - name: "CarrierConfigResCommon_Sys", - aaptflags: ["--keep-raw-values"], - product_specific: true, -} diff --git a/resource-overlay/common/CarrierConfig/Android.mk b/resource-overlay/common/CarrierConfig/Android.mk new file mode 100644 index 0000000..110f2a4 --- /dev/null +++ b/resource-overlay/common/CarrierConfig/Android.mk @@ -0,0 +1,17 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRODUCT_MODULE := true +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := CarrierConfigResCommon_Sys + +LOCAL_SDK_VERSION := current + +LOCAL_AAPT_FLAGS := --keep-raw-values + +include $(BUILD_RRO_PACKAGE) diff --git a/resource-overlay/common/Frameworks/Android.bp b/resource-overlay/common/Frameworks/Android.bp deleted file mode 100644 index 56c30aa..0000000 --- a/resource-overlay/common/Frameworks/Android.bp +++ /dev/null @@ -1,9 +0,0 @@ -// -// SPDX-FileCopyrightText: 2024-2025 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - -runtime_resource_overlay { - name: "FrameworksResCommon_Sys", - product_specific: true, -} diff --git a/resource-overlay/common/Frameworks/Android.mk b/resource-overlay/common/Frameworks/Android.mk new file mode 100644 index 0000000..b9d6646 --- /dev/null +++ b/resource-overlay/common/Frameworks/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRODUCT_MODULE := true +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := FrameworksResCommon_Sys +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/resource-overlay/common/Frameworks/res/values/config.xml b/resource-overlay/common/Frameworks/res/values/config.xml index cd197e4..1bd0d6b 100644 --- a/resource-overlay/common/Frameworks/res/values/config.xml +++ b/resource-overlay/common/Frameworks/res/values/config.xml @@ -119,8 +119,8 @@ 7 - - true + + true true @@ -359,4 +359,7 @@ true + + + true diff --git a/resource-overlay/common/SystemUI/Android.bp b/resource-overlay/common/SystemUI/Android.bp deleted file mode 100644 index 412628c..0000000 --- a/resource-overlay/common/SystemUI/Android.bp +++ /dev/null @@ -1,9 +0,0 @@ -// -// SPDX-FileCopyrightText: 2024-2025 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - -runtime_resource_overlay { - name: "SystemUIResCommon_Sys", - product_specific: true, -} diff --git a/resource-overlay/common/SystemUI/Android.mk b/resource-overlay/common/SystemUI/Android.mk new file mode 100644 index 0000000..b40fbe9 --- /dev/null +++ b/resource-overlay/common/SystemUI/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRODUCT_MODULE := true +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := SystemUIResCommon_Sys +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/resource-overlay/common/Telecomm/Android.bp b/resource-overlay/common/Telecomm/Android.bp deleted file mode 100644 index f5cb999..0000000 --- a/resource-overlay/common/Telecomm/Android.bp +++ /dev/null @@ -1,9 +0,0 @@ -// -// SPDX-FileCopyrightText: 2024-2025 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - -runtime_resource_overlay { - name: "TelecommResCommon_Sys", - product_specific: true, -} diff --git a/resource-overlay/common/Telecomm/Android.mk b/resource-overlay/common/Telecomm/Android.mk new file mode 100644 index 0000000..9858458 --- /dev/null +++ b/resource-overlay/common/Telecomm/Android.mk @@ -0,0 +1,16 @@ +ifeq ($(TARGET_FWK_SUPPORTS_FULL_VALUEADDS), true) +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRODUCT_MODULE := true +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := TelecommResCommon_Sys +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) +endif diff --git a/resource-overlay/common/Telephony/Android.bp b/resource-overlay/common/Telephony/Android.bp deleted file mode 100644 index 9a14af6..0000000 --- a/resource-overlay/common/Telephony/Android.bp +++ /dev/null @@ -1,9 +0,0 @@ -// -// SPDX-FileCopyrightText: 2024-2025 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - -runtime_resource_overlay { - name: "TelephonyResCommon_Sys", - product_specific: true, -} diff --git a/resource-overlay/common/Telephony/Android.mk b/resource-overlay/common/Telephony/Android.mk new file mode 100644 index 0000000..232f580 --- /dev/null +++ b/resource-overlay/common/Telephony/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRODUCT_MODULE := true +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := TelephonyResCommon_Sys +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/resource-overlay/common/Wifi/Android.bp b/resource-overlay/common/Wifi/Android.bp deleted file mode 100644 index 8132a05..0000000 --- a/resource-overlay/common/Wifi/Android.bp +++ /dev/null @@ -1,9 +0,0 @@ -// -// SPDX-FileCopyrightText: 2024-2025 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - -runtime_resource_overlay { - name: "WifiResCommon_Sys", - product_specific: true, -} diff --git a/resource-overlay/common/Wifi/Android.mk b/resource-overlay/common/Wifi/Android.mk new file mode 100644 index 0000000..3bff4e6 --- /dev/null +++ b/resource-overlay/common/Wifi/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_PRODUCT_MODULE := true +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := WifiResCommon_Sys +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/resource-overlay/holi/Android.mk b/resource-overlay/holi/Android.mk new file mode 100644 index 0000000..5053e7d --- /dev/null +++ b/resource-overlay/holi/Android.mk @@ -0,0 +1 @@ +include $(call all-subdir-makefiles) diff --git a/resource-overlay/holi/Frameworks/Android.bp b/resource-overlay/holi/Frameworks/Android.bp deleted file mode 100644 index 0e0b40d..0000000 --- a/resource-overlay/holi/Frameworks/Android.bp +++ /dev/null @@ -1,9 +0,0 @@ -// -// SPDX-FileCopyrightText: 2024-2025 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - -runtime_resource_overlay { - name: "FrameworksResTarget", - vendor: true, -} diff --git a/resource-overlay/holi/Frameworks/Android.mk b/resource-overlay/holi/Frameworks/Android.mk new file mode 100644 index 0000000..b5d09b0 --- /dev/null +++ b/resource-overlay/holi/Frameworks/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_VENDOR_MODULE := true +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := FrameworksResTarget +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/resource-overlay/holi/Wifi/Android.bp b/resource-overlay/holi/Wifi/Android.bp deleted file mode 100644 index 80f6d42..0000000 --- a/resource-overlay/holi/Wifi/Android.bp +++ /dev/null @@ -1,9 +0,0 @@ -// -// SPDX-FileCopyrightText: 2024-2025 The LineageOS Project -// SPDX-License-Identifier: Apache-2.0 -// - -runtime_resource_overlay { - name: "WifiResTarget", - vendor: true, -} diff --git a/resource-overlay/holi/Wifi/Android.mk b/resource-overlay/holi/Wifi/Android.mk new file mode 100644 index 0000000..b1fe113 --- /dev/null +++ b/resource-overlay/holi/Wifi/Android.mk @@ -0,0 +1,14 @@ +LOCAL_PATH:= $(call my-dir) +include $(CLEAR_VARS) + +LOCAL_VENDOR_MODULE := true +LOCAL_CERTIFICATE := platform + +LOCAL_SRC_FILES := $(call all-subdir-java-files) + +LOCAL_RESOURCE_DIR := $(LOCAL_PATH)/res + +LOCAL_PACKAGE_NAME := WifiResTarget +LOCAL_SDK_VERSION := current + +include $(BUILD_RRO_PACKAGE) diff --git a/rootdir/bin/init.qcom.early_boot.sh b/rootdir/bin/init.qcom.early_boot.sh index ad8f106..01d14b7 100644 --- a/rootdir/bin/init.qcom.early_boot.sh +++ b/rootdir/bin/init.qcom.early_boot.sh @@ -441,6 +441,15 @@ case "$target" in ;; esac +baseband=`getprop ro.baseband` +#enable atfwd daemon all targets except sda, apq, qcs +case "$baseband" in + "apq" | "sda" | "qcs" ) + setprop persist.vendor.radio.atfwd.start false;; + *) + setprop persist.vendor.radio.atfwd.start true;; +esac + #set default lcd density #Since lcd density has read only #property, it will not overwrite previous set diff --git a/rootdir/bin/init.qcom.sensors.sh b/rootdir/bin/init.qcom.sensors.sh new file mode 100644 index 0000000..dcc0556 --- /dev/null +++ b/rootdir/bin/init.qcom.sensors.sh @@ -0,0 +1,33 @@ +#!/vendor/bin/sh +# Copyright (c) 2020 The Linux Foundation. All rights reserved. +# +# Redistribution and use in source and binary forms, with or without +# modification, are permitted provided that the following conditions are met: +# * Redistributions of source code must retain the above copyright +# notice, this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright +# notice, this list of conditions and the following disclaimer in the +# documentation and/or other materials provided with the distribution. +# * Neither the name of The Linux Foundation nor +# the names of its contributors may be used to endorse or promote +# products derived from this software without specific prior written +# permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +# NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR +# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, +# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, +# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; +# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, +# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR +# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF +# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +# + +# +# Function to start sensors for SSC enabled platforms +# +cp /vendor/etc/sensors/scripts/* /data/vendor/sensors/scripts/ +chmod a+rw /data/vendor/sensors/scripts/* diff --git a/rootdir/etc/init/hw/init.mmi.rc b/rootdir/etc/init/hw/init.mmi.rc index 4aa6544..19ba89e 100644 --- a/rootdir/etc/init/hw/init.mmi.rc +++ b/rootdir/etc/init/hw/init.mmi.rc @@ -258,9 +258,6 @@ on post-fs-data mkdir /data/vendor/fpc 0700 system system mkdir /data/vendor/.fps 0770 system vendor_fingerp - mkdir /data/vendor/focaltech 0770 system system - restorecon /data/vendor/focaltech - # Required by touchRec for write the touch data mkdir /data/vendor/touchrec 0770 input input chown input input /data/vendor/touchrec/bootindex diff --git a/rootdir/etc/init/hw/init.qcom.rc b/rootdir/etc/init/hw/init.qcom.rc index 7a16641..5aad4d4 100644 --- a/rootdir/etc/init/hw/init.qcom.rc +++ b/rootdir/etc/init/hw/init.qcom.rc @@ -397,15 +397,11 @@ on property:sys.boot_completed=1 #Reinit lmkd to reconfigure lmkd properties setprop lmkd.reinit 1 - # Power hal - chown system system /sys/devices/system/cpu/cpu0/cpufreq/schedutil/up_rate_limit_us - chown system system /sys/devices/system/cpu/cpu0/cpufreq/schedutil/down_rate_limit_us - chown system system /sys/devices/system/cpu/cpu6/cpufreq/schedutil/up_rate_limit_us - chown system system /sys/devices/system/cpu/cpu6/cpufreq/schedutil/down_rate_limit_us - chmod 0664 /sys/devices/system/cpu/cpu0/cpufreq/schedutil/up_rate_limit_us - chmod 0664 /sys/devices/system/cpu/cpu0/cpufreq/schedutil/down_rate_limit_us - chmod 0664 /sys/devices/system/cpu/cpu6/cpufreq/schedutil/up_rate_limit_us - chmod 0664 /sys/devices/system/cpu/cpu6/cpufreq/schedutil/down_rate_limit_us +on property:persist.vendor.radio.atfwd.start=false + stop vendor.atfwd + +on property:vendor.radio.atfwd.start=false + stop vendor.atfwd # corefile limit on property:persist.debug.trace=1 @@ -576,6 +572,11 @@ on property:sys.boot_completed=1 on property:ro.vendor.ril.mbn_copy_completed=1 write /data/vendor/radio/copy_complete 1 +service vendor.atfwd /vendor/bin/ATFWD-daemon + class late_start + user system + group system radio + service hostapd_fst /vendor/bin/hw/hostapd -dd -g /data/vendor/wifi/hostapd/global class main capabilities NET_ADMIN NET_RAW diff --git a/rootdir/etc/ueventd.rc b/rootdir/etc/ueventd.rc index f8730d8..0e8fbba 100644 --- a/rootdir/etc/ueventd.rc +++ b/rootdir/etc/ueventd.rc @@ -342,9 +342,6 @@ firmware_directories /vendor/firmware_mnt/image/ /sys/class/fts/touch_aoi aoi_set 0660 root system /sys/class/fts/touch_aoi power_set 0660 root system -#Focaltech FPS -/dev/focaltech_fp 0660 system system - # Goodix fingerprint device /dev/goodix_fp 0660 system system diff --git a/sepolicy/vendor/device.te b/sepolicy/vendor/device.te index d39eb5b..fc470fd 100644 --- a/sepolicy/vendor/device.te +++ b/sepolicy/vendor/device.te @@ -1,7 +1,6 @@ # Fingerprint type egis_device, dev_type; type etsd_device, dev_type; -type focaltech_fp_device, dev_type; type goodix_device, dev_type; # Moto partitions diff --git a/sepolicy/vendor/file_contexts b/sepolicy/vendor/file_contexts index 3c2f631..8a3e731 100644 --- a/sepolicy/vendor/file_contexts +++ b/sepolicy/vendor/file_contexts @@ -56,16 +56,11 @@ /(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-service-ets u:object_r:hal_fingerprint_default_exec:s0 /(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-service-fpc u:object_r:hal_fingerprint_default_exec:s0 /(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-service\.fogos u:object_r:hal_fingerprint_default_exec:s0 -/(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-service\.rhodei u:object_r:hal_fingerprint_default_exec:s0 -/(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-service\.rhodep u:object_r:hal_fingerprint_default_exec:s0 /data/vendor/.fps(/.*)? u:object_r:fingerprint_vendor_data_file:s0 /data/vendor/egis(/.*)? u:object_r:fingerprint_vendor_data_file:s0 /data/vendor/fpc(/.*)? u:object_r:fingerprint_vendor_data_file:s0 -/data/vendor/focal(/.*)? u:object_r:fingerprint_vendor_data_file:s0 -/data/vendor/focaltech(/.*)? u:object_r:fingerprint_vendor_data_file:s0 /data/vendor/gf_data(/.*)? u:object_r:fingerprint_vendor_data_file:s0 /dev/esfp0 u:object_r:egis_device:s0 -/dev/focaltech_fp u:object_r:focaltech_fp_device:s0 /dev/goodix_fp u:object_r:goodix_device:s0 /sys/devices/soc/0.et320(/.*)? u:object_r:vendor_sysfs_fingerprint:s0 @@ -95,19 +90,17 @@ # Touch /(vendor|system/vendor)/bin/hw/vendor\.lineage\.touch@1\.0-service\.bangkk u:object_r:hal_lineage_touch_default_exec:s0 /(vendor|system/vendor)/bin/hw/vendor\.lineage\.touch@1\.0-service\.fogos u:object_r:hal_lineage_touch_default_exec:s0 -/(vendor|system/vendor)/bin/hw/vendor\.lineage\.touch@1\.0-service\.rhodei u:object_r:hal_lineage_touch_default_exec:s0 -/(vendor|system/vendor)/bin/hw/vendor\.lineage\.touch@1\.0-service\.rhodep u:object_r:hal_lineage_touch_default_exec:s0 /sys/devices/platform/soc/4a80000\.spi/spi_master/spi0/spi0\.[01]/touchscreen/primary(/.*)? u:object_r:vendor_sysfs_touchpanel:s0 # Thermal /dev/mmi_sys_temp u:object_r:vendor_thermal_device:s0 +/(vendor|system/vendor)/bin/hw/android\.hardware\.thermal@2\.0-service\.mock u:object_r:hal_thermal_default_exec:s0 # Vendor init scripts /(vendor|system/vendor)/bin/load_touch\.sh u:object_r:vendor_qti_init_shell_exec:s0 /(vendor|system/vendor)/bin/init\.mmi\.laser\.sh u:object_r:vendor_mmi_laser_exec:s0 /(vendor|system/vendor)/bin/init\.mmi\.touch\.sh u:object_r:vendor_init_touch_exec:s0 /(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-goodixservice u:object_r:hal_fingerprint_default_exec:s0 -/(vendor|system/vendor)/bin/hw/android\.hardware\.biometrics\.fingerprint@2\.1-focalservice u:object_r:hal_fingerprint_default_exec:s0 /(vendor|system/vendor)/bin/init\.oem\.(fingerprint2|fingerprint\.overlay)\.sh u:object_r:vendor_init_fingerprint_exec:s0 /(vendor|system/vendor)/bin/init\.oem\.hw\.sh u:object_r:vendor_init_hw_exec:s0 @@ -117,7 +110,6 @@ # Vibrator /sys/devices/platform/soc/990000.i2c/i2c-1/1-005a/leds/vibrator(/.*)? u:object_r:vendor_sysfs_vibrator:s0 -/sys/devices/platform/soc/soc:ldo_vib/leds/vibrator(/.*)? u:object_r:vendor_sysfs_vibrator:s0 # Wakeups /sys/devices/virtual/input/input[0-9]+/wakeup[0-9]+(/.*)? u:object_r:sysfs_wakeup:s0 diff --git a/sepolicy/vendor/genfs_contexts b/sepolicy/vendor/genfs_contexts index 83748fc..917e220 100644 --- a/sepolicy/vendor/genfs_contexts +++ b/sepolicy/vendor/genfs_contexts @@ -69,9 +69,12 @@ genfscon sysfs /devices/virtual/touchscreen genfscon sysfs /devices/platform/soc/a94000.i2c/i2c-2/2-0049/touchscreen u:object_r:vendor_sysfs_touchpanel:s0 genfscon sysfs /devices/platform/soc/4a80000.spi/spi_master/spi0/spi0.[01] u:object_r:vendor_sysfs_touchpanel:s0 +# USB +genfscon sysfs /devices/platform/soc/4e00000.ssusb/mode u:object_r:vendor_sysfs_usb_device:s0 + # Vibrator genfscon sysfs /devices/platform/soc/984000.i2c/i2c-0/0-005a/leds/vibrator u:object_r:sysfs_vibrator:s0 -genfscon sysfs /devices/platform/soc/soc:ldo_vib/leds/vibrator u:object_r:vendor_sysfs_vibrator:s0 +genfscon sysfs /sys/devices/platform/soc/soc:ldo_vib/leds/vibrator(/.*)? u:object_r:vendor_sysfs_vibrator:s0 # Wakeup genfscon sysfs /devices/platform/soc/984000.i2c/i2c-0/0-005a/wakeup/wakeup u:object_r:sysfs_wakeup:s0 @@ -83,10 +86,10 @@ genfscon sysfs /devices/platform/soc/soc:mmi,charger/wakeup genfscon sysfs /devices/platform/soc/soc:mmi,charger/power/wakeup u:object_r:sysfs_wakeup:s0 genfscon sysfs /devices/platform/soc/soc:mmi,charger/power_supply/mmi_battery/wakeup u:object_r:sysfs_wakeup:s0 genfscon sysfs /devices/platform/soc/soc:mmi,charger/power_supply/mmi_battery/power/wakeup u:object_r:sysfs_wakeup:s0 -genfscon sysfs /devices/platform/soc/soc:mmi,discrete-charging/power_supply/battery/wakeup u:object_r:sysfs_wakeup:s0 genfscon sysfs /devices/platform/soc/1c40000.qcom,spmi/spmi-0/spmi0-02/1c40000.qcom,spmi:qcom,pm7250b@2:qcom,qpnp-smb5-mmi/power_supply/battery/wakeup u:object_r:sysfs_wakeup:s0 genfscon sysfs /devices/platform/soc/1c40000.qcom,spmi/spmi-0/spmi0-02/1c40000.qcom,spmi:qcom,pm7250b@2:qcom,qpnp-smb5-mmi/power_supply/mmi_battery/wakeup u:object_r:sysfs_wakeup:s0 genfscon sysfs /devices/platform/soc/1c40000.qcom,spmi/spmi-0/spmi0-02/1c40000.qcom,spmi:qcom,pm7250b@2:qcom,qpnp-smb5/power_supply/qcom_battery/wakeup u:object_r:sysfs_wakeup:s0 +genfscon sysfs /devices/platform/soc/1c40000.qcom,spmi/spmi-0/spmi0-02/1c40000.qcom,spmi:qcom,pm7250b@2:qcom,qpnp-smb5/power_supply/usb/wakeup u:object_r:sysfs_wakeup:s0 genfscon sysfs /devices/platform/soc/4c90000.i2c/i2c-2/2-006a/power_supply/bq25960-standalone/wakeup u:object_r:sysfs_wakeup:s0 genfscon sysfs /devices/platform/soc/soc:mmi_chrg_manager/power_supply/mmi_chrg_manager/wakeup u:object_r:sysfs_wakeup:s0 genfscon sysfs /devices/platform/soc/soc:qcom,msm-audio-apr/soc:qcom,msm-audio-apr:qcom,q6core-audio/soc:qcom,msm-audio-apr:qcom,q6core-audio:sound/Listen u:object_r:sysfs_wakeup:s0 diff --git a/sepolicy/vendor/hal_fingerprint_default.te b/sepolicy/vendor/hal_fingerprint_default.te index d16c49c..0d79bb5 100644 --- a/sepolicy/vendor/hal_fingerprint_default.te +++ b/sepolicy/vendor/hal_fingerprint_default.te @@ -1,14 +1,12 @@ allow hal_fingerprint_default { etsd_device egis_device - focaltech_fp_device goodix_device tee_device graphics_device }: chr_file rw_file_perms; allow hal_fingerprint_default self:binder { call transfer }; -allow hal_fingerprint_default self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl; allow hal_fingerprint_default self:netlink_socket create_socket_perms_no_ioctl; r_dir_file(hal_fingerprint_default, firmware_file) get_prop(hal_fingerprint_default, build_bootimage_prop) @@ -21,9 +19,6 @@ allow hal_fingerprint_default uhid_device:chr_file rw_file_perms; allow hal_fingerprint_default vendor_sysfs_fingerprint:{ file lnk_file } read; allow hal_fingerprint_default vendor_data_tzstorage_file:dir rw_dir_perms; allow hal_fingerprint_default vendor_data_tzstorage_file:file create_file_perms; -allow hal_fingerprint_default vndbinder_device:chr_file rw_file_perms; -binder_call(hal_fingerprint_default, vndservicemanager); -allow hal_fingerprint_default hal_fingerprint_vndservice:service_manager add; binder_call(hal_fingerprint_default, hal_fingerprint_default) binder_call(hal_fingerprint_default, hal_health_default) diff --git a/sepolicy/vendor/hal_thermal_default.te b/sepolicy/vendor/hal_thermal_default.te new file mode 100644 index 0000000..2ccabe4 --- /dev/null +++ b/sepolicy/vendor/hal_thermal_default.te @@ -0,0 +1,8 @@ +allow hal_thermal_default sysfs_thermal:dir r_dir_perms; +allow hal_thermal_default sysfs_thermal:file rw_file_perms; +allow hal_thermal_default proc_stat:file r_file_perms; + +allow hal_thermal_default self:netlink_kobject_uevent_socket create_socket_perms_no_ioctl; + +# read thermal config +get_prop(hal_thermal_default, vendor_thermal_prop) diff --git a/sepolicy/vendor/property.te b/sepolicy/vendor/property.te index 167417c..bb50574 100644 --- a/sepolicy/vendor/property.te +++ b/sepolicy/vendor/property.te @@ -5,3 +5,6 @@ vendor_internal_prop(vendor_mot_fingerprint_prop); vendor_internal_prop(vendor_mot_hw_prop); vendor_internal_prop(vendor_mot_touch_prop); vendor_internal_prop(vendor_mot_nfc_prop); + +# Thermal engine +vendor_internal_prop(vendor_thermal_prop) diff --git a/sepolicy/vendor/property_contexts b/sepolicy/vendor/property_contexts index f1e63b1..252414c 100644 --- a/sepolicy/vendor/property_contexts +++ b/sepolicy/vendor/property_contexts @@ -21,3 +21,6 @@ vendor.nfc.fw_status u:object_r:vendor_mot_nfc_prop:s0 persist.vendor.hardware.fingerprint u:object_r:vendor_mot_fingerprint_prop:s0 vendor.hw.fps.ident u:object_r:vendor_mot_fingerprint_prop:s0 vendor.hw.fingerprint.status u:object_r:vendor_mot_fingerprint_prop:s0 + +# Thermal engine +vendor.thermal.config u:object_r:vendor_thermal_prop:s0 diff --git a/sepolicy/vendor/thermal-engine.te b/sepolicy/vendor/thermal-engine.te new file mode 100644 index 0000000..7791706 --- /dev/null +++ b/sepolicy/vendor/thermal-engine.te @@ -0,0 +1,7 @@ +allow vendor_thermal-engine { proc_stat proc_loadavg }:file r_file_perms; +allow vendor_thermal-engine vendor_thermal_device:chr_file rw_file_perms; +rw_dir_file(vendor_thermal-engine, vendor_sysfs_battery_supply) +rw_dir_file(vendor_thermal-engine, vendor_sysfs_usb_supply) + +set_prop(vendor_thermal-engine, vendor_thermal_prop); +r_dir_file(vendor_thermal-engine, sysfs_thermal) diff --git a/sepolicy/vendor/vendor_thermal-engine.te b/sepolicy/vendor/vendor_thermal-engine.te deleted file mode 100644 index b76e121..0000000 --- a/sepolicy/vendor/vendor_thermal-engine.te +++ /dev/null @@ -1,4 +0,0 @@ -allow vendor_thermal-engine { proc_stat proc_loadavg }:file r_file_perms; -allow vendor_thermal-engine vendor_thermal_device:chr_file rw_file_perms; -r_dir_file(vendor_thermal-engine, vendor_sysfs_battery_supply) -r_dir_file(vendor_thermal-engine, vendor_sysfs_usb_supply) diff --git a/sepolicy/vendor/vndservice.te b/sepolicy/vendor/vndservice.te deleted file mode 100644 index 4e57aa3..0000000 --- a/sepolicy/vendor/vndservice.te +++ /dev/null @@ -1 +0,0 @@ -type hal_fingerprint_vndservice, vndservice_manager_type; diff --git a/sepolicy/vendor/vndservice_contexts b/sepolicy/vendor/vndservice_contexts deleted file mode 100644 index ac0bbc3..0000000 --- a/sepolicy/vendor/vndservice_contexts +++ /dev/null @@ -1 +0,0 @@ -FocalFingerprintService u:object_r:hal_fingerprint_vndservice:s0 diff --git a/setup-makefiles.py b/setup-makefiles.py deleted file mode 100755 index 32947cf..0000000 --- a/setup-makefiles.py +++ /dev/null @@ -1 +0,0 @@ -#!./extract-files.py --regenerate_makefiles diff --git a/setup-makefiles.sh b/setup-makefiles.sh new file mode 100755 index 0000000..c64c683 --- /dev/null +++ b/setup-makefiles.sh @@ -0,0 +1,52 @@ +#!/bin/bash +# +# SPDX-FileCopyrightText: 2016 The CyanogenMod Project +# SPDX-FileCopyrightText: 2017-2024 The LineageOS Project +# +# SPDX-License-Identifier: Apache-2.0 +# + +set -e + +# Load extract_utils and do some sanity checks +MY_DIR="${BASH_SOURCE%/*}" +if [[ ! -d "${MY_DIR}" ]]; then MY_DIR="${PWD}"; fi + +ANDROID_ROOT="${MY_DIR}/../../.." + +HELPER="${ANDROID_ROOT}/tools/extract-utils/extract_utils.sh" +if [ ! -f "${HELPER}" ]; then + echo "Unable to find helper script at ${HELPER}" + exit 1 +fi +source "${HELPER}" + +# Initialize the helper for common +setup_vendor "${DEVICE_COMMON}" "${VENDOR_COMMON:-$VENDOR}" "${ANDROID_ROOT}" true + +# Warning headers and guards +write_headers "bangkk fogos" + +# The standard common blobs +write_makefiles "${MY_DIR}/proprietary-files.txt" + +# Finish +write_footers + +if [ -s "${MY_DIR}/../../${VENDOR}/${DEVICE}/proprietary-files.txt" ]; then + # Reinitialize the helper for device + setup_vendor "${DEVICE}" "${VENDOR}" "${ANDROID_ROOT}" false + + # Warning headers and guards + write_headers + + # The standard device blobs + write_makefiles "${MY_DIR}/../../${VENDOR}/${DEVICE}/proprietary-files.txt" + + if [ -f "${MY_DIR}/../../${VENDOR}/${DEVICE}/proprietary-firmware.txt" ]; then + append_firmware_calls_to_makefiles "${MY_DIR}/../../${VENDOR}/${DEVICE}/proprietary-firmware.txt" + fi + + # Finish + write_footers +fi diff --git a/update-sha1sums.py b/update-sha1sums.py new file mode 100755 index 0000000..e2d9ae5 --- /dev/null +++ b/update-sha1sums.py @@ -0,0 +1,73 @@ +#!/usr/bin/env python +# +# Copyright (C) 2016 The CyanogenMod Project +# Copyright (C) 2017-2020 The LineageOS Project +# +# 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. +# + +import os +import sys +from hashlib import sha1 + +device='sm6375-common' +vendor='motorola' + +with open('proprietary-files.txt', 'r') as f: + lines = f.read().splitlines() +vendorPath = '../../../vendor/' + vendor + '/' + device + '/proprietary' +needSHA1 = False + + +def cleanup(): + for index, line in enumerate(lines): + # Skip empty or commented lines + if len(line) == 0 or line[0] == '#' or '|' not in line: + continue + + # Drop SHA1 hash, if existing + lines[index] = line.split('|')[0] + + +def update(): + for index, line in enumerate(lines): + # Skip empty lines + if len(line) == 0: + continue + + # Check if we need to set SHA1 hash for the next files + if line[0] == '#': + needSHA1 = (' - from' in line) + continue + + if needSHA1: + # Remove existing SHA1 hash + line = line.split('|')[0] + + filePath = line.split(';')[0].split(':')[-1] + if filePath[0] == '-': + filePath = filePath[1:] + + with open(os.path.join(vendorPath, filePath), 'rb') as f: + hash = sha1(f.read()).hexdigest() + + lines[index] = '%s|%s' % (line, hash) + + +if len(sys.argv) == 2 and sys.argv[1] == '-c': + cleanup() +else: + update() + +with open('proprietary-files.txt', 'w') as file: + file.write('\n'.join(lines) + '\n')